Repository navigation
MHD equilibria on the CuPy backend - #714
Draft
max-models wants to merge 4 commits into
Draft
max-models wants to merge 4 commits into
max-models wants to merge 4 commits into
Conversation
Equilibria with host-only setup (AdhocTorus q_kind 1/2, AdhocTorusQPsi, EQDSKequilibrium) run their __init__ on the NumPy backend (setup_on_host) and hold only host data. SciPy spline evaluations go through host_call, GVEC/DESC evaluations through @evaluate_on_host: device arguments are copied to the host and the result back, once per call; NumPy arguments are evaluated as before. Tokamak no longer builds its default EQDSKequilibrium on the NumPy backend itself. New test_equils_cupy.py compares every equilibrium of equils on CuPy (GPU, or cunumpy's fake CuPy with host geometry kernels) with NumPy. Solves #696. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
max-models
added a commit
that referenced
this pull request
Oct 7, 2026
Stack the PR on #714. Conflicts in CUDA_STRATEGY.md: kept the linear_vlasov_ampere checklist entry and #690's decision in the Next entry (without the steps done below), the marker exchange note of #712, and the polar-splines open question of #714. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 8, 2026
Draft
max-models
added this pull request to stack #728
October 8, 2026 05:45
max-models
removed this pull request from stack #728
October 8, 2026 06:00
max-models
added this pull request to stack #729
October 8, 2026 06:00
max-models
marked this pull request as draft
October 8, 2026 09:14
This branch has not been deployed
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Stack: part 7 of 14, based on #713 (merge that first), next: #718. Full order: #709 → #708 → #711 → #712 → #705 → #713 → #714 → #718 → #720 → #721 → #724 → #725 → #723 → #722.
Solves the following issue(s):
Solves #696, part of #650 (see
CUDA_STRATEGY.md). Every equilibrium infields_background/equils.pycan now be created and evaluated on the CuPy backend. The time loop does not change: it uses the projected equilibrium.Core changes:
AdhocToruswithq_kind1 or 2: SciPyquad/UnivariateSplinegot device arrays.AdhocTorusQPsi:odeint/fsolvegot device arrays.EQDSKequilibrium:RectBivariateSplinegot the device arrays fromxp.linspace.GVECequilibriumandDESCequilibrium: gvec and DESC/JAX got device arrays.HomogenSlab,ShearedSlab,ShearFluid,ScrewPinch,AdhocToruswithq_kind=0,CircularTokamak,ConstantVelocity,HomogenSlabITG,CurrentSheet, the generic ones).AdhocTorus.psi_r(q_kind=0) didout *= ...on a 0-d device array, which fails on CuPy whenpsiis called with arrays. It is nowout = out * ....fields_background/base.py:setup_on_host: a decorator for__init__. It runs the setup on the NumPy backend (file reading, ODE solves, SciPy fits), so these equilibria hold only host data on either backend. Used onAdhocTorus,AdhocTorusQPsiandEQDSKequilibrium.host_call(fun, *args, **kwargs): calls a host-only function, copying device arguments to the host and array results back once per call. Without device arguments it is a plain call, so the NumPy path does not change. Used for every SciPy spline evaluation:psi_r/p_rofAdhocTorus,psi_rofAdhocTorusQPsi, andpsi/q_psi/g_psi/p_psiof EQDSK.evaluate_on_host: the same as a method decorator. Used on the GVECbv,jv,p0,n0and the DESCbv,jv,p0,n0,gradB1.gradB_xyzof EQDSK makes about 10psicalls, so 10 round trips. This is fine because equilibria are only evaluated at setup: initial conditions, projections onto the FEEC spaces and mappings. A device B-spline evaluation of the SciPy knots and coefficients would remove these copies. It is listed as an open question inCUDA_STRATEGY.md.Tokamak: the workaround from PR 19 is removed. It no longer builds its defaultEQDSKequilibriuminsideuse_backend("numpy"). The field-line tracing (SciPy) still runs on the NumPy backend.fields_background/tests/test_equils_cupy.py.What it checks: 19 cases that cover every equilibrium class of
equils, including EQDSK, GVEC and DESC with the files shipped in the repo or with the packages.test_all_equilibria_have_caseschecks that no class is missing. Each case is created on NumPy and on CuPy, and 30 logical-domain methods (absB0,p0,n0,b2,unit_b1,gradB1,curl_unit_b2,j2, …) are evaluated:psi/g_torwith all derivatives for the axisymmetric equilibria.Every array result must be a device array and match NumPy to 1e-12.
test_equil_fake_cupyruns without a GPU, in a subprocess on the fake CuPy. The fake CuPy cannot launch CUDA kernels, sohost_geometry_kernels()runs the four geometry entry kernels with their pyccel version on the host buffers of the fake arrays. The CUDA geometry kernels have their own parity and emulation tests. Theemulated_launches()of CUDA version of the linear_vlasov_ampere accumulation #705 would also work here, but it compiles every launch, and these cases make hundreds of domain evaluations.test_equil_cupyruns the same check on a GPU.Model-specific changes:
None.
Documentation changes:
CUDA_STRATEGY.md:Testing (macOS, no GPU; pyccel kernels compiled with GNU/Fortran; GPU tests not run):
devel)fields_background/tests geometry/testskinetic_background/tests post_processing/tests/test_orbits_tools.py feec/tests/test_field_init.pyThe 21 new passes are the 19 fake-CuPy cases,
test_all_equilibria_have_casesandtest_host_call_numpy_is_plain_call. The 19 new skips are the GPU tests (test_equil_cupy). The DESC case takes about 35 s, because it loads W7-X from the desc package.🤖 Generated with Claude Code