-
Notifications
You must be signed in to change notification settings - Fork 158
Switch to TestItems.jl setup #3096
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
JoshuaLampert
wants to merge
27
commits into
main
Choose a base branch
from
testitems
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+6,799
−6,819
Draft
Changes from 8 commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
331f6ab
initial TestItems.jl setup
JoshuaLampert 8ffb860
Merge branch 'main' into testitems
JoshuaLampert 8777ee0
comment broken testset
JoshuaLampert 3e250bc
migrate threaded, MPI, and KernelAbstraction tests
JoshuaLampert 9f4ab26
run threaded tests by default again
JoshuaLampert 51fa586
do not need to depend on TestItems
JoshuaLampert 9f41a50
fix MPI failures
JoshuaLampert 8b7d5a3
migrate GPU tests
JoshuaLampert b142728
clean up
JoshuaLampert 31340f3
Update test/runtests.jl
JoshuaLampert 3835ae2
Merge branch 'main' into testitems
JoshuaLampert 6873ac5
fix copy/paste error from merge conflict
JoshuaLampert 38faa53
Merge branch 'main' into testitems
JoshuaLampert f766e23
fix merge
JoshuaLampert 4ae4f2c
migrate remaining 1D tests
JoshuaLampert a1db7e4
format
JoshuaLampert cd1a794
remove unnecessary additions
JoshuaLampert c75bbd4
migrate remaining tree_part1
JoshuaLampert 9c36098
Merge branch 'main' into testitems
JoshuaLampert 8b1fbfa
migrate tree_part2
JoshuaLampert 3b1e053
Merge branch 'testitems' of https://github.com/trixi-framework/Trixi.…
JoshuaLampert 46813cc
migrate remaining tree tests
JoshuaLampert a0d173f
migrate miscellaneous tests
JoshuaLampert 84e8ceb
format
JoshuaLampert d84f173
fix some tests
JoshuaLampert c82b758
add missing at-test and fix reference value
JoshuaLampert 6f1bedd
Merge branch 'main' into testitems
JoshuaLampert File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,151 +1,138 @@ | ||
| using Test | ||
| using MPI: mpiexec | ||
| import Trixi | ||
| using TestItemRunner | ||
|
|
||
| # We run tests in parallel with CI jobs setting the `TRIXI_TEST` environment | ||
| # variable to determine the subset of tests to execute. | ||
| # By default, we just run the threaded tests since they are relatively cheap | ||
| # and test a good amount of different functionality. | ||
| # We run subsets of the test suite in parallel CI jobs by setting the `TRIXI_TEST` | ||
| # environment variable. Its value is matched against the `tags` attached to each | ||
| # `@testitem`. By default (`TRIXI_TEST == "threaded"`) we run everything. | ||
| const TRIXI_TEST = get(ENV, "TRIXI_TEST", "threaded") | ||
| # Some GitHub CI runners may have not much RAM and just 3 virtual CPU cores. | ||
|
|
||
| # Some GitHub CI runners may not have much RAM and just 3 virtual CPU cores. | ||
| # In this case, we do not want to use all of the cores to speed-up CI. | ||
| const TRIXI_MPI_NPROCS = clamp(Sys.CPU_THREADS - 1, 2, 3) | ||
| const TRIXI_NTHREADS = clamp(Sys.CPU_THREADS, 2, 3) | ||
|
|
||
| @time @testset "Trixi.jl tests" begin | ||
| # This is placed first since tests error out otherwise if `TRIXI_TEST == "all"`, | ||
| # at least on some systems. | ||
| @time if TRIXI_TEST == "all" || TRIXI_TEST == "mpi" | ||
| # Do a dummy `@test true`: | ||
| # If the process errors out the testset would error out as well, | ||
| # cf. https://github.com/JuliaParallel/MPI.jl/pull/391 | ||
| @test true | ||
|
|
||
| # We provide a `--heap-size-hint` to avoid/reduce out-of-memory errors during CI testing | ||
| run(`$(mpiexec()) -n $TRIXI_MPI_NPROCS $(Base.julia_cmd()) --threads=1 --check-bounds=yes --heap-size-hint=0.5G $(joinpath(@__DIR__, "test_mpi.jl"))`) | ||
| end | ||
|
|
||
| @time if TRIXI_TEST == "all" || TRIXI_TEST == "threaded" || | ||
| TRIXI_TEST == "threaded_legacy" | ||
| # Do a dummy `@test true`: | ||
| # If the process errors out the testset would error out as well, | ||
| # cf. https://github.com/JuliaParallel/MPI.jl/pull/391 | ||
| @test true | ||
|
|
||
| run(`$(Base.julia_cmd()) --threads=$TRIXI_NTHREADS --check-bounds=yes --code-coverage=none $(joinpath(@__DIR__, "test_threaded.jl"))`) | ||
| end | ||
|
|
||
| # Downgrade CI currently has issues with running julia processes via `run`, see | ||
| # https://github.com/trixi-framework/Trixi.jl/pull/2507#issuecomment-3990318366 | ||
| # So we run test_threaded.jl serially. | ||
| # For `TRIXI_TEST = "all"`, test_threaded.jl is already covered by the threaded run, so we don't need to run it again. | ||
| @time if TRIXI_TEST == "downgrade" | ||
| include(joinpath(@__DIR__, "test_threaded.jl")) | ||
| end | ||
|
|
||
| @time if TRIXI_TEST == "all" || TRIXI_TEST == "tree_part1" | ||
| include(joinpath(@__DIR__, "test_tree_1d.jl")) | ||
| include(joinpath(@__DIR__, "test_tree_2d_part1.jl")) | ||
| end | ||
| @time if TRIXI_TEST == "all" || TRIXI_TEST == "tree_part2" | ||
| include(joinpath(@__DIR__, "test_tree_2d_part2.jl")) | ||
| end | ||
| @time if TRIXI_TEST == "all" || TRIXI_TEST == "tree_part3" | ||
| include(joinpath(@__DIR__, "test_tree_2d_part3.jl")) | ||
| end | ||
| @time if TRIXI_TEST == "all" || TRIXI_TEST == "tree_part4" | ||
| include(joinpath(@__DIR__, "test_tree_3d_part1.jl")) | ||
| end | ||
| @time if TRIXI_TEST == "all" || TRIXI_TEST == "tree_part5" | ||
| include(joinpath(@__DIR__, "test_tree_3d_part2.jl")) | ||
| end | ||
| @time if TRIXI_TEST == "all" || TRIXI_TEST == "tree_part6" | ||
| include(joinpath(@__DIR__, "test_tree_3d_part3.jl")) | ||
| end | ||
|
|
||
| @time if TRIXI_TEST == "all" || TRIXI_TEST == "structured" | ||
| include(joinpath(@__DIR__, "test_structured_1d.jl")) | ||
| include(joinpath(@__DIR__, "test_structured_2d.jl")) | ||
| include(joinpath(@__DIR__, "test_structured_3d.jl")) | ||
| end | ||
|
|
||
| @time if TRIXI_TEST == "all" || TRIXI_TEST == "p4est_part1" | ||
| include(joinpath(@__DIR__, "test_p4est_2d.jl")) | ||
| end | ||
| @time if TRIXI_TEST == "all" || TRIXI_TEST == "p4est_part2" | ||
| include(joinpath(@__DIR__, "test_p4est_3d.jl")) | ||
| end | ||
|
|
||
| @time if TRIXI_TEST == "all" || TRIXI_TEST == "t8code_part1" | ||
| include(joinpath(@__DIR__, "test_t8code_2d.jl")) | ||
| end | ||
| @time if TRIXI_TEST == "all" || TRIXI_TEST == "t8code_part2" | ||
| include(joinpath(@__DIR__, "test_t8code_3d.jl")) | ||
| end | ||
| # A few suites cannot run in the ordinary in-process `@run_package_tests` model: | ||
| # they need a specially-launched Julia process - `mpi` (multiple ranks via | ||
| # `mpiexec`), `threaded` (multiple threads via `--threads`), and | ||
| # `kernelabstractions` (a different threading backend, selected via a preference | ||
| # that only takes effect on a fresh Julia start). We handle them by *relaunching* | ||
| # Julia/`mpiexec` on this very file: the launched worker re-enters `runtests.jl` | ||
| # with `TRIXI_TEST_RUN_ITEMS` set and then runs the tag-filtered test items | ||
| # in-process (`TestItemRunner` evaluates items in the current process, so this | ||
| # also works for every MPI rank). The `TRIXI_TEST` value of such a suite selects | ||
| # the items via the equally-named tag; `threaded_legacy` reuses the `threaded` | ||
| # items but is launched on a different Julia version by CI. | ||
| const SPECIAL_PROCESS_SUITES = ("mpi", "threaded", "kernelabstractions") | ||
| const IN_WORKER = haskey(ENV, "TRIXI_TEST_RUN_ITEMS") | ||
|
|
||
| target_tag(suite) = suite == "threaded_legacy" ? :threaded : Symbol(suite) | ||
|
|
||
| # Special suites this (parent) invocation will dispatch into their own processes. | ||
| const SUITES_TO_DISPATCH = if IN_WORKER | ||
| String[] | ||
| elseif TRIXI_TEST == "all" | ||
| collect(SPECIAL_PROCESS_SUITES) | ||
| elseif TRIXI_TEST in SPECIAL_PROCESS_SUITES || TRIXI_TEST == "threaded_legacy" | ||
| [TRIXI_TEST] | ||
| else | ||
| String[] | ||
| end | ||
|
|
||
| @time if TRIXI_TEST == "all" || TRIXI_TEST == "unstructured_dgmulti" | ||
| include(joinpath(@__DIR__, "test_unstructured_2d.jl")) | ||
| include(joinpath(@__DIR__, "test_dgmulti_1d.jl")) | ||
| include(joinpath(@__DIR__, "test_dgmulti_2d.jl")) | ||
| include(joinpath(@__DIR__, "test_dgmulti_3d.jl")) | ||
| end | ||
| # `import` is only allowed at top level, so load here what `dispatch_special_suite` | ||
| # needs: `MPI` for `mpiexec`, and `Trixi` to toggle the threading backend preference. | ||
| if "mpi" in SUITES_TO_DISPATCH | ||
| import MPI | ||
| end | ||
| if "kernelabstractions" in SUITES_TO_DISPATCH | ||
| import Trixi | ||
| end | ||
|
|
||
| @time if TRIXI_TEST == "all" || TRIXI_TEST == "parabolic_part1" | ||
| include(joinpath(@__DIR__, "test_parabolic_1d.jl")) | ||
| include(joinpath(@__DIR__, "test_parabolic_2d.jl")) | ||
| end | ||
| @time if TRIXI_TEST == "all" || TRIXI_TEST == "parabolic_part2" | ||
| include(joinpath(@__DIR__, "test_parabolic_3d.jl")) | ||
| end | ||
| # The GPU suites run their items only when the respective backend is `functional()`, | ||
| # so requesting `CUDA`/`AMDGPU` on a machine without that GPU warns and runs nothing | ||
| # instead of erroring. | ||
| RUN_CUDA = false | ||
| if !IN_WORKER && TRIXI_TEST in ("all", "CUDA") | ||
| import CUDA | ||
| RUN_CUDA = CUDA.functional() | ||
| RUN_CUDA || @warn "Unable to run CUDA tests on this machine" | ||
| end | ||
| RUN_AMDGPU = false | ||
| if !IN_WORKER && TRIXI_TEST in ("all", "AMDGPU") | ||
| import AMDGPU | ||
| RUN_AMDGPU = AMDGPU.functional() | ||
| RUN_AMDGPU || @warn "Unable to run AMDGPU tests on this machine" | ||
| end | ||
|
|
||
| @time if TRIXI_TEST == "all" || TRIXI_TEST == "misc_part1" | ||
| include(joinpath(@__DIR__, "test_unit.jl")) | ||
| include(joinpath(@__DIR__, "test_type.jl")) | ||
| include(joinpath(@__DIR__, "test_visualization.jl")) | ||
| end | ||
| @time if TRIXI_TEST == "all" || TRIXI_TEST == "misc_part2" | ||
| include(joinpath(@__DIR__, "test_special_elixirs.jl")) | ||
| include(joinpath(@__DIR__, "test_aqua.jl")) | ||
| end | ||
| # Relaunch Julia/`mpiexec` for a suite that needs a special process. The worker | ||
| # re-enters this file with `TRIXI_TEST=<suite>` and `TRIXI_TEST_RUN_ITEMS=true`. | ||
| function run_worker(cmd, suite) | ||
| run(addenv(cmd, "TRIXI_TEST_RUN_ITEMS" => "true", "TRIXI_TEST" => suite)) | ||
| end | ||
|
|
||
| @time if TRIXI_TEST == "all" || TRIXI_TEST == "performance_specializations" | ||
| include(joinpath(@__DIR__, "test_performance_specializations_2d.jl")) | ||
| include(joinpath(@__DIR__, "test_performance_specializations_3d.jl")) | ||
| function dispatch_special_suite(suite) | ||
| project = dirname(Base.active_project()) | ||
| julia = Base.julia_cmd() | ||
|
|
||
| if suite == "mpi" | ||
| cmd = `$(MPI.mpiexec()) -n $TRIXI_MPI_NPROCS $julia --threads=1 --check-bounds=yes --heap-size-hint=0.5G --project=$project $(@__FILE__)` | ||
| run_worker(cmd, suite) | ||
| elseif suite == "threaded" || suite == "threaded_legacy" | ||
| cmd = `$julia --threads=$TRIXI_NTHREADS --check-bounds=yes --code-coverage=none --project=$project $(@__FILE__)` | ||
| run_worker(cmd, suite) | ||
| elseif suite == "kernelabstractions" | ||
| # The threading backend is selected via a preference that is read on Julia | ||
| # startup, so we set it here (in the parent) and restore it afterwards; | ||
| # the relaunched worker picks it up. | ||
| previous_backend = Trixi._PREFERENCE_THREADING | ||
| Trixi.set_threading_backend!(:kernelabstractions) | ||
| try | ||
| cmd = `$julia --threads=$TRIXI_NTHREADS --check-bounds=yes --project=$project $(@__FILE__)` | ||
| run_worker(cmd, suite) | ||
| finally | ||
| Trixi.set_threading_backend!(Symbol(previous_backend)) | ||
| end | ||
| end | ||
| end | ||
|
|
||
| @time if TRIXI_TEST == "all" || TRIXI_TEST == "paper_self_gravitating_gas_dynamics" | ||
| include(joinpath(@__DIR__, "test_paper_self_gravitating_gas_dynamics.jl")) | ||
| end | ||
| if !isempty(SUITES_TO_DISPATCH) | ||
| # Dispatch each requested special suite into its own process; the worker(s) | ||
| # run the tagged items. For a single special suite that is all we do; for | ||
| # `all` we additionally run the remaining (in-process) items below. | ||
| foreach(dispatch_special_suite, SUITES_TO_DISPATCH) | ||
| end | ||
|
|
||
| @time if TRIXI_TEST == "all" || TRIXI_TEST == "CUDA" | ||
| import CUDA | ||
| if CUDA.functional() | ||
| include(joinpath(@__DIR__, "test_cuda_2d.jl")) | ||
| include(joinpath(@__DIR__, "test_cuda_3d.jl")) | ||
| if !IN_WORKER && (TRIXI_TEST in SPECIAL_PROCESS_SUITES || TRIXI_TEST == "threaded_legacy") | ||
| # A single special suite was requested and dispatched above; nothing to run | ||
| # in this process. | ||
| else | ||
| # In-process run. Either we are inside a launched worker (run just that suite's | ||
| # tagged items), or this is an ordinary partition / `all` (in which case we | ||
| # exclude the special suites, which must run in their own processes). | ||
| CI_ON_WINDOWS = (get(ENV, "GITHUB_ACTIONS", "false") == "true") && Sys.iswindows() | ||
| special_tags = (:mpi, :threaded, :kernelabstractions) | ||
| tag = target_tag(TRIXI_TEST) | ||
|
|
||
| @run_package_tests filter = ti -> begin | ||
| if TRIXI_TEST == "all" | ||
| # The special suites run in dedicated processes (see above). | ||
| any(t -> t in ti.tags, special_tags) && return false | ||
| else | ||
| @warn "Unable to run CUDA tests on this machine" | ||
| tag in ti.tags || return false | ||
| end | ||
| end | ||
|
|
||
| @time if TRIXI_TEST == "all" || TRIXI_TEST == "AMDGPU" | ||
| import AMDGPU | ||
| if AMDGPU.functional() | ||
| include(joinpath(@__DIR__, "test_amdgpu_2d.jl")) | ||
| include(joinpath(@__DIR__, "test_amdgpu_3d.jl")) | ||
| else | ||
| @warn "Unable to run AMDGPU tests on this machine" | ||
| # CI with MPI fails often on Windows for some examples; skip those there. | ||
| if CI_ON_WINDOWS && :mpi_skip_windows in ti.tags | ||
| return false | ||
| end | ||
| # GPU items run only when the respective backend is functional. | ||
| :CUDA in ti.tags && !RUN_CUDA && return false | ||
| :AMDGPU in ti.tags && !RUN_AMDGPU && return false | ||
| return true | ||
| end | ||
| end | ||
|
|
||
| @time if TRIXI_TEST == "all" || TRIXI_TEST == "kernelabstractions" | ||
| previous_backend = Trixi._PREFERENCE_THREADING | ||
| Trixi.set_threading_backend!(:kernelabstractions) | ||
| # relaunching julia | ||
| try | ||
| run(`$(Base.julia_cmd()) --threads=$TRIXI_NTHREADS --check-bounds=yes $(abspath("test_kernelabstractions.jl"))`) | ||
| finally | ||
| # Restore previous threading backend for later tests | ||
| Trixi.set_threading_backend!(Symbol(previous_backend)) | ||
| end | ||
| end | ||
| # Common setup shared by all `@testitem`s. Listing `setup=[Setup]` on a test item | ||
| # makes the `@test_trixi_include` helper macro (and the packages `test_trixi.jl` | ||
| # pulls in) available inside it. `using Trixi`/`using Test` are already provided | ||
| # automatically by the default imports of every `@testitem`/`@testsnippet`. | ||
| @testsnippet Setup begin | ||
| include("test_trixi.jl") | ||
| end | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.