Skip to content
This repository has been archived by the owner on May 27, 2021. It is now read-only.

'MethodError' message doesn't show 'Closest candidates' #493

Closed
samo-lin opened this issue Nov 8, 2019 · 2 comments
Closed

'MethodError' message doesn't show 'Closest candidates' #493

samo-lin opened this issue Nov 8, 2019 · 2 comments

Comments

@samo-lin
Copy link

samo-lin commented Nov 8, 2019

Problem

'MethodError' message doesn't show 'Closest candidates' if the function/method has more than one argument. Here is an illustration with floats:

$> julia

julia> using CUDAnative, CuArrays


julia> f1(a::Float32) = return
f1 (generic function with 1 method)

julia> f2(a::Float32, b::Float32) = return
f2 (generic function with 1 method)

julia> # Call with arguments of correct type.
       a = Float32(3.0)
3.0f0

julia> @cuda f1(a)

julia> @cuda f2(a, a)

julia> # Call with arguments of wrong type.
       a = Float64(3.0)
3.0

julia> @cuda f1(a)
ERROR: MethodError: no method matching f1(::Type{Float64})
Closest candidates are:
  f1(!Matched::Float32) at REPL[2]:1
Stacktrace:
 [1] method_age(::Function, ::Tuple{DataType}) at /apps/dom/UES/jenkins/7.0.UP01/gpu/easybuild/software/Julia/1.2.0-CrayGNU-19.10-cuda-10.1/extensions/packages/CUDAnative/Lr0yj/src/execution.jl:76
 [2] macro expansion at /apps/dom/UES/jenkins/7.0.UP01/gpu/easybuild/software/Julia/1.2.0-CrayGNU-19.10-cuda-10.1/extensions/packages/CUDAnative/Lr0yj/src/execution.jl:372 [inlined]
 [3] #cufunction#176(::Nothing, ::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::typeof(cufunction), ::typeof(f1), ::Type{Tuple{Float64}}) at /apps/dom/UES/jenkins/7.0.UP01/gpu/easybuild/software/Julia/1.2.0-CrayGNU-19.10-cuda-10.1/extensions/packages/CUDAnative/Lr0yj/src/execution.jl:357
 [4] cufunction(::Function, ::Type) at /apps/dom/UES/jenkins/7.0.UP01/gpu/easybuild/software/Julia/1.2.0-CrayGNU-19.10-cuda-10.1/extensions/packages/CUDAnative/Lr0yj/src/execution.jl:357
 [5] top-level scope at /apps/dom/UES/jenkins/7.0.UP01/gpu/easybuild/software/Julia/1.2.0-CrayGNU-19.10-cuda-10.1/extensions/packages/CUDAnative/Lr0yj/src/execution.jl:174
 [6] top-level scope at gcutils.jl:87
 [7] top-level scope at /apps/dom/UES/jenkins/7.0.UP01/gpu/easybuild/software/Julia/1.2.0-CrayGNU-19.10-cuda-10.1/extensions/packages/CUDAnative/Lr0yj/src/execution.jl:171

julia> @cuda f2(a, a)
ERROR: MethodError: no method matching f2(::Type{Float64}, ::Type{Float64})
Stacktrace:
 [1] method_age(::Function, ::Tuple{DataType,DataType}) at /apps/dom/UES/jenkins/7.0.UP01/gpu/easybuild/software/Julia/1.2.0-CrayGNU-19.10-cuda-10.1/extensions/packages/CUDAnative/Lr0yj/src/execution.jl:76
 [2] macro expansion at /apps/dom/UES/jenkins/7.0.UP01/gpu/easybuild/software/Julia/1.2.0-CrayGNU-19.10-cuda-10.1/extensions/packages/CUDAnative/Lr0yj/src/execution.jl:372 [inlined]
 [3] #cufunction#176(::Nothing, ::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::typeof(cufunction), ::typeof(f2), ::Type{Tuple{Float64,Float64}}) at /apps/dom/UES/jenkins/7.0.UP01/gpu/easybuild/software/Julia/1.2.0-CrayGNU-19.10-cuda-10.1/extensions/packages/CUDAnative/Lr0yj/src/execution.jl:357
 [4] cufunction(::Function, ::Type) at /apps/dom/UES/jenkins/7.0.UP01/gpu/easybuild/software/Julia/1.2.0-CrayGNU-19.10-cuda-10.1/extensions/packages/CUDAnative/Lr0yj/src/execution.jl:357
 [5] top-level scope at /apps/dom/UES/jenkins/7.0.UP01/gpu/easybuild/software/Julia/1.2.0-CrayGNU-19.10-cuda-10.1/extensions/packages/CUDAnative/Lr0yj/src/execution.jl:174
 [6] top-level scope at gcutils.jl:87
 [7] top-level scope at /apps/dom/UES/jenkins/7.0.UP01/gpu/easybuild/software/Julia/1.2.0-CrayGNU-19.10-cuda-10.1/extensions/packages/CUDAnative/Lr0yj/src/execution.jl:171

and here is an illustration with CuArrays:

$> julia

julia> using CUDAnative, CuArrays


julia> f3(A::CuDeviceArray{Float32}) = return
f3 (generic function with 1 method)

julia> f4(A::CuDeviceArray{Float32}, B::CuDeviceArray{Float32}) = return
f4 (generic function with 1 method)

julia> # Call with arguments of correct type.
       A = CuArrays.zeros(Float32, 3)
3-element CuArray{Float32,1}:
 0.0
 0.0
 0.0

julia> @cuda f3(A)

julia> @cuda f4(A, A)

julia> # Call with arguments of wrong type.
       A = CuArrays.zeros(Float64, 3)
3-element CuArray{Float64,1}:
 0.0
 0.0
 0.0

julia> @cuda f3(A)
ERROR: MethodError: no method matching f3(::Type{CuDeviceArray{Float64,1,CUDAnative.AS.Global}})
Closest candidates are:
  f3(!Matched::CuDeviceArray{Float32,N,A} where A where N) at REPL[2]:1
Stacktrace:
 [1] method_age(::Function, ::Tuple{DataType}) at /apps/dom/UES/jenkins/7.0.UP01/gpu/easybuild/software/Julia/1.2.0-CrayGNU-19.10-cuda-10.1/extensions/packages/CUDAnative/Lr0yj/src/execution.jl:76
 [2] macro expansion at /apps/dom/UES/jenkins/7.0.UP01/gpu/easybuild/software/Julia/1.2.0-CrayGNU-19.10-cuda-10.1/extensions/packages/CUDAnative/Lr0yj/src/execution.jl:372 [inlined]
 [3] #cufunction#176(::Nothing, ::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::typeof(cufunction), ::typeof(f3), ::Type{Tuple{CuDeviceArray{Float64,1,CUDAnative.AS.Global}}}) at /apps/dom/UES/jenkins/7.0.UP01/gpu/easybuild/software/Julia/1.2.0-CrayGNU-19.10-cuda-10.1/extensions/packages/CUDAnative/Lr0yj/src/execution.jl:357
 [4] cufunction(::Function, ::Type) at /apps/dom/UES/jenkins/7.0.UP01/gpu/easybuild/software/Julia/1.2.0-CrayGNU-19.10-cuda-10.1/extensions/packages/CUDAnative/Lr0yj/src/execution.jl:357
 [5] top-level scope at /apps/dom/UES/jenkins/7.0.UP01/gpu/easybuild/software/Julia/1.2.0-CrayGNU-19.10-cuda-10.1/extensions/packages/CUDAnative/Lr0yj/src/execution.jl:174
 [6] top-level scope at gcutils.jl:87
 [7] top-level scope at /apps/dom/UES/jenkins/7.0.UP01/gpu/easybuild/software/Julia/1.2.0-CrayGNU-19.10-cuda-10.1/extensions/packages/CUDAnative/Lr0yj/src/execution.jl:171

julia> @cuda f4(A, A)
ERROR: MethodError: no method matching f4(::Type{CuDeviceArray{Float64,1,CUDAnative.AS.Global}}, ::Type{CuDeviceArray{Float64,1,CUDAnative.AS.Global}})
Stacktrace:
 [1] method_age(::Function, ::Tuple{DataType,DataType}) at /apps/dom/UES/jenkins/7.0.UP01/gpu/easybuild/software/Julia/1.2.0-CrayGNU-19.10-cuda-10.1/extensions/packages/CUDAnative/Lr0yj/src/execution.jl:76
 [2] macro expansion at /apps/dom/UES/jenkins/7.0.UP01/gpu/easybuild/software/Julia/1.2.0-CrayGNU-19.10-cuda-10.1/extensions/packages/CUDAnative/Lr0yj/src/execution.jl:372 [inlined]
 [3] #cufunction#176(::Nothing, ::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::typeof(cufunction), ::typeof(f4), ::Type{Tuple{CuDeviceArray{Float64,1,CUDAnative.AS.Global},CuDeviceArray{Float64,1,CUDAnative.AS.Global}}}) at /apps/dom/UES/jenkins/7.0.UP01/gpu/easybuild/software/Julia/1.2.0-CrayGNU-19.10-cuda-10.1/extensions/packages/CUDAnative/Lr0yj/src/execution.jl:357
 [4] cufunction(::Function, ::Type) at /apps/dom/UES/jenkins/7.0.UP01/gpu/easybuild/software/Julia/1.2.0-CrayGNU-19.10-cuda-10.1/extensions/packages/CUDAnative/Lr0yj/src/execution.jl:357
 [5] top-level scope at /apps/dom/UES/jenkins/7.0.UP01/gpu/easybuild/software/Julia/1.2.0-CrayGNU-19.10-cuda-10.1/extensions/packages/CUDAnative/Lr0yj/src/execution.jl:174
 [6] top-level scope at gcutils.jl:87
 [7] top-level scope at /apps/dom/UES/jenkins/7.0.UP01/gpu/easybuild/software/Julia/1.2.0-CrayGNU-19.10-cuda-10.1/extensions/packages/CUDAnative/Lr0yj/src/execution.jl:171


Printing always the 'Closest candidates' would be particularly useful for debugging something like this:

julia> using CUDAnative, CuArrays


julia> f5(A::CuArray{Float32}, B::CuArray{Float32}) = return  # Function declaration uses the wrong type (should use CuDeviceArray)
f5 (generic function with 1 method)

julia> # Call with arguments of correct type, but the function declaration uses the wrong type.
       A = CuArrays.zeros(Float32, 3)
3-element CuArray{Float32,1}:
 0.0
 0.0
 0.0

julia> @cuda f5(A, A)
ERROR: MethodError: no method matching f5(::Type{CuDeviceArray{Float32,1,CUDAnative.AS.Global}}, ::Type{CuDeviceArray{Float32,1,CUDAnative.AS.Global}})
Stacktrace:
 [1] method_age(::Function, ::Tuple{DataType,DataType}) at /apps/dom/UES/jenkins/7.0.UP01/gpu/easybuild/software/Julia/1.2.0-CrayGNU-19.10-cuda-10.1/extensions/packages/CUDAnative/Lr0yj/src/execution.jl:76
 [2] macro expansion at /apps/dom/UES/jenkins/7.0.UP01/gpu/easybuild/software/Julia/1.2.0-CrayGNU-19.10-cuda-10.1/extensions/packages/CUDAnative/Lr0yj/src/execution.jl:372 [inlined]
 [3] #cufunction#176(::Nothing, ::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::typeof(cufunction), ::typeof(f5), ::Type{Tuple{CuDeviceArray{Float32,1,CUDAnative.AS.Global},CuDeviceArray{Float32,1,CUDAnative.AS.Global}}}) at /apps/dom/UES/jenkins/7.0.UP01/gpu/easybuild/software/Julia/1.2.0-CrayGNU-19.10-cuda-10.1/extensions/packages/CUDAnative/Lr0yj/src/execution.jl:357
 [4] cufunction(::Function, ::Type) at /apps/dom/UES/jenkins/7.0.UP01/gpu/easybuild/software/Julia/1.2.0-CrayGNU-19.10-cuda-10.1/extensions/packages/CUDAnative/Lr0yj/src/execution.jl:357
 [5] top-level scope at /apps/dom/UES/jenkins/7.0.UP01/gpu/easybuild/software/Julia/1.2.0-CrayGNU-19.10-cuda-10.1/extensions/packages/CUDAnative/Lr0yj/src/execution.jl:174
 [6] top-level scope at gcutils.jl:87
 [7] top-level scope at /apps/dom/UES/jenkins/7.0.UP01/gpu/easybuild/software/Julia/1.2.0-CrayGNU-19.10-cuda-10.1/extensions/packages/CUDAnative/Lr0yj/src/execution.jl:171

Suggestion

Printing always the 'Closest candidates'.

Appendix

Code for reproduction without output (to copy and paste to REPL):

using CUDAnative, CuArrays

f1(a::Float32) = return
f2(a::Float32, b::Float32) = return

# Call with arguments of correct type.
a = Float32(3.0)
@cuda f1(a)
@cuda f2(a, a)

# Call with arguments of wrong type.
a = Float64(3.0)
@cuda f1(a)
@cuda f2(a, a)
using CUDAnative, CuArrays

f3(A::CuDeviceArray{Float32}) = return
f4(A::CuDeviceArray{Float32}, B::CuDeviceArray{Float32}) = return

# Call with arguments of correct type.
A = CuArrays.zeros(Float32, 3)
@cuda f3(A)
@cuda f4(A, A)

# Call with arguments of wrong type.
A = CuArrays.zeros(Float64, 3)
@cuda f3(A)
@cuda f4(A, A)
using CUDAnative, CuArrays

f5(A::CuArray{Float32}, B::CuArray{Float32}) = return  # Function declaration uses the wrong type (should use CuDeviceArray)

# Call with arguments of correct type, but the function declaration uses the wrong type.
A = CuArrays.zeros(Float32, 3)
@cuda f5(A, A)
@maleadt
Copy link
Member

maleadt commented Nov 8, 2019

You don't get these on the CPU either:

julia> f1(a)
ERROR: MethodError: no method matching f1(::Float64)
Closest candidates are:
  f1(::Float32) at REPL[22]:1
Stacktrace:
 [1] top-level scope at REPL[30]:1

julia> f2(a, a)
ERROR: MethodError: no method matching f2(::Float64, ::Float64)
Stacktrace:
 [1] top-level scope at REPL[31]:1

And we just reuse the MethodError infrastructure from there. Note that the output here shows an error with the kind of MethodError generated, which has been fixed in #472. But if you want better output for the MethodError suggestions, please file an issue upstream (on the Julia issue tracker).

@maleadt maleadt closed this as completed Nov 8, 2019
@samo-lin
Copy link
Author

samo-lin commented Nov 8, 2019

OK, sorry, I didn't realize that this is not an issue specific to CUDAnative. I will therefore open an issue there. Thanks!!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants