aegir-genie
GENIE neutrino event generation for the SHiP experiment's aegir framework.
Loading...
Searching...
No Matches
philox_rng.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2026 CERN for the benefit of the SHiP Collaboration
2//
3// SPDX-License-Identifier: LGPL-3.0-or-later
4
5// philox_rng.hpp โ€” counter-based RNG shared by the event-generator sources
6//
7// Vendored from aegir (src/philox_rng.hpp) pending a shared helper package;
8// keep in sync with the original (the backward-compatible `ctr1` sub-stream
9// parameter below is pending upstreaming). LGPL-3.0-or-later, see README.md
10// ยง Licensing.
11//
12// Random123 Philox 4x32 is deterministic per seed with no shared state, so
13// each event seeds a fresh instance and generation is reproducible and
14// thread-safe by construction.
15//
16// The counter advances sequentially (ctr[0]++ per 4-word block) and the
17// Philox output block is buffered; uniform() returns successive words of the
18// buffered output. This preserves Philox's guaranteed period โ€” an earlier
19// version fed the output back into the counter (output-feedback mode) and
20// returned ctr[0] + 1 as its first word, forfeiting both the period and the
21// intended first draw.
22
23#pragma once
24
25#include <Random123/philox.h>
26
27#include <cstdint>
28
29namespace aegir {
30
31class PhiloxRng {
32 public:
33 // key_hi selects an independent stream, so different generators seeded with
34 // the same event number draw uncorrelated sequences. ctr1 initializes the
35 // second counter word, giving each (seed, key_hi, ctr1) triple a disjoint
36 // counter range โ€” use it for per-event sub-streams of one seed without
37 // perturbing the key (a key derived as seed ^ event would collide across
38 // seeds: XOR is not injective in (seed, event)).
39 explicit PhiloxRng(std::uint32_t seed, std::uint32_t key_hi = 0xBEEFCAFE,
40 std::uint32_t ctr1 = 0)
41 : key_{{seed, key_hi}}, ctr_{{0, ctr1, 0, 0}} {}
42
43 double uniform() {
44 if (idx_ >= 4) {
45 buf_ = rng_(ctr_, key_);
46 ctr_[0]++;
47 idx_ = 0;
48 }
49 // Map a 32-bit word to [0, 1)
50 return buf_[idx_++] * (1.0 / 4294967296.0);
51 }
52
53 double uniform(double lo, double hi) { return lo + (hi - lo) * uniform(); }
54
55 private:
56 r123::Philox4x32 rng_;
57 r123::Philox4x32::key_type key_;
58 r123::Philox4x32::ctr_type ctr_;
59 r123::Philox4x32::ctr_type buf_{};
60 int idx_ = 4;
61};
62
63} // namespace aegir
Definition philox_rng.hpp:31
PhiloxRng(std::uint32_t seed, std::uint32_t key_hi=0xBEEFCAFE, std::uint32_t ctr1=0)
Definition philox_rng.hpp:39
double uniform(double lo, double hi)
Definition philox_rng.hpp:53
double uniform()
Definition philox_rng.hpp:43
Definition genie_config.hpp:22