Repository navigation
Custom cut, scale, PDF and bias functions through UMAMI - #264
Merged
Merged
Conversation
…as functions Add UMAMI input keys for particle count, PDG ids, momentum fraction, scale, PDG id and beam index, and output keys CUT, SCALE, PDF and BIAS. A new CustomFunction generator calls a loaded UMAMI library on the event momenta. Cuts, EnergyScale, PartonDensity (via CustomPdf) and Integrand accept these custom functions.
bin/init_custom_func writes custom_<function>/ with a UMAMI wrapper, a function body for one phase-space point (C, C++, Fortran, CUDA or HIP), the UMAMI header and a Makefile that builds lib/custom_<function>.so. Options are taken from the command line or asked interactively. The run card gets a [custom_functions] section with the library paths.
The libraries are built from custom_<kind>/ if present, and loaded before the matrix elements in every context and gridpack. Custom cuts and scales get the PDG ids of the first flavor, the bias those of the sampled flavor. A custom PDF replaces the PDF grid (alpha_s still comes from the PDF set) and disables the systematics.
…eights The integrand weight includes the bias b, so adaptation, unweighting and the channel allocation see |w| b. The signed running integral, which gives the reported cross section, accumulates w / b, and the event records carry b so that the combined events are written with weight w_unw / b.
test_mg7_custom_functions.py compares a custom cut, scale, PDF and bias with the equivalent built-in settings on p p > t t~, and builds and evaluates every function in every language with a toolchain. A new Usage page describes bin/init_custom_func and the function signatures.
UmamiFunctions holds one std::function per UMAMI entry point. The dlopen path fills it from the library symbols, and Context::add_matrix_element takes it directly, so matrix elements can be implemented without a shared library.
Worker threads can then call back into Python. The abort check and the DLPack deleters of Python-owned tensors take the GIL themselves.
ms.PythonFunction calls a Python function on numpy arrays or torch tensors with selectable UMAMI inputs and outputs, and Context.add_matrix_element adds it to a context. The inputs are zero-copy views of the madspace buffers. The results are checked for type, dtype, shape and device before they are copied back. torch functions run on the stream of the GPU runtime.
_madspace_py_loader imports it, so pybind11-stubgen failed to import the staged package in the ENABLE_DOCS builds of CI.
[custom_functions] takes a .so library or a .py file. custom_function_loader loads both, for bin/generate_events and gridpacks. bin/init_custom_func gains the python-numpy and python-torch languages, which need no build. torch is limited to one thread on the CPU, where madspace already splits the batches.
oliviermattelaer
self-requested a review
October 14, 2026 09:34
Contributor
|
One comment on this:
One limitation, is that all parameter are hardcoded in the cuts/... Other points that we should consider is to allow to have different mu_f1, mu_f2 and mu_r One suggestion would be to add tt~j with custom eta cut to check the mirroring part |
Contributor
Author
|
@oliviermattelaer Thanks for the feedback!
|
Combine the second-beam PDF (pdf_grid2) with custom PDFs, which get the other beam index for mirrored events. The custom bias now sees the mapped momenta, as the mirror is applied inside the mapping.
- cuts return bool in all templates, the wrappers convert to 1 or 0 - torch functions get tensors on the right GPU (Device::device_index) - check the device of a custom library when it is loaded - bound check of the particle count in the GPU wrapper - add a p p > t t~ j test with an asymmetric jet cut for the mirroring
- parameters declared in parameters.h (X-macro, also for Fortran through the preprocessor) or PARAMETERS in Python, set in the run card as [custom_functions] <kind>_parameters.<name> = value, passed through umami_set_parameter; gridpacks keep the values - a custom scale returns the renormalization scale and the factorization scales of both incoming particles (UMAMI_OUT_REN_SCALE, UMAMI_OUT_FACT_SCALE_1/2 replace UMAMI_OUT_SCALE) - PythonFunction supports parameters, per UMAMI instance - Fortran templates are .F90
theoheimel
marked this pull request as ready for review
October 17, 2026 13:47
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.
Custom cuts, scales, parton densities and event biases for MG7 runs. Each one is either a UMAMI shared library or a Python file using numpy or torch, called by madspace in batches like a matrix element.
All steps are in. CUDA and HIP builds, and torch functions on GPUs, are untested (no GPU was available).
Design
PARTICLE_COUNT,PDG_IDS,MOMENTUM_FRACTION,SCALE,PDG_ID,BEAM_INDEX.CUT,SCALE,PDF,BIAS, all doubles.user_dynamical_scale.scale_factorand the fixed-scale options still apply.UmamiFunctions, a table ofstd::functions, builds aMatrixElementApiwithout a shared library, throughContext::add_matrix_element.ms.PythonFunctionimplements UMAMI in Python with selectable inputs and outputs. It passes zero-copy numpy or torch views, and checks the type, dtype, shape and device of the results. torch runs on the GPU stream of the runtime. numpy is CPU only.Checklist
UMAMI keys, madspace
CustomFunctionandCustomPdf, options onCuts/EnergyScale/PartonDensity/Integrand, Python bindingsBias handling in the event generator (unbiased cross section, unweighted weights divided by the bias)
bin/init_custom_funcand templates (C, C++, Fortran, CUDA, HIP)Run card
[custom_functions]section andlaunch.pywiringAcceptance tests
Documentation page under Usage
UmamiFunctionsandContext::add_matrix_elementGIL release in the madspace bindings
ms.PythonFunctionand its unit tests.soor.pyin[custom_functions],python-numpy/python-torchinbin/init_custom_func, gridpack supportAcceptance tests and documentation for Python functions