From 44b1db3f1362701f9f0c64b31c7a00cb59e0fd22 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 29 Jun 2026 18:15:32 +0200 Subject: [PATCH 1/4] fix allocations --- src/cpu.jl | 14 +++++--------- test/runtests.jl | 5 +++++ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/cpu.jl b/src/cpu.jl index 7ee786635..89991f986 100644 --- a/src/cpu.jl +++ b/src/cpu.jl @@ -97,16 +97,12 @@ end # Inference barriers function __run(obj, ndrange, iterspace, args, dynamic, static_threads) N = length(iterspace) - Nthreads = Threads.nthreads() - if Nthreads == 1 - len, rem = N, 0 + nthreads = Threads.nthreads() + Nthreads, len, rem = if nthreads == 1 + 1, N, 0 else - len, rem = divrem(N, Nthreads) - end - # not enough iterations for all the threads? - if len == 0 - Nthreads = N - len, rem = 1, 0 + l, r = divrem(N, nthreads) + l == 0 ? (N, 1, 0) : (nthreads, l, r) end if Nthreads == 1 __thread_run(1, len, rem, obj, ndrange, iterspace, args, dynamic) diff --git a/test/runtests.jl b/test/runtests.jl index f395b70dc..da102bbab 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -17,6 +17,11 @@ A = zeros(Int, Threads.nthreads()) kern_static(CPU(static = true), (1,))(A, ndrange = length(A)) @test A == 1:Threads.nthreads() +@testset "__run does not box (no per-launch Core.Box)" begin + ci = only(code_lowered(KernelAbstractions.__run, NTuple{6, Any})) + @test !any(e -> occursin("Box", string(e)), ci.code) +end + @kernel cpu = false function my_no_cpu_kernel(a) end @test_throws ErrorException("This kernel is unavailable for backend CPU") my_no_cpu_kernel(CPU()) From d1b2d0565a4f66f8f196e44793e7f7fe45cc3948 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 29 Jun 2026 18:22:18 +0200 Subject: [PATCH 2/4] bump version --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 85c8ed0e4..90a297d34 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "KernelAbstractions" uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" authors = ["Valentin Churavy and contributors"] -version = "0.9.41" +version = "0.9.42" [deps] Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" From cf718ea52ec99b2df25a0e80927b83a27d329c35 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 29 Jun 2026 23:19:19 +0200 Subject: [PATCH 3/4] let .. end --- src/cpu.jl | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/cpu.jl b/src/cpu.jl index 89991f986..94e1f716c 100644 --- a/src/cpu.jl +++ b/src/cpu.jl @@ -97,23 +97,28 @@ end # Inference barriers function __run(obj, ndrange, iterspace, args, dynamic, static_threads) N = length(iterspace) - nthreads = Threads.nthreads() - Nthreads, len, rem = if nthreads == 1 - 1, N, 0 + Nthreads = Threads.nthreads() + if Nthreads == 1 + len, rem = N, 0 else - l, r = divrem(N, nthreads) - l == 0 ? (N, 1, 0) : (nthreads, l, r) + len, rem = divrem(N, Nthreads) + end + if len == 0 + Nthreads = N + len, rem = 1, 0 end if Nthreads == 1 __thread_run(1, len, rem, obj, ndrange, iterspace, args, dynamic) else - if static_threads - Threads.@threads :static for tid in 1:Nthreads - __thread_run(tid, len, rem, obj, ndrange, iterspace, args, dynamic) - end - else - @sync for tid in 1:Nthreads - Threads.@spawn __thread_run(tid, len, rem, obj, ndrange, iterspace, args, dynamic) + let len = len, rem = rem, Nthreads = Nthreads + if static_threads + Threads.@threads :static for tid in 1:Nthreads + __thread_run(tid, len, rem, obj, ndrange, iterspace, args, dynamic) + end + else + @sync for tid in 1:Nthreads + Threads.@spawn __thread_run(tid, len, rem, obj, ndrange, iterspace, args, dynamic) + end end end end From d94c08e5e6bd0d9ef477f477d35fa6f09cf6f8f3 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Mon, 29 Jun 2026 23:37:23 +0200 Subject: [PATCH 4/4] Add comment for thread iteration check Add comment to check for thread iteration limits --- src/cpu.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cpu.jl b/src/cpu.jl index 94e1f716c..f590ff3dd 100644 --- a/src/cpu.jl +++ b/src/cpu.jl @@ -103,6 +103,7 @@ function __run(obj, ndrange, iterspace, args, dynamic, static_threads) else len, rem = divrem(N, Nthreads) end + # not enough iterations for all the threads? if len == 0 Nthreads = N len, rem = 1, 0