Review fixes for #166 (backend separation) - #179
Open
oliviermattelaer wants to merge 18 commits into
Open
oliviermattelaer wants to merge 18 commits into
oliviermattelaer wants to merge 18 commits into
Conversation
… setup The backend split moved `constexpr int nMF` out of process_function_definitions.inc into madmatrix::ProcessTables, which CPPProcess.cc did not include, while the generated initProc still sizes tIPF_partner1/partner2/value as nMF * nIPF. Every process with merged flavor couplings (nIPF > 0, e.g. MSSM_SLHA2 u u~ > n1 n1) failed with "use of undeclared identifier 'nMF'". Include ProcessTables.h and pull nMF in next to `using namespace ProcessData`, where nIPF already comes from, so the generated text is unchanged. u u~ > n1 n1 now builds on scalar and simd_128 and reproduces the pre-split MeanMatrixElemValue (0.000570885 +- 6.9555e-06). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The backend split hard-coded the color choice in calculate_jamps as `jamp2_sv[ncolor * iParity + icol] += cxabs2( jamp_sv[icol] )` for icol < ncolor. Before, it went through the per-process jampflow_lines / jamp_flow_col holes of process_matrix.inc, which set_color_flow_lines_cpp still computes but which nothing emitted any more. For a process whose color sum runs on the (n-2)! DDM basis the two differ: g g > g g g has ncolor = 6 but picks among ncolor_flow = 24 trace flows, rebuilt from the DDM jamps through the Kleiss-Kuijf relations. The split filled 6 slots with the wrong amplitudes and left 18 at zero, so the selected color (the LHE color flow) was wrong while the matrix element stayed bit-identical -- which is why an ME-only comparison could not see it. Same 1024 events, simd_128: 24 distinct flows selected on the merge base, 12 on the split, one of them 568 times. Write those lines to a generated ColorFlows.inc, #included by backend/<variant>/SigmaKin.cc right after EvaluateDiagrams.inc in the same scope, and have it expose jampflow_sv; the color choice loops over ncolor_flow again (cpu, simd and gpu). Checked through UMAMI on identical momenta and random numbers: g g > g g g (scalar, simd_128 mixed and FPTYPE=d), g g > t t~ and e+ e- > mu+ mu- reproduce the merge base's per-event color and helicity sequences and matrix elements exactly. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… path Four regressions against the merge base in backend/gpu, all restored to the merge base's own lines: * DeviceAccessJamp2 lost kernelAccessIcolConst, which the color choice in sigmaKin still calls (compile error). * MatrixElementKernels.cc lost #include "CPPProcess.h", while the device kernel still sizes its color-choice buffer from CPPProcess::ncolor_flow (compile error). * calculate_jamps wrote its jamps with nhel = 1. allJamps is the [2][ncolor][nGoodHel][nevt] super-buffer, where nhel is the color stride, and color_sum_kernel reads it back with nGoodHel: for ncolor > 1 and more than one good helicity writer and reader address different slots, and helicities overwrite each other. Write with dcNGoodHel again (it is 1 during the good-helicity scan, nGoodHel in sigmaKin). * The color-choice accumulation into colAllJamp2s lost its atomicAdd. That buffer has no helicity dimension and the good helicities run concurrently (one stream each, or blockIdx.y in the async path), so a plain += races. No CUDA/HIP toolchain was available: the device semantics (the last two items) are untested here. What was checked is a host -fsyntax-only of every gpu translation unit against minimal CUDA/cuBLAS/thrust stubs, run differentially: the merge base's GPU code is clean under the same stubs, the split had the two compile errors above, and with this commit it is clean again for g g > t t~ and g g > g g g. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…r sum
The split made any process whose '^2' constraint leaves more than one
amplitude order abort at generation, on the reasoning that the shared
backend/{cpu,simd}/color_sum.cc cannot carry a process-specific variant.
But those backend sources are compiled once per P* directory, against
that directory's generated ProcessData.h / ColorData.h, so a compile-time
switch is enough -- the same pattern as ColorMatrixData::shouldUseBlas.
* ProcessData.h always defines nampso, njampso = ncolor * nampso and
nsqampso (1, ncolor, 1 without split orders); CPPProcess's
split_order_constants now alias them.
* ColorData.h carries the sqSoIndex / chosenSqso pairing tables (the
trivial 1x1 ones when unsplit).
* backend/{cpu,simd}/color_sum.cc gain color_sum_cpu_splitorders, the
pair loop of the former color_sum_splitorders.cc template (ALL ordered
pairs, never a triangle), selected by `if constexpr( nampso > 1 )`, so
the unsplit path's source is untouched. That template is removed.
* The calculate_jamps / sigmaKin jamp buffers are sized njampso again,
where the merge base used the jamp_ncolor hole; the BLAS buffers keep
ncolor behind a static_assert (cpp_blas_wanted is already false when
split).
* backend/gpu/SigmaKin.cc static_asserts nampso == 1, the replacement
for the template's #error under MGONGPUCPP_GPUIMPL.
Validation against the merge base on identical momenta and random
numbers (1024 events through UMAMI): unsplit processes (g g > t t~,
g g > g g g, e+ e- > mu+ mu-, MSSM u u~ > n1 n1, u u~ > u u~ QED^2==0)
stay bit-identical; with FPTYPE=d, u u~ > u u~ QED^2<=4 and
u u~ > d d~ g QED^2==2 are bit-identical and u u~ > u u~ QED^2==2 agrees to
9e-16, same per-event color and helicity choices, on simd_128 and
scalar. At the RAMBO 1000 GeV point the interference is
-5.5828746494657286e-02 against the recorded -5.5828746494657258e-02.
test_standalone_split_orders_interference passes again. The host (clang) stub
syntax check of the GPU build refuses a split process with the new
static_assert message and stays clean for unsplit ones.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
TREX_ProcessExporter.generate_subprocess_directory called
self._link_backend_dirs_in_P(matrix_element), which is defined nowhere,
so `output standalone_trex` raised AttributeError on the first
subprocess. TREX deliberately stays on the old layout ("for TREX for now
no /backend"), and one TREX P* directory builds both the C++ and the
CUDA library, so there is no single backend variant to link anyway.
Note this is not the first thing that stops TREX: on main already,
edit_rwgt_header looks up PLUGIN_export_cpp on model_handling (trex.py
defines it in its own namespace), and librex.so does not compile with
Apple clang (Rex.h:1609 builds std::bad_any_cast from a string). Both
are pre-existing and untouched here. Checked by driving
`output standalone_trex` for g g > t t~ through a PYTHONPATH plugin copy
with the first of those patched out locally: before this commit it
stops with this AttributeError, after it the output is written without
a traceback.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…_include
CPPProcess.h, Parameters.h and HelAmps_<model>.h decided "am I the simd
backend?" with #if __has_include("mgOnGpuVectors.h"). That asks whether
some file of that name is reachable on the include path, and -I$(SRC) is
on it: a stray src/mgOnGpuVectors.h -- TREX copies one there, and an
older output can leave one behind -- silently moves a scalar or GPU
build onto the SIMD path. Reproduced by dropping the simd header into
src/ of a g g > t t~ output: BACKEND=scalar then fails with
"redefinition of 'neppV'".
backend/simd/mgOnGpuConfig.h, and the legacy single-layout
mgOnGpuConfig.h TREX still uses (which always ships the header), now
define MGONGPU_HAS_VECTORS_H, and the three shared headers test that.
The stray-header case builds and matches again; g g > t t~ (scalar and
simd_128) and MSSM u u~ > n1 n1 are bit-identical to the merge base, and
the GPU stub syntax check stays clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ards Two of the mixed-precision guards in backend/simd/color_sum.cc (deltaMEs_next, and the store into the second neppV page) had dropped `defined MGONGPU_CPPSIMD`, while nParityCS in the same file and nParity in SigmaKin.cc keep it. The three have to agree: without the SIMD term color_sum_cpu would write MEs at ievt0 + neppV for a page the caller neither zeroed nor owns. Not reachable today -- mgOnGpuVectors.h does not even compile without MGONGPU_CPPSIMD (`const int neppV = MGONGPU_CPPSIMD`) -- so this only restores the merge base's guards. color_sum_cpu is now textually the same in backend/cpu and backend/simd. simd_128 output is bit-identical. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…e dirs
The backend/{cpu,simd,gpu} and src/rambo from_template lists were built
from `sorted(os.listdir(...))`, i.e. whatever happened to be in those
directories when madmatrix.output was imported. Reproduced: a
backend/cpu/.DS_Store (which macOS Finder creates routinely) was copied
into every generated output.
template_sources() keeps only regular, non-hidden .h/.cc files, which is
everything these directories are meant to hold: the copied file sets are
unchanged (30/31/32/9), while .DS_Store and an editor backup umami.cc~
placed in the template dirs no longer reach the output.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
sigmaKin and everything it calls moved to backend/<variant>/SigmaKin.cc, but get_sigmaKin_lines still read process_sigmaKin_function.inc and %-substituted it for every subprocess, and the result was thrown away: process_function_definitions.inc no longer has a hole for it. The split nevertheless kept editing that template in step with the three SigmaKin.cc copies, which made it a fourth copy of the same code that no build compiles, and the obvious place for the next fix to land in three copies out of four. get_sigmaKin_lines now returns nothing (it keeps the base class's multichannel guard); process_sigmaKin_function.inc and color_sum_blas_loop.inc, reachable only through it, are removed, with their class attributes. The generated sources are byte-identical for g g > t t~ and MSSM u u~ > n1 n1. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
get_all_sigmaKin_lines no longer calls get_matrix_single_process, and the
per-process color_sum.cc it used to write is gone, which leaves without
any caller:
* OneProcessExporterMadMatrix.get_matrix_single_process, and
jamp_ncolor(), which only it (and the sigmaKin rendering dropped in the
previous commit) used -- the jamp buffers are sized by
ProcessData::njampso now;
* process_matrix.inc (single_process_template), whose color-choice and
jamp-copy lines live in backend/<variant>/SigmaKin.cc and
ColorFlows.inc now;
* color_sum_blas.inc (blas_color_sum_template), whose body was copied
into backend/{cpu,simd}/color_sum.cc and would only have drifted from
it.
Comments that named them are updated. Generated sources are
byte-identical for g g > t t~ and MSSM u u~ > n1 n1, and
test_standalone_split_orders_interference passes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ckends The SIMD helpers of MemoryAccessVectors.h exist only in backend/simd. backend/cpu/ and backend/gpu/ each kept a MemoryAccessVectors.h holding nothing but #include "mgOnGpuConfig.h" / "mgOnGpuCxtypes.h" (and, for cpu, an empty namespace), copied into every output only so that five MemoryAccess*.h per backend could include it. Those five now include mgOnGpuCxtypes.h directly -- exactly what the stub provided beyond the mgOnGpuConfig.h they already include -- and the two stubs are removed. Scalar builds are bit-identical (g g > t t~, MSSM u u~ > n1 n1, u u~ > u u~ QED^2==2) and the GPU stub syntax check stays clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ackend/common
Nine files were byte-identical in backend/cpu, backend/simd and
backend/gpu -- constexpr_math.h, CrossSectionKernels.h, EventStatistics.h
and the MemoryAccess{Amplitudes,Denominators,Numerators,RandomNumbers,
Wavefunctions,Weights}.h -- i.e. three copies of ~1300 lines kept in step
by hand. They move to backend/common/, which output.py copies like the
variants and madmatrix.mk / madmatrix_src.mk search after
backend/<variant>/ (and list as prerequisites, so touching one rebuilds).
No file name is in both backend/common and a variant directory, on
purpose: a quoted #include resolves in the including file's own
directory first, so a common header would pick up a common "host"
version of a file even in a build whose variant overrides it. For the
same reason the six files shared only by cpu and simd (CrossSectionKernels.cc,
MatrixElementKernels.{cc,h}, MemoryAccessHelpers.h, MemoryBuffers.h,
mgOnGpuFptypes.h) stay where they are.
Outputs are bit-identical (g g > t t~ scalar and simd_128, g g > g g g,
MSSM u u~ > n1 n1, u u~ > u u~ QED^2==2), the GPU stub syntax check is
clean, and test_standalone_split_orders_interference passes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* output.py: the backend/ copy is no longer "step 1, not yet wired into the build"; and the backend sources, while read from the single top-level backend/<variant>/ and backend/common/ dirs, are compiled once per P* directory -- necessarily, since they include that directory's generated ProcessData.h / ColorData.h / ProcessTables.h. The old wording suggested one shared compilation, which is the misreading that made split orders look impossible to support. * model_handling.py: calculate_jamps lives in backend/*/SigmaKin.cc, not a CalculateJamps.cc that never existed, and EvaluateDiagrams.inc is #included by SigmaKin.cc, not written for CPPProcess.cc; a duplicated comment line on edit_colordata is dropped. * process_function_definitions.inc: SigmaKin.cc #includes ColorFlows.inc too. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The backend split moved fpeEnable(), the runtime SIGFPE-trap switch with its <cfenv> dependency and one-shot static latch, out of the generated CPPProcess.cc into constexpr_math.h -- a header otherwise about compile-time math, which every translation unit that wants constexpr sqrt/pow includes, and where nobody looking for where FPE traps get enabled would think to look. It now lives in backend/common/fpe.h, included by CPPProcess.cc, its only caller (under MGONGPUCPP_DEBUG); constexpr_math.h loses <cfenv>. MatrixElementKernels.cc's own fetestexcept use already includes <cfenv> itself. CPPProcess.cc compiles with -DMGONGPUCPP_DEBUG on cpu and simd, the default build is bit-identical, and the GPU stub check stays clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Moving helcolDenominators from process_function_definitions.inc into ProcessData.h dropped its "assume nprocesses == 1 (#272 and #343)" comment, the only in-tree record that the size-1 array is an assumption: den_factors is joined over every matrix element of the P* directory, and ProcessData.h computes nproc > 1 two lines above. Put the caveat back and point at MadGraph7 issue #168, which tracks sizing it properly. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The setters the backend split added to backend/{cpu,simd}/SigmaKin.cc,
and backend/gpu/MemoryBuffers.h, call memcpy without including
<cstring>. With clang/libc++ (macOS) it arrives transitively, so every
local build passed; with GCC/libstdc++ it does not, and every madmatrix
build on the Linux CI runners stopped at
backend/cpu/SigmaKin.cc:71:5: error: 'memcpy' was not declared in this scope
That single error is behind 33 of the 34 failing checks on #166 and
#179: every mg7 run (no info.json, events, gridpack, MadSpin, Pythia8,
Rivet, reweight or systematics output), the standalone builds (no
matrix element) and the check command's missing "MG7 SA" column.
Reproduced and checked locally with g++-16: before, the CI error and
unittest_31's failure reproduce; after, both CPU backends build, and
test_check_language_function_epem_aa, test_standalone_cpp,
test_standalone_split_orders_interference and test_e_e_collision_mg7
pass with CXX=g++-16 (the mg7 build demonstrably compiling with it,
40.23(42) pb against the 40.3 pb reference).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
testIO_FDgauge_madmatrix records the generated src/HelAmps_sm.h, which the backend split changed in two intended ways: the single namespace madmatrix replaces the mg5amcGpu/mg5amcCpu pair, and mgOnGpuVectors.h is included only by the simd backend (on MGONGPU_HAS_VECTORS_H, falling back to mgOnGpuCxtypes.h). Those are the only two differences; regenerated with `-U testIO_FDgauge_madmatrix -F 10`, and the test passes. No other golden under IOTestsComparison records madmatrix output. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
In the FD gauge HelAmps_<model>.h carries define_gauge_dir and calculate_propagator_factor, pasted from helas_fd.h. Unlike the helas routines around them they are plain functions, not templates, and were marked INLINE -- which is empty unless HELINL=1 -- so with the default build they are ordinary external definitions in a header. That was harmless while only CPPProcess.cc included HelAmps. With the backend split CPPProcess.h includes it and SigmaKin.cc (which now makes the helas calls) and umami.cc include CPPProcess.h, so the process library failed to link: duplicate symbol 'madmatrix::define_gauge_dir(...)' in umami.o, CPPProcess.o, SigmaKin.o which is acceptancetest_uncovered_merged (test_standalone_cpp_fd_output_consistency) on #179, and was hidden behind the memcpy compile error on #166. A non-template function defined in a header must be inline whatever HELINL says, so the two are now `inline` (ALWAYS_INLINE kept on the declarations). The FD-gauge u/d-flavour q q > h q q q q~ QCD=0 process now builds and prints all 54 matrix elements on scalar and simd_128, with HELINL=1, and with g++-16; test_standalone_cpp_fd_output_consistency, test_madmatrix_fd_vs_fortran and test_madmatrix_fd_simd_lanes pass with clang and GCC; the GPU stub check is clean. The FD-gauge madmatrix golden records helas_fd.h and is regenerated for exactly these lines. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
Fixes for the review of #166, as a PR into
backend_seperation_PRso they can be looked at (and accepted or dropped) separately from the split itself. One commit per item, in the order of the review comment; each commit message says what was wrong, how it was reproduced and how the fix was checked, so any of them can be reverted on its own.Needs fixing (review items 1-3), plus three regressions found while fixing them
a2c5a52nMFback in scope forinitProc: every merged-flavor model (e.g. MSSMu u~ > n1 n1) failed to compile. Now builds and reproduces the merge-base ME.4f37adbncolor_flowflows again. The split hard-codedjamp2_sv[ncolor*iParity+icol] += cxabs2(jamp_sv[icol]), dropping the per-processjampflow_lines. For DDM (all-gluon) processesncolor != ncolor_flow: ong g > g g g(6 DDM jamps, 24 flows) the split selected 12 distinct flows, one of them 568/1024 times, against 24 on the merge base. MEs were bit-identical, so an ME-only comparison cannot see it. The flow lines now go to a generatedColorFlows.incthatSigmaKin.ccincludes.4db0133backend/gpudid not compile (DeviceAccessJamp2::kernelAccessIcolConstand#include "CPPProcess.h"inMatrixElementKernels.ccwere dropped), and two device-semantics regressions:calculate_jampswrote jamps withnhel = 1whilecolor_sum_kernelreads the[2][ncolor][nGoodHel][nevt]buffer withnGoodHel(nhelis the color stride), and theatomicAddon the helicity-sharedcolAllJamp2sbecame a racy+=. All restored to the merge base's own lines.e364c25.ccfiles are compiled once per P* directory against its generated headers, so a compile-time switch suffices (same pattern asshouldUseBlas):ProcessData::nampso/njampso/nsqampso, pairing tables inColorData.h,color_sum_cpu_splitorders(the old template's pair loop) underif constexpr( nampso > 1 ), jamp buffers sizednjampso; GPUstatic_assertsnampso == 1like the old#error.color_sum_splitorders.ccis folded in and removed.ce3908a_link_backend_dirs_in_Pintrex.py.Worth changing (review items 4-6)
9507875mgOnGpuVectors.hon aMGONGPU_HAS_VECTORS_Hconfig macro instead of__has_include, which a straysrc/mgOnGpuVectors.h(TREX copies one) turned true for scalar/GPU builds. Reproduced: the stray header brokeBACKEND=scalar; now it builds and matches.0ce9731MGONGPU_CPPSIMDin the two mixed-mode guards ofbackend/simd/color_sum.cc, so they agree withnParityCS/nParity. Latent only; output unchanged.c501a7d.h/.ccfiles from the backend andsrc/rambotemplate dirs: a.DS_Storeplaced there used to land in every output.Optional cleanup (review items 8-11, 13-14; 15 partly)
d76b6b2process_sigmaKin_function.inc(result was discarded; it was being kept in sync as a 4th copy ofSigmaKin.cc); remove it andcolor_sum_blas_loop.inc.6603911get_matrix_single_process,jamp_ncolor,process_matrix.inc,color_sum_blas.inc: no caller left.0cbc16fMemoryAccessVectors.hofbackend/cpuandbackend/gpu.8701fe0backend/common/for the 9 files byte-identical in all three backends, searched afterbackend/<variant>/. Deliberately no name in both: a quoted#includeresolves in the including file's directory first, so a common "host" header would shadow a GPU override. The 6 files shared only by cpu and simd therefore stay duplicated.e4cf21bCalculateJamps.ccthat never existed; backend sources described as compiled once when they are compiled per P* and must be).06b52cdfpeEnable()moves fromconstexpr_math.hto its ownbackend/common/fpe.h.c5db8e9nprocesses == 1caveat onhelcolDenominators; the actual sizing is #168.Items 7 (
HRDCOD=1, already broken onmain) and 12 (.gitignore PROC*) are intentionally not addressed here.CI fixes (the 34 checks that fail on #166 as well)
1e93379#include <cstring>inbackend/{cpu,simd}/SigmaKin.ccandbackend/gpu/MemoryBuffers.h, which callmemcpy. clang/libc++ pulls it in transitively, GCC/libstdc++ does not, so on the Linux runners every madmatrix build stopped atSigmaKin.cc:71: error: 'memcpy' was not declared in this scope. That one error is 33 of the 34 red checks on #166 (everyacceptancetest_mg7_*, allcheck_xsec_processes,acceptancetest_30/32,unittest_31). Reproduced locally withg++-16; with the fix,test_check_language_function_epem_aa,test_standalone_cpp,test_standalone_split_orders_interferenceandtest_e_e_collision_mg7pass underCXX=g++-16.61201d4define_gauge_dir/calculate_propagator_factorare non-template functions defined inHelAmps_<model>.hbut markedINLINE, which is empty unlessHELINL=1. Now thatCPPProcess.hincludes HelAmps andSigmaKin.cc/umami.ccincludeCPPProcess.h, the process library failed to link with duplicate symbols (acceptancetest_uncovered_merged, hidden behind thememcpyerror on #166). Markedinline; the FD tests pass with clang and GCC and the golden is regenerated for these lines.fb9bc7dtestIO_FDgauge_madmatrixgolden (HelAmps_sm.h): the only differences are the two intended ones, themadmatrixnamespace and the backend-conditionalmgOnGpuVectors.hinclude.Validation
aa9d133fa, through UMAMI with identical momenta and random numbers (1024 events):g g > t t~,g g > g g g,e+ e- > mu+ mu-, MSSMu u~ > n1 n1,u u~ > u u~ QED^2==0are bit-identical in ME, per-event selected color and selected helicity (simd_128 mixed; scalar andFPTYPE=dspot-checked).FPTYPE=d:u u~ > u u~ QED^2<=4andu u~ > d d~ g QED^2==2bit-identical,u u~ > u u~ QED^2==2to 9e-16;u u~ > t t~ QED^2==2is analytically zero and noise (~1e-15) on both. In mixed precision the interference differs at the float level (~1e-6 relative), as expected from the float color sum under cancellation. At the RAMBO 1000 GeV point the interference is-5.5828746494657286e-02against the recorded-5.5828746494657258e-02.test_standalone_split_orders_interferencepasses (it cannot on the current branch).backend_seperation_PR(scipymissing; an order-dependent MadLoop IOTest that passes alone).backend/gputranslation unit was syntax-checked on the host against minimal CUDA/cuBLAS/thrust stubs, differentially: the merge base's GPU code is clean under the same stubs,backend_seperation_PRshows the two compile errors above, this branch is clean (and a split-order process hits the newstatic_assert). The stride andatomicAddfixes are device semantics that check cannot see, so please build and run the cuda backend before merging.Also noted, not fixed here
main:edit_rwgt_headerlooks upPLUGIN_export_cpponmodel_handling(trex.py defines it in its own namespace), andlibrex.sodoes not compile with Apple clang (Rex.h:1609). Candidates for a separate issue.🤖 Generated with Claude Code