Skip to content

Pr/rzmap covfie backend#2344

Merged
sethrj merged 23 commits into
celeritas-project:developfrom
rahmans1:pr/rzmap-covfie-backend
Apr 13, 2026
Merged

Pr/rzmap covfie backend#2344
sethrj merged 23 commits into
celeritas-project:developfrom
rahmans1:pr/rzmap-covfie-backend

Conversation

@rahmans1

@rahmans1 rahmans1 commented Mar 31, 2026

Copy link
Copy Markdown
Contributor

Add covfie backend for RZMapField

Add a covfie-backed implementation of RZMapField for storage and bilinear
interpolation on the R-Z grid, with GPU acceleration via covfie's device
backends.

Core implementation

  • Add CovfieRZFieldTraits defining the 2D covfie pipeline for RZ maps:
    host path uses affine→clamp→linear→strided→array with float2 storage;
    device path uses the same pipeline with CUDA/HIP device array backends
    (hardware texture interpolation was evaluated but switched to software
    interpolation for consistency)
  • Add RZMapFieldData.covfie.hh with four ownership/memspace specializations
    and RZMapField.covfie.hh that evaluates the field at (r, z) and projects
    Br onto Cartesian Bx/By
  • Add RZMapFieldParams.covfie.cc with pimpl-based constructor that transposes
    from [Z][R] input stride to covfie's (R, Z) ordering
  • Wire #if CELERITAS_USE_COVFIE dispatch into RZMapFieldData.hh,
    RZMapField.hh, and RZMapFieldParams.hh
  • Add RZAdapterField to hide covfie C++20 headers from RZMapMagneticField.hh

Non-covfie path removal

When covfie is enabled, the original UniformGrid + Collection code path is
removed (matching the CartMapField pattern):

  • Inline CELER_NOT_CONFIGURED stubs in RZMapFieldParams.hh
  • Minimal complete RZMapFieldParamsData stub in RZMapFieldData.hh #else
    block
  • using RZMapField = detail::NotImplementedField<RZMapFieldParamsData> when
    covfie is disabled; DISABLED_SimpleCmsRZFieldAlongStepTest guards tests

Out-of-bounds behavior

Return {0, 0, 0} for positions outside the field grid, matching the
non-covfie convention. Without this, covfie's clamp behavior returns nonzero
boundary values at substep positions that can reach r ~ 5e20 cm when
step_length is infinite (vacuum track with no cross sections), causing NaN
in the RK error state.

Test updates

  • Add RZMapFieldTest.device verifying covfie field values on GPU
  • Add analytical interpolation validation in RZMapFieldTest
  • Update SimpleCmsRZFieldAlongStepTest expected values for covfie bilinear
    interpolation
  • Acknowledge known float32 precision limit in msc_rzfield_finegrid: step
    ~6e-7 cm is below machine epsilon at r~125 cm; use ScopedLogStorer
    to explicitly capture the resulting "failed to change position" errors in
    float32+debug builds

Limitations and future work

  • Field storage is float32 regardless of CELERITAS_REAL_TYPE; full double
    support requires templating CovfieRZFieldTraits on real_type and a
    double-precision convert_bfield tool in acts-project/covfie
  • Multi-region field map support is possible given the zero-outside-bounds
    behavior; would require a dispatcher field class and mixed-field action

This PR is AI-assisted (Claude Code, claude-opus-4-6, claude-sonnet-4-6). Follows from discussion in #2298

Sakib Rahman added 5 commits March 30, 2026 22:24
Define CovfieRZFieldTraits for 2D (R,Z) field interpolation, mirroring
the existing 3D CovfieFieldTraits. The host pipeline uses
affine->clamp->linear->strided->array with float2 storage, while the
CUDA device path uses hardware texture interpolation for performance.

Prompt: "Replace RZMapField with covfie backend for storage and bilinear
interpolation on the R-Z grid, with CUDA texture acceleration on GPU"

Assisted-by: Claude Opus 4.6
Add RZMapFieldData.covfie.hh with 4 ownership specializations (host
value/reference, device value/reference) using CovfieRZFieldTraits, and
RZMapField.covfie.hh which evaluates the 2D (R,Z) field via covfie and
projects Br to Cartesian Bx/By components.

Prompt: "Add covfie backend for RZMapField: create data ownership types and
field evaluation class mirroring the CartMapField covfie pattern"

Assisted-by: Claude Opus 4.6
Add RZMapFieldParams.covfie.cc with pimpl-based constructor that builds
a 2D covfie field from RZMapFieldInput, transposing from [Z][R] input
stride to covfie's (R,Z) ordering. Update RZMapFieldParams.hh to use
pimpl when covfie is enabled and ParamsDataStore when disabled.

Prompt: "Add covfie params constructor for RZMapField, mirroring
CartMapFieldParams.covfie.cc with pimpl pattern"

Assisted-by: Claude Opus 4.6
Add #if CELERITAS_USE_COVFIE guards to RZMapFieldData.hh and
RZMapField.hh to dispatch to covfie implementations when enabled,
preserving the original UniformGrid+Collection code path when disabled.
Guard RZMapFieldParams.cc with #if !CELERITAS_USE_COVFIE. Add
RZMapFieldParams.covfie.cc to the covfie CMake source list.

Prompt: "Wire the covfie dispatch into existing RZMapField headers and
CMakeLists.txt, matching CartMapField pattern"

Assisted-by: Claude Opus 4.6
Add a CUDA/HIP device test that evaluates RZMapField on GPU and compares
against expected values from CUDA texture interpolation. Update the host
test expected values to use #if CELERITAS_USE_COVFIE so both covfie
(bilinear) and non-covfie (1D-per-component) code paths are tested.

Prompt: "Add device test for RZMapField covfie backend and ensure host
test works for both covfie-enabled and covfie-disabled builds"

Assisted-by: Claude Opus 4.6
@rahmans1 rahmans1 requested a review from sethrj March 31, 2026 02:35
@rahmans1 rahmans1 added enhancement New feature or request ai-assisted Generated/refactored substantially with agentic/LLM AI tools labels Mar 31, 2026
@github-actions

github-actions Bot commented Mar 31, 2026

Copy link
Copy Markdown

Test summary

 6 020 files   9 737 suites   19m 24s ⏱️
 2 278 tests  2 235 ✅  43 💤 0 ❌
34 032 runs  33 845 ✅ 187 💤 0 ❌

Results for commit 218cfa4.

♻️ This comment has been updated with latest results.

Sakib Rahman and others added 3 commits March 31, 2026 09:09
Update the #else branch expected values to match current upstream
develop, which changed after the cms-tiny.field.json test data was
updated.

Prompt: "Fix CI failure: non-covfie RZMapFieldTest.all expected values
are stale and don't match current upstream develop"

Assisted-by: Claude Opus 4.6
Replace cuda_texture with cuda_device_array as the device storage
backend for the RZ field map, unifying the CUDA/HIP/CPU backend chain
to use the same affine<clamp<linear<strided<>>>> pipeline with software
interpolation on all platforms. Build the device field bottom-up using
cross-type constructors so each layer preserves its configuration during
the host-to-device transfer.

Remove incorrect CELER_FUNCTION annotations from host-only methods in
value<device>, initialize field_view pointer to nullptr, replace
std::hypot with the device-safe hypot from corecel/math/Algorithms.hh,
and fix the non-covfie stub Impl/ImplDeleter definitions to compile
without covfie. Update device test expected values to match software
interpolation (identical to host) and tighten tolerance to 1e-7.

Prompt: "Switch RZMapField covfie CUDA backend from cuda_texture to
cuda_device_array with bottom-up layer construction, fix host-only
CELER_FUNCTION annotations, and update device test expected values"

Assisted-by: Claude Sonnet 4.6
@rahmans1

rahmans1 commented Apr 8, 2026

Copy link
Copy Markdown
Contributor Author

Test Failure Analysis

Environment:
geant4@11.3.2
covfie@0.15.3
vecgeom@1.2.11

Observe following test failure:

jug_dev+> ubuntu@LPO-174581:~/celeritas-dd4hep/celeritas-covfie-unpatched/build$ ctest -R Fields --output-on-failure -V
UpdateCTestConfiguration  from :/home/srahman1/celeritas-dd4hep/celeritas-covfie-unpatched/build/DartConfiguration.tcl
Parse Config file:/home/srahman1/celeritas-dd4hep/celeritas-covfie-unpatched/build/DartConfiguration.tcl
UpdateCTestConfiguration  from :/home/srahman1/celeritas-dd4hep/celeritas-covfie-unpatched/build/DartConfiguration.tcl
Parse Config file:/home/srahman1/celeritas-dd4hep/celeritas-covfie-unpatched/build/DartConfiguration.tcl
Test project /home/srahman1/celeritas-dd4hep/celeritas-covfie-unpatched/build
Constructing a list of tests
Done constructing a list of tests
Updating test list for fixtures
Added 0 tests to meet fixture requirements
Checking test dependency graph...
Checking test dependency graph end
test 242
    Start 242: celeritas/field/Fields

242: Test command: /home/srahman1/celeritas-dd4hep/celeritas-covfie-unpatched/build/test/celeritas/field_Fields
242: Working Directory: /home/srahman1/celeritas-dd4hep/celeritas-covfie-unpatched/build/test/celeritas
242: Environment variables:
242:  CELER_LOG=warning
242:  CELER_LOG_LOCAL=warning
242:  CELER_DISABLE_PARALLEL=1
242: Test timeout computed to be: 1500
242: Celeritas version 0.7+43c588fa
242: [==========] Running 10 tests from 8 test suites.
242: [----------] Global test environment set-up.
242: [----------] 1 test from UniformZFieldTest
242: [ RUN      ] UniformZFieldTest.all
242: [       OK ] UniformZFieldTest.all (0 ms)
242: [----------] 1 test from UniformZFieldTest (0 ms total)
242:
242: [----------] 1 test from UniformFieldTest
242: [ RUN      ] UniformFieldTest.all
242: [       OK ] UniformFieldTest.all (0 ms)
242: [----------] 1 test from UniformFieldTest (0 ms total)
242:
242: [----------] 1 test from CMSParameterizedFieldTest
242: [ RUN      ] CMSParameterizedFieldTest.all
242: [       OK ] CMSParameterizedFieldTest.all (0 ms)
242: [----------] 1 test from CMSParameterizedFieldTest (0 ms total)
242:
242: [----------] 2 tests from RZMapFieldTest
242: [ RUN      ] RZMapFieldTest.all
242: /home/srahman1/celeritas-dd4hep/celeritas-covfie-unpatched/src/celeritas/field/RZMapFieldInputIO.json.cc:90: warning: No units given in RZ field input: assuming CGS for length (cm) and SI for strength (T)
242: [       OK ] RZMapFieldTest.all (2 ms)
242: [ RUN      ] RZMapFieldTest.device
242: /home/srahman1/celeritas-dd4hep/celeritas-covfie-unpatched/src/celeritas/field/RZMapFieldInputIO.json.cc:90: warning: No units given in RZ field input: assuming CGS for length (cm) and SI for strength (T)
242: /home/srahman1/celeritas-dd4hep/celeritas-covfie-unpatched/test/celeritas/field/Fields.test.cc:228: Failure
242: Values in: actual
242:  Expected: expected_field
242: 23 of 24 elements differ
242: by 9.9999999999999995e-08 relative error or 1.0000000000000001e-09 absolute error
242:  i      expected_field             actual         Difference
242:  0                   0     155742662339379     155742662339379
242:  2      3.811202287674                   0                  -1
242:  3 0.000557730426456419     306532574995193 5.49607051103112e+17
242:  4 0.000557730426456419    781649587627.412 1.40148277832658e+15
242:  5        3.8078203125    1621962324.95216    425955582.993213
242:  6  0.0023259673673599    36700623331.6485    15778649282299.9
242:  7  0.0023259673673599 1.01676731791199e+16 4.3713739589824e+18
242:  8      3.804498046875      53331557897105    14018027408611.1
242:  9  0.0053047110587328 7.97174403377726e+21 1.5027668699606e+24
242: 10  0.0053047110587328 2.21377621992811e+26 4.17322677035107e+28
242: 11        3.8012359375 2.09485918426896e+29 5.51099489406256e+28
242: 12  0.0094939613342285 4.33704065424445e+29 4.56820972991342e+31
242: 13  0.0094939613342285 1.11838154357221e+30 1.17799251987695e+32
242: 14        3.7980328125 1.70691903462106e+30 4.49421876768227e+29
242: 15  0.0149389093193622 2.08244840965634e+30 1.39397620344164e+32
242: 16  0.0149389093193622 2.51719314115237e+30 1.6849912449029e+32
242: 17           3.7849625 2.76635580571946e+30 7.30880637712912e+29
242: 18  0.0215377738208854 2.90965377922898e+30 1.35095381882387e+32
242: 19  0.0215377738208854 2.77248509423713e+30 1.28726632440936e+32
242: 20           3.7723875 2.53047475211907e+30 6.70788658937893e+29
242: 21  0.0283599192434375 2.10650307006855e+30 7.42774706791874e+31
242: 22  0.0283599192434375 1.72454086347049e+30 6.08090893583749e+31
242: 23      3.762944140625 1.13708384650316e+30 3.02179305354848e+29
242:
242:
242: [  FAILED  ] RZMapFieldTest.device (123 ms)
242: [----------] 2 tests from RZMapFieldTest (126 ms total)
242:
242: [----------] 1 test from CylMapFieldTest
242: [ RUN      ] CylMapFieldTest.all
242: [       OK ] CylMapFieldTest.all (0 ms)
242: [----------] 1 test from CylMapFieldTest (0 ms total)
242:
242: [----------] 1 test from CovfieCartImportTest
242: [ RUN      ] CovfieCartImportTest.load_2x3x4
242: [       OK ] CovfieCartImportTest.load_2x3x4 (1 ms)
242: [----------] 1 test from CovfieCartImportTest (1 ms total)
242:
242: [----------] 1 test from CovfieRZImportTest
242: [ RUN      ] CovfieRZImportTest.load_2x3
242: [       OK ] CovfieRZImportTest.load_2x3 (0 ms)
242: [----------] 1 test from CovfieRZImportTest (0 ms total)
242:
242: [----------] 2 tests from CartMapFieldTest
242: [ RUN      ] CartMapFieldTest.host
242: [       OK ] CartMapFieldTest.host (24 ms)
242: [ RUN      ] CartMapFieldTest.device
242: [       OK ] CartMapFieldTest.device (19 ms)
242: [----------] 2 tests from CartMapFieldTest (44 ms total)
242:
242: [----------] Global test environment tear-down
242: [==========] 10 tests from 8 test suites ran. (173 ms total)
242: [  PASSED  ] 9 tests.
242: [  FAILED  ] 1 test, listed below:
242: [  FAILED  ] RZMapFieldTest.device
242:
242:  1 FAILED TEST
242: /home/srahman1/celeritas-dd4hep/celeritas-covfie-unpatched/build/test/celeritas/field_Fields: tests FAILED
1/1 Test #242: celeritas/field/Fields ...........***Failed  Error regular expression found in output. Regex=[tests FAILED]  2.12 sec
Celeritas version 0.7+43c588fa
[==========] Running 10 tests from 8 test suites.
[----------] Global test environment set-up.
[----------] 1 test from UniformZFieldTest
[ RUN      ] UniformZFieldTest.all
[       OK ] UniformZFieldTest.all (0 ms)
[----------] 1 test from UniformZFieldTest (0 ms total)

[----------] 1 test from UniformFieldTest
[ RUN      ] UniformFieldTest.all
[       OK ] UniformFieldTest.all (0 ms)
[----------] 1 test from UniformFieldTest (0 ms total)

[----------] 1 test from CMSParameterizedFieldTest
[ RUN      ] CMSParameterizedFieldTest.all
[       OK ] CMSParameterizedFieldTest.all (0 ms)
[----------] 1 test from CMSParameterizedFieldTest (0 ms total)

[----------] 2 tests from RZMapFieldTest
[ RUN      ] RZMapFieldTest.all
/home/srahman1/celeritas-dd4hep/celeritas-covfie-unpatched/src/celeritas/field/RZMapFieldInputIO.json.cc:90: warning: No units given in RZ field input: assuming CGS for length (cm) and SI for strength (T)
[       OK ] RZMapFieldTest.all (2 ms)
[ RUN      ] RZMapFieldTest.device
/home/srahman1/celeritas-dd4hep/celeritas-covfie-unpatched/src/celeritas/field/RZMapFieldInputIO.json.cc:90: warning: No units given in RZ field input: assuming CGS for length (cm) and SI for strength (T)
/home/srahman1/celeritas-dd4hep/celeritas-covfie-unpatched/test/celeritas/field/Fields.test.cc:228: Failure
Values in: actual
 Expected: expected_field
23 of 24 elements differ
by 9.9999999999999995e-08 relative error or 1.0000000000000001e-09 absolute error
 i      expected_field             actual         Difference
 0                   0     155742662339379     155742662339379
 2      3.811202287674                   0                  -1
 3 0.000557730426456419     306532574995193 5.49607051103112e+17
 4 0.000557730426456419    781649587627.412 1.40148277832658e+15
 5        3.8078203125    1621962324.95216    425955582.993213
 6  0.0023259673673599    36700623331.6485    15778649282299.9
 7  0.0023259673673599 1.01676731791199e+16 4.3713739589824e+18
 8      3.804498046875      53331557897105    14018027408611.1
 9  0.0053047110587328 7.97174403377726e+21 1.5027668699606e+24
10  0.0053047110587328 2.21377621992811e+26 4.17322677035107e+28
11        3.8012359375 2.09485918426896e+29 5.51099489406256e+28
12  0.0094939613342285 4.33704065424445e+29 4.56820972991342e+31
13  0.0094939613342285 1.11838154357221e+30 1.17799251987695e+32
14        3.7980328125 1.70691903462106e+30 4.49421876768227e+29
15  0.0149389093193622 2.08244840965634e+30 1.39397620344164e+32
16  0.0149389093193622 2.51719314115237e+30 1.6849912449029e+32
17           3.7849625 2.76635580571946e+30 7.30880637712912e+29
18  0.0215377738208854 2.90965377922898e+30 1.35095381882387e+32
19  0.0215377738208854 2.77248509423713e+30 1.28726632440936e+32
20           3.7723875 2.53047475211907e+30 6.70788658937893e+29
21  0.0283599192434375 2.10650307006855e+30 7.42774706791874e+31
22  0.0283599192434375 1.72454086347049e+30 6.08090893583749e+31
23      3.762944140625 1.13708384650316e+30 3.02179305354848e+29


[  FAILED  ] RZMapFieldTest.device (123 ms)
[----------] 2 tests from RZMapFieldTest (126 ms total)

[----------] 1 test from CylMapFieldTest
[ RUN      ] CylMapFieldTest.all
[       OK ] CylMapFieldTest.all (0 ms)
[----------] 1 test from CylMapFieldTest (0 ms total)

[----------] 1 test from CovfieCartImportTest
[ RUN      ] CovfieCartImportTest.load_2x3x4
[       OK ] CovfieCartImportTest.load_2x3x4 (1 ms)
[----------] 1 test from CovfieCartImportTest (1 ms total)

[----------] 1 test from CovfieRZImportTest
[ RUN      ] CovfieRZImportTest.load_2x3
[       OK ] CovfieRZImportTest.load_2x3 (0 ms)
[----------] 1 test from CovfieRZImportTest (0 ms total)

[----------] 2 tests from CartMapFieldTest
[ RUN      ] CartMapFieldTest.host
[       OK ] CartMapFieldTest.host (24 ms)
[ RUN      ] CartMapFieldTest.device
[       OK ] CartMapFieldTest.device (19 ms)
[----------] 2 tests from CartMapFieldTest (44 ms total)

[----------] Global test environment tear-down
[==========] 10 tests from 8 test suites ran. (173 ms total)
[  PASSED  ] 9 tests.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] RZMapFieldTest.device

 1 FAILED TEST
/home/srahman1/celeritas-dd4hep/celeritas-covfie-unpatched/build/test/celeritas/field_Fields: tests FAILED


0% tests passed, 1 tests failed out of 1

Label Time Summary:
gpu     =   2.12 sec*proc (1 test)
unit    =   2.12 sec*proc (1 test)

Total Test time (real) =   2.13 sec

The following tests FAILED:
        242 - celeritas/field/Fields (Failed)                   gpu unit
Errors while running CTest

Resolution

However, the failure mostly goes away if the following patch is applied to covfie

--- /opt/software/linux-x86_64_v2/covfie-0.15.3-k3ofxdijeof4nufzfmci5hzlgp3lscmn/include/covfie/core/backend/transformer/clamp.hpp      1969-12-31 19:00:00.000000000 -0500
+++ src/covfie_patches/covfie/core/backend/transformer/clamp.hpp        2026-04-08 21:45:23.534731291 -0400
@@ -6,7 +6,6 @@

 #pragma once

-#include <algorithm>
 #include <concepts>
 #include <iostream>
 #include <type_traits>
@@ -157,12 +156,18 @@
         {
         }

+        template <typename S>
+        COVFIE_HOST_DEVICE static S clamp_scalar(S v, S lo, S hi)
+        {
+            return v < lo ? lo : (v > hi ? hi : v);
+        }
+
         template <std::size_t... Is>
         COVFIE_HOST_DEVICE typename contravariant_input_t::vector_t
         adjust(typename contravariant_input_t::vector_t coord, std::index_sequence<Is...>)
             const
         {
-            return {std::clamp(coord[Is], m_min[Is], m_max[Is])...};
+            return {clamp_scalar(coord[Is], m_min[Is], m_max[Is])...};
         }

         COVFIE_HOST_DEVICE typename covariant_output_t::vector_t
 ctest -R Fields --output-on-failure -V
UpdateCTestConfiguration  from :/home/srahman1/celeritas-dd4hep/celeritas-covfie-patch/build/DartConfiguration.tcl
Parse Config file:/home/srahman1/celeritas-dd4hep/celeritas-covfie-patch/build/DartConfiguration.tcl
UpdateCTestConfiguration  from :/home/srahman1/celeritas-dd4hep/celeritas-covfie-patch/build/DartConfiguration.tcl
Parse Config file:/home/srahman1/celeritas-dd4hep/celeritas-covfie-patch/build/DartConfiguration.tcl
Test project /home/srahman1/celeritas-dd4hep/celeritas-covfie-patch/build
Constructing a list of tests
Done constructing a list of tests
Updating test list for fixtures
Added 0 tests to meet fixture requirements
Checking test dependency graph...
Checking test dependency graph end
test 242
    Start 242: celeritas/field/Fields

242: Test command: /home/srahman1/celeritas-dd4hep/celeritas-covfie-patch/build/test/celeritas/field_Fields
242: Working Directory: /home/srahman1/celeritas-dd4hep/celeritas-covfie-patch/build/test/celeritas
242: Environment variables:
242:  CELER_LOG=warning
242:  CELER_LOG_LOCAL=warning
242:  CELER_DISABLE_PARALLEL=1
242: Test timeout computed to be: 1500
242: Celeritas version 0.7+8de0cb3d4
242: [==========] Running 10 tests from 8 test suites.
242: [----------] Global test environment set-up.
242: [----------] 1 test from UniformZFieldTest
242: [ RUN      ] UniformZFieldTest.all
242: [       OK ] UniformZFieldTest.all (0 ms)
242: [----------] 1 test from UniformZFieldTest (0 ms total)
242:
242: [----------] 1 test from UniformFieldTest
242: [ RUN      ] UniformFieldTest.all
242: [       OK ] UniformFieldTest.all (0 ms)
242: [----------] 1 test from UniformFieldTest (0 ms total)
242:
242: [----------] 1 test from CMSParameterizedFieldTest
242: [ RUN      ] CMSParameterizedFieldTest.all
242: [       OK ] CMSParameterizedFieldTest.all (0 ms)
242: [----------] 1 test from CMSParameterizedFieldTest (0 ms total)
242:
242: [----------] 2 tests from RZMapFieldTest
242: [ RUN      ] RZMapFieldTest.all
242: /home/srahman1/celeritas-dd4hep/celeritas-covfie-patch/src/celeritas/field/RZMapFieldInputIO.json.cc:90: warning: No units given in RZ field input: assuming CGS for length (cm) and SI for strength (T)
242: [       OK ] RZMapFieldTest.all (3 ms)
242: [ RUN      ] RZMapFieldTest.device
242: /home/srahman1/celeritas-dd4hep/celeritas-covfie-patch/src/celeritas/field/RZMapFieldInputIO.json.cc:90: warning: No units given in RZ field input: assuming CGS for length (cm) and SI for strength (T)
242: /home/srahman1/celeritas-dd4hep/celeritas-covfie-patch/test/celeritas/field/Fields.test.cc:228: Failure
242: Values in: actual
242:  Expected: expected_field
242: 3 of 24 elements differ
242: by 9.9999999999999995e-08 relative error or 1.0000000000000001e-09 absolute error
242:  i      expected_field             actual         Difference
242:  5        3.8078203125      3.807820703125 1.02584935171346e-07
242:  8      3.804498046875        3.8044984375 1.02674517134475e-07
242: 20           3.7723875      3.772387109375 -1.03548482201774e-07
242:
242:
242: [  FAILED  ] RZMapFieldTest.device (94 ms)
242: [----------] 2 tests from RZMapFieldTest (97 ms total)
242:
242: [----------] 1 test from CylMapFieldTest
242: [ RUN      ] CylMapFieldTest.all
242: [       OK ] CylMapFieldTest.all (0 ms)
242: [----------] 1 test from CylMapFieldTest (0 ms total)
242:
242: [----------] 1 test from CovfieCartImportTest
242: [ RUN      ] CovfieCartImportTest.load_2x3x4
242: [       OK ] CovfieCartImportTest.load_2x3x4 (0 ms)
242: [----------] 1 test from CovfieCartImportTest (0 ms total)
242:
242: [----------] 1 test from CovfieRZImportTest
242: [ RUN      ] CovfieRZImportTest.load_2x3
242: [       OK ] CovfieRZImportTest.load_2x3 (0 ms)
242: [----------] 1 test from CovfieRZImportTest (0 ms total)
242:
242: [----------] 2 tests from CartMapFieldTest
242: [ RUN      ] CartMapFieldTest.host
242: [       OK ] CartMapFieldTest.host (23 ms)
242: [ RUN      ] CartMapFieldTest.device
242: [       OK ] CartMapFieldTest.device (20 ms)
242: [----------] 2 tests from CartMapFieldTest (44 ms total)
242:
242: [----------] Global test environment tear-down
242: [==========] 10 tests from 8 test suites ran. (142 ms total)
242: [  PASSED  ] 9 tests.
242: [  FAILED  ] 1 test, listed below:
242: [  FAILED  ] RZMapFieldTest.device
242:
242:  1 FAILED TEST
242: /home/srahman1/celeritas-dd4hep/celeritas-covfie-patch/build/test/celeritas/field_Fields: tests FAILED
1/1 Test #242: celeritas/field/Fields ...........***Failed  Error regular expression found in output. Regex=[tests FAILED]  2.09 sec
Celeritas version 0.7+8de0cb3d4
[==========] Running 10 tests from 8 test suites.
[----------] Global test environment set-up.
[----------] 1 test from UniformZFieldTest
[ RUN      ] UniformZFieldTest.all
[       OK ] UniformZFieldTest.all (0 ms)
[----------] 1 test from UniformZFieldTest (0 ms total)

[----------] 1 test from UniformFieldTest
[ RUN      ] UniformFieldTest.all
[       OK ] UniformFieldTest.all (0 ms)
[----------] 1 test from UniformFieldTest (0 ms total)

[----------] 1 test from CMSParameterizedFieldTest
[ RUN      ] CMSParameterizedFieldTest.all
[       OK ] CMSParameterizedFieldTest.all (0 ms)
[----------] 1 test from CMSParameterizedFieldTest (0 ms total)

[----------] 2 tests from RZMapFieldTest
[ RUN      ] RZMapFieldTest.all
/home/srahman1/celeritas-dd4hep/celeritas-covfie-patch/src/celeritas/field/RZMapFieldInputIO.json.cc:90: warning: No units given in RZ field input: assuming CGS for length (cm) and SI for strength (T)
[       OK ] RZMapFieldTest.all (3 ms)
[ RUN      ] RZMapFieldTest.device
/home/srahman1/celeritas-dd4hep/celeritas-covfie-patch/src/celeritas/field/RZMapFieldInputIO.json.cc:90: warning: No units given in RZ field input: assuming CGS for length (cm) and SI for strength (T)
/home/srahman1/celeritas-dd4hep/celeritas-covfie-patch/test/celeritas/field/Fields.test.cc:228: Failure
Values in: actual
 Expected: expected_field
3 of 24 elements differ
by 9.9999999999999995e-08 relative error or 1.0000000000000001e-09 absolute error
 i      expected_field             actual         Difference
 5        3.8078203125      3.807820703125 1.02584935171346e-07
 8      3.804498046875        3.8044984375 1.02674517134475e-07
20           3.7723875      3.772387109375 -1.03548482201774e-07


[  FAILED  ] RZMapFieldTest.device (94 ms)
[----------] 2 tests from RZMapFieldTest (97 ms total)

[----------] 1 test from CylMapFieldTest
[ RUN      ] CylMapFieldTest.all
[       OK ] CylMapFieldTest.all (0 ms)
[----------] 1 test from CylMapFieldTest (0 ms total)

[----------] 1 test from CovfieCartImportTest
[ RUN      ] CovfieCartImportTest.load_2x3x4
[       OK ] CovfieCartImportTest.load_2x3x4 (0 ms)
[----------] 1 test from CovfieCartImportTest (0 ms total)

[----------] 1 test from CovfieRZImportTest
[ RUN      ] CovfieRZImportTest.load_2x3
[       OK ] CovfieRZImportTest.load_2x3 (0 ms)
[----------] 1 test from CovfieRZImportTest (0 ms total)

[----------] 2 tests from CartMapFieldTest
[ RUN      ] CartMapFieldTest.host
[       OK ] CartMapFieldTest.host (23 ms)
[ RUN      ] CartMapFieldTest.device
[       OK ] CartMapFieldTest.device (20 ms)
[----------] 2 tests from CartMapFieldTest (44 ms total)

[----------] Global test environment tear-down
[==========] 10 tests from 8 test suites ran. (142 ms total)
[  PASSED  ] 9 tests.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] RZMapFieldTest.device

 1 FAILED TEST
/home/srahman1/celeritas-dd4hep/celeritas-covfie-patch/build/test/celeritas/field_Fields: tests FAILED


0% tests passed, 1 tests failed out of 1

Label Time Summary:
gpu     =   2.09 sec*proc (1 test)
unit    =   2.09 sec*proc (1 test)

Total Test time (real) =   2.10 sec

The following tests FAILED:
        242 - celeritas/field/Fields (Failed)                   gpu unit
Errors while running CTest

Sakib Rahman added 3 commits April 8, 2026 20:40
Add RZMapFieldTest.interp_validation with two synthetic cases whose
values at non-grid points are analytically known:
- Case 1 (both paths): Br=r, Bz=z — linear functions reproduced exactly
  by both 1D-per-component and covfie bilinear interpolation
- Case 2 (covfie only): Br=r+z, Bz=r+z — bilinear exactly reproduces
  linear functions with cross-axis dependence, confirming covfie does
  true 2D interpolation; guarded by CELERITAS_USE_COVFIE since
  1D-per-component correctly does not reproduce cross-axis variation

Prompt: "Add a test that validates RZMapField interpolation against
analytically known values using synthetic linear fields: one that varies
on a single axis (ground truth for both paths) and one that varies on
both axes (proving covfie does true 2D bilinear interpolation)"

Assisted-by: Claude Sonnet 4.6
Covfie stores field values as float32 internally; GPU arithmetic produces
slightly different rounding from CPU for 3 of 24 sample points (~1.03e-7
relative error), just exceeding the original 1e-7 tolerance. Widening to
2e-7 accommodates float32 precision on device while remaining tight enough
to catch significant regressions.

Prompt: "Widen RZMapFieldTest.device tolerance from 1e-7 to 2e-7 to
accommodate float32 GPU rounding differences introduced by covfie's
internal float storage"

Assisted-by: Claude Sonnet 4.6
- msc_rzfield: add #if CELERITAS_USE_COVFIE branch with covfie bilinear
  interpolation values (displacement=0.495, angle=-0.927); the large
  difference from the non-covfie values (displacement=0.552, angle=0.095)
  arises because the test particle is in a region of strong cross-axis
  field gradients where 1D-per-component and bilinear interpolation diverge
- msc_rzfield_finegrid: widen angle tolerance from EXPECT_SOFT_EQ to
  EXPECT_SOFT_NEAR with 1e-11, accommodating a 6e-12 relative difference
  due to float32 field storage in covfie

Prompt: "Update SimpleCmsRZFieldAlongStepTest to add covfie-specific
expected values for msc_rzfield where bilinear interpolation gives
physically different results from 1D-per-component in strong gradient
regions, and widen the msc_rzfield_finegrid angle tolerance to accommodate
float32 rounding from covfie's internal field storage"

Assisted-by: Claude Sonnet 4.6
@codecov

codecov Bot commented Apr 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 67.96875% with 41 lines in your changes missing coverage. Please review.
✅ Project coverage is 87.19%. Comparing base (ab0b5d5) to head (218cfa4).
⚠️ Report is 1 commits behind head on develop.

Files with missing lines Patch % Lines
src/celeritas/field/RZMapFieldData.covfie.hh 34.61% 17 Missing ⚠️
src/celeritas/field/RZMapFieldParams.covfie.cc 87.30% 5 Missing and 3 partials ⚠️
src/celeritas/field/RZMapFieldParams.hh 0.00% 7 Missing ⚠️
src/accel/RZMapMagneticField.cc 0.00% 4 Missing ⚠️
src/celeritas/field/detail/NotImplementedField.hh 0.00% 4 Missing ⚠️
src/celeritas/field/RZMapField.covfie.hh 93.75% 0 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop    #2344      +/-   ##
===========================================
- Coverage    87.26%   87.19%   -0.08%     
===========================================
  Files         1382     1385       +3     
  Lines        43943    43998      +55     
  Branches     13949    13479     -470     
===========================================
+ Hits         38346    38363      +17     
+ Misses        4523     4401     -122     
- Partials      1074     1234     +160     
Files with missing lines Coverage Δ
...eleritas/alongstep/AlongStepRZMapFieldMscAction.hh 71.42% <ø> (ø)
src/celeritas/field/RZMapFieldData.hh 100.00% <100.00%> (+7.69%) ⬆️
src/celeritas/field/detail/CovfieRZFieldTraits.hh 100.00% <100.00%> (ø)
src/celeritas/field/RZMapField.covfie.hh 93.75% <93.75%> (ø)
src/accel/RZMapMagneticField.cc 0.00% <0.00%> (ø)
src/celeritas/field/detail/NotImplementedField.hh 0.00% <0.00%> (ø)
src/celeritas/field/RZMapFieldParams.hh 0.00% <0.00%> (-66.67%) ⬇️
src/celeritas/field/RZMapFieldParams.covfie.cc 87.30% <87.30%> (ø)
src/celeritas/field/RZMapFieldData.covfie.hh 34.61% <34.61%> (ø)

... and 115 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Replace 20-line bottom-up manual layer-by-layer construction with a
single cross-type field copy: field = std::make_unique<field_t>(*other.field).

covfie's cross-type field constructor propagates through all transformer
layers (affine->clamp->linear->strided), with strided's cross-type
owning_data_t constructor triggering cuda_device_array's constructor
from array_1d_like backends, performing the H2D transfer at the bottom
of the chain.

Prompt: "use the cross-copy constructor approach to simplify H2D device
field construction instead of manually building from the bottom up layer
by layer"

Assisted-by: Claude Sonnet 4.6
Comment thread src/celeritas/field/RZMapFieldData.hh
Comment thread test/celeritas/field/Fields.test.cc Outdated
Comment thread test/celeritas/field/Fields.test.cc Outdated
Comment thread test/celeritas/field/Fields.test.cc Outdated
Sakib Rahman added 6 commits April 9, 2026 10:27
The CI has a C++17/C++20 split: library sources compile as C++20 but
some test files (e.g. AlongStep.test.cc) compile as C++17. When
CELERITAS_USE_COVFIE is ON, the include chain:

  AlongStepRZMapFieldMscAction.hh -> RZMapFieldData.hh
    -> RZMapFieldData.covfie.hh -> detail/CovfieRZFieldTraits.hh
    -> covfie/core/parameter_pack.hpp  (uses C++20 "requires")

caused C++17 builds to fail.

Fix by ensuring covfie types never appear in any .hh included by C++17
TUs:

- RZMapFieldData.hh (covfie path): define only the primary template
  declaration and the const_reference/device specialization with a
  void const* field_view (no covfie types). The other three
  specializations remain in RZMapFieldData.covfie.hh which is only
  included from .covfie.cc and .cu files.
- RZMapFieldData.covfie.hh: include RZMapFieldData.hh for the primary
  template; remove the const_reference/device specialization (now in
  .hh).
- RZMapField.covfie.hh: add rzmap_get_view<M> function template that
  uses if constexpr (with M as template parameter so the discarded
  branch is not instantiated) to either cast void const* on device or
  call get_view() on host. Store ParamsRef const& instead of a direct
  field view reference.
- RZMapFieldParams.covfie.cc: assign device_ref_ fields explicitly
  since const_reference/device no longer has an operator=(value/device).
- AlongStepRZMapFieldMscAction.hh: remove spurious include of
  RZMapFieldData.hh (the class only holds SPConstFieldParams; it never
  references RZMapFieldParamsData directly).

The non-covfie build path and the CartMapField backend are unaffected.

Prompt: "The CI has a C++17/C++20 split where library source files compile
as C++20 but some test files compile as C++17. When CELERITAS_USE_COVFIE
is ON, covfie's parameter_pack.hpp uses C++20 requires clauses that leak
into C++17 TUs through the public RZMapFieldData.hh include chain. Fix
this by hiding all covfie types from public headers so that C++17 TUs
never see covfie includes. Use void const* type erasure for the device
const_reference specialization, with the cast back to the concrete view
type happening only in .cu files compiled as C++20."

Assisted-by: Claude Sonnet 4.6
The action's .cc and .cu files include RZMapField.hh, which when covfie
is enabled pulls in covfie headers requiring C++20. The file was
previously registered via the unconditional celeritas_polysource() call,
placing it in the main celeritas library target that does not directly
link Extcovfie and therefore does not inherit cxx_std_20 from covfie's
INTERFACE_COMPILE_FEATURES.

Move the action into _celer_covfie_src alongside
AlongStepCartMapFieldMscAction so it is compiled in a target that
directly links Extcovfie. Add the corresponding non-covfie fallback in
the else() branch and remove the unconditional celeritas_polysource()
call.

Prompt: "AlongStepRZMapFieldMscAction.cc includes RZMapField.hh which
pulls in covfie headers requiring C++20, but the file is compiled in a
target that does not directly link Extcovfie and therefore compiles at
C++17. AlongStepCartMapFieldMscAction avoids this because it is placed
in _celer_covfie_src which directly links Extcovfie and inherits
cxx_std_20 from covfie's INTERFACE_COMPILE_FEATURES. Apply the same fix
to AlongStepRZMapFieldMscAction."

Assisted-by: Claude Sonnet 4.6
RZMapMagneticField.hh included RZMapField.hh, which when covfie is
enabled pulls in covfie headers requiring C++20. This broke compilation
of any downstream .cc file (e.g. celer-g4/DetectorConstruction.cc)
that includes the header but is compiled at C++17.

Apply the same adapter pattern used by CartMapMagneticField: introduce
RZAdapterField, a plain struct whose operator() is defined in a new
RZMapMagneticField.cc. The .cc file includes RZMapField.hh and is
compiled as part of the accel library, which already links Extcovfie
and therefore compiles at C++20. The .hh now only includes
RZMapFieldParams.hh (which forward-declares RZMapFieldParamsData),
exposing no covfie types to downstream users.

Prompt: "DetectorConstruction.cc in celer-g4 includes
RZMapMagneticField.hh which pulls in RZMapField.hh and covfie headers
requiring C++20, but DetectorConstruction.cc is compiled at C++17.
CartMapMagneticField.hh avoids this by using a CartAdapterField struct
whose operator() is implemented in CartMapMagneticField.cc, keeping the
covfie include out of the header. Apply the same pattern to
RZMapMagneticField."

Assisted-by: Claude Sonnet 4.6
Before this change, RZMapField had a separate Collection-based CPU
implementation predating covfie, guarded by #if !CELERITAS_USE_COVFIE
throughout. CartMapField already followed a cleaner pattern: a minimal
stub in the data header, inline CELER_NOT_CONFIGURED stubs in the params
header, and a one-line type alias in the field header. This commit brings
RZMapField into alignment with that pattern, removing ~350 lines of
duplicated guard logic.

Changes:
- Delete RZMapFieldParams.cc: its only content was non-covfie stubs, now
  replaced by inline stubs in RZMapFieldParams.hh inside a
  #if !(CELERITAS_USE_COVFIE || __DOXYGEN__) block, matching
  CartMapFieldParams.hh exactly (Impl struct, ImplDeleter, ctor,
  host_ref, device_ref all CELER_NOT_CONFIGURED or CELER_UNREACHABLE).
- Add minimal RZMapFieldParamsData<W,M> stub in RZMapFieldData.hh's
  #else block (one field: FieldDriverOptions options) so the type is
  always a complete primary template, mirroring CartMapFieldData.hh.
- Generalize detail::NotImplementedField from a Cart-specific class to a
  template<template<Ownership, MemSpace> class ParamsData> class, keeping
  using ParamsRef = NativeCRef<ParamsData> so FieldTrackPropagator<Field>
  can still access Field::ParamsRef as a concrete type. Remove the
  CartMapFieldData.hh include from NotImplementedField.hh (each field
  header includes its own data header instead).
- Update CartMapField.hh to pass CartMapFieldParamsData explicitly:
  using CartMapField = detail::NotImplementedField<CartMapFieldParamsData>
- Simplify RZMapField.hh's #else block to include RZMapFieldData.hh and
  alias: using RZMapField = detail::NotImplementedField<RZMapFieldParamsData>
- Remove RZMapFieldParams.cc from src/celeritas/CMakeLists.txt SOURCES.
  Add AlongStepRZMapFieldMscAction to the covfie-OFF else() branch
  alongside AlongStepCartMapFieldMscAction so it links against the stubs.
- Disable RZMapFieldTest via #define RZMapFieldTest DISABLED_RZMapFieldTest
  when !CELERITAS_USE_COVFIE (DISABLED_ GoogleTest pattern, matching how
  Cart tests are not gated but RZ tests would fail without a field map).
- Disable SimpleCmsRZFieldAlongStepTest the same way in AlongStep.test.cc
  and gate its two CTest entries on CELERITAS_USE_covfie in
  test/celeritas/CMakeLists.txt to avoid the no-tests-written failure.
- Remove non-bilinear Case 1 from Fields.test.cc interp_validation since
  the Collection-based interpolation path no longer exists; keep only the
  bilinear cross-term check (Case 2) and relax tolerance to 2e-7.

Prompt: "RZMapField currently has a Collection-based CPU implementation
predating covfie, with many #if CELERITAS_USE_COVFIE guards scattered
across the field, data, params headers and test files. CartMapField
follows a cleaner pattern with minimal stubs and no guards in most places.
Remove the non-covfie RZMapField code path so that RZMapField matches the
CartMapField pattern exactly: a minimal complete type stub in the data
header's #else block, inline CELER_NOT_CONFIGURED stubs in the params
header, and a one-line NotImplementedField type alias in the field header.
Generalize detail::NotImplementedField to support both CartMapField and
RZMapField without duplicating it. Use the DISABLED_ GoogleTest prefix
trick (not full #if wrapping) to skip RZ tests when covfie is off, exactly
as Cart tests are handled. Do not add guards in RZ test files where the
analogous Cart code does not have them. Remove Case 1 from
interp_validation in Fields.test.cc since the non-bilinear interpolation
path is gone. Delete RZMapFieldParams.cc. Update CMakeLists to compile
AlongStepRZMapFieldMscAction in the covfie-OFF branch and gate the
SimpleCmsRZFieldAlongStep CTest entries on CELERITAS_USE_covfie."

Assisted-by: Claude Sonnet 4.6
…Test

The msc_rzfield test body contained a #if CELERITAS_USE_COVFIE guard with
separate expected displacement and angle values for the non-covfie path.
Since SimpleCmsRZFieldAlongStepTest is already disabled via the DISABLED_
prefix when covfie is OFF, the #else branch was dead code that could never
execute. Remove the guard and retain only the covfie expected values.

Prompt: "Remove remaining #if CELERITAS_USE_COVFIE guards from
SimpleCmsRZFieldAlongStepTest test bodies. The whole fixture is disabled
when covfie is OFF so any #else branches with non-covfie expected values
are dead code and should be deleted."

Assisted-by: Claude Sonnet 4.6
The displacement and angle expectations used EXPECT_SOFT_EQ (1e-12
relative tolerance) but CI hardware produces results with ~1e-8 relative
deviation from the reference values, likely due to differing FMA
instruction scheduling across GPU architectures. Switch to
EXPECT_SOFT_NEAR with 1e-7 to accommodate this cross-platform variation.

Prompt: "Relax the tolerance on the displacement and angle checks in
SimpleCmsRZFieldAlongStepTest.msc_rzfield to accommodate floating-point
variation across GPU hardware. The CI machine gives a result differing
by ~1e-8 relative error from the reference value, which exceeds the
default EXPECT_SOFT_EQ tolerance of 1e-12."

Assisted-by: Claude Sonnet 4.6
@rahmans1 rahmans1 marked this pull request as ready for review April 9, 2026 18:47
@rahmans1 rahmans1 requested a review from esseivaju as a code owner April 9, 2026 18:47
@rahmans1 rahmans1 requested a review from sethrj April 9, 2026 18:47
Comment thread src/celeritas/field/RZMapField.covfie.hh Outdated
@esseivaju

Copy link
Copy Markdown
Member

The CI build error seems internal to covfie, we should probably submit a fix:

 /__w/celeritas/celeritas/build/_deps/covfie-src/lib/core/covfie/core/backend/transformer/clamp.hpp(165): error #20013-D: calling a constexpr __host__ function("clamp") from a __host__ __device__ function("adjust") is not allowed. The experimental flag '--expt-relaxed-constexpr' can be used to allow this.
                return {std::clamp(coord[Is], m_min[Is], m_max[Is])...};

@sethrj sethrj left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Once we figure out that failing test, anyway…

Comment thread src/celeritas/field/RZMapFieldData.hh
Comment thread src/celeritas/field/RZMapField.covfie.hh Outdated
@rahmans1

Copy link
Copy Markdown
Contributor Author

@sethrj Just documenting here because it's relevant. The path we chose determines how we fail the SimpleCmsRZFieldAlongStepTest.msc_rzfield test here in single precision build whereas the previous non-covfie implementation succeeds by essentially hiding it. Should we adapt our implentation to follow the original rz behavior of returning zero field out of bounds?

Covfie Path

The track is at z = -700 cm in vacuum with no cross sections, so:

step_length = phys_mfp / total_macro_xs ≈ 2.49e21 cm  (effectively infinite)

The DormandPrince RK integrator evaluates the field at 7 substep positions:

pos_substep = pos + a_ij * step * k_j

With step = 2.49e21 cm, even a small coefficient like a_21 = 0.2 places a
substep at r ~ 5e20 cm — far outside the grid (max_r = 900 cm).

Covfie clamps the out-of-bounds query to the nearest
grid boundary and returns the boundary field value (e.g. Bz ≈ 3.8 T). This
nonzero B produces a nonzero Lorentz force F = q v × B at the substep, which
feeds into the RK error estimate:

err_state = Σ e_i * k_i * step

With step = 2.49e21 and finite momentum derivatives k_i from the nonzero B,
err_state overflows to inf or NaN. Then:

rel_err_sq = |err_state|² / |state|²  →  NaN

and CELER_ENSURE(result >= 0) in FieldUtils.hh fires.

Non-Covfie Path

It does a initial check on bounds returning {0, 0, 0} outside the grid means B = 0 → force F = 0
→ momentum derivatives k_i for out-of-bounds substeps are {vx, vy, vz, 0, 0, 0}
(position advances but momentum does not change). The momentum component of
err_state is zero; the position component is large but finite. rel_err_sq is
finite and non-negative → no assertion failure. The step is then halved repeatedly
due to large error, hits max_nsteps = 100, and returns a looping result without
crashing.

@rahmans1

Copy link
Copy Markdown
Contributor Author

Now the second error in SimpleCmsRZFieldAlongStepTest.msc_rzfield_finegrid here, that actually happened in the original non-covfie implementation path as well but because the test passed the expected value test, it never got reported.

In msc_rzfield_finegrid, the "failed to change position" error is a known float32 precision artifact — the step 6.1e-7 cm is below the ULP at r≈125 cm. This is logged silently in CI today because the test happens to pass with the non-covfie expected values. But it's a real error being swallowed.

Unless we want to play around with the mfp, the right fix is probably to add a ScopedLogStorer (as done in LeadBoxAlongStepTest.position_change) so the test explicitly captures and expects those error messages in debug builds, rather than letting them pass through silently. This makes the known limitation visible and intentional instead of accidental. If the expected values are then updated to match the covfie interpolation output, the test would be both correct and self-documenting about the float32 precision edge case.

@rahmans1

Copy link
Copy Markdown
Contributor Author

The CI build error seems internal to covfie, we should probably submit a fix:

 /__w/celeritas/celeritas/build/_deps/covfie-src/lib/core/covfie/core/backend/transformer/clamp.hpp(165): error #20013-D: calling a constexpr __host__ function("clamp") from a __host__ __device__ function("adjust") is not allowed. The experimental flag '--expt-relaxed-constexpr' can be used to allow this.
                return {std::clamp(coord[Is], m_min[Is], m_max[Is])...};

@esseivaju acts-project/covfie#98 already did but nobody has reviewed it yet.

@sethrj

sethrj commented Apr 11, 2026

Copy link
Copy Markdown
Member

@rahmans1 Good debugging. I think a follow-on PR should impose a global limit on the maximum step size, and/or we should get an initial guess on the propagation step (e.g. using the safety distance or straight-line distance) before doing the field substep convergence.

Regarding the failure (CC @esseivaju ): please git am this patch; I think it'll fix it.

From 85055ac41f9f850eb7926e5a2e6d586fff4fc48e Mon Sep 17 00:00:00 2001
From: Seth R Johnson <johnsonsr@ornl.gov>
Date: Sat, 11 Apr 2026 07:33:43 -0400
Subject: [PATCH] Work around covfie std usage

---
 src/CMakeLists.txt | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 49b80b529..e19972275 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -166,6 +166,14 @@ if(CELERITAS_USE_covfie)
     list(APPEND _covfie_libs $<COMPILE_ONLY:covfie::hip> Celeritas::ExtDeviceApi)
   endif()
   target_link_libraries(Extcovfie INTERFACE ${_covfie_libs})
+
+  if(CELERITAS_USE_CUDA AND covfie_VERSION VERSION_LESS_EQUAL 0.15.3)
+    # See https://github.com/acts-project/covfie/pull/98 :
+    # avoid warning/runtime failure due to use of std::clamp in device code
+    target_compile_options(Extcovfie
+      INTERFACE "$<$<COMPILE_LANGUAGE:CUDA>:--expt-relaxed-constexpr>"
+    )
+  endif()
 endif()
 
 #----------------------------------------------------------------------------#
-- 
2.53.0

esseivaju and others added 4 commits April 11, 2026 15:15
In float32, the step length ~6e-7 cm is below machine epsilon at r~125
cm, causing all tracks to fail to change position in debug builds. Add a
ScopedLogStorer to explicitly capture and expect these errors in
float32+debug builds, and widen the angle tolerance for float32 builds.

Prompt: "Add ScopedLogStorer to msc_rzfield_finegrid to explicitly handle float32 precision limit where step length is below machine epsilon, and widen angle tolerance for float32 builds"
Assisted-by: Claude Sonnet 4.6
Store grid bounds from RZMapFieldInput in RZMapFieldParamsData and add
a bounds check in RZMapField::operator(). Without this, covfie clamps
out-of-bounds queries to boundary values, causing NaN in the RK error
state when step length is infinite (vacuum track with no cross sections).

Prompt: "Return zero outside field grid bounds in RZMapField: store min/max bounds from RZMapFieldInput in RZMapFieldParamsData and check them in RZMapField::operator()"
Assisted-by: Claude Sonnet 4.6

@sethrj sethrj left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome! Thanks for tracking down the bugs and getting the implementation switched over.

@sethrj sethrj merged commit cf8d83d into celeritas-project:develop Apr 13, 2026
42 checks passed
@rahmans1 rahmans1 deleted the pr/rzmap-covfie-backend branch April 16, 2026 18:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-assisted Generated/refactored substantially with agentic/LLM AI tools enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants