aegir
Phlex-based simulation framework for the SHiP experiment.
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// Random123 Philox 4x32 is deterministic per seed with no shared state, so
8// each event seeds a fresh instance and generation is reproducible and
9// thread-safe by construction.
10//
11// The counter advances sequentially (ctr[0]++ per 4-word block) and the
12// Philox output block is buffered; uniform() returns successive words of the
13// buffered output. This preserves Philox's guaranteed period — an earlier
14// version fed the output back into the counter (output-feedback mode) and
15// returned ctr[0] + 1 as its first word, forfeiting both the period and the
16// intended first draw.
17
18#pragma once
19
20#include <Random123/philox.h>
21
22#include <cstdint>
23
24namespace aegir {
25
26class PhiloxRng {
27 public:
28 // key_hi selects an independent stream, so different generators seeded with
29 // the same event number draw uncorrelated sequences. ctr1 initializes the
30 // second counter word, giving each (seed, key_hi, ctr1) triple a disjoint
31 // counter range — use it for per-event sub-streams of one seed without
32 // perturbing the key (a key derived as seed ^ event would collide across
33 // seeds: XOR is not injective in (seed, event)).
34 explicit PhiloxRng(std::uint32_t seed, std::uint32_t key_hi = 0xBEEFCAFE,
35 std::uint32_t ctr1 = 0)
36 : key_{{seed, key_hi}}, ctr_{{0, ctr1, 0, 0}} {}
37
38 double uniform() {
39 if (idx_ >= 4) {
40 buf_ = rng_(ctr_, key_);
41 ctr_[0]++;
42 idx_ = 0;
43 }
44 // Map a 32-bit word to [0, 1)
45 return buf_[idx_++] * (1.0 / 4294967296.0);
46 }
47
48 double uniform(double lo, double hi) { return lo + (hi - lo) * uniform(); }
49
50 private:
51 r123::Philox4x32 rng_;
52 r123::Philox4x32::key_type key_;
53 r123::Philox4x32::ctr_type ctr_;
54 r123::Philox4x32::ctr_type buf_{};
55 int idx_ = 4;
56};
57
58} // namespace aegir
Definition philox_rng.hpp:26
PhiloxRng(std::uint32_t seed, std::uint32_t key_hi=0xBEEFCAFE, std::uint32_t ctr1=0)
Definition philox_rng.hpp:34
double uniform(double lo, double hi)
Definition philox_rng.hpp:48
double uniform()
Definition philox_rng.hpp:38
Definition math_utils.hpp:12