KernelAbstractions.jl icon indicating copy to clipboard operation
KernelAbstractions.jl copied to clipboard

MethodError: no method matching __index_Local_Linear() from a CPU kernel

Open tkf opened this issue 4 years ago • 2 comments

I get MethodError: no method matching __index_Local_Linear() from code that I expect to work (g):

julia> @kernel function f(xs)
           i = @index(Local, Linear)
           xs[i] = 1
       end
f (generic function with 5 methods)

julia> @kernel function g(xs)
           xs[@index(Local, Linear)] = 1
       end
g (generic function with 5 methods)

julia> xs = zeros(3); f(CPU())(xs; ndrange = 3) |> wait; xs
3-element Array{Float64,1}:
 1.0
 1.0
 1.0

julia> xs = zeros(3); g(CPU())(xs; ndrange = 3) |> wait; xs
ERROR: TaskFailedException:
MethodError: no method matching __index_Local_Linear()

Looking at @macroexpand, the function f that works contains KernelAbstractions.__index_Local_Linear(var"##I#253") while the function gthat throws contains KernelAbstractions.__index_Local_Linear()


Full session

shell> git log -n1 --oneline
b2f7105 (HEAD -> master, origin/master) performant matmul example for KA (#208)

(@v1.5) pkg> activate .
 Activating environment at `~/.julia/dev/KernelAbstractions/Project.toml`

julia> using KernelAbstractions

julia> @macroexpand @kernel function f(xs)
           i = @index(Local, Linear)
           xs[i] = 1
       end
quote
    function cpu_f(xs; )
        let
            $(Expr(:aliasscope))
            begin
                var"##N#254" = length((KernelAbstractions.__workitems_iterspace)())
                begin
                    #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:262 =#
                    for var"##I#253" = (KernelAbstractions.__workitems_iterspace)()
                        #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:263 =#
                        (KernelAbstractions.__validindex)(var"##I#253") || continue
                        #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:264 =#
                        i = KernelAbstractions.__index_Local_Linear(var"##I#253")
                        #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:265 =#
                        xs[i] = 1
                    end
                end
            end
            $(Expr(:popaliasscope))
            return nothing
        end
    end
    function gpu_f(xs; )
        let
            #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:79 =#
            if (KernelAbstractions.__validindex)()
                #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:80 =#
                begin
                    #= REPL[5]:1 =#
                    #= REPL[5]:2 =#
                    i = KernelAbstractions.__index_Local_Linear()
                    #= REPL[5]:3 =#
                    xs[i] = 1
                end
            end
            #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:82 =#
            return nothing
        end
    end
    begin
        #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:52 =#
        if !($(Expr(:isdefined, :f)))
            #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:53 =#
            begin
                $(Expr(:meta, :doc))
                f(dev::Device) = begin
                        #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:53 =#
                        f(dev, (KernelAbstractions.NDIteration.DynamicSize)(), (KernelAbstractions.NDIteration.DynamicSize)())
                    end
            end
            #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:54 =#
            f(dev::Device, size) = begin
                    #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:54 =#
                    f(dev, (KernelAbstractions.NDIteration.StaticSize)(size), (KernelAbstractions.NDIteration.DynamicSize)())
                end
            #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:55 =#
            f(dev::Device, size, range) = begin
                    #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:55 =#
                    f(dev, (KernelAbstractions.NDIteration.StaticSize)(size), (KernelAbstractions.NDIteration.StaticSize)(range))
                end
            #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:56 =#
            function f(::Device, ::S, ::NDRange) where {Device <: CPU, S <: KernelAbstractions.NDIteration._Size, NDRange <: KernelAbstractions.NDIteration._Size}
                #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:56 =#
                #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:57 =#
                return (KernelAbstractions.Kernel){Device, S, NDRange, typeof(cpu_f)}(cpu_f)
            end
            #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:59 =#
            function f(::Device, ::S, ::NDRange) where {Device <: GPU, S <: KernelAbstractions.NDIteration._Size, NDRange <: KernelAbstractions.NDIteration._Size}
                #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:59 =#
                #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:60 =#
                return (KernelAbstractions.Kernel){Device, S, NDRange, typeof(gpu_f)}(gpu_f)
            end
        end
    end
end

julia> @macroexpand @kernel function g(xs)
           xs[@index(Local, Linear)] = 1
       end
quote
    function cpu_g(xs; )
        let
            $(Expr(:aliasscope))
            begin
                var"##N#256" = length((KernelAbstractions.__workitems_iterspace)())
                begin
                    #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:262 =#
                    for var"##I#255" = (KernelAbstractions.__workitems_iterspace)()
                        #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:263 =#
                        (KernelAbstractions.__validindex)(var"##I#255") || continue
                        #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:264 =#
                        #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:265 =#
                        xs[KernelAbstractions.__index_Local_Linear()] = 1
                    end
                end
            end
            $(Expr(:popaliasscope))
            return nothing
        end
    end
    function gpu_g(xs; )
        let
            #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:79 =#
            if (KernelAbstractions.__validindex)()
                #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:80 =#
                begin
                    #= REPL[6]:1 =#
                    #= REPL[6]:2 =#
                    xs[KernelAbstractions.__index_Local_Linear()] = 1
                end
            end
            #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:82 =#
            return nothing
        end
    end
    begin
        #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:52 =#
        if !($(Expr(:isdefined, :g)))
            #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:53 =#
            begin
                $(Expr(:meta, :doc))
                g(dev::Device) = begin
                        #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:53 =#
                        g(dev, (KernelAbstractions.NDIteration.DynamicSize)(), (KernelAbstractions.NDIteration.DynamicSize)())
                    end
            end
            #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:54 =#
            g(dev::Device, size) = begin
                    #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:54 =#
                    g(dev, (KernelAbstractions.NDIteration.StaticSize)(size), (KernelAbstractions.NDIteration.DynamicSize)())
                end
            #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:55 =#
            g(dev::Device, size, range) = begin
                    #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:55 =#
                    g(dev, (KernelAbstractions.NDIteration.StaticSize)(size), (KernelAbstractions.NDIteration.StaticSize)(range))
                end
            #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:56 =#
            function g(::Device, ::S, ::NDRange) where {Device <: CPU, S <: KernelAbstractions.NDIteration._Size, NDRange <: KernelAbstractions.NDIteration._Size}
                #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:56 =#
                #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:57 =#
                return (KernelAbstractions.Kernel){Device, S, NDRange, typeof(cpu_g)}(cpu_g)
            end
            #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:59 =#
            function g(::Device, ::S, ::NDRange) where {Device <: GPU, S <: KernelAbstractions.NDIteration._Size, NDRange <: KernelAbstractions.NDIteration._Size}
                #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:59 =#
                #= /home/arakaki/.julia/dev/KernelAbstractions/src/macros.jl:60 =#
                return (KernelAbstractions.Kernel){Device, S, NDRange, typeof(gpu_g)}(gpu_g)
            end
        end
    end
end

tkf avatar Feb 22 '21 07:02 tkf

Should this work too?

julia> @kernel function h(xs)
           @uniform i = @index(Group, Linear)
           xs[i] = 1
       end
h (generic function with 5 methods)

julia> xs = zeros(10); h(CPU())(xs; ndrange = 10) |> wait
ERROR: TaskFailedException:
MethodError: no method matching __index_Group_Linear()

By the way, I see that the kernel language macros are defined by matching macro names. But, IIUC, they are not implemented in a way that can support

import KernelAbstractions as KA
macro myindex(args...)
    esc(:($KA.@index($(args..))))
end
KA.@kernel function f(xs)
    KA.@index(Group, Linear)
    @myindex(Group, Linear)
end

FYI, I've created https://github.com/tkf/ContextualMacros.jl for supporting cases like these and use them in FLoops.jl, FGenerators.jl, and GeneratorsX.jl. I don't particularity like my solution but I think it's at least robust (so far).

tkf avatar Feb 22 '21 08:02 tkf

Yes currently @index is only recognized as a top-level expression, and the real macro @kernel and @index is just a placeholder

vchuravy avatar Feb 22 '21 16:02 vchuravy