Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
7464f0d
mg7 merged-flavor: refuse unsupported coupling topologies with a clea…
oliviermattelaer Jun 23, 2026
3de7092
tests/CI: split MSSM p p > go go test into mg7 + madevent, wire into CI
oliviermattelaer Jun 24, 2026
7b8714f
docs: record Fortran mechanism + single-leg consumer finding
oliviermattelaer Jun 24, 2026
1577230
mg7 merged-flavor: support single-merged-leg flavored couplings (inde…
oliviermattelaer Jun 24, 2026
1d6b170
docs: refined Step 3 plan (per-event gather for dependent flavored co…
oliviermattelaer Jun 24, 2026
e10960b
mg7 merged-flavor: add per-event AoSoA plumbing for flavored couplings
Qubitol Jun 24, 2026
2b71232
mg7 merged-flavor: support dependent (running-alphas) flavored couplings
Qubitol Jun 24, 2026
3dabe55
tests: positive p p > go go mg7 consistency check
Qubitol Jun 24, 2026
a808b0a
docs: record Step 3 (dependent flavored couplings) done
Qubitol Jun 24, 2026
e9e8421
Merge branch 'claude/feat-madmatrix-aloha-merge' into claude/mg7-flv-…
oliviermattelaer Jun 25, 2026
852b6a2
Merge remote-tracking branch 'origin/main' into claude/mg7-flv-single…
oliviermattelaer Jun 25, 2026
693dcc0
mg7: pin gogo generation test to madevent + add red mg7 xsec tracker
oliviermattelaer Jun 25, 2026
1c6d88a
Merge pull request #20 from MadGraphTeam/claude/mystifying-burnell-2c…
oliviermattelaer Jun 25, 2026
73c7c1e
remove claude instructions
oliviermattelaer Jul 2, 2026
f586ec5
Merge remote-tracking branch 'origin/main' into claude/mg7-flv-single…
oliviermattelaer Jul 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .github/workflows/acceptancetest_madevent.yml
Original file line number Diff line number Diff line change
Expand Up @@ -981,3 +981,18 @@ jobs:
cd $GITHUB_WORKSPACE
cp input/.mg5_configuration_default.txt input/mg5_configuration.txt
./tests/test_manager.py test_density_mode_doublettbar -pA -t0 -l INFO

acceptancetest_mssm_gogo:
# Fortran madevent supports MSSM p p > go go (merged-flavor squark/gluino
# vertices); the mg7/madmatrix counterpart now also supports it and is
# checked per-flavor (test_standalone_mg7_mssm_gogo in acceptancetest_mg7.yml).
runs-on: ubuntu-24.04
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork == true
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/checkout_mg5
- uses: ./.github/actions/restore-pip-cache
- name: test one of the test test_madevent_mssm_gogo
run: |
cd $GITHUB_WORKSPACE
./tests/test_manager.py test_madevent_mssm_gogo -pA -t0 -l INFO
40 changes: 40 additions & 0 deletions .github/workflows/acceptancetest_mg7.yml
Original file line number Diff line number Diff line change
Expand Up @@ -177,4 +177,44 @@ jobs:
export PATH="$HOME/.cache/HEPtools/bin:$PATH"
./tests/test_manager.py test_generation_heft_mg7 -pA -t0 -l INFO

acceptancetest_mg7_mssm_gogo:
# mg7/madmatrix now generates the MSSM merged-flavor squark/gluino vertices
# (single-merged-leg / event-by-event flavored couplings); standalone_mg7
# reproduces the Fortran standalone per-flavor |M|^2 (~1e-4). This is a
# matrix-element (standalone) check only -- full mg7 event generation for
# merged-flavor processes is not wired up yet (see test_madevent_merged_
# flavor_uq_mg7). The madevent counterpart is test_madevent_mssm_gogo in
# acceptancetest_madevent.yml.
runs-on: ubuntu-24.04
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork == true
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/checkout_mg5
- uses: ./.github/actions/restore-pip-cache
- name: test one of the test test_standalone_mg7_mssm_gogo
run: |
cd $GITHUB_WORKSPACE
./tests/test_manager.py test_standalone_mg7_mssm_gogo -pA -t0 -l INFO

acceptancetest_mg7_mssm_gogo_xsec:
# KNOWN-FAILING (not xfail): standalone_mg7 reproduces the per-flavor |M|^2
# for MSSM p p > go go (test_standalone_mg7_mssm_gogo), but full mg7 event
# generation for merged-flavor processes is not wired up yet -- the madspace
# integrator does not produce the cross-section. This pins the mg7 result to
# the madevent reference (4.541638 pb, run_01 of test_generation_from_file_1)
# and is expected to be red until the mg7 integrator handles merged-flavor
# p p > go go. Self-skips if the madspace + LHAPDF(NNPDF23) stack is absent.
runs-on: ubuntu-24.04
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork == true
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/checkout_mg5
- uses: ./.github/actions/restore-pip-cache
- uses: ./.github/actions/restore_heptools_lhapdf
- name: test one of the test test_generation_from_file_1_mg7
run: |
cd $GITHUB_WORKSPACE
export PATH="$HOME/.cache/HEPtools/bin:$PATH"
./tests/test_manager.py test_generation_from_file_1_mg7 -pA -t0 -l INFO


50 changes: 46 additions & 4 deletions madgraph/iolibs/export_cpp.py
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,10 @@ def generate_parameters_class_files(self):
self.write_set_parameters(self.params_dep)
replace_dict['set_dependent_couplings'] = \
self.write_set_parameters(list(self.coups_dep.values()))
# Only independent flavored couplings use the FLV_COUPLING value[] pointer mechanism;
# dependent (running-alphas) ones are gathered event-by-event (see model_handling / Step 3).
replace_dict['set_flv_couplings'] = \
self.write_flv_couplings(self.coups_flv_dep+self.coups_flv_indep)
self.write_flv_couplings(self.coups_flv_indep)

replace_dict['print_independent_parameters'] = \
self.write_print_parameters(self.params_indep)
Expand Down Expand Up @@ -373,17 +375,57 @@ def write_set_parameters(self, params):

return "\n".join(res_strings)

def _assert_flv_couplings_supported(self, params):
"""Refuse, with a clear and actionable message, the merged-flavor
coupling structures the C++ (mg7/standalone_mg7) backend cannot yet
generate correctly, instead of crashing or emitting wrong/uncompilable
code.

Supported: one- and two-merged-leg "partner" vertices, with either
flavor-*independent* or *dependent* (event-by-event, running-alphas)
couplings. Single-merged-leg vertices (one merged fermion + an unmerged
partner, e.g. the electroweak MSSM squark-quark-neutralino vertices) are
serialized like the Fortran side (the unmerged partner is given flavor
index 1) and gated by the merged leg (see get_coupling_def). Dependent
flavored couplings (e.g. the SUSY-QCD MSSM gluino-squark-quark vertices)
are gathered event-by-event into cDPF_* / flvCOUPs_dep (Step 3).

Not yet supported (raises):

* a vertex with more than two merged-flavor legs (never seen so far).

The Fortran 'madevent'/'standalone' output supports the remaining cases.
See docs/mg7_merged_flavor_mssm_design.md.
"""
for coupl in params:
for key in coupl.flavors:
nb_merged = len([i for i in key if i != 0])
if nb_merged in (1, 2):
continue
raise InvalidCmd(
"merged-flavor C++ output (mg7/standalone_mg7) does not yet "
"support this process: flavor coupling %s connects %d "
"merged-flavor legs; only one or two are supported. Use "
"'output madevent' or 'output standalone' for this process. "
"See docs/mg7_merged_flavor_mssm_design.md for details."
% (coupl.name, nb_merged))

def write_flv_couplings(self, params):
"""Write out the lines of independent parameters"""

self._assert_flv_couplings_supported(params)
def_flv = []
# For each parameter, write name = expr;
for coupl in params:
for key, c in coupl.flavors.items():
# get first/second index
k1, k2 = [i for i in key if i!=0]
nonzero = [i for i in key if i != 0]
if len(nonzero) == 2:
k1, k2 = nonzero
else:
# single merged leg: unmerged partner has flavor index 1
k1 = nonzero[0]; k2 = 1
def_flv.append('%(name)s.partner[%(in)i] = %(out)i;' % {'name': coupl.name,'in': k1-1, 'out': k2-1})
def_flv.append('%(name)s.partner2[%(out)i] = %(in)i;' % {'name': coupl.name,'in': k1-1, 'out': k2-1})
def_flv.append('%(name)s.partner2[%(out)i] = %(in)i;' % {'name': coupl.name,'in': k1-1, 'out': k2-1})
def_flv.append('%(name)s.val[%(in)i] = &%(coupl)s;' % {'name': coupl.name,'in': k1-1, 'coupl': c})

return "\n".join(def_flv)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,11 @@ namespace mg5amcCpu
static constexpr auto idcoupAccessBuffer = MemoryAccessCouplingsBase::idcoupAccessBuffer;
static constexpr auto idcoupAccessBufferConst = MemoryAccessCouplingsBase::idcoupAccessBufferConst;

// Per-flavor stride (in fptype's) between two consecutive flavor slots of a flavored coupling value buffer.
// For dependent (event-by-event, running-alphas) couplings the value is an AOSOA record [nx2][neppC]
// (real and imaginary SIMD lanes), so consecutive flavor slots are nx2*neppC fptype's apart.
static constexpr int flv_stride = MemoryAccessCouplingsBase::neppC * mgOnGpu::nx2;

// Expose selected functions from MemoryAccessCouplings
static constexpr auto ieventAccessRecordConst = MemoryAccessCouplings::ieventAccessRecordConst;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ namespace mg5amcCpu
// Expose selected functions from MemoryAccessCouplingsFixedBase
static constexpr auto iicoupAccessBufferConst = MemoryAccessCouplingsFixedBase::iicoupAccessBufferConst;

// Per-flavor stride (in fptype's) between two consecutive flavor slots of a flavored coupling value buffer.
// For fixed (independent) couplings the value is a single scalar complex (real,imag): nx2 fptype's, broadcast across the SIMD vector.
static constexpr int flv_stride = mgOnGpu::nx2;

// Locate a field (output) in a memory buffer (input) from a kernel event-indexing mechanism (internal) and the given field indexes (input)
// [Signature (const, SCALAR OR VECTOR) ===> cxtype_sv kernelAccessConst( const fptype* buffer ) <===]
static __host__ __device__ inline const cxtype_sv
Expand Down
9 changes: 7 additions & 2 deletions madgraph/iolibs/template_files/madmatrix/cpp_hel_amps_h.inc
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,16 @@ namespace mg5amcCpu
: partner1(p1), partner2(p2), value(v) {}
};

template<int SIZE, int STRIDE>
// FSTRIDE is the number of fptype's used to store one flavor slot of the value buffer:
// - independent (fixed) flavored couplings: FSTRIDE = nx2 = 2 (a single scalar complex, broadcast across the SIMD vector)
// - dependent (event-by-event, running-alphas) flavored couplings: FSTRIDE = nx2*neppC (an AOSOA SIMD record)
// It must match C_ACCESS::flv_stride of the access type the consuming vertex routine is instantiated with.
template<int SIZE, int STRIDE, int FSTRIDE = 2>
class FLV_COUPLING_ARRAY {

static_assert(SIZE >= 0, "flvCOUPs SIZE must be non-negative");
static_assert(STRIDE > 0, "flvCOUPs STRIDE must be positive");
static_assert(FSTRIDE > 0, "flvCOUPs FSTRIDE must be positive");
const int* const partner1;
const int* const partner2;
const fptype* const value;
Expand All @@ -78,7 +83,7 @@ namespace mg5amcCpu
return FLV_COUPLING_VIEW{
partner1 + i*STRIDE,
partner2 + i*STRIDE,
value + i*2*STRIDE
value + i*FSTRIDE*STRIDE
};
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,14 @@ namespace mg5amcCpu
// nIPF are the number of SM independent flavor couplings, of type FLV_COUPLING
constexpr int nMF = FLV_COUPLING::max_flavor;
constexpr int nIPF = %(nipf)i;
// nDPF are the number of dependent (event-by-event, running-alphas) flavor couplings
constexpr int nDPF = %(ndpf)i;
static_assert( nIPC <= nicoup );
static_assert( nIPD >= 0 ); // Hack to avoid build warnings when nIPD==0 is unused
static_assert( nIPC >= 0 ); // Hack to avoid build warnings when nIPC==0 is unused
static_assert( nMF >= 0 ); // Hack to avoid build warnings when nMF ==0 is unused
static_assert( nIPF >= 0 ); // Hack to avoid build warnings when nIPF==0 is unused
static_assert( nDPF >= 0 ); // Hack to avoid build warnings when nDPF==0 is unused
#ifdef MGONGPU_HARDCODE_PARAM
%(cipdhrdcod)s
%(cipchrdcod)s
Expand All @@ -130,6 +133,12 @@ namespace mg5amcCpu
#endif
#endif

// Dependent (event-by-event, running-alphas) flavor couplings: partner indices and
// the per-flavor idcoup are pure compile-time constants (the complex values are
// gathered per event page in calculate_jamps), so they are emitted the same way in
// all build modes (no CUDA constant memory copy needed).
%(cdpfdecl)s

// AV Jan 2024 (PR #625): this ugly #define was the only way I found to avoid creating arrays[nBsm] in CPPProcess.cc if nBsm is 0
// The problem is that nBsm is determined when generating Parameters.h, which happens after CPPProcess.cc has already been generated
// For simplicity, keep this code hardcoded also for SM processes (a nullptr is needed as in the case nBsm == 0)
Expand Down
Loading
Loading