From 1f91edaca6948b1dd7e0087f5b7dffcd08127222 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Thu, 20 Jun 2024 13:30:55 -0400 Subject: [PATCH 01/20] Use preferences to switch between SIMD and KernelAbstractions --- Project.toml | 3 ++- src/WaterLily.jl | 21 ++++++++++++++------- src/util.jl | 19 ++++++++++++++++--- 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/Project.toml b/Project.toml index 10fae339..627eac49 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "WaterLily" uuid = "ed894a53-35f9-47f1-b17f-85db9237eebd" authors = ["Gabriel Weymouth "] -version = "1.1" +version = "1.1.0" [deps] DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" @@ -9,6 +9,7 @@ EllipsisNotation = "da5c29d0-fa7d-589e-88eb-ea29b0a81949" ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +Preferences = "21216c6a-2e73-6563-6e65-726566657250" Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" Reexport = "189a3867-3050-52da-a836-e630ba90ab69" Requires = "ae029012-a4dd-5104-9daa-d747884805df" diff --git a/src/WaterLily.jl b/src/WaterLily.jl index bdb39de6..471804d5 100644 --- a/src/WaterLily.jl +++ b/src/WaterLily.jl @@ -134,15 +134,22 @@ export restart_sim! # Check number of threads when loading WaterLily """ - check_nthreads(::Val{1}) + check_nthreads() Check the number of threads available for the Julia session that loads WaterLily. -A warning is shown when running in serial (JULIA_NUM_THREADS=1). +A warning is shown when running in serial (JULIA_NUM_THREADS=1) with KernelAbstractions enabled. """ -check_nthreads(::Val{1}) = @warn("\nUsing WaterLily in serial (ie. JULIA_NUM_THREADS=1) is not recommended because \ - it disables the GPU backend and defaults to serial CPU."* - "\nUse JULIA_NUM_THREADS=auto, or any number of threads greater than 1, to allow multi-threading in CPU or GPU backends.") -check_nthreads(_) = nothing +function check_nthreads() + if backend == :KernelAbstractions && Threads.nthreads() == 1 + @warn """ + Using WaterLily in serial (ie. JULIA_NUM_THREADS=1) is not recommended because + it defaults to serial CPU execution."* + Use JULIA_NUM_THREADS=auto, or any number of threads greater than 1, to allow multi-threading in CPU backends. + + For a low-overhead single-threaded CPU only backend set: `WaterLily.set_backend("SIMD")` + """ + end +end # Backward compatibility for extensions if !isdefined(Base, :get_extension) @@ -155,7 +162,7 @@ function __init__() @require WriteVTK = "64499a7a-5c06-52f2-abe2-ccb03c286192" include("../ext/WaterLilyWriteVTKExt.jl") @require ReadVTK = "dc215faf-f008-4882-a9f7-a79a826fadc3" include("../ext/WaterLilyReadVTKExt.jl") end - check_nthreads(Val{Threads.nthreads()}()) + check_nthreads() end end # module diff --git a/src/util.jl b/src/util.jl index 5edc8be6..55c4ca6d 100644 --- a/src/util.jl +++ b/src/util.jl @@ -65,6 +65,19 @@ macro inside(ex) end |> esc end +# Could also use ScopedValues in Julia 1.11+ +const backend = Symbol(@load_preference("backend", "KernelAbstractions")) +function set_backend(new_backend::String) + if !(new_backend in ("SIMD", "KernelAbstractions")) + throw(ArgumentError("Invalid backend: \"$(new_backend)\"")) + end + + # Set it in our runtime values, as well as saving it to disk + @set_preferences!("backend" => new_backend) + @info("New backend set; restart your Julia session for this change to take effect!") +end + + """ @loop over @@ -99,7 +112,7 @@ macro loop(args...) setdiff!(sym,[I]) # don't want to pass I as an argument @gensym(kern, kern_) # generate unique kernel function names for serial and KA execution return quote - function $kern($(rep.(sym)...),::Val{1}) + function $kern($(rep.(sym)...),::Val{:SIMD}) @simd for $I ∈ $R @fastmath @inbounds $ex end @@ -109,10 +122,10 @@ macro loop(args...) $I += I0 @fastmath @inbounds $ex end - function $kern($(rep.(sym)...),_) + function $kern($(rep.(sym)...),::Val{:KernelAbstractions}) $kern_(get_backend($(sym[1])),64)($(sym...),$R[1]-oneunit($R[1]),ndrange=size($R)) end - $kern($(sym...),Val{Threads.nthreads()}()) # dispatch to SIMD for -t 1, or KA otherwise + $kern($(sym...),Val{$backend}()) # dispatch to SIMD or KA otherwise end |> esc end function grab!(sym,ex::Expr) From 4b7a8468a2ac44eca03c02c4bf21e2acc62e6671 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Thu, 20 Jun 2024 13:35:49 -0400 Subject: [PATCH 02/20] fixup! Use preferences to switch between SIMD and KernelAbstractions --- src/util.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/util.jl b/src/util.jl index 55c4ca6d..6988fd0c 100644 --- a/src/util.jl +++ b/src/util.jl @@ -66,6 +66,7 @@ macro inside(ex) end # Could also use ScopedValues in Julia 1.11+ +using Preferences const backend = Symbol(@load_preference("backend", "KernelAbstractions")) function set_backend(new_backend::String) if !(new_backend in ("SIMD", "KernelAbstractions")) From e77bca4e6a9d393e040cbe980ea17295f41bc9d3 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Thu, 20 Jun 2024 13:39:22 -0400 Subject: [PATCH 03/20] fixup! Use preferences to switch between SIMD and KernelAbstractions --- src/util.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util.jl b/src/util.jl index 6988fd0c..96780c5f 100644 --- a/src/util.jl +++ b/src/util.jl @@ -126,7 +126,7 @@ macro loop(args...) function $kern($(rep.(sym)...),::Val{:KernelAbstractions}) $kern_(get_backend($(sym[1])),64)($(sym...),$R[1]-oneunit($R[1]),ndrange=size($R)) end - $kern($(sym...),Val{$backend}()) # dispatch to SIMD or KA otherwise + $kern($(sym...),Val{$(QuoteNode(backend))}()) # dispatch to SIMD or KA otherwise end |> esc end function grab!(sym,ex::Expr) From b01cdce0e00d85331b2a63cf885c6f394c5148b5 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Thu, 20 Jun 2024 14:17:07 -0400 Subject: [PATCH 04/20] don't limit workgroups to 64 --- src/util.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util.jl b/src/util.jl index 96780c5f..80efd415 100644 --- a/src/util.jl +++ b/src/util.jl @@ -124,7 +124,7 @@ macro loop(args...) @fastmath @inbounds $ex end function $kern($(rep.(sym)...),::Val{:KernelAbstractions}) - $kern_(get_backend($(sym[1])),64)($(sym...),$R[1]-oneunit($R[1]),ndrange=size($R)) + $kern_(get_backend($(sym[1])))($(sym...),$R[1]-oneunit($R[1]),ndrange=size($R)) end $kern($(sym...),Val{$(QuoteNode(backend))}()) # dispatch to SIMD or KA otherwise end |> esc From f0b351f6c5b1e6003ab6895869fc796146d02342 Mon Sep 17 00:00:00 2001 From: Bernat Font Date: Thu, 22 May 2025 01:14:39 +0200 Subject: [PATCH 05/20] Updated loop macro and cleaned up Preferences.jl routines. When the SIMD backend is selected, the loop macro generates only the for loop, without a function wrapper. Also, dispatch based on number of threads has been removed, and now only the backend-specific kernel is compiled. The CI needs to be fixed for the allocations tests, which first needs to set the SIMD backend, and then re-run the tests. --- .gitignore | 1 + src/WaterLily.jl | 2 +- src/util.jl | 41 ++++++++++++++++++++++------------------- test/alloctest.jl | 2 ++ test/maintests.jl | 2 ++ 5 files changed, 28 insertions(+), 20 deletions(-) diff --git a/.gitignore b/.gitignore index 8cd2947b..b7d3610f 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ .vscode/ .DS_Store Manifest.toml +LocalPreferences.toml /docs/build/ # gfx diff --git a/src/WaterLily.jl b/src/WaterLily.jl index 67ec14fb..99528196 100644 --- a/src/WaterLily.jl +++ b/src/WaterLily.jl @@ -6,7 +6,7 @@ module WaterLily using DocStringExtensions include("util.jl") -export L₂,BC!,@inside,inside,δ,apply!,loc,@log +export L₂,BC!,@inside,inside,δ,apply!,loc,@log,set_backend,backend using Reexport @reexport using KernelAbstractions: @kernel,@index,get_backend diff --git a/src/util.jl b/src/util.jl index 960d1186..0119abb6 100644 --- a/src/util.jl +++ b/src/util.jl @@ -91,7 +91,7 @@ end # Could also use ScopedValues in Julia 1.11+ using Preferences -const backend = Symbol(@load_preference("backend", "KernelAbstractions")) +const backend = @load_preference("backend", "KernelAbstractions") function set_backend(new_backend::String) if !(new_backend in ("SIMD", "KernelAbstractions")) throw(ArgumentError("Invalid backend: \"$(new_backend)\"")) @@ -102,7 +102,6 @@ function set_backend(new_backend::String) @info("New backend set; restart your Julia session for this change to take effect!") end - """ @loop over @@ -132,26 +131,30 @@ Note that `get_backend` is used on the _first_ variable in `expr` (`a` in this e """ macro loop(args...) ex,_,itr = args - _,I,R = itr.args; sym = [] - grab!(sym,ex) # get arguments and replace composites in `ex` - setdiff!(sym,[I]) # don't want to pass I as an argument - @gensym(kern, kern_) # generate unique kernel function names for serial and KA execution - return quote - function $kern($(rep.(sym)...),::Val{:SIMD}) + _,I,R = itr.args + @static if backend == "KernelAbstractions" + sym = [] + grab!(sym,ex) # get arguments and replace composites in `ex` + setdiff!(sym,[I]) # don't want to pass I as an argument + @gensym(kern, kern_) # generate unique kernel function names for serial and KA execution + return quote + @kernel function $kern_($(rep.(sym)...),@Const(I0)) # replace composite arguments + $I = @index(Global,Cartesian) + $I += I0 + @fastmath @inbounds $ex + end + function $kern($(rep.(sym)...)) + $kern_(get_backend($(sym[1])))($(sym...),$R[1]-oneunit($R[1]),ndrange=size($R)) + end + $kern($(sym...)) + end |> esc + else # backend == "SIMD" + return quote @simd for $I ∈ $R @fastmath @inbounds $ex end - end - @kernel function $kern_($(rep.(sym)...),@Const(I0)) # replace composite arguments - $I = @index(Global,Cartesian) - $I += I0 - @fastmath @inbounds $ex - end - function $kern($(rep.(sym)...),::Val{:KernelAbstractions}) - $kern_(get_backend($(sym[1])))($(sym...),$R[1]-oneunit($R[1]),ndrange=size($R)) - end - $kern($(sym...),Val{$(QuoteNode(backend))}()) # dispatch to SIMD or KA otherwise - end |> esc + end |> esc + end end function grab!(sym,ex::Expr) ex.head == :. && return union!(sym,[ex]) # grab composite name and return diff --git a/test/alloctest.jl b/test/alloctest.jl index 5e860d2c..a6e41d10 100644 --- a/test/alloctest.jl +++ b/test/alloctest.jl @@ -1,5 +1,7 @@ using BenchmarkTools, Printf +backend == "KernelAbstractions" && (set_backend("SIMD"); exit()) + @testset "mom_step! allocations" begin function Sim(θ;L=32,U=1,Re=100,perdir=()) function map(x,t) diff --git a/test/maintests.jl b/test/maintests.jl index 10e79a5d..59136e2f 100644 --- a/test/maintests.jl +++ b/test/maintests.jl @@ -1,6 +1,8 @@ using GPUArrays using ReadVTK, WriteVTK +backend == "SIMD" && (set_backend("KernelAbstractions"); exit()) + @info "Test backends: $(join(arrays,", "))" @testset "util.jl" begin I = CartesianIndex(1,2,3,4) From 2369279bc9de4ce56a6e20ce96c20b8c943dca9a Mon Sep 17 00:00:00 2001 From: Bernat Font Date: Thu, 22 May 2025 01:21:38 +0200 Subject: [PATCH 06/20] Small bug fix. --- src/WaterLily.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WaterLily.jl b/src/WaterLily.jl index 99528196..4c4f0e8e 100644 --- a/src/WaterLily.jl +++ b/src/WaterLily.jl @@ -169,7 +169,7 @@ Check the number of threads available for the Julia session that loads WaterLily A warning is shown when running in serial (JULIA_NUM_THREADS=1) with KernelAbstractions enabled. """ function check_nthreads() - if backend == :KernelAbstractions && Threads.nthreads() == 1 + if backend == "KernelAbstractions" && Threads.nthreads() == 1 @warn """ Using WaterLily in serial (ie. JULIA_NUM_THREADS=1) is not recommended because it defaults to serial CPU execution."* From 2c629c20020ddf67d2acc9291052a33dd499e0bc Mon Sep 17 00:00:00 2001 From: Bernat Font Date: Thu, 22 May 2025 01:24:25 +0200 Subject: [PATCH 07/20] Cleaned up -t 1 warning message. --- src/WaterLily.jl | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/WaterLily.jl b/src/WaterLily.jl index 4c4f0e8e..08b8c47f 100644 --- a/src/WaterLily.jl +++ b/src/WaterLily.jl @@ -171,11 +171,9 @@ A warning is shown when running in serial (JULIA_NUM_THREADS=1) with KernelAbstr function check_nthreads() if backend == "KernelAbstractions" && Threads.nthreads() == 1 @warn """ - Using WaterLily in serial (ie. JULIA_NUM_THREADS=1) is not recommended because - it defaults to serial CPU execution."* - Use JULIA_NUM_THREADS=auto, or any number of threads greater than 1, to allow multi-threading in CPU backends. - - For a low-overhead single-threaded CPU only backend set: `WaterLily.set_backend("SIMD")` + Using WaterLily in serial (ie. JULIA_NUM_THREADS=1) is not recommended because it defaults to serial CPU execution. + Use JULIA_NUM_THREADS=auto, or any number of threads greater than 1, to allow multi-threading in CPU backends. + For a low-overhead single-threaded CPU only backend set: WaterLily.set_backend("SIMD") """ end end From 5f17edef71a55cbe0ebb26206d07905e62e4f767 Mon Sep 17 00:00:00 2001 From: Bernat Font Date: Thu, 22 May 2025 01:42:52 +0200 Subject: [PATCH 08/20] testing 64,64 workgroup size --- src/util.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util.jl b/src/util.jl index 0119abb6..f8829591 100644 --- a/src/util.jl +++ b/src/util.jl @@ -144,7 +144,7 @@ macro loop(args...) @fastmath @inbounds $ex end function $kern($(rep.(sym)...)) - $kern_(get_backend($(sym[1])))($(sym...),$R[1]-oneunit($R[1]),ndrange=size($R)) + $kern_(get_backend($(sym[1])),(64,64))($(sym...),$R[1]-oneunit($R[1]),ndrange=size($R)) end $kern($(sym...)) end |> esc From f1621be73421d6bde4b0f5c65de63a46f3eb76fc Mon Sep 17 00:00:00 2001 From: Bernat Font Date: Thu, 22 May 2025 02:26:36 +0200 Subject: [PATCH 09/20] Workgroup size is 64, like master. --- src/util.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util.jl b/src/util.jl index f8829591..a2b24a4f 100644 --- a/src/util.jl +++ b/src/util.jl @@ -144,7 +144,7 @@ macro loop(args...) @fastmath @inbounds $ex end function $kern($(rep.(sym)...)) - $kern_(get_backend($(sym[1])),(64,64))($(sym...),$R[1]-oneunit($R[1]),ndrange=size($R)) + $kern_(get_backend($(sym[1])),64)($(sym...),$R[1]-oneunit($R[1]),ndrange=size($R)) end $kern($(sym...)) end |> esc From 6f9aa992dd18ce62d72881d48cf2483a583e19c0 Mon Sep 17 00:00:00 2001 From: Bernat Font Date: Thu, 22 May 2025 16:57:25 +0200 Subject: [PATCH 10/20] Wrapped SIMD kernels in a fuction too, as single-threaded test were 40pc slower than master... --- src/util.jl | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/util.jl b/src/util.jl index a2b24a4f..c6172d6e 100644 --- a/src/util.jl +++ b/src/util.jl @@ -132,11 +132,11 @@ Note that `get_backend` is used on the _first_ variable in `expr` (`a` in this e macro loop(args...) ex,_,itr = args _,I,R = itr.args + sym = [] + grab!(sym,ex) # get arguments and replace composites in `ex` + setdiff!(sym,[I]) # don't want to pass I as an argument + @gensym(kern, kern_) # generate unique kernel function names for serial and KA execution @static if backend == "KernelAbstractions" - sym = [] - grab!(sym,ex) # get arguments and replace composites in `ex` - setdiff!(sym,[I]) # don't want to pass I as an argument - @gensym(kern, kern_) # generate unique kernel function names for serial and KA execution return quote @kernel function $kern_($(rep.(sym)...),@Const(I0)) # replace composite arguments $I = @index(Global,Cartesian) @@ -150,9 +150,12 @@ macro loop(args...) end |> esc else # backend == "SIMD" return quote - @simd for $I ∈ $R - @fastmath @inbounds $ex + function $kern($(rep.(sym)...)) + @simd for $I ∈ $R + @fastmath @inbounds $ex + end end + $kern($(sym...)) end |> esc end end From fb85fd13cb71accf555e6c0cd22179bd9b56947f Mon Sep 17 00:00:00 2001 From: Bernat Font Date: Thu, 22 May 2025 20:27:31 +0200 Subject: [PATCH 11/20] First attempt at adjusting CI to work with LocalPreferences --- .github/workflows/ci.yml | 18 ++++++++++++++++-- test/alloctest.jl | 3 +-- test/maintests.jl | 3 +-- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 502084cb..aa616cb4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,10 +56,24 @@ jobs: ${{ runner.os }}-test-${{ env.cache-name }}- ${{ runner.os }}-test- ${{ runner.os }}- - - uses: julia-actions/julia-buildpkg@v1 - - uses: julia-actions/julia-runtest@v1 + # - uses: julia-actions/julia-buildpkg@v1 + # - uses: julia-actions/julia-runtest@v1 + - name: Setup and run WaterLily tests env: JULIA_NUM_THREADS: ${{ matrix.nthreads }} + shell: bash + run: | + if [ "${{ matrix.nthreads }}" = "auto" ] + then + printf "[WaterLily]\nbackend = \"KernelAbstractions\"" > LocalPreferences.toml + else + printf "[WaterLily]\nbackend = \"SIMD\"" > LocalPreferences.toml + fi + shell: julia --color=yes {0} + run: | + using Pkg + Pkg.activate(".") + Pkg.test(; coverage=true) - uses: julia-actions/julia-processcoverage@v1 - uses: codecov/codecov-action@v5 with: diff --git a/test/alloctest.jl b/test/alloctest.jl index a6e41d10..f0fa3c76 100644 --- a/test/alloctest.jl +++ b/test/alloctest.jl @@ -1,7 +1,6 @@ using BenchmarkTools, Printf -backend == "KernelAbstractions" && (set_backend("SIMD"); exit()) - +backend != "SIMD" && throw(ArgumentError("KernelAbstractions backend not allowed to run allocations tests, use SIMD backend")) @testset "mom_step! allocations" begin function Sim(θ;L=32,U=1,Re=100,perdir=()) function map(x,t) diff --git a/test/maintests.jl b/test/maintests.jl index 59136e2f..1268c857 100644 --- a/test/maintests.jl +++ b/test/maintests.jl @@ -1,8 +1,7 @@ using GPUArrays using ReadVTK, WriteVTK -backend == "SIMD" && (set_backend("KernelAbstractions"); exit()) - +backend != "KernelAbstractions" && throw(ArgumentError("SIMD backend not allowed to run main tests, use KernelAbstractions backend")) @info "Test backends: $(join(arrays,", "))" @testset "util.jl" begin I = CartesianIndex(1,2,3,4) From 2c7c41eea400f075f03e993a6ff421903fda03b8 Mon Sep 17 00:00:00 2001 From: Bernat Font Date: Thu, 22 May 2025 20:37:47 +0200 Subject: [PATCH 12/20] CI fix. --- .github/workflows/ci.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index aa616cb4..af492dff 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -69,11 +69,7 @@ jobs: else printf "[WaterLily]\nbackend = \"SIMD\"" > LocalPreferences.toml fi - shell: julia --color=yes {0} - run: | - using Pkg - Pkg.activate(".") - Pkg.test(; coverage=true) + julia --color=yes -e "using Pkg; Pkg.activate(\".\"); Pkg.test(; coverage=true);" - uses: julia-actions/julia-processcoverage@v1 - uses: codecov/codecov-action@v5 with: From 4ea8e73fbf654ccde067621887e12cad7e6717ce Mon Sep 17 00:00:00 2001 From: Bernat Font Date: Thu, 22 May 2025 23:08:11 +0200 Subject: [PATCH 13/20] Added automatic specialization for kernel functions generated with loop macro. --- Project.toml | 6 ++++-- src/util.jl | 9 +++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/Project.toml b/Project.toml index 752bc8d9..bacbdece 100644 --- a/Project.toml +++ b/Project.toml @@ -9,9 +9,10 @@ EllipsisNotation = "da5c29d0-fa7d-589e-88eb-ea29b0a81949" ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" -Preferences = "21216c6a-2e73-6563-6e65-726566657250" LoggingExtras = "e6f89c97-d47a-5376-807f-9c37f3926c36" +Preferences = "21216c6a-2e73-6563-6e65-726566657250" Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" Reexport = "189a3867-3050-52da-a836-e630ba90ab69" Requires = "ae029012-a4dd-5104-9daa-d747884805df" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" @@ -20,8 +21,8 @@ TOML = "fa267f1f-6049-4f14-aa54-33bafae1ed76" [weakdeps] AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" -GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326" GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" +GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326" Meshing = "e6723b4c-ebff-59f1-b4b7-d97aa5274f73" Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" ReadVTK = "dc215faf-f008-4882-a9f7-a79a826fadc3" @@ -42,6 +43,7 @@ EllipsisNotation = "1.8" ForwardDiff = "^0.10.18" KernelAbstractions = "0.9.1" LoggingExtras = "1.1" +Random = "1.11.0" Reexport = "^1.2.2" Requires = "1.3" StaticArrays = "^1.1.0" diff --git a/src/util.jl b/src/util.jl index c6172d6e..00a815fe 100644 --- a/src/util.jl +++ b/src/util.jl @@ -1,5 +1,6 @@ using KernelAbstractions: get_backend, @index, @kernel using LoggingExtras +using Random # custom log macro _psolver = Logging.LogLevel(-123) # custom log level for pressure solver, needs the negative sign @@ -135,6 +136,7 @@ macro loop(args...) sym = [] grab!(sym,ex) # get arguments and replace composites in `ex` setdiff!(sym,[I]) # don't want to pass I as an argument + symT = symtypes(sym) # generate a list of types for each symbol @gensym(kern, kern_) # generate unique kernel function names for serial and KA execution @static if backend == "KernelAbstractions" return quote @@ -143,14 +145,14 @@ macro loop(args...) $I += I0 @fastmath @inbounds $ex end - function $kern($(rep.(sym)...)) + function $kern($(joinsymtype(rep.(sym),symT)...)) where {$(symT...)} $kern_(get_backend($(sym[1])),64)($(sym...),$R[1]-oneunit($R[1]),ndrange=size($R)) end $kern($(sym...)) end |> esc else # backend == "SIMD" return quote - function $kern($(rep.(sym)...)) + function $kern($(joinsymtype(rep.(sym),symT)...)) where {$(symT...)} @simd for $I ∈ $R @fastmath @inbounds $ex end @@ -169,6 +171,9 @@ grab!(sym,ex::Symbol) = union!(sym,[ex]) # grab symbol name grab!(sym,ex) = nothing rep(ex) = ex rep(ex::Expr) = ex.head == :. ? Symbol(ex.args[2].value) : ex +symtypes(sym) = [Symbol.(randstring('A':'Z',4)) for _ in 1:length(sym)] +joinsymtype(sym::Symbol,symT::Symbol) = Expr(:(::), sym, symT) +joinsymtype(sym,symT) = zip(sym,symT) .|> x->joinsymtype(x...) using StaticArrays """ From eea319b17ad9df0c3ca00ca91546ede61ff358ed Mon Sep 17 00:00:00 2001 From: Bernat Font Date: Thu, 22 May 2025 23:41:24 +0200 Subject: [PATCH 14/20] Cleaned up CI. --- .github/workflows/ci.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index af492dff..f0edd0a1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,9 +56,7 @@ jobs: ${{ runner.os }}-test-${{ env.cache-name }}- ${{ runner.os }}-test- ${{ runner.os }}- - # - uses: julia-actions/julia-buildpkg@v1 - # - uses: julia-actions/julia-runtest@v1 - - name: Setup and run WaterLily tests + - name: WaterLily tests env: JULIA_NUM_THREADS: ${{ matrix.nthreads }} shell: bash @@ -69,7 +67,7 @@ jobs: else printf "[WaterLily]\nbackend = \"SIMD\"" > LocalPreferences.toml fi - julia --color=yes -e "using Pkg; Pkg.activate(\".\"); Pkg.test(; coverage=true);" + julia --proj --color=yes -e "using Pkg; Pkg.test(; coverage=true);" - uses: julia-actions/julia-processcoverage@v1 - uses: codecov/codecov-action@v5 with: From 12396106fbab6adf950da601f6057c011c3651a8 Mon Sep 17 00:00:00 2001 From: Bernat Font Date: Thu, 22 May 2025 23:45:14 +0200 Subject: [PATCH 15/20] Adding pkg Random in tests. --- Project.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index d8126407..f798b5b9 100644 --- a/Project.toml +++ b/Project.toml @@ -64,10 +64,11 @@ Makie = "537997a7-5e4e-5d89-9595-2241ea00577e" Meshing = "e6723b4c-ebff-59f1-b4b7-d97aa5274f73" PerformanceTestTools = "dc46b164-d16f-48ec-a853-60448fc869fe" Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" ReadVTK = "dc215faf-f008-4882-a9f7-a79a826fadc3" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228" WriteVTK = "64499a7a-5c06-52f2-abe2-ccb03c286192" [targets] -test = ["Test", "BenchmarkTools", "CUDA", "AMDGPU", "GPUArrays", "WriteVTK", "ReadVTK", "JLD2"] +test = ["Test", "BenchmarkTools", "CUDA", "AMDGPU", "GPUArrays", "WriteVTK", "ReadVTK", "JLD2", "Random"] From a50deb1eca5472625de530e5acb151e780110ef7 Mon Sep 17 00:00:00 2001 From: Bernat Font Date: Thu, 22 May 2025 23:52:34 +0200 Subject: [PATCH 16/20] Trying to fix Random pkg error in CI. --- Project.toml | 5 ++--- src/util.jl | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Project.toml b/Project.toml index f798b5b9..e8d7172e 100644 --- a/Project.toml +++ b/Project.toml @@ -21,8 +21,8 @@ TOML = "fa267f1f-6049-4f14-aa54-33bafae1ed76" [weakdeps] AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" -GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326" GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a" +GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326" JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819" Meshing = "e6723b4c-ebff-59f1-b4b7-d97aa5274f73" Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" @@ -64,11 +64,10 @@ Makie = "537997a7-5e4e-5d89-9595-2241ea00577e" Meshing = "e6723b4c-ebff-59f1-b4b7-d97aa5274f73" PerformanceTestTools = "dc46b164-d16f-48ec-a853-60448fc869fe" Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" -Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" ReadVTK = "dc215faf-f008-4882-a9f7-a79a826fadc3" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228" WriteVTK = "64499a7a-5c06-52f2-abe2-ccb03c286192" [targets] -test = ["Test", "BenchmarkTools", "CUDA", "AMDGPU", "GPUArrays", "WriteVTK", "ReadVTK", "JLD2", "Random"] +test = ["Test", "BenchmarkTools", "CUDA", "AMDGPU", "GPUArrays", "WriteVTK", "ReadVTK", "JLD2"] diff --git a/src/util.jl b/src/util.jl index 00a815fe..14fbf672 100644 --- a/src/util.jl +++ b/src/util.jl @@ -1,6 +1,5 @@ using KernelAbstractions: get_backend, @index, @kernel using LoggingExtras -using Random # custom log macro _psolver = Logging.LogLevel(-123) # custom log level for pressure solver, needs the negative sign @@ -171,7 +170,8 @@ grab!(sym,ex::Symbol) = union!(sym,[ex]) # grab symbol name grab!(sym,ex) = nothing rep(ex) = ex rep(ex::Expr) = ex.head == :. ? Symbol(ex.args[2].value) : ex -symtypes(sym) = [Symbol.(randstring('A':'Z',4)) for _ in 1:length(sym)] +using Random +symtypes(sym) = [Symbol.(Random.randstring('A':'Z',4)) for _ in 1:length(sym)] joinsymtype(sym::Symbol,symT::Symbol) = Expr(:(::), sym, symT) joinsymtype(sym,symT) = zip(sym,symT) .|> x->joinsymtype(x...) From d2b3ade22b1901001a6a41e22bd9955a3987bd43 Mon Sep 17 00:00:00 2001 From: Bernat Font Date: Thu, 22 May 2025 23:57:48 +0200 Subject: [PATCH 17/20] Bumping CI to Julia 1.11, trying to fix Random pkg error during tests --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f0edd0a1..d131a8a0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,7 +26,7 @@ jobs: fail-fast: false matrix: version: - - '1.10' + - '1.11' os: - ubuntu-latest - macOS-latest @@ -67,7 +67,7 @@ jobs: else printf "[WaterLily]\nbackend = \"SIMD\"" > LocalPreferences.toml fi - julia --proj --color=yes -e "using Pkg; Pkg.test(; coverage=true);" + julia --proj --color=yes -e "using Pkg; Pkg.instantiate(); Pkg.test(; coverage=true);" - uses: julia-actions/julia-processcoverage@v1 - uses: codecov/codecov-action@v5 with: From 87cddb8ae70cc78928c019564451bfd18b26a70e Mon Sep 17 00:00:00 2001 From: Bernat Font Date: Fri, 23 May 2025 00:08:52 +0200 Subject: [PATCH 18/20] Removed x86 architecture from CI. --- .github/workflows/ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d131a8a0..3993e4d5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,7 +33,6 @@ jobs: - windows-latest arch: - x64 - - x86 nthreads: - '1' - 'auto' From f8633ea3b82aa8a8abb8a9d21573cc017da5331d Mon Sep 17 00:00:00 2001 From: Bernat Font Date: Sat, 24 May 2025 16:02:28 +0200 Subject: [PATCH 19/20] Moved nthreads check outside of __init__ so it is only checked once and not for every ext module when loading. --- src/WaterLily.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WaterLily.jl b/src/WaterLily.jl index 1d91fca8..13b202f6 100644 --- a/src/WaterLily.jl +++ b/src/WaterLily.jl @@ -180,6 +180,7 @@ function check_nthreads() """ end end +check_nthreads() # Backward compatibility for extensions if !isdefined(Base, :get_extension) @@ -196,7 +197,6 @@ function __init__() @require Meshing = "e6723b4c-ebff-59f1-b4b7-d97aa5274f73" include("../ext/WaterLilyMeshingExt.jl") @require JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819" include("../ext/WaterLilyJLD2Ext.jl") end - check_nthreads() end end # module From 7da05269fc7bfca0807a5c9bb631005b343c6bd5 Mon Sep 17 00:00:00 2001 From: Bernat Font Date: Sat, 24 May 2025 16:23:51 +0200 Subject: [PATCH 20/20] Added test for new routines used in automatic kernel generation. --- test/maintests.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/maintests.jl b/test/maintests.jl index d3ca2085..20973d13 100644 --- a/test/maintests.jl +++ b/test/maintests.jl @@ -1,5 +1,5 @@ using GPUArrays -using ReadVTK, WriteVTK, JLD2 +using ReadVTK, WriteVTK, JLD2, Random backend != "KernelAbstractions" && throw(ArgumentError("SIMD backend not allowed to run main tests, use KernelAbstractions backend")) @info "Test backends: $(join(arrays,", "))" @@ -18,6 +18,10 @@ backend != "KernelAbstractions" && throw(ArgumentError("SIMD backend not allowed WaterLily.grab!(sym,ex) @test ex == :(a[I, i] = Math.add(b[I], func(I, q))) @test sym == [:a, :I, :i, :(p.b), :q] + sym = [:a,:b,:c] + Random.seed!(99) + symT = WaterLily.symtypes(sym) + @test WaterLily.joinsymtype(sym,symT) == Expr[:(a::MDFZ), :(b::AXYU), :(c::RFIB)] for f ∈ arrays p = zeros(4,5) |> f