KernelAbstractions.jl
KernelAbstractions.jl copied to clipboard
MethodError: no method matching __index_Local_Linear() from a CPU kernel
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
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).
Yes currently @index is only recognized as a top-level expression, and the real macro @kernel and @index is just a placeholder