From f772bd3c87688b73027327ab1eca97db27f41446 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas Date: Fri, 24 Oct 2025 09:42:13 -0400 Subject: [PATCH 1/9] Add OpenCL.jl backend support for CPU-based debugging MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds support for OpenCL.jl with pocl as a CPU-based backend for debugging GPU issues without requiring actual GPU hardware. This is particularly useful for debugging issues like #375 where complex nested types fail with GPU kernels. Changes: - Add OpenCL to weakdeps and extensions in Project.toml - Create OpenCLExt extension with CLBackend support - Add OpenCL backend to test/utils.jl - Add OpenCL test group to GitHub Actions CI - Update README to document OpenCL backend The OpenCL backend uses pocl_jll as a CPU target that behaves like GPU targets, allowing developers to reproduce and debug GPU-specific issues in CI or on systems without GPU hardware. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .github/workflows/CI.yml | 1 + Project.toml | 4 ++++ README.md | 1 + ext/OpenCLExt.jl | 11 +++++++++++ test/utils.jl | 3 +++ 5 files changed, 20 insertions(+) create mode 100644 ext/OpenCLExt.jl diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 99e14c44..9b5a46d6 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -34,6 +34,7 @@ jobs: group: - CPU - JLArrays + - OpenCL uses: "SciML/.github/.github/workflows/tests.yml@master" with: julia-version: "${{ matrix.version }}" diff --git a/Project.toml b/Project.toml index b5733067..cbe8d943 100644 --- a/Project.toml +++ b/Project.toml @@ -30,6 +30,7 @@ AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" JLArrays = "27aeb0d3-9eb9-45fb-866b-73c2ecf80fcb" Metal = "dde4c033-4e86-420c-a63e-0dd931031962" +OpenCL = "08131aa3-fb12-5dee-8b74-c09406e224a2" oneAPI = "8f75cd03-7ff8-4ecb-9b8f-daf728133b1b" [extensions] @@ -37,6 +38,7 @@ AMDGPUExt = ["AMDGPU"] CUDAExt = ["CUDA"] JLArraysExt = ["JLArrays"] MetalExt = ["Metal"] +OpenCLExt = ["OpenCL"] oneAPIExt = ["oneAPI"] [compat] @@ -53,6 +55,7 @@ KernelAbstractions = "0.9" LinearSolve = "3" Metal = "1" MuladdMacro = "0.2" +OpenCL = "0.9" Parameters = "0.12" RecursiveArrayTools = "3" SciMLBase = "2.92" @@ -70,5 +73,6 @@ CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" JLArrays = "27aeb0d3-9eb9-45fb-866b-73c2ecf80fcb" Metal = "dde4c033-4e86-420c-a63e-0dd931031962" +OpenCL = "08131aa3-fb12-5dee-8b74-c09406e224a2" oneAPI = "8f75cd03-7ff8-4ecb-9b8f-daf728133b1b" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/README.md b/README.md index cdf4e30a..e6a4ac90 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ SciML's GPU support extends to a wide array of hardware, including: | AMD | ROCm | [AMDGPU.jl](https://github.com/JuliaGPU/AMDGPU.jl) | `AMDGPU.ROCBackend()` | | Intel | OneAPI | [OneAPI.jl](https://github.com/JuliaGPU/oneAPI.jl) | `oneAPI.oneAPIBackend()` | | Apple (M-Series) | Metal | [Metal.jl](https://github.com/JuliaGPU/Metal.jl) | `Metal.MetalBackend()` | +| CPU (for debugging) | OpenCL | [OpenCL.jl](https://github.com/JuliaGPU/OpenCL.jl) | `OpenCL.CLBackend()` | For this tutorial we will demonstrate the CUDA backend for NVIDIA GPUs, though any of the other GPUs can be used by simply swapping out the `backend` choice. diff --git a/ext/OpenCLExt.jl b/ext/OpenCLExt.jl new file mode 100644 index 00000000..fbfdf4c9 --- /dev/null +++ b/ext/OpenCLExt.jl @@ -0,0 +1,11 @@ +module OpenCLExt +using OpenCL +import DiffEqGPU + +using .OpenCL +import .OpenCL: CLBackend + +DiffEqGPU.maxthreads(::CLBackend) = 256 +DiffEqGPU.maybe_prefer_blocks(::CLBackend) = CLBackend() + +end diff --git a/test/utils.jl b/test/utils.jl index a60bb9e0..58e4786f 100644 --- a/test/utils.jl +++ b/test/utils.jl @@ -11,6 +11,9 @@ elseif GROUP == "oneAPI" elseif GROUP == "Metal" using Metal Metal.MetalBackend() +elseif GROUP == "OpenCL" + using OpenCL + OpenCL.CLBackend() elseif GROUP == "JLArrays" using JLArrays JLArrays.JLBackend() From d93757022b785938846edcea48a5f6bbf411af2e Mon Sep 17 00:00:00 2001 From: ChrisRackauckas Date: Fri, 24 Oct 2025 09:50:14 -0400 Subject: [PATCH 2/9] Remove OpenCL and pocl_jll from direct dependencies They should only be in weakdeps and extras, not in the main deps section. --- Project.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Project.toml b/Project.toml index cbe8d943..f0fd5754 100644 --- a/Project.toml +++ b/Project.toml @@ -30,7 +30,6 @@ AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" JLArrays = "27aeb0d3-9eb9-45fb-866b-73c2ecf80fcb" Metal = "dde4c033-4e86-420c-a63e-0dd931031962" -OpenCL = "08131aa3-fb12-5dee-8b74-c09406e224a2" oneAPI = "8f75cd03-7ff8-4ecb-9b8f-daf728133b1b" [extensions] @@ -74,5 +73,5 @@ GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" JLArrays = "27aeb0d3-9eb9-45fb-866b-73c2ecf80fcb" Metal = "dde4c033-4e86-420c-a63e-0dd931031962" OpenCL = "08131aa3-fb12-5dee-8b74-c09406e224a2" -oneAPI = "8f75cd03-7ff8-4ecb-9b8f-daf728133b1b" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +oneAPI = "8f75cd03-7ff8-4ecb-9b8f-daf728133b1b" From 709b4298e78fda3562f11322485077607ac6529b Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Fri, 24 Oct 2025 09:54:01 -0400 Subject: [PATCH 3/9] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e6a4ac90..8df6285b 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ SciML's GPU support extends to a wide array of hardware, including: | AMD | ROCm | [AMDGPU.jl](https://github.com/JuliaGPU/AMDGPU.jl) | `AMDGPU.ROCBackend()` | | Intel | OneAPI | [OneAPI.jl](https://github.com/JuliaGPU/oneAPI.jl) | `oneAPI.oneAPIBackend()` | | Apple (M-Series) | Metal | [Metal.jl](https://github.com/JuliaGPU/Metal.jl) | `Metal.MetalBackend()` | -| CPU (for debugging) | OpenCL | [OpenCL.jl](https://github.com/JuliaGPU/OpenCL.jl) | `OpenCL.CLBackend()` | +| CPU (fast kernels) | OpenCL | [OpenCL.jl](https://github.com/JuliaGPU/OpenCL.jl) | `OpenCL.CLBackend()` | For this tutorial we will demonstrate the CUDA backend for NVIDIA GPUs, though any of the other GPUs can be used by simply swapping out the `backend` choice. From f9bedc2b77c139108a043b770b11b5a6b849c2a7 Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Fri, 24 Oct 2025 10:00:48 -0400 Subject: [PATCH 4/9] Update Project.toml --- Project.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Project.toml b/Project.toml index f0fd5754..ef88c09c 100644 --- a/Project.toml +++ b/Project.toml @@ -30,6 +30,7 @@ AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" JLArrays = "27aeb0d3-9eb9-45fb-866b-73c2ecf80fcb" Metal = "dde4c033-4e86-420c-a63e-0dd931031962" +OpenCL = "08131aa3-fb12-5dee-8b74-c09406e224a2" oneAPI = "8f75cd03-7ff8-4ecb-9b8f-daf728133b1b" [extensions] From 9a1ec018764d65063a56aa462131e5683f025343 Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Fri, 24 Oct 2025 10:22:36 -0400 Subject: [PATCH 5/9] Update Project.toml --- test/Project.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/test/Project.toml b/test/Project.toml index 6e853ca2..afbed817 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -8,6 +8,7 @@ ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" JLArrays = "27aeb0d3-9eb9-45fb-866b-73c2ecf80fcb" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +OpenCL = "08131aa3-fb12-5dee-8b74-c09406e224a2" Optimization = "7f7a1694-90dd-40f0-9382-eb1efda571ba" OptimizationOptimisers = "42dfb2eb-d2b4-4451-abcd-913932933ac1" OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" From 3fb876c34830fce9fc21cc6a39a7bae0be39913f Mon Sep 17 00:00:00 2001 From: ChrisRackauckas Date: Sat, 25 Oct 2025 09:30:59 -0400 Subject: [PATCH 6/9] Fix backend type name: CLBackend -> OpenCLBackend The correct backend type name in OpenCL.jl is OpenCLBackend, not CLBackend. --- ext/OpenCLExt.jl | 6 +++--- test/utils.jl | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ext/OpenCLExt.jl b/ext/OpenCLExt.jl index fbfdf4c9..c2a038bf 100644 --- a/ext/OpenCLExt.jl +++ b/ext/OpenCLExt.jl @@ -3,9 +3,9 @@ using OpenCL import DiffEqGPU using .OpenCL -import .OpenCL: CLBackend +import .OpenCL: OpenCLBackend -DiffEqGPU.maxthreads(::CLBackend) = 256 -DiffEqGPU.maybe_prefer_blocks(::CLBackend) = CLBackend() +DiffEqGPU.maxthreads(::OpenCLBackend) = 256 +DiffEqGPU.maybe_prefer_blocks(::OpenCLBackend) = OpenCLBackend() end diff --git a/test/utils.jl b/test/utils.jl index 58e4786f..730cd880 100644 --- a/test/utils.jl +++ b/test/utils.jl @@ -13,7 +13,7 @@ elseif GROUP == "Metal" Metal.MetalBackend() elseif GROUP == "OpenCL" using OpenCL - OpenCL.CLBackend() + OpenCL.OpenCLBackend() elseif GROUP == "JLArrays" using JLArrays JLArrays.JLBackend() From 08ecdc925ed194db0e50b88892aa9b4445c1124a Mon Sep 17 00:00:00 2001 From: ChrisRackauckas Date: Sat, 25 Oct 2025 09:39:31 -0400 Subject: [PATCH 7/9] Update to OpenCL v0.10 with KernelAbstractions backend support - Update compat to allow OpenCL v0.9 and v0.10 - Add OpenCL back to weakdeps (it was accidentally removed) - Tested with OpenCL v0.10.6 which includes OpenCLBackend type - OpenCLExt now compiles and works correctly with OpenCL v0.10 --- Project.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Project.toml b/Project.toml index ef88c09c..d4d1eb4d 100644 --- a/Project.toml +++ b/Project.toml @@ -15,6 +15,7 @@ KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" LinearSolve = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" MuladdMacro = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" +OpenCL = "08131aa3-fb12-5dee-8b74-c09406e224a2" Parameters = "d96e819e-fc66-5662-9728-84c9c7592b0a" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" @@ -30,7 +31,6 @@ AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" JLArrays = "27aeb0d3-9eb9-45fb-866b-73c2ecf80fcb" Metal = "dde4c033-4e86-420c-a63e-0dd931031962" -OpenCL = "08131aa3-fb12-5dee-8b74-c09406e224a2" oneAPI = "8f75cd03-7ff8-4ecb-9b8f-daf728133b1b" [extensions] @@ -55,7 +55,7 @@ KernelAbstractions = "0.9" LinearSolve = "3" Metal = "1" MuladdMacro = "0.2" -OpenCL = "0.9" +OpenCL = "0.9, 0.10" Parameters = "0.12" RecursiveArrayTools = "3" SciMLBase = "2.92" From 2db573657737a2aceaffd300cc24809d16691e44 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas Date: Sat, 25 Oct 2025 10:01:45 -0400 Subject: [PATCH 8/9] Add pocl_jll for CPU-based OpenCL testing - Add pocl_jll to extras for testing - Update test/utils.jl to load pocl_jll when GROUP=OpenCL - OpenCL backend requires pocl_jll to provide CPU-based OpenCL drivers - Without pocl_jll, OpenCL has no platforms/devices available --- Project.toml | 3 ++- test/utils.jl | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Project.toml b/Project.toml index d4d1eb4d..8efec9ea 100644 --- a/Project.toml +++ b/Project.toml @@ -15,7 +15,6 @@ KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" LinearSolve = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" MuladdMacro = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" -OpenCL = "08131aa3-fb12-5dee-8b74-c09406e224a2" Parameters = "d96e819e-fc66-5662-9728-84c9c7592b0a" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" @@ -31,6 +30,7 @@ AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" JLArrays = "27aeb0d3-9eb9-45fb-866b-73c2ecf80fcb" Metal = "dde4c033-4e86-420c-a63e-0dd931031962" +OpenCL = "08131aa3-fb12-5dee-8b74-c09406e224a2" oneAPI = "8f75cd03-7ff8-4ecb-9b8f-daf728133b1b" [extensions] @@ -76,3 +76,4 @@ Metal = "dde4c033-4e86-420c-a63e-0dd931031962" OpenCL = "08131aa3-fb12-5dee-8b74-c09406e224a2" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" oneAPI = "8f75cd03-7ff8-4ecb-9b8f-daf728133b1b" +pocl_jll = "627d6b7a-bbe6-5189-83e7-98cc0a5aeadd" diff --git a/test/utils.jl b/test/utils.jl index 730cd880..b89b9d16 100644 --- a/test/utils.jl +++ b/test/utils.jl @@ -12,7 +12,7 @@ elseif GROUP == "Metal" using Metal Metal.MetalBackend() elseif GROUP == "OpenCL" - using OpenCL + using OpenCL, pocl_jll OpenCL.OpenCLBackend() elseif GROUP == "JLArrays" using JLArrays From 9629e9c3c982b2caefb1ccc82290a3cbd5819f43 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas Date: Sat, 25 Oct 2025 11:29:27 -0400 Subject: [PATCH 9/9] Add pocl_jll to test/Project.toml CI tests need pocl_jll in the test environment dependencies. --- test/Project.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/Project.toml b/test/Project.toml index afbed817..6c2c0ed1 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -14,10 +14,11 @@ OptimizationOptimisers = "42dfb2eb-d2b4-4451-abcd-913932933ac1" OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" +SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" StochasticDiffEq = "789caeaf-c7a9-5a7d-9973-96adeb23e2a0" -SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" TOML = "fa267f1f-6049-4f14-aa54-33bafae1ed76" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" +pocl_jll = "627d6b7a-bbe6-5189-83e7-98cc0a5aeadd"