Skip to content

Commit ddb25a5

Browse files
leiosvchuravy
andcommitted
adding attempt to force inbounds at the kernel level
Co-authored-by: Valentin Churavy <vchuravy@users.noreply.github.com>
1 parent c1c6887 commit ddb25a5

File tree

3 files changed

+49
-11
lines changed

3 files changed

+49
-11
lines changed

src/KernelAbstractions.jl

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,28 +53,44 @@ synchronize(backend)
5353
```
5454
"""
5555
macro kernel(expr)
56-
__kernel(expr, #=generate_cpu=#true)
56+
__kernel(expr, #=generate_cpu=#true, #=force_inbounds=#false)
5757
end
5858

5959
"""
60-
@kernel cpu=false function f(args) end
60+
@kernel config function f(args) end
6161
62-
Disable code-generation of the CPU function. This relaxes semantics such that
63-
KernelAbstractions primitives can be used in non-kernel functions.
62+
This allows for two different configurations:
63+
64+
1. `cpu={true, false}`: Disables code-generation of the CPU function. This relaxes semantics such that KernelAbstractions primitives can be used in non-kernel functions.
65+
2. `inbounds={false, true}`: Enables a forced `@inbounds` macro around the function definition in the case the user is using too many `@inbounds` already in their kernel. Note that this can lead to incorrect results, crashes, etc and is fundamentally unsafe. Be careful!
6466
6567
- [`@context`](@ref)
6668
6769
!!! warn
6870
This is an experimental feature.
6971
"""
70-
macro kernel(config, expr)
71-
if config isa Expr && config.head == :(=) &&
72-
config.args[1] == :cpu && config.args[2] isa Bool
73-
generate_cpu = config.args[2]
72+
macro kernel(ex...)
73+
if length(ex) == 1
74+
__kernel(ex[1], true, false)
7475
else
75-
error("Configuration should be of form `cpu=false` got $config")
76+
generate_cpu = true
77+
force_inbounds = false
78+
for i = 1:length(ex)-1
79+
if ex[i] isa Expr && ex[i].head == :(=) &&
80+
ex[i].args[1] == :cpu && ex[i].args[2] isa Bool
81+
generate_cpu = ex[i].args[2]
82+
elseif ex[i] isa Expr && ex[i].head == :(=) &&
83+
ex[i].args[1] == :inbounds && ex[i].args[2] isa Bool
84+
force_inbounds = ex[i].args[2]
85+
else
86+
error("Configuration should be of form:\n"*
87+
"* `cpu=true`\n"*
88+
"* `inbounds=false`\n"*
89+
"got `", ex[i], "`")
90+
end
91+
end
92+
__kernel(ex[end], generate_cpu, force_inbounds)
7693
end
77-
__kernel(expr, generate_cpu)
7894
end
7995

8096
"""

src/macros.jl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,16 @@ function find_return(stmt)
1010
end
1111

1212
# XXX: Proper errors
13-
function __kernel(expr, generate_cpu=true)
13+
function __kernel(expr, generate_cpu=true, force_inbounds=false)
1414
def = splitdef(expr)
1515
name = def[:name]
1616
args = def[:args]
17+
if force_inbounds
18+
body_qt = quote
19+
@inbounds $(def[:body])
20+
end
21+
def[:body] = body_qt
22+
end
1723

1824
find_return(expr) && error("Return statement not permitted in a kernel function $name")
1925

test/runtests.jl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,22 @@ kern_static(CPU(static=true), (1,))(A, ndrange=length(A))
2121
end
2222
@test_throws ErrorException("This kernel is unavailable for backend CPU") my_no_cpu_kernel(CPU())
2323

24+
# testing multiple configurations at the same time
25+
@kernel cpu=false inbounds=false function my_no_cpu_kernel2(a)
26+
end
27+
@test_throws ErrorException("This kernel is unavailable for backend CPU") my_no_cpu_kernel2(CPU())
28+
29+
if Base.JLOptions().check_bounds == 0 || Base.JLOptions().check_bounds == 1
30+
# testing bounds errors
31+
@kernel inbounds=false my_bounded_kernel(a) = a[1]
32+
@test_throws BoundsError(Int64[],(1,)) my_bounded_kernel(CPU())(Int[], ndrange=1)
33+
end
34+
35+
if Base.JLOptions().check_bounds == 0 || Base.JLOptions().check_bounds == 2
36+
@kernel inbounds=true my_inbounds_kernel(a) = a[1]
37+
@test nothing == my_inbounds_kernel(CPU())(Int[], ndrange=1)
38+
end
39+
2440
struct NewBackend <: KernelAbstractions.GPU end
2541
@testset "Default host implementation" begin
2642
backend = NewBackend()

0 commit comments

Comments
 (0)