From b69c8c5e7ed030259cef6ae2f00d2f577b6134e5 Mon Sep 17 00:00:00 2001 From: Max Date: Wed, 7 Oct 2026 22:55:46 +0200 Subject: [PATCH] Declare kernel outputs for PyccelKernels Each kernel folder's __init__.py declares the arguments its kernel writes to (OUTPUTS, passed to cunumpy as host_options={"outputs": OUTPUTS}); the PyccelKernel wraps in feec/mass.py, boundary_mass.py and basis_projection_ops.py pass outputs= too. The parity tests compare the declared outputs; new tests check the declarations on the NumPy backend and in the CPU emulation of the CUDA kernels. Solves #342. Co-Authored-By: Claude Opus 5.5 --- CUDA_STRATEGY.md | 10 +++++ .../eval_spline_mpi_markers/__init__.py | 5 ++- .../eval_spline_mpi_matrix/__init__.py | 5 ++- .../__init__.py | 5 ++- src/struphy/feec/basis_projection_ops.py | 1 + src/struphy/feec/boundary_mass.py | 4 +- .../feec/kernels/hybrid_weight/__init__.py | 5 ++- .../__init__.py | 7 ++- .../__init__.py | 7 ++- .../__init__.py | 7 ++- .../__init__.py | 7 ++- .../kernels/get_dofs_local_3_form/__init__.py | 5 ++- .../__init__.py | 5 ++- .../kernels/solve_local_main_loop/__init__.py | 5 ++- .../__init__.py | 5 ++- src/struphy/feec/mass.py | 5 ++- .../kernels/kernel_evaluate/__init__.py | 5 ++- .../kernels/kernel_evaluate_pic/__init__.py | 5 ++- .../kernels/kernel_pullpush/__init__.py | 5 ++- .../kernels/kernel_pullpush_pic/__init__.py | 5 ++- .../kernels/cc_lin_mhd_5d_D/__init__.py | 5 ++- .../kernels/cc_lin_mhd_5d_M/__init__.py | 5 ++- .../kernels/cc_lin_mhd_5d_curlb/__init__.py | 5 ++- .../kernels/cc_lin_mhd_5d_gradB/__init__.py | 5 ++- .../cc_lin_mhd_5d_gradB_dg/__init__.py | 5 ++- .../cc_lin_mhd_5d_gradB_dg_init/__init__.py | 5 ++- .../kernels/cc_lin_mhd_6d_1/__init__.py | 5 ++- .../kernels/cc_lin_mhd_6d_2/__init__.py | 5 ++- .../kernels/charge_density_0form/__init__.py | 5 ++- .../kernels/div_u_weak_1form/__init__.py | 5 ++- .../kernels/gc_density_0form/__init__.py | 5 ++- .../kernels/gc_mag_density_0form/__init__.py | 5 ++- .../kernels/linear_vlasov_ampere/__init__.py | 5 ++- .../kernels/pc_lin_mhd_6d/__init__.py | 7 ++- .../kernels/pc_lin_mhd_6d_full/__init__.py | 5 ++- .../kernels/vlasov_maxwell/__init__.py | 5 ++- .../canonical_kinetic_particles/__init__.py | 5 ++- .../__init__.py | 7 ++- .../__init__.py | 7 ++- .../kernels/eval_energy_5d/__init__.py | 5 ++- .../kernels/eval_gradB_ediff/__init__.py | 5 ++- .../eval_guiding_center_from_6d/__init__.py | 5 ++- .../__init__.py | 5 ++- .../eval_magnetic_energy_PBb/__init__.py | 5 ++- .../eval_magnetic_moment_5d/__init__.py | 5 ++- .../kernels/thermal_energy/__init__.py | 5 ++- .../pushing/kernels/bstar_2form/__init__.py | 5 ++- .../kernels/bstar_parallel_3form/__init__.py | 5 ++- .../driftkinetic_hamiltonian/__init__.py | 5 ++- .../grad_driftkinetic_hamiltonian/__init__.py | 5 ++- .../kernels/push_bxu_H1vec/__init__.py | 5 ++- .../kernels/push_bxu_Hcurl/__init__.py | 5 ++- .../pushing/kernels/push_bxu_Hdiv/__init__.py | 5 ++- .../kernels/push_bxu_Hdiv_pauli/__init__.py | 5 ++- .../__init__.py | 7 ++- .../kernels/push_eta_stage/__init__.py | 5 ++- .../__init__.py | 7 ++- .../__init__.py | 7 ++- .../__init__.py | 7 ++- .../__init__.py | 7 ++- .../__init__.py | 7 ++- .../__init__.py | 7 ++- .../__init__.py | 7 ++- .../__init__.py | 7 ++- .../kernels/push_gc_cc_J1_H1vec/__init__.py | 5 ++- .../kernels/push_gc_cc_J1_Hcurl/__init__.py | 5 ++- .../kernels/push_gc_cc_J1_Hdiv/__init__.py | 5 ++- .../kernels/push_gc_cc_J2_dg_Hdiv/__init__.py | 5 ++- .../push_gc_cc_J2_dg_init_Hdiv/__init__.py | 5 ++- .../push_gc_cc_J2_stage_H1vec/__init__.py | 5 ++- .../push_gc_cc_J2_stage_Hdiv/__init__.py | 5 ++- .../pushing/kernels/push_pc_GXu/__init__.py | 5 ++- .../kernels/push_pc_GXu_full/__init__.py | 5 ++- .../push_pc_eta_stage_H1vec/__init__.py | 5 ++- .../push_pc_eta_stage_Hcurl/__init__.py | 5 ++- .../push_pc_eta_stage_Hdiv/__init__.py | 5 ++- .../push_random_diffusion_stage/__init__.py | 5 ++- .../kernels/push_v_sph_pressure/__init__.py | 5 ++- .../push_v_sph_pressure_ideal_gas/__init__.py | 5 ++- .../kernels/push_v_viscosity/__init__.py | 5 ++- .../kernels/push_v_with_efield/__init__.py | 5 ++- .../kernels/push_vxb_analytic/__init__.py | 5 ++- .../kernels/push_vxb_implicit/__init__.py | 5 ++- .../__init__.py | 5 ++- .../pic/pushing/kernels/reflect/__init__.py | 5 ++- .../kernels/sph_isotherm_kappa/__init__.py | 5 ++- .../sph_mean_velocity_coeffs/__init__.py | 5 ++- .../kernels/sph_pressure_coeffs/__init__.py | 5 ++- .../kernels/sph_viscosity_tensor/__init__.py | 5 ++- .../pushing/kernels/unit_b_1form/__init__.py | 5 ++- .../box_based_evaluation_flat/__init__.py | 5 ++- .../box_based_evaluation_meshgrid/__init__.py | 5 ++- .../kernels/naive_evaluation_flat/__init__.py | 5 ++- .../naive_evaluation_meshgrid/__init__.py | 5 ++- src/struphy/pic/tests/cuda_parity_cases.py | 33 +++++++++++++- src/struphy/pic/tests/test_cuda_emulation.py | 38 +++++----------- src/struphy/pic/tests/test_cuda_parity.py | 44 +++++++++++++++++-- 97 files changed, 493 insertions(+), 124 deletions(-) diff --git a/CUDA_STRATEGY.md b/CUDA_STRATEGY.md index daf0d25f0..55498ec72 100644 --- a/CUDA_STRATEGY.md +++ b/CUDA_STRATEGY.md @@ -537,6 +537,16 @@ They are replaced by one test module, `pic/tests/cuda_parity_cases.py`: `PARITY_ `assert_kernels_agree` (one test per case), `test_cuda_emulation.py` to the CPU emulation, and `test_cuda_kernels_have_parity_cases` checks that the CUDA kernels and the parity cases match. +**Declared kernel outputs (#342).** Each kernel folder's `__init__.py` declares the arguments its kernel writes +to, by position, as `OUTPUTS` and passes them to cunumpy (`Kernel.from_folder(..., host_options={"outputs": +OUTPUTS})`); the `PyccelKernel(...)` wraps in `feec/mass.py`, `feec/boundary_mass.py` and +`feec/basis_projection_ops.py` pass `outputs=` too. Scratch arrays inside argument objects (`DerhamArguments.bn1`, +...) are not outputs. On the CuPy fallback only the outputs are copied back to the device; the GPU parity test +(`assert_kernels_agree`) compares only the outputs; `test_declared_outputs` checks on the NumPy backend that a kernel +changes its outputs and no other argument, and the CPU emulation test checks the same for the CUDA kernel. +`KernelCatalog.from_package` does not see the folders' `OUTPUTS`, so `test_cuda_parity` takes the kernels from the +folders (`DECLARED`). A new kernel folder declares `OUTPUTS` (`test_kernels_declare_outputs`). + ## PR 18 implementation notes Geometry evaluation runs on the GPU for every analytic mapping (`kind_map` 10–12, 20–22, 30–32). diff --git a/src/struphy/bsplines/kernels/eval_spline_mpi_markers/__init__.py b/src/struphy/bsplines/kernels/eval_spline_mpi_markers/__init__.py index faedc1370..51a9b6d32 100644 --- a/src/struphy/bsplines/kernels/eval_spline_mpi_markers/__init__.py +++ b/src/struphy/bsplines/kernels/eval_spline_mpi_markers/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -eval_spline_mpi_markers = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: values +OUTPUTS = (8,) + +eval_spline_mpi_markers = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/bsplines/kernels/eval_spline_mpi_matrix/__init__.py b/src/struphy/bsplines/kernels/eval_spline_mpi_matrix/__init__.py index 4b453f794..b501e532c 100644 --- a/src/struphy/bsplines/kernels/eval_spline_mpi_matrix/__init__.py +++ b/src/struphy/bsplines/kernels/eval_spline_mpi_matrix/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -eval_spline_mpi_matrix = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: values +OUTPUTS = (10,) + +eval_spline_mpi_matrix = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/bsplines/kernels/eval_spline_mpi_sparse_meshgrid/__init__.py b/src/struphy/bsplines/kernels/eval_spline_mpi_sparse_meshgrid/__init__.py index f7ae87826..8600c77fa 100644 --- a/src/struphy/bsplines/kernels/eval_spline_mpi_sparse_meshgrid/__init__.py +++ b/src/struphy/bsplines/kernels/eval_spline_mpi_sparse_meshgrid/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -eval_spline_mpi_sparse_meshgrid = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: values +OUTPUTS = (10,) + +eval_spline_mpi_sparse_meshgrid = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/feec/basis_projection_ops.py b/src/struphy/feec/basis_projection_ops.py index ba2c29dec..d87782299 100644 --- a/src/struphy/feec/basis_projection_ops.py +++ b/src/struphy/feec/basis_projection_ops.py @@ -2084,6 +2084,7 @@ def assemble(self, weights=None): basis_projection_kernels, "assemble_dofs_for_weighted_basisfuns_" + str(V.ldim) + "d", ), + outputs=(0,), # writes the matrix data ) logger.debug(f"Assemble block {i, j}") diff --git a/src/struphy/feec/boundary_mass.py b/src/struphy/feec/boundary_mass.py index 9c2953245..1382cd98d 100644 --- a/src/struphy/feec/boundary_mass.py +++ b/src/struphy/feec/boundary_mass.py @@ -173,8 +173,8 @@ def __init__( # for each active face, precompute per-space surface quadrature/geometric data self._setup_surface_data() - # load assembly kernel - self._assembly_kernel = PyccelKernel(mass_kernels.surface_kernel_3d_mat) + # load assembly kernel (writes the matrix data, its last argument) + self._assembly_kernel = PyccelKernel(mass_kernels.surface_kernel_3d_mat, outputs=(-1,)) self.assemble() diff --git a/src/struphy/feec/kernels/hybrid_weight/__init__.py b/src/struphy/feec/kernels/hybrid_weight/__init__.py index 7af87b677..c190ed2f5 100644 --- a/src/struphy/feec/kernels/hybrid_weight/__init__.py +++ b/src/struphy/feec/kernels/hybrid_weight/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -hybrid_weight = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: data1, data2, data3 +OUTPUTS = (15, 16, 17) + +hybrid_weight = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/feec/local_projectors/kernels/get_dofs_local_1_form_ec_component/__init__.py b/src/struphy/feec/local_projectors/kernels/get_dofs_local_1_form_ec_component/__init__.py index 7ebfc1574..039630c75 100644 --- a/src/struphy/feec/local_projectors/kernels/get_dofs_local_1_form_ec_component/__init__.py +++ b/src/struphy/feec/local_projectors/kernels/get_dofs_local_1_form_ec_component/__init__.py @@ -4,4 +4,9 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -get_dofs_local_1_form_ec_component = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: f_eval_aux +OUTPUTS = (2,) + +get_dofs_local_1_form_ec_component = Kernel.from_folder( + __name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS} +) diff --git a/src/struphy/feec/local_projectors/kernels/get_dofs_local_1_form_ec_component_weighted/__init__.py b/src/struphy/feec/local_projectors/kernels/get_dofs_local_1_form_ec_component_weighted/__init__.py index 9002340c1..a3d0d785c 100644 --- a/src/struphy/feec/local_projectors/kernels/get_dofs_local_1_form_ec_component_weighted/__init__.py +++ b/src/struphy/feec/local_projectors/kernels/get_dofs_local_1_form_ec_component_weighted/__init__.py @@ -4,4 +4,9 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -get_dofs_local_1_form_ec_component_weighted = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: f_eval_aux +OUTPUTS = (6,) + +get_dofs_local_1_form_ec_component_weighted = Kernel.from_folder( + __name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS} +) diff --git a/src/struphy/feec/local_projectors/kernels/get_dofs_local_2_form_ec_component/__init__.py b/src/struphy/feec/local_projectors/kernels/get_dofs_local_2_form_ec_component/__init__.py index 04d7262b0..1a3e78ed2 100644 --- a/src/struphy/feec/local_projectors/kernels/get_dofs_local_2_form_ec_component/__init__.py +++ b/src/struphy/feec/local_projectors/kernels/get_dofs_local_2_form_ec_component/__init__.py @@ -4,4 +4,9 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -get_dofs_local_2_form_ec_component = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: f_eval_aux +OUTPUTS = (2,) + +get_dofs_local_2_form_ec_component = Kernel.from_folder( + __name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS} +) diff --git a/src/struphy/feec/local_projectors/kernels/get_dofs_local_2_form_ec_component_weighted/__init__.py b/src/struphy/feec/local_projectors/kernels/get_dofs_local_2_form_ec_component_weighted/__init__.py index 2c27eab86..091907165 100644 --- a/src/struphy/feec/local_projectors/kernels/get_dofs_local_2_form_ec_component_weighted/__init__.py +++ b/src/struphy/feec/local_projectors/kernels/get_dofs_local_2_form_ec_component_weighted/__init__.py @@ -4,4 +4,9 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -get_dofs_local_2_form_ec_component_weighted = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: f_eval_aux +OUTPUTS = (7,) + +get_dofs_local_2_form_ec_component_weighted = Kernel.from_folder( + __name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS} +) diff --git a/src/struphy/feec/local_projectors/kernels/get_dofs_local_3_form/__init__.py b/src/struphy/feec/local_projectors/kernels/get_dofs_local_3_form/__init__.py index e684886ec..692975a95 100644 --- a/src/struphy/feec/local_projectors/kernels/get_dofs_local_3_form/__init__.py +++ b/src/struphy/feec/local_projectors/kernels/get_dofs_local_3_form/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -get_dofs_local_3_form = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: f_eval +OUTPUTS = (2,) + +get_dofs_local_3_form = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/feec/local_projectors/kernels/get_dofs_local_3_form_weighted/__init__.py b/src/struphy/feec/local_projectors/kernels/get_dofs_local_3_form_weighted/__init__.py index 1c6556895..137bb5a33 100644 --- a/src/struphy/feec/local_projectors/kernels/get_dofs_local_3_form_weighted/__init__.py +++ b/src/struphy/feec/local_projectors/kernels/get_dofs_local_3_form_weighted/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -get_dofs_local_3_form_weighted = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: f_eval +OUTPUTS = (8,) + +get_dofs_local_3_form_weighted = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/feec/local_projectors/kernels/solve_local_main_loop/__init__.py b/src/struphy/feec/local_projectors/kernels/solve_local_main_loop/__init__.py index b973111c4..0ea091d02 100644 --- a/src/struphy/feec/local_projectors/kernels/solve_local_main_loop/__init__.py +++ b/src/struphy/feec/local_projectors/kernels/solve_local_main_loop/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -solve_local_main_loop = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: out +OUTPUTS = (2,) + +solve_local_main_loop = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/feec/local_projectors/kernels/solve_local_main_loop_weighted/__init__.py b/src/struphy/feec/local_projectors/kernels/solve_local_main_loop_weighted/__init__.py index 9fd6131fe..5f2b7aea7 100644 --- a/src/struphy/feec/local_projectors/kernels/solve_local_main_loop_weighted/__init__.py +++ b/src/struphy/feec/local_projectors/kernels/solve_local_main_loop_weighted/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -solve_local_main_loop_weighted = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: out +OUTPUTS = (8,) + +solve_local_main_loop_weighted = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/feec/mass.py b/src/struphy/feec/mass.py index e56a19af0..0e229dd32 100644 --- a/src/struphy/feec/mass.py +++ b/src/struphy/feec/mass.py @@ -1935,6 +1935,7 @@ def _load_assembly_kernel(self): mass_kernels, "kernel_" + str(self._V.ldim) + "d_mat", ), + outputs=(-1,), # writes the matrix data ) @property @@ -2570,7 +2571,7 @@ def eval_quad(self, W, coeffs, out=None): assert isinstance(out, (list, tuple)) # load assembly kernel - kernel = PyccelKernel(getattr(mass_kernels, "kernel_" + str(W.ldim) + "d_eval")) + kernel = PyccelKernel(getattr(mass_kernels, "kernel_" + str(W.ldim) + "d_eval"), outputs=(-1,)) # writes `out` # loop over components for a, wspace in enumerate(Wspaces): @@ -2673,6 +2674,7 @@ def __init__(self, derham, V, W, weights=None, nquads=None): mass_kernels, "kernel_" + str(self._V.ldim) + "d_matrixfree", ), + outputs=(-2,), # writes the data of `out` (the last argument is the input vector) ) self._diag_kernel = PyccelKernel( @@ -2680,6 +2682,7 @@ def __init__(self, derham, V, W, weights=None, nquads=None): mass_kernels, "kernel_" + str(self._V.ldim) + "d_diag", ), + outputs=(-1,), # writes the diagonal data ) # temporary with ghost regions for the diagonal (contributions to other processes are exchanged) diff --git a/src/struphy/geometry/kernels/kernel_evaluate/__init__.py b/src/struphy/geometry/kernels/kernel_evaluate/__init__.py index 2dce667df..86641f545 100644 --- a/src/struphy/geometry/kernels/kernel_evaluate/__init__.py +++ b/src/struphy/geometry/kernels/kernel_evaluate/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -kernel_evaluate = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: mat_f +OUTPUTS = (5,) + +kernel_evaluate = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/geometry/kernels/kernel_evaluate_pic/__init__.py b/src/struphy/geometry/kernels/kernel_evaluate_pic/__init__.py index 84ab2776b..232efa05b 100644 --- a/src/struphy/geometry/kernels/kernel_evaluate_pic/__init__.py +++ b/src/struphy/geometry/kernels/kernel_evaluate_pic/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -kernel_evaluate_pic = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: mat_f +OUTPUTS = (3,) + +kernel_evaluate_pic = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/geometry/kernels/kernel_pullpush/__init__.py b/src/struphy/geometry/kernels/kernel_pullpush/__init__.py index 3d3ca4de1..6dfb2c205 100644 --- a/src/struphy/geometry/kernels/kernel_pullpush/__init__.py +++ b/src/struphy/geometry/kernels/kernel_pullpush/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -kernel_pullpush = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: out +OUTPUTS = (8,) + +kernel_pullpush = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/geometry/kernels/kernel_pullpush_pic/__init__.py b/src/struphy/geometry/kernels/kernel_pullpush_pic/__init__.py index 682cdf221..a23c932a7 100644 --- a/src/struphy/geometry/kernels/kernel_pullpush_pic/__init__.py +++ b/src/struphy/geometry/kernels/kernel_pullpush_pic/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -kernel_pullpush_pic = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: out +OUTPUTS = (5,) + +kernel_pullpush_pic = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/accumulation/kernels/cc_lin_mhd_5d_D/__init__.py b/src/struphy/pic/accumulation/kernels/cc_lin_mhd_5d_D/__init__.py index 27af54854..fd8ecbf4d 100644 --- a/src/struphy/pic/accumulation/kernels/cc_lin_mhd_5d_D/__init__.py +++ b/src/struphy/pic/accumulation/kernels/cc_lin_mhd_5d_D/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -cc_lin_mhd_5d_D = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: mat12, mat13, mat23 +OUTPUTS = (3, 4, 5) + +cc_lin_mhd_5d_D = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/accumulation/kernels/cc_lin_mhd_5d_M/__init__.py b/src/struphy/pic/accumulation/kernels/cc_lin_mhd_5d_M/__init__.py index b2f152444..65309988a 100644 --- a/src/struphy/pic/accumulation/kernels/cc_lin_mhd_5d_M/__init__.py +++ b/src/struphy/pic/accumulation/kernels/cc_lin_mhd_5d_M/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -cc_lin_mhd_5d_M = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: vec1, vec2, vec3 +OUTPUTS = (9, 10, 11) + +cc_lin_mhd_5d_M = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/accumulation/kernels/cc_lin_mhd_5d_curlb/__init__.py b/src/struphy/pic/accumulation/kernels/cc_lin_mhd_5d_curlb/__init__.py index c8bfc2422..7b158ed13 100644 --- a/src/struphy/pic/accumulation/kernels/cc_lin_mhd_5d_curlb/__init__.py +++ b/src/struphy/pic/accumulation/kernels/cc_lin_mhd_5d_curlb/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -cc_lin_mhd_5d_curlb = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: mat11 to vec3 +OUTPUTS = tuple(range(3, 12)) + +cc_lin_mhd_5d_curlb = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/accumulation/kernels/cc_lin_mhd_5d_gradB/__init__.py b/src/struphy/pic/accumulation/kernels/cc_lin_mhd_5d_gradB/__init__.py index 33cdbb970..d7519aae2 100644 --- a/src/struphy/pic/accumulation/kernels/cc_lin_mhd_5d_gradB/__init__.py +++ b/src/struphy/pic/accumulation/kernels/cc_lin_mhd_5d_gradB/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -cc_lin_mhd_5d_gradB = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: vec1, vec2, vec3 +OUTPUTS = (9, 10, 11) + +cc_lin_mhd_5d_gradB = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/accumulation/kernels/cc_lin_mhd_5d_gradB_dg/__init__.py b/src/struphy/pic/accumulation/kernels/cc_lin_mhd_5d_gradB_dg/__init__.py index 15ead0123..7fe56051a 100644 --- a/src/struphy/pic/accumulation/kernels/cc_lin_mhd_5d_gradB_dg/__init__.py +++ b/src/struphy/pic/accumulation/kernels/cc_lin_mhd_5d_gradB_dg/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -cc_lin_mhd_5d_gradB_dg = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: vec1, vec2, vec3 +OUTPUTS = (3, 4, 5) + +cc_lin_mhd_5d_gradB_dg = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/accumulation/kernels/cc_lin_mhd_5d_gradB_dg_init/__init__.py b/src/struphy/pic/accumulation/kernels/cc_lin_mhd_5d_gradB_dg_init/__init__.py index 464b9a7a9..61d48afd2 100644 --- a/src/struphy/pic/accumulation/kernels/cc_lin_mhd_5d_gradB_dg_init/__init__.py +++ b/src/struphy/pic/accumulation/kernels/cc_lin_mhd_5d_gradB_dg_init/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -cc_lin_mhd_5d_gradB_dg_init = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: vec1, vec2, vec3 +OUTPUTS = (3, 4, 5) + +cc_lin_mhd_5d_gradB_dg_init = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/accumulation/kernels/cc_lin_mhd_6d_1/__init__.py b/src/struphy/pic/accumulation/kernels/cc_lin_mhd_6d_1/__init__.py index be58bb73f..2deeae23b 100644 --- a/src/struphy/pic/accumulation/kernels/cc_lin_mhd_6d_1/__init__.py +++ b/src/struphy/pic/accumulation/kernels/cc_lin_mhd_6d_1/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -cc_lin_mhd_6d_1 = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: mat12, mat13, mat23 +OUTPUTS = (3, 4, 5) + +cc_lin_mhd_6d_1 = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/accumulation/kernels/cc_lin_mhd_6d_2/__init__.py b/src/struphy/pic/accumulation/kernels/cc_lin_mhd_6d_2/__init__.py index 7aaac64c9..daad46474 100644 --- a/src/struphy/pic/accumulation/kernels/cc_lin_mhd_6d_2/__init__.py +++ b/src/struphy/pic/accumulation/kernels/cc_lin_mhd_6d_2/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -cc_lin_mhd_6d_2 = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: mat11 to vec3 +OUTPUTS = tuple(range(3, 12)) + +cc_lin_mhd_6d_2 = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/accumulation/kernels/charge_density_0form/__init__.py b/src/struphy/pic/accumulation/kernels/charge_density_0form/__init__.py index b136492c0..aae4e3397 100644 --- a/src/struphy/pic/accumulation/kernels/charge_density_0form/__init__.py +++ b/src/struphy/pic/accumulation/kernels/charge_density_0form/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -charge_density_0form = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: vec +OUTPUTS = (3,) + +charge_density_0form = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/accumulation/kernels/div_u_weak_1form/__init__.py b/src/struphy/pic/accumulation/kernels/div_u_weak_1form/__init__.py index a53a9782b..9898dee75 100644 --- a/src/struphy/pic/accumulation/kernels/div_u_weak_1form/__init__.py +++ b/src/struphy/pic/accumulation/kernels/div_u_weak_1form/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -div_u_weak_1form = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: vec1, vec2, vec3 +OUTPUTS = (3, 4, 5) + +div_u_weak_1form = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/accumulation/kernels/gc_density_0form/__init__.py b/src/struphy/pic/accumulation/kernels/gc_density_0form/__init__.py index 9ba544769..3fbe54e81 100644 --- a/src/struphy/pic/accumulation/kernels/gc_density_0form/__init__.py +++ b/src/struphy/pic/accumulation/kernels/gc_density_0form/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -gc_density_0form = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: vec +OUTPUTS = (3,) + +gc_density_0form = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/accumulation/kernels/gc_mag_density_0form/__init__.py b/src/struphy/pic/accumulation/kernels/gc_mag_density_0form/__init__.py index d7bfa1346..f207c7756 100644 --- a/src/struphy/pic/accumulation/kernels/gc_mag_density_0form/__init__.py +++ b/src/struphy/pic/accumulation/kernels/gc_mag_density_0form/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -gc_mag_density_0form = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: vec +OUTPUTS = (3,) + +gc_mag_density_0form = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/accumulation/kernels/linear_vlasov_ampere/__init__.py b/src/struphy/pic/accumulation/kernels/linear_vlasov_ampere/__init__.py index 0fed66c87..035b53986 100644 --- a/src/struphy/pic/accumulation/kernels/linear_vlasov_ampere/__init__.py +++ b/src/struphy/pic/accumulation/kernels/linear_vlasov_ampere/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -linear_vlasov_ampere = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: mat11 to vec3 +OUTPUTS = tuple(range(3, 12)) + +linear_vlasov_ampere = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/accumulation/kernels/pc_lin_mhd_6d/__init__.py b/src/struphy/pic/accumulation/kernels/pc_lin_mhd_6d/__init__.py index ddb2e6fb4..616275df4 100644 --- a/src/struphy/pic/accumulation/kernels/pc_lin_mhd_6d/__init__.py +++ b/src/struphy/pic/accumulation/kernels/pc_lin_mhd_6d/__init__.py @@ -4,4 +4,9 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -pc_lin_mhd_6d = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: mat11_11, mat12_11, mat13_11, mat22_11, mat23_11, mat33_11, +# mat11_12, mat12_12, mat13_12, mat22_12, mat23_12, mat33_12, mat11_22, mat12_22, mat13_22, mat22_22, mat23_22, +# mat33_22, vec1_1, vec2_1, vec3_1, vec1_2, vec2_2, vec3_2 +OUTPUTS = (3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 21, 22, 23, 24, 25, 26, 39, 40, 41, 42, 43, 44) + +pc_lin_mhd_6d = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/accumulation/kernels/pc_lin_mhd_6d_full/__init__.py b/src/struphy/pic/accumulation/kernels/pc_lin_mhd_6d_full/__init__.py index 97a011e8b..456e05263 100644 --- a/src/struphy/pic/accumulation/kernels/pc_lin_mhd_6d_full/__init__.py +++ b/src/struphy/pic/accumulation/kernels/pc_lin_mhd_6d_full/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -pc_lin_mhd_6d_full = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: mat11_11 to vec3_3 +OUTPUTS = tuple(range(3, 48)) + +pc_lin_mhd_6d_full = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/accumulation/kernels/vlasov_maxwell/__init__.py b/src/struphy/pic/accumulation/kernels/vlasov_maxwell/__init__.py index 8cfb5fc55..19cee8249 100644 --- a/src/struphy/pic/accumulation/kernels/vlasov_maxwell/__init__.py +++ b/src/struphy/pic/accumulation/kernels/vlasov_maxwell/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -vlasov_maxwell = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: mat11 to vec3 +OUTPUTS = tuple(range(3, 12)) + +vlasov_maxwell = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/diagnostics/kernels/canonical_kinetic_particles/__init__.py b/src/struphy/pic/diagnostics/kernels/canonical_kinetic_particles/__init__.py index 48f837548..c7f49bbb2 100644 --- a/src/struphy/pic/diagnostics/kernels/canonical_kinetic_particles/__init__.py +++ b/src/struphy/pic/diagnostics/kernels/canonical_kinetic_particles/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -canonical_kinetic_particles = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: res +OUTPUTS = (0,) + +canonical_kinetic_particles = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/diagnostics/kernels/eval_canonical_toroidal_moment_5d/__init__.py b/src/struphy/pic/diagnostics/kernels/eval_canonical_toroidal_moment_5d/__init__.py index 7c0d66d24..a826c4798 100644 --- a/src/struphy/pic/diagnostics/kernels/eval_canonical_toroidal_moment_5d/__init__.py +++ b/src/struphy/pic/diagnostics/kernels/eval_canonical_toroidal_moment_5d/__init__.py @@ -4,4 +4,9 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -eval_canonical_toroidal_moment_5d = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: markers +OUTPUTS = (0,) + +eval_canonical_toroidal_moment_5d = Kernel.from_folder( + __name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS} +) diff --git a/src/struphy/pic/diagnostics/kernels/eval_canonical_toroidal_moment_6d/__init__.py b/src/struphy/pic/diagnostics/kernels/eval_canonical_toroidal_moment_6d/__init__.py index fb815faa4..3bd33e1af 100644 --- a/src/struphy/pic/diagnostics/kernels/eval_canonical_toroidal_moment_6d/__init__.py +++ b/src/struphy/pic/diagnostics/kernels/eval_canonical_toroidal_moment_6d/__init__.py @@ -4,4 +4,9 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -eval_canonical_toroidal_moment_6d = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: markers +OUTPUTS = (0,) + +eval_canonical_toroidal_moment_6d = Kernel.from_folder( + __name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS} +) diff --git a/src/struphy/pic/diagnostics/kernels/eval_energy_5d/__init__.py b/src/struphy/pic/diagnostics/kernels/eval_energy_5d/__init__.py index 2e2c02830..da11b29d1 100644 --- a/src/struphy/pic/diagnostics/kernels/eval_energy_5d/__init__.py +++ b/src/struphy/pic/diagnostics/kernels/eval_energy_5d/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -eval_energy_5d = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: markers +OUTPUTS = (0,) + +eval_energy_5d = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/diagnostics/kernels/eval_gradB_ediff/__init__.py b/src/struphy/pic/diagnostics/kernels/eval_gradB_ediff/__init__.py index 80e6a8201..e35d2ae9f 100644 --- a/src/struphy/pic/diagnostics/kernels/eval_gradB_ediff/__init__.py +++ b/src/struphy/pic/diagnostics/kernels/eval_gradB_ediff/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -eval_gradB_ediff = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (0,) + +eval_gradB_ediff = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/diagnostics/kernels/eval_guiding_center_from_6d/__init__.py b/src/struphy/pic/diagnostics/kernels/eval_guiding_center_from_6d/__init__.py index 161f4bf10..984ff87e6 100644 --- a/src/struphy/pic/diagnostics/kernels/eval_guiding_center_from_6d/__init__.py +++ b/src/struphy/pic/diagnostics/kernels/eval_guiding_center_from_6d/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -eval_guiding_center_from_6d = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: markers +OUTPUTS = (0,) + +eval_guiding_center_from_6d = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/diagnostics/kernels/eval_magnetic_background_energy/__init__.py b/src/struphy/pic/diagnostics/kernels/eval_magnetic_background_energy/__init__.py index 4402687bc..6f4ba75f0 100644 --- a/src/struphy/pic/diagnostics/kernels/eval_magnetic_background_energy/__init__.py +++ b/src/struphy/pic/diagnostics/kernels/eval_magnetic_background_energy/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -eval_magnetic_background_energy = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: markers +OUTPUTS = (0,) + +eval_magnetic_background_energy = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/diagnostics/kernels/eval_magnetic_energy_PBb/__init__.py b/src/struphy/pic/diagnostics/kernels/eval_magnetic_energy_PBb/__init__.py index b6475cd0c..90e1014be 100644 --- a/src/struphy/pic/diagnostics/kernels/eval_magnetic_energy_PBb/__init__.py +++ b/src/struphy/pic/diagnostics/kernels/eval_magnetic_energy_PBb/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -eval_magnetic_energy_PBb = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: markers +OUTPUTS = (0,) + +eval_magnetic_energy_PBb = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/diagnostics/kernels/eval_magnetic_moment_5d/__init__.py b/src/struphy/pic/diagnostics/kernels/eval_magnetic_moment_5d/__init__.py index 02ae3acd8..f88bd9265 100644 --- a/src/struphy/pic/diagnostics/kernels/eval_magnetic_moment_5d/__init__.py +++ b/src/struphy/pic/diagnostics/kernels/eval_magnetic_moment_5d/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -eval_magnetic_moment_5d = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: markers +OUTPUTS = (0,) + +eval_magnetic_moment_5d = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/diagnostics/kernels/thermal_energy/__init__.py b/src/struphy/pic/diagnostics/kernels/thermal_energy/__init__.py index 326b75882..3866e6cb3 100644 --- a/src/struphy/pic/diagnostics/kernels/thermal_energy/__init__.py +++ b/src/struphy/pic/diagnostics/kernels/thermal_energy/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -thermal_energy = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: res +OUTPUTS = (0,) + +thermal_energy = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/bstar_2form/__init__.py b/src/struphy/pic/pushing/kernels/bstar_2form/__init__.py index cea1e83ad..a3b28a3b4 100644 --- a/src/struphy/pic/pushing/kernels/bstar_2form/__init__.py +++ b/src/struphy/pic/pushing/kernels/bstar_2form/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -bstar_2form = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +bstar_2form = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/bstar_parallel_3form/__init__.py b/src/struphy/pic/pushing/kernels/bstar_parallel_3form/__init__.py index 20ce21b71..1380958bd 100644 --- a/src/struphy/pic/pushing/kernels/bstar_parallel_3form/__init__.py +++ b/src/struphy/pic/pushing/kernels/bstar_parallel_3form/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -bstar_parallel_3form = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +bstar_parallel_3form = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/driftkinetic_hamiltonian/__init__.py b/src/struphy/pic/pushing/kernels/driftkinetic_hamiltonian/__init__.py index ae1cf069d..f297dc991 100644 --- a/src/struphy/pic/pushing/kernels/driftkinetic_hamiltonian/__init__.py +++ b/src/struphy/pic/pushing/kernels/driftkinetic_hamiltonian/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -driftkinetic_hamiltonian = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +driftkinetic_hamiltonian = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/grad_driftkinetic_hamiltonian/__init__.py b/src/struphy/pic/pushing/kernels/grad_driftkinetic_hamiltonian/__init__.py index 1ebe8b1a6..a71e77859 100644 --- a/src/struphy/pic/pushing/kernels/grad_driftkinetic_hamiltonian/__init__.py +++ b/src/struphy/pic/pushing/kernels/grad_driftkinetic_hamiltonian/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -grad_driftkinetic_hamiltonian = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +grad_driftkinetic_hamiltonian = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/push_bxu_H1vec/__init__.py b/src/struphy/pic/pushing/kernels/push_bxu_H1vec/__init__.py index a42e017cd..2bc1dc3d6 100644 --- a/src/struphy/pic/pushing/kernels/push_bxu_H1vec/__init__.py +++ b/src/struphy/pic/pushing/kernels/push_bxu_H1vec/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -push_bxu_H1vec = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +push_bxu_H1vec = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/push_bxu_Hcurl/__init__.py b/src/struphy/pic/pushing/kernels/push_bxu_Hcurl/__init__.py index 8f07d5295..952f71d8b 100644 --- a/src/struphy/pic/pushing/kernels/push_bxu_Hcurl/__init__.py +++ b/src/struphy/pic/pushing/kernels/push_bxu_Hcurl/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -push_bxu_Hcurl = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +push_bxu_Hcurl = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/push_bxu_Hdiv/__init__.py b/src/struphy/pic/pushing/kernels/push_bxu_Hdiv/__init__.py index ce4a76f60..0fe720316 100644 --- a/src/struphy/pic/pushing/kernels/push_bxu_Hdiv/__init__.py +++ b/src/struphy/pic/pushing/kernels/push_bxu_Hdiv/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -push_bxu_Hdiv = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +push_bxu_Hdiv = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/push_bxu_Hdiv_pauli/__init__.py b/src/struphy/pic/pushing/kernels/push_bxu_Hdiv_pauli/__init__.py index 124a2aa03..588109995 100644 --- a/src/struphy/pic/pushing/kernels/push_bxu_Hdiv_pauli/__init__.py +++ b/src/struphy/pic/pushing/kernels/push_bxu_Hdiv_pauli/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -push_bxu_Hdiv_pauli = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +push_bxu_Hdiv_pauli = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/push_deterministic_diffusion_stage/__init__.py b/src/struphy/pic/pushing/kernels/push_deterministic_diffusion_stage/__init__.py index 28b8bc04a..b1675edb1 100644 --- a/src/struphy/pic/pushing/kernels/push_deterministic_diffusion_stage/__init__.py +++ b/src/struphy/pic/pushing/kernels/push_deterministic_diffusion_stage/__init__.py @@ -4,4 +4,9 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -push_deterministic_diffusion_stage = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +push_deterministic_diffusion_stage = Kernel.from_folder( + __name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS} +) diff --git a/src/struphy/pic/pushing/kernels/push_eta_stage/__init__.py b/src/struphy/pic/pushing/kernels/push_eta_stage/__init__.py index c15cc7df7..8eb94d296 100644 --- a/src/struphy/pic/pushing/kernels/push_eta_stage/__init__.py +++ b/src/struphy/pic/pushing/kernels/push_eta_stage/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -push_eta_stage = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +push_eta_stage = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/push_gc_Bstar_discrete_gradient_1st_order/__init__.py b/src/struphy/pic/pushing/kernels/push_gc_Bstar_discrete_gradient_1st_order/__init__.py index 679af23ac..f1e64f813 100644 --- a/src/struphy/pic/pushing/kernels/push_gc_Bstar_discrete_gradient_1st_order/__init__.py +++ b/src/struphy/pic/pushing/kernels/push_gc_Bstar_discrete_gradient_1st_order/__init__.py @@ -4,4 +4,9 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -push_gc_Bstar_discrete_gradient_1st_order = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +push_gc_Bstar_discrete_gradient_1st_order = Kernel.from_folder( + __name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS} +) diff --git a/src/struphy/pic/pushing/kernels/push_gc_Bstar_discrete_gradient_1st_order_newton/__init__.py b/src/struphy/pic/pushing/kernels/push_gc_Bstar_discrete_gradient_1st_order_newton/__init__.py index c2353c0b2..0b34ce8e5 100644 --- a/src/struphy/pic/pushing/kernels/push_gc_Bstar_discrete_gradient_1st_order_newton/__init__.py +++ b/src/struphy/pic/pushing/kernels/push_gc_Bstar_discrete_gradient_1st_order_newton/__init__.py @@ -4,4 +4,9 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -push_gc_Bstar_discrete_gradient_1st_order_newton = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +push_gc_Bstar_discrete_gradient_1st_order_newton = Kernel.from_folder( + __name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS} +) diff --git a/src/struphy/pic/pushing/kernels/push_gc_Bstar_discrete_gradient_2nd_order/__init__.py b/src/struphy/pic/pushing/kernels/push_gc_Bstar_discrete_gradient_2nd_order/__init__.py index 36ccd7504..b29a2e6d4 100644 --- a/src/struphy/pic/pushing/kernels/push_gc_Bstar_discrete_gradient_2nd_order/__init__.py +++ b/src/struphy/pic/pushing/kernels/push_gc_Bstar_discrete_gradient_2nd_order/__init__.py @@ -4,4 +4,9 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -push_gc_Bstar_discrete_gradient_2nd_order = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +push_gc_Bstar_discrete_gradient_2nd_order = Kernel.from_folder( + __name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS} +) diff --git a/src/struphy/pic/pushing/kernels/push_gc_Bstar_explicit_multistage/__init__.py b/src/struphy/pic/pushing/kernels/push_gc_Bstar_explicit_multistage/__init__.py index 6c3cc2553..93f13d700 100644 --- a/src/struphy/pic/pushing/kernels/push_gc_Bstar_explicit_multistage/__init__.py +++ b/src/struphy/pic/pushing/kernels/push_gc_Bstar_explicit_multistage/__init__.py @@ -4,4 +4,9 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -push_gc_Bstar_explicit_multistage = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +push_gc_Bstar_explicit_multistage = Kernel.from_folder( + __name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS} +) diff --git a/src/struphy/pic/pushing/kernels/push_gc_bxEstar_dg_1st_order_newton/__init__.py b/src/struphy/pic/pushing/kernels/push_gc_bxEstar_dg_1st_order_newton/__init__.py index 9d338fb59..cde9382a0 100644 --- a/src/struphy/pic/pushing/kernels/push_gc_bxEstar_dg_1st_order_newton/__init__.py +++ b/src/struphy/pic/pushing/kernels/push_gc_bxEstar_dg_1st_order_newton/__init__.py @@ -4,4 +4,9 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -push_gc_bxEstar_dg_1st_order_newton = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +push_gc_bxEstar_dg_1st_order_newton = Kernel.from_folder( + __name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS} +) diff --git a/src/struphy/pic/pushing/kernels/push_gc_bxEstar_discrete_gradient_1st_order/__init__.py b/src/struphy/pic/pushing/kernels/push_gc_bxEstar_discrete_gradient_1st_order/__init__.py index b448e012c..cda6756a8 100644 --- a/src/struphy/pic/pushing/kernels/push_gc_bxEstar_discrete_gradient_1st_order/__init__.py +++ b/src/struphy/pic/pushing/kernels/push_gc_bxEstar_discrete_gradient_1st_order/__init__.py @@ -4,4 +4,9 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -push_gc_bxEstar_discrete_gradient_1st_order = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +push_gc_bxEstar_discrete_gradient_1st_order = Kernel.from_folder( + __name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS} +) diff --git a/src/struphy/pic/pushing/kernels/push_gc_bxEstar_discrete_gradient_2nd_order/__init__.py b/src/struphy/pic/pushing/kernels/push_gc_bxEstar_discrete_gradient_2nd_order/__init__.py index 9f85ee929..2f33964a7 100644 --- a/src/struphy/pic/pushing/kernels/push_gc_bxEstar_discrete_gradient_2nd_order/__init__.py +++ b/src/struphy/pic/pushing/kernels/push_gc_bxEstar_discrete_gradient_2nd_order/__init__.py @@ -4,4 +4,9 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -push_gc_bxEstar_discrete_gradient_2nd_order = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +push_gc_bxEstar_discrete_gradient_2nd_order = Kernel.from_folder( + __name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS} +) diff --git a/src/struphy/pic/pushing/kernels/push_gc_bxEstar_explicit_multistage/__init__.py b/src/struphy/pic/pushing/kernels/push_gc_bxEstar_explicit_multistage/__init__.py index 3b9218ad5..3b1385b20 100644 --- a/src/struphy/pic/pushing/kernels/push_gc_bxEstar_explicit_multistage/__init__.py +++ b/src/struphy/pic/pushing/kernels/push_gc_bxEstar_explicit_multistage/__init__.py @@ -4,4 +4,9 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -push_gc_bxEstar_explicit_multistage = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +push_gc_bxEstar_explicit_multistage = Kernel.from_folder( + __name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS} +) diff --git a/src/struphy/pic/pushing/kernels/push_gc_cc_J1_H1vec/__init__.py b/src/struphy/pic/pushing/kernels/push_gc_cc_J1_H1vec/__init__.py index 199881490..074ba4283 100644 --- a/src/struphy/pic/pushing/kernels/push_gc_cc_J1_H1vec/__init__.py +++ b/src/struphy/pic/pushing/kernels/push_gc_cc_J1_H1vec/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -push_gc_cc_J1_H1vec = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +push_gc_cc_J1_H1vec = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/push_gc_cc_J1_Hcurl/__init__.py b/src/struphy/pic/pushing/kernels/push_gc_cc_J1_Hcurl/__init__.py index 05256db56..ff6c49b88 100644 --- a/src/struphy/pic/pushing/kernels/push_gc_cc_J1_Hcurl/__init__.py +++ b/src/struphy/pic/pushing/kernels/push_gc_cc_J1_Hcurl/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -push_gc_cc_J1_Hcurl = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +push_gc_cc_J1_Hcurl = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/push_gc_cc_J1_Hdiv/__init__.py b/src/struphy/pic/pushing/kernels/push_gc_cc_J1_Hdiv/__init__.py index 090ff3eef..11ad60e87 100644 --- a/src/struphy/pic/pushing/kernels/push_gc_cc_J1_Hdiv/__init__.py +++ b/src/struphy/pic/pushing/kernels/push_gc_cc_J1_Hdiv/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -push_gc_cc_J1_Hdiv = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +push_gc_cc_J1_Hdiv = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/push_gc_cc_J2_dg_Hdiv/__init__.py b/src/struphy/pic/pushing/kernels/push_gc_cc_J2_dg_Hdiv/__init__.py index 05770fb3a..c8b8cdcca 100644 --- a/src/struphy/pic/pushing/kernels/push_gc_cc_J2_dg_Hdiv/__init__.py +++ b/src/struphy/pic/pushing/kernels/push_gc_cc_J2_dg_Hdiv/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -push_gc_cc_J2_dg_Hdiv = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (1,) + +push_gc_cc_J2_dg_Hdiv = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/push_gc_cc_J2_dg_init_Hdiv/__init__.py b/src/struphy/pic/pushing/kernels/push_gc_cc_J2_dg_init_Hdiv/__init__.py index 064befbc0..314151685 100644 --- a/src/struphy/pic/pushing/kernels/push_gc_cc_J2_dg_init_Hdiv/__init__.py +++ b/src/struphy/pic/pushing/kernels/push_gc_cc_J2_dg_init_Hdiv/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -push_gc_cc_J2_dg_init_Hdiv = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (1,) + +push_gc_cc_J2_dg_init_Hdiv = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/push_gc_cc_J2_stage_H1vec/__init__.py b/src/struphy/pic/pushing/kernels/push_gc_cc_J2_stage_H1vec/__init__.py index 91054e0bf..1e4d4fdf4 100644 --- a/src/struphy/pic/pushing/kernels/push_gc_cc_J2_stage_H1vec/__init__.py +++ b/src/struphy/pic/pushing/kernels/push_gc_cc_J2_stage_H1vec/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -push_gc_cc_J2_stage_H1vec = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +push_gc_cc_J2_stage_H1vec = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/push_gc_cc_J2_stage_Hdiv/__init__.py b/src/struphy/pic/pushing/kernels/push_gc_cc_J2_stage_Hdiv/__init__.py index 8ebfc7b16..ff9573923 100644 --- a/src/struphy/pic/pushing/kernels/push_gc_cc_J2_stage_Hdiv/__init__.py +++ b/src/struphy/pic/pushing/kernels/push_gc_cc_J2_stage_Hdiv/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -push_gc_cc_J2_stage_Hdiv = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +push_gc_cc_J2_stage_Hdiv = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/push_pc_GXu/__init__.py b/src/struphy/pic/pushing/kernels/push_pc_GXu/__init__.py index bd6eb9d4e..527345f66 100644 --- a/src/struphy/pic/pushing/kernels/push_pc_GXu/__init__.py +++ b/src/struphy/pic/pushing/kernels/push_pc_GXu/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -push_pc_GXu = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +push_pc_GXu = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/push_pc_GXu_full/__init__.py b/src/struphy/pic/pushing/kernels/push_pc_GXu_full/__init__.py index 05b5e8a31..e99a58374 100644 --- a/src/struphy/pic/pushing/kernels/push_pc_GXu_full/__init__.py +++ b/src/struphy/pic/pushing/kernels/push_pc_GXu_full/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -push_pc_GXu_full = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +push_pc_GXu_full = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/push_pc_eta_stage_H1vec/__init__.py b/src/struphy/pic/pushing/kernels/push_pc_eta_stage_H1vec/__init__.py index 4115028d7..585ffd144 100644 --- a/src/struphy/pic/pushing/kernels/push_pc_eta_stage_H1vec/__init__.py +++ b/src/struphy/pic/pushing/kernels/push_pc_eta_stage_H1vec/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -push_pc_eta_stage_H1vec = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +push_pc_eta_stage_H1vec = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/push_pc_eta_stage_Hcurl/__init__.py b/src/struphy/pic/pushing/kernels/push_pc_eta_stage_Hcurl/__init__.py index 19d494201..2b16c329a 100644 --- a/src/struphy/pic/pushing/kernels/push_pc_eta_stage_Hcurl/__init__.py +++ b/src/struphy/pic/pushing/kernels/push_pc_eta_stage_Hcurl/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -push_pc_eta_stage_Hcurl = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +push_pc_eta_stage_Hcurl = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/push_pc_eta_stage_Hdiv/__init__.py b/src/struphy/pic/pushing/kernels/push_pc_eta_stage_Hdiv/__init__.py index d0b559420..cc12613ea 100644 --- a/src/struphy/pic/pushing/kernels/push_pc_eta_stage_Hdiv/__init__.py +++ b/src/struphy/pic/pushing/kernels/push_pc_eta_stage_Hdiv/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -push_pc_eta_stage_Hdiv = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +push_pc_eta_stage_Hdiv = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/push_random_diffusion_stage/__init__.py b/src/struphy/pic/pushing/kernels/push_random_diffusion_stage/__init__.py index ead4c2b54..c1664863f 100644 --- a/src/struphy/pic/pushing/kernels/push_random_diffusion_stage/__init__.py +++ b/src/struphy/pic/pushing/kernels/push_random_diffusion_stage/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -push_random_diffusion_stage = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +push_random_diffusion_stage = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/push_v_sph_pressure/__init__.py b/src/struphy/pic/pushing/kernels/push_v_sph_pressure/__init__.py index 59a384356..07cbec3cd 100644 --- a/src/struphy/pic/pushing/kernels/push_v_sph_pressure/__init__.py +++ b/src/struphy/pic/pushing/kernels/push_v_sph_pressure/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -push_v_sph_pressure = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +push_v_sph_pressure = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/push_v_sph_pressure_ideal_gas/__init__.py b/src/struphy/pic/pushing/kernels/push_v_sph_pressure_ideal_gas/__init__.py index 0ac91045b..94009992e 100644 --- a/src/struphy/pic/pushing/kernels/push_v_sph_pressure_ideal_gas/__init__.py +++ b/src/struphy/pic/pushing/kernels/push_v_sph_pressure_ideal_gas/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -push_v_sph_pressure_ideal_gas = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +push_v_sph_pressure_ideal_gas = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/push_v_viscosity/__init__.py b/src/struphy/pic/pushing/kernels/push_v_viscosity/__init__.py index 9f97cbd54..3af102414 100644 --- a/src/struphy/pic/pushing/kernels/push_v_viscosity/__init__.py +++ b/src/struphy/pic/pushing/kernels/push_v_viscosity/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -push_v_viscosity = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +push_v_viscosity = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/push_v_with_efield/__init__.py b/src/struphy/pic/pushing/kernels/push_v_with_efield/__init__.py index 32e8138c1..d4fd5d948 100644 --- a/src/struphy/pic/pushing/kernels/push_v_with_efield/__init__.py +++ b/src/struphy/pic/pushing/kernels/push_v_with_efield/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -push_v_with_efield = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +push_v_with_efield = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/push_vxb_analytic/__init__.py b/src/struphy/pic/pushing/kernels/push_vxb_analytic/__init__.py index 7cf7779c5..1d1d16363 100644 --- a/src/struphy/pic/pushing/kernels/push_vxb_analytic/__init__.py +++ b/src/struphy/pic/pushing/kernels/push_vxb_analytic/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -push_vxb_analytic = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +push_vxb_analytic = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/push_vxb_implicit/__init__.py b/src/struphy/pic/pushing/kernels/push_vxb_implicit/__init__.py index cd0b8f3ff..ccbc03b2b 100644 --- a/src/struphy/pic/pushing/kernels/push_vxb_implicit/__init__.py +++ b/src/struphy/pic/pushing/kernels/push_vxb_implicit/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -push_vxb_implicit = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +push_vxb_implicit = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/push_weights_with_efield_lin_va/__init__.py b/src/struphy/pic/pushing/kernels/push_weights_with_efield_lin_va/__init__.py index 9cd7f9228..1f145291a 100644 --- a/src/struphy/pic/pushing/kernels/push_weights_with_efield_lin_va/__init__.py +++ b/src/struphy/pic/pushing/kernels/push_weights_with_efield_lin_va/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -push_weights_with_efield_lin_va = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +push_weights_with_efield_lin_va = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/reflect/__init__.py b/src/struphy/pic/pushing/kernels/reflect/__init__.py index 31c85772d..35480bdb7 100644 --- a/src/struphy/pic/pushing/kernels/reflect/__init__.py +++ b/src/struphy/pic/pushing/kernels/reflect/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -reflect = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: markers +OUTPUTS = (0,) + +reflect = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/sph_isotherm_kappa/__init__.py b/src/struphy/pic/pushing/kernels/sph_isotherm_kappa/__init__.py index 8aee82be1..62653c52c 100644 --- a/src/struphy/pic/pushing/kernels/sph_isotherm_kappa/__init__.py +++ b/src/struphy/pic/pushing/kernels/sph_isotherm_kappa/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -sph_isotherm_kappa = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +sph_isotherm_kappa = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/sph_mean_velocity_coeffs/__init__.py b/src/struphy/pic/pushing/kernels/sph_mean_velocity_coeffs/__init__.py index 064a0f411..6da31fac3 100644 --- a/src/struphy/pic/pushing/kernels/sph_mean_velocity_coeffs/__init__.py +++ b/src/struphy/pic/pushing/kernels/sph_mean_velocity_coeffs/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -sph_mean_velocity_coeffs = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +sph_mean_velocity_coeffs = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/sph_pressure_coeffs/__init__.py b/src/struphy/pic/pushing/kernels/sph_pressure_coeffs/__init__.py index 23c1fc506..8889b956e 100644 --- a/src/struphy/pic/pushing/kernels/sph_pressure_coeffs/__init__.py +++ b/src/struphy/pic/pushing/kernels/sph_pressure_coeffs/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -sph_pressure_coeffs = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +sph_pressure_coeffs = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/sph_viscosity_tensor/__init__.py b/src/struphy/pic/pushing/kernels/sph_viscosity_tensor/__init__.py index e9af1c7b7..fc5f3ef3a 100644 --- a/src/struphy/pic/pushing/kernels/sph_viscosity_tensor/__init__.py +++ b/src/struphy/pic/pushing/kernels/sph_viscosity_tensor/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -sph_viscosity_tensor = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +sph_viscosity_tensor = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/pushing/kernels/unit_b_1form/__init__.py b/src/struphy/pic/pushing/kernels/unit_b_1form/__init__.py index a39be1798..320ca9a67 100644 --- a/src/struphy/pic/pushing/kernels/unit_b_1form/__init__.py +++ b/src/struphy/pic/pushing/kernels/unit_b_1form/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -unit_b_1form = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: args_markers +OUTPUTS = (2,) + +unit_b_1form = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/sph/kernels/box_based_evaluation_flat/__init__.py b/src/struphy/pic/sph/kernels/box_based_evaluation_flat/__init__.py index 0b319a513..b0fbb0dc6 100644 --- a/src/struphy/pic/sph/kernels/box_based_evaluation_flat/__init__.py +++ b/src/struphy/pic/sph/kernels/box_based_evaluation_flat/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -box_based_evaluation_flat = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: out +OUTPUTS = (19,) + +box_based_evaluation_flat = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/sph/kernels/box_based_evaluation_meshgrid/__init__.py b/src/struphy/pic/sph/kernels/box_based_evaluation_meshgrid/__init__.py index f2e706de3..e989365b1 100644 --- a/src/struphy/pic/sph/kernels/box_based_evaluation_meshgrid/__init__.py +++ b/src/struphy/pic/sph/kernels/box_based_evaluation_meshgrid/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -box_based_evaluation_meshgrid = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: out +OUTPUTS = (19,) + +box_based_evaluation_meshgrid = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/sph/kernels/naive_evaluation_flat/__init__.py b/src/struphy/pic/sph/kernels/naive_evaluation_flat/__init__.py index 9b026904b..c8cd8dfca 100644 --- a/src/struphy/pic/sph/kernels/naive_evaluation_flat/__init__.py +++ b/src/struphy/pic/sph/kernels/naive_evaluation_flat/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -naive_evaluation_flat = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: out +OUTPUTS = (13,) + +naive_evaluation_flat = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/sph/kernels/naive_evaluation_meshgrid/__init__.py b/src/struphy/pic/sph/kernels/naive_evaluation_meshgrid/__init__.py index 60de44768..10fa42ba8 100644 --- a/src/struphy/pic/sph/kernels/naive_evaluation_meshgrid/__init__.py +++ b/src/struphy/pic/sph/kernels/naive_evaluation_meshgrid/__init__.py @@ -4,4 +4,7 @@ from struphy.utils.cuda_arguments import CUDA_STRUCTS -naive_evaluation_meshgrid = Kernel.from_folder(__name__, structs=CUDA_STRUCTS) +# the arguments the kernel writes to, by position: out +OUTPUTS = (13,) + +naive_evaluation_meshgrid = Kernel.from_folder(__name__, structs=CUDA_STRUCTS, host_options={"outputs": OUTPUTS}) diff --git a/src/struphy/pic/tests/cuda_parity_cases.py b/src/struphy/pic/tests/cuda_parity_cases.py index e2ce0a5d5..024318ff8 100644 --- a/src/struphy/pic/tests/cuda_parity_cases.py +++ b/src/struphy/pic/tests/cuda_parity_cases.py @@ -1,8 +1,9 @@ """Inputs for the pyccel/CUDA parity tests: for every kernel with a CUDA version, the cases it is checked on. Test-only: ``test_cuda_parity.py`` (on a GPU) and ``test_cuda_emulation.py`` (without one) run each case on both -kernel versions and compare every array. ``build(case)`` returns the kernel's positional arguments on the active -backend; a kernel that is ported to CUDA gets an entry here. +kernel versions and compare the arrays of the arguments the kernel declares as outputs (``OUTPUTS`` in its folder's +``__init__.py``); the other arrays must stay unchanged. ``build(case)`` returns the kernel's positional arguments on +the active backend; a kernel that is ported to CUDA gets an entry here. """ from collections.abc import Callable, Sequence @@ -14,6 +15,8 @@ from struphy.geometry.base import inside_logical_cube from struphy.geometry.domains import Cuboid +from struphy.kernel_arguments.local_projectors_args_cuda import CudaLocalProjectorsArguments +from struphy.kernel_arguments.pusher_args_cuda import CudaDerhamArguments, CudaDomainArguments, CudaMarkerArguments from struphy.ode.utils import ButcherTableau from struphy.pic.tests.kernel_test_args import ( BOUNDARY_CONDITIONS, @@ -45,6 +48,32 @@ class ParityCases: """Launch size, if it is not one thread per row of the first array.""" +# pyccel argument class name -> the fields of its CUDA struct, the data of an argument object (the pyccel scratch +# arrays bn1, ..., bd3 of DerhamArguments are not fields) +STRUCT_FIELDS = { + cls.__name__.removeprefix("Cuda"): tuple(field.name for field in cls.struct.fields) + for cls in (CudaMarkerArguments, CudaDerhamArguments, CudaDomainArguments, CudaLocalProjectorsArguments) +} + + +def argument_arrays(args, indices=None): + """Host copies of the arrays among `args` (or among the arguments `indices`), by name. + + An array argument is named ``"argument "``; a pyccel argument object contributes the arrays among its struct + fields, ``"argument ."`` (the names of ``cunumpy.kernel_testing.assert_kernels_agree``). + """ + found = {} + for i in range(len(args)) if indices is None else (i % len(args) for i in indices): + value = args[i] + if isinstance(value, np.ndarray): + found[f"argument {i}"] = value.copy() + for field in STRUCT_FIELDS.get(type(value).__name__, ()): + item = getattr(value, field, None) + if isinstance(item, np.ndarray): + found[f"argument {i}.{field}"] = item.copy() + return found + + # ---------------------------------------------------------------- pushers diff --git a/src/struphy/pic/tests/test_cuda_emulation.py b/src/struphy/pic/tests/test_cuda_emulation.py index 793bb9525..9ecec905f 100644 --- a/src/struphy/pic/tests/test_cuda_emulation.py +++ b/src/struphy/pic/tests/test_cuda_emulation.py @@ -9,50 +9,36 @@ from cunumpy.kernel_testing import emulation_compiler from struphy.geometry.tests import spline_mapping_cases -from struphy.kernel_arguments.pusher_args_cuda import CudaDerhamArguments, CudaDomainArguments, CudaMarkerArguments from struphy.pic.tests.cuda_emulation import emulate_struct_kernel -from struphy.pic.tests.cuda_parity_cases import PARITY_CASES +from struphy.pic.tests.cuda_parity_cases import PARITY_CASES, argument_arrays from struphy.pic.tests.kernel_test_args import N_GEOMETRY_DOMAINS from struphy.pic.tests.test_cuda_parity import CUDA_KERNELS -# pyccel argument class name -> its CUDA version -CUDA_CLASSES = { - cls.__name__.removeprefix("Cuda"): cls for cls in (CudaMarkerArguments, CudaDerhamArguments, CudaDomainArguments) -} - requires_compiler = pytest.mark.skipif(emulation_compiler() is None, reason="no C++ compiler") -def arrays(args): - """The arrays among the arguments and inside the argument objects, as host copies.""" - out = [] - for a in args: - if isinstance(a, np.ndarray): - out.append(a.copy()) - elif type(a).__name__ in CUDA_CLASSES: # a pyccel argument object: the fields of its CUDA struct - fields = (getattr(a, f.name, None) for f in CUDA_CLASSES[type(a).__name__].struct.fields) - out += [f.copy() for f in fields if isinstance(f, np.ndarray)] - return out - - @requires_compiler @pytest.mark.parametrize("name", list(PARITY_CASES)) def test_emulated_parity(name): + """The emulated CUDA kernel writes the declared outputs like the pyccel kernel, and nothing else.""" kernel, spec = CUDA_KERNELS[name], PARITY_CASES[name] + outputs = kernel.host_kernel.outputs with xp.use_backend("numpy"): for case in spec.cases: host_args = spec.build(case) emulated_args = spec.build(case) - before = arrays(host_args) + before = argument_arrays(emulated_args) kernel(*host_args) n_threads = spec.n_threads(emulated_args) if spec.n_threads else None emulate_struct_kernel(kernel.cuda_kernel, *emulated_args, n_threads=n_threads) - host, emulated = arrays(host_args), arrays(emulated_args) - assert any(not np.array_equal(a, b) for a, b in zip(before, host)), ( - f"{name}{case}: the kernel changed nothing" - ) - for h, e in zip(host, emulated): - np.testing.assert_allclose(e, h, rtol=spec.rtol, atol=spec.atol, err_msg=f"{name}{case}") + host, emulated = argument_arrays(host_args, outputs), argument_arrays(emulated_args, outputs) + for key, value in argument_arrays(emulated_args).items(): + if key not in emulated: + np.testing.assert_array_equal(value, before[key], err_msg=f"{name}{case}: {key} is not an output") + for key in host: + np.testing.assert_allclose( + emulated[key], host[key], rtol=spec.rtol, atol=spec.atol, err_msg=f"{name}{case}: {key}" + ) @requires_compiler diff --git a/src/struphy/pic/tests/test_cuda_parity.py b/src/struphy/pic/tests/test_cuda_parity.py index 75d53245f..7d5011145 100644 --- a/src/struphy/pic/tests/test_cuda_parity.py +++ b/src/struphy/pic/tests/test_cuda_parity.py @@ -1,4 +1,9 @@ -"""Parity of every CUDA kernel with its pyccel kernel, on the cases of ``cuda_parity_cases.PARITY_CASES``.""" +"""Parity of every CUDA kernel with its pyccel kernel, on the cases of ``cuda_parity_cases.PARITY_CASES``. + +The parity test compares the arguments each kernel declares as outputs (``OUTPUTS`` in its folder's +``__init__.py``, passed to cunumpy as ``host_options={"outputs": OUTPUTS}``); ``test_declared_outputs`` checks the +declarations on the NumPy backend. +""" import importlib @@ -15,7 +20,7 @@ from struphy.pic.pushing.kernels.push_vxb_analytic import push_vxb_analytic from struphy.pic.pushing.kernels.push_vxb_implicit import push_vxb_implicit from struphy.pic.pushing.kernels.push_weights_with_efield_lin_va import push_weights_with_efield_lin_va -from struphy.pic.tests.cuda_parity_cases import PARITY_CASES +from struphy.pic.tests.cuda_parity_cases import PARITY_CASES, argument_arrays from struphy.utils.cuda_arguments import CUDA_STRUCTS # all kernel packages (one folder per kernel), for tests that go through every kernel @@ -30,8 +35,13 @@ "struphy.feec.local_projectors.kernels", ) CATALOGS = {package: KernelCatalog.from_package(package, structs=CUDA_STRUCTS) for package in PACKAGES} +# the kernels as their folders declare them (with OUTPUTS, which from_package does not know), by package +DECLARED = { + package: KernelCatalog({name: getattr(importlib.import_module(f"{package}.{name}"), name) for name in catalog}) + for package, catalog in CATALOGS.items() +} # every kernel with a CUDA version, by name -CUDA_KERNELS = {name: kernel for catalog in CATALOGS.values() for name, kernel in catalog.parity_cases()} +CUDA_KERNELS = {name: kernel for catalog in DECLARED.values() for name, kernel in catalog.parity_cases()} # (kernel name, case index) of every parity case, as pytest parameters PARITY_PARAMS = [ pytest.param(name, index, id=f"{name}-{index}") @@ -68,9 +78,37 @@ def test_cuda_kernels_have_parity_cases(): assert all(len(spec.cases) > 0 for spec in PARITY_CASES.values()) +def test_kernels_declare_outputs(): + """Every kernel folder declares the arguments its kernel writes to, by position (``OUTPUTS``).""" + for catalog in DECLARED.values(): + for name, kernel in catalog.items(): + outputs, n_params = kernel.host_kernel.outputs, len(kernel.host_parameters()) + assert outputs, f"{name}: declare OUTPUTS in its __init__.py" + assert all(isinstance(i, int) and -n_params <= i < n_params for i in outputs), (name, outputs) + + +@pytest.mark.parametrize("name", list(PARITY_CASES)) +def test_declared_outputs(name): + """On the NumPy backend, the kernel changes its declared outputs and no other argument, in every parity case.""" + kernel, spec = CUDA_KERNELS[name], PARITY_CASES[name] + with xp.use_backend("numpy"): + for case in spec.cases: + args = spec.build(case) + before = argument_arrays(args) + kernel(*args) + outputs = argument_arrays(args, kernel.host_kernel.outputs) + assert any(not np.array_equal(value, before[key]) for key, value in outputs.items()), ( + f"{name}{case}: the kernel changed none of its outputs" + ) + for key, value in argument_arrays(args).items(): + if key not in outputs: + np.testing.assert_array_equal(value, before[key], err_msg=f"{name}{case}: {key} is not an output") + + @requires_cupy @pytest.mark.parametrize("name, index", PARITY_PARAMS) def test_parity(name, index): + """assert_kernels_agree compares the declared outputs of the kernel (``kernel.host_kernel.outputs``).""" check_case(name, index, assert_kernels_agree)