Kira, FireFly and Fermat (external)

The content on this page was written by AI under human supervision.

Kira is public software by P. Maierhöfer, J. Usovitsch, P. Uwer, J. Klappert, F. Lange and Z. Wu for integration-by-parts (IBP) reduction. You give it the definition of a family of Feynman integrals and a list of the integrals you need, and it writes each one as an exact linear combination of a few master integrals. Two other public programs do its arithmetic: Fermat (R. H. Lewis) simplifies the rational-function coefficients during a symbolic solve, and FireFly (J. Klappert, S. Y. Klein and F. Lange) can instead rebuild those coefficients from many fast solves over finite fields. BootLoops uses this stack for the reductions on its Feynman-integral pages and adds a lightly patched Kira build plus four Python scripts that split, restage and diagnose large Kira jobs, with a small shared module that reads Kira's integral numbering.

What it does

A multi-loop diagram defines a family of integrals that differ only in the integer powers $a_1,\dots,a_n$ on its propagators $D_i$, with negative powers standing for numerator factors. In dimensional regularization the integral of a total derivative vanishes,

$$\int d^dk\;\frac{\partial}{\partial k^\mu}\left[\frac{v^\mu}{D_1^{a_1}\cdots D_n^{a_n}}\right]=0,$$

and carrying out the derivative gives a linear relation among integrals of the family, with coefficients rational in the dimension $d$ and the kinematic invariants. Kira generates these relations for every "seed" integral in a range you choose and solves the sparse linear system. Each requested integral then comes out in terms of the master integralsthe few integrals of the family that the linear relations cannot eliminate; every other integral is a rational-function combination of them. Reducing the derivatives of the masters the same way gives their differential equations. All arithmetic is exact, so a finished reduction has no numerical error. If the seed range is too small to reach every target, Kira's log reports integrals left unreduced and the range must grow.

A Kira job is a directory with config/integralfamilies.yaml, config/kinematics.yaml and a jobs.yaml, run as kira jobs.yaml --parallel=N. Each reduce entry names a topology, a sector and the seed bounds. A sector is the subset of propagators with positive powers, written as an integer bit mask, so powers [1,1,0,0] are sector 3. The bounds are r (sum of positive powers), s (sum of numerator powers) and d (extra powers beyond one per line). select_mandatory_list points at a file of target integrals written like fam[2,1,0,0,-1,0]. run_initiate generates the equations; run_triangular and run_back_substitution solve them through Fermat, or run_firefly solves them by finite-field reconstructionsolve the system many times with every symbol replaced by an integer modulo a large prime, then reconstruct the exact rational functions from those samples, avoiding the huge intermediate expressions of a symbolic solve. Results go to results/<family>/, solver state to results/kira.db. Fermat is closed-source freeware, installed from its own site and found through FERMATPATH.

BootLoops' Kira is a fork of Kira 3.1 with two small patches, kept in the kira-dev repository (GitHub organization BootLoops-ai) with upstream's history and license intact; the changes are on the branch bootloops, release tag bootloops-1.0, and FireFly is built unmodified. One patch silences a harmless SQLite "cannot commit" line that otherwise fills long logs; the other lets each worker thread normalize coefficients through its own Fermat process instead of queueing on one. In side-by-side tests the reduction output is byte-identical to stock Kira's; a speedup is expected only on deep reductions and has not been demonstrated at moderate depth. Two upstream build options matter: -Djemalloc=true, whose allocator copes far better with long reductions, and -Dweight_width=128, which builds a second binary kira128 for the one case where the standard build stops with Integral weight representation exceeds 64 bits. Keep the 64-bit build as the default and rerun only the failing job under kira128.

The scripts, shown below, are for large families, a thousand sectors or more. parallel_kira_gen.py spreads Kira's equation generation, which uses little more than one core whatever --parallel says, over many Kira processes. build_restage.py shrinks the seed box of a job whose equation generation runs out of memory or crawls (Seedling treats seed-range choice in general). ffsave_degree_census.py says which coefficients of a FireFly run that will not finish carry the blow-up. parallel_kira_gen_uds.py builds equations for a few chosen sectors from Kira's own operator templates, and the top-emit command of parallel_kira_gen.py uses the same templates to write the top sector's equation file without running Kira. pyred_weight.py is the module both the FireFly report and top-emit use to convert between an integral's index list and the integer weight Kira stores for it in results/kira.db.

Kira checkpoints its Fermat solve in results/kira.db, so after a crash you back up results/ and rerun the same command in the same directory. A FireFly solve resumes only once ff_save/shift exists, and generation has no checkpoint. Agreement between primes inside one FireFly run does not show a table is right: BootLoops checks tables with Trust, which certifies each table entry against the linear system it came from, or repeats the reduction with FIRE (A. V. Smirnov and F. S. Chukharev), a separate public IBP program. When a reconstruction in more than one symbolic variable stalls, see Numkin and the degree_alias module of Ratfit, which decides whether a reconstruction that keeps failing on the same entries needs a larger interpolation grid or more primes.

Examples

Restage a job whose generation runs out of memory. Take the self-test's fixture: a directory with a jobs.yaml and a target file de_targets for a family fam with four propagators and two numerator slots,

fam[1,1,0,0,0,0]
fam[2,1,0,0,-1,0]
fam[1,0,1,1,0,-2]
python3 tools/kira-stack/build_restage.py --dir DIR --fam fam --nprops 4

The old jobs.yaml is kept as jobs.yaml.pre_restage (change the suffix with --backup-suffix) and the new one has one reduce entry per target sector, highest sector number first, each with the smallest box that covers its own targets:

        - {topologies: [fam], sectors: [13], r: 3, s: 2, d: 0}
        - {topologies: [fam], sectors: [3], r: 3, s: 1, d: 1}

followed by select_mandatory_list, integral_ordering: 5, run_initiate: true and run_triangular/run_firefly set to false (--tail-file replaces this block). The script prints one line per directory with its counts, and a JSON record written in the same directory holds the target count, the number of sectors given their own entry, and the overall box, here [3, 2, 1]. --nprops (default 14) must equal the family's propagator count: a positive power in a numerator slot stops the script with an error, but too large a value silently assigns wrong sectors.

Generate the equations of a large family in parallel. The script's usage summary:

setup    REF OUT [--fam F --top T --r R --s S --tops S1,..]
launch   OUT [--parallel P --nice N --host HOST]
status   OUT
top-emit OUT [--db RUNDIR --out-dir DIR]      # option (c), engine-free
merge    OUT TARGET [--top-from DIR] [--dedupe]
probe    REF [--r R --s S --tops S1,..]       # setup+launch+wait+verify, small

REF is a finished Kira directory for the family, whose config/ and sectormappings/ the shards reuse; OUT is new. setup requires --fam, --r and --s, reads the targets from REF/<file> (--targets, default de_targets_m2), and writes one shard_<id>/ for each sector obtained from --top by removing one propagator (or per --tops entry, or per group in a --manifest JSON file). Pass --no-pm (no preferred_masters at generation) and add --targets-mode own-sectors when the real targets all sit in the top sector. Do not mix shard output with tables from a run that used preferred masters, since the masters can differ. launch starts one detached kira jobs.yaml --parallel=P per shard. status prints one line per shard. merge writes the union of the shard equation files into TARGET/tmp/<family>/ for a single solve with run_initiate: false, drops duplicates, and writes SYSTEMconfig and masters. It warns if the top sector is missing: that sector lies in no shard. Supply it from a finished ordinary run through --top-from DIR, or run top-emit OUT and then merge OUT TARGET --top-from OUT/top_emit. top-emit writes OUT/top_emit/tmp/<family>/SYSTEM_<family>_<top>.gz straight from the operator templates in REF/sectormappings/, plus a record TOP_EMIT_META.json. It reads the weight bit widths and integral_ordering from a finished shard's results/kira.db (or --db RUNDIR) and stops with an error if the databases disagree or the ordering differs from the --io given at setup. Its file has no symmetry relations and no equation selection, so the merged system is larger than Kira's own and must be checked the same way. Before trusting a merged system, compare its equations as a set against an ordinary serial run of a smaller case. probe runs a small sharded trial and checks that equations appearing in two shards are identical.

Find which coefficients are blowing up in a stuck FireFly run.

python3 tools/kira-stack/ffsave_degree_census.py <rundir> [--vars d,s2,s12] [--workers N] [--out census.json]

<rundir> must contain ff_save/states/, de_targets, preferred, results/<family>/masters and results/kira.db; name the family with --family, and copy ff_save/states/ first if Kira is still running, because the files rotate. The script checks that its decoder for Kira's integer tags reproduces every integral name in those files and stops if not. It then writes JSON, by default FF_DEGREE_CENSUS.json in the run directory. Each item of entries gives target, master, the numerator and denominator degrees deg_num and deg_den that FireFly has already measured, and whether the entry was finished (done). The fields target_src and master_src say how each name was recovered: file, custom, or inverse for integrals that appear in no name file. --vars names Kira's symbols in order and adds per-variable degrees; --workers 16 reads the gzip files in parallel.

Routines

Patched Kira build (the kira-dev repository)

Sharded generation (tools/kira-stack/parallel_kira_gen.py)

Direct per-sector generation (tools/kira-stack/parallel_kira_gen_uds.py)

Seed-range restaging (tools/kira-stack/build_restage.py)

FireFly state report (tools/kira-stack/ffsave_degree_census.py)

Weight codec (tools/kira-stack/pyred_weight.py)

Self-test (tools/kira-stack/selftest.py)

Used on this site

Requirements and source

Kira needs a C++17 compiler, Meson and Ninja, GiNaC (with CLN), zlib, and GMP for FireFly; yaml-cpp, FireFly and FLINT are built as Meson subprojects if absent, and Fermat must be installed to run it. Clone kira-dev, check out bootloops (or the tag bootloops-1.0) and build with

meson setup build --buildtype=release -Dfirefly=true -Dflint=true --prefix=<install>
ninja -C build install

adding -Djemalloc=true (recommended) and, for the second binary, -Dweight_width=128. The scripts need only Python 3 (standard library) and live in tools/kira-stack/ in the separate bootloops-dev repository (same organization), released under the MIT license; their self-test is python3 selftest.py in that directory and ends with kira-stack selftest: ALL PASS (7/7). Keep --parallel at 8 or below and cap Kira's memory rather than letting it swap.

Kira and FireFly are GPL-3.0; the patches carry the same license with upstream's files intact, and PATCHES.md and PATCHES.diff at the root of kira-dev record the whole delta. Upstream: gitlab.com/kira-pyred/kira, gitlab.com/firefly-library/firefly, home.bway.net/lewis (Fermat), gitlab.com/feynmanIntegrals/fire (FIRE). Work that uses the stack should cite the Kira papers (Maierhöfer, Usovitsch and Uwer, arXiv:1705.05610; Klappert, Lange, Maierhöfer and Usovitsch, arXiv:2008.06494), the FireFly papers (arXiv:1904.00009, arXiv:2004.01463) and, for the method, Laporta, arXiv:hep-ph/0102033.

← back to the tools index