Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
samo-lin opened this issue Nov 8, 2019 · 0 comments · Fixed by #53165
Closed

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

samo-lin opened this issue Nov 8, 2019 · 0 comments · Fixed by #53165
Labels
error messages Better, more actionable error messages

Comments

@samo-lin
Copy link

samo-lin commented Nov 8, 2019

Problem

'MethodError' message does not show 'Closest candidates' if the function/method has more than one argument. In the following you can find some examples which rely on the CUDA packages; however @maleadt pointed out here that this issue is not specific for the CUDA packages.

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)
@kshyatt kshyatt added the error messages Better, more actionable error messages label Nov 8, 2019
efwright added a commit to efwright/julia that referenced this issue Dec 3, 2019
vtjnash added a commit that referenced this issue Feb 1, 2024
Updated version of #33793

Closes #33793
Fixes #33793
Co-authored-by: Eric Wright <efwright@udel.edu>
vtjnash added a commit that referenced this issue Feb 3, 2024
Updated version of #33793. Always show up to 3 methods, even if no
arguments types match on some of them, but rank ones with fewer
arguments before those with more arguments.

Closes #33793
Fixes #33793
Fixes #46236
Co-authored-by: Eric Wright <efwright@udel.edu>
vtjnash added a commit that referenced this issue Feb 10, 2024
Updated version of #33793. Always show up to 3 methods, even if no
arguments types match on some of them, but rank ones with fewer
arguments before those with more arguments.

Closes #33793
Fixes #33793
Fixes #46236
Co-authored-by: Eric Wright <efwright@udel.edu>
(this diff best viewed with whitespace ignored)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
error messages Better, more actionable error messages
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants