Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions src/accel/LocalTransporter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,10 @@ void LocalTransporter::Push(G4Track& g4track)
*/
track.event_id = EventId{0};

// Add track id and initialize step counter
track.track_id = g4track.GetTrackId();
track.step_count = g4track.GetCurrentStepNumber();

buffer_.push_back(track);
buffer_accum_.energy += track.energy.value();
if (buffer_.size() >= auto_flush_)
Expand Down
3 changes: 3 additions & 0 deletions src/celeritas/global/CoreTrackView.hh
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ CoreTrackView::operator=(TrackInitializer const& init)
// Initialize the simulation state
this->sim() = init.sim;

// Initializer RNG state
this->rng() = init.rng;

// Initialize the particle attributes
this->particle() = init.particle;

Expand Down
4 changes: 3 additions & 1 deletion src/celeritas/phys/Primary.hh
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ struct Primary
Real3 direction{0, 0, 0};
real_type time{};
EventId event_id;
PrimaryId primary_id;
unsigned int geant_track_id{};
unsigned int geant_step_count{};
PrimaryId primary_id; //! todo: remove this in the future.
real_type weight{1.0};
};

Expand Down
1 change: 1 addition & 0 deletions src/celeritas/phys/PrimaryGenerator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ auto PrimaryGenerator::operator()() -> result_type
p.direction = sample_dir_(rng_);
p.time = 0;
p.event_id = EventId{event_count_};
p.primary_id = PrimaryId{event_count_ * primaries_per_event_ + i};
}
++event_count_;
return result;
Expand Down
2 changes: 2 additions & 0 deletions src/celeritas/track/TrackInitData.hh
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "corecel/data/Collection.hh"
#include "corecel/data/CollectionAlgorithms.hh"
#include "corecel/data/CollectionBuilder.hh"
#include "corecel/random/data/RngData.hh"
#include "corecel/sys/Device.hh"
#include "corecel/sys/ThreadId.hh"
#include "geocel/Types.hh"
Expand Down Expand Up @@ -69,6 +70,7 @@ struct TrackInitializer
SimTrackInitializer sim;
GeoTrackInitializer geo;
ParticleTrackInitializer particle;
RngStateInitializer rng;

//! True if assigned and valid
explicit CELER_FUNCTION operator bool() const
Expand Down
78 changes: 78 additions & 0 deletions src/celeritas/track/detail/FillRngStateInitializer.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
//------------------------------- -*- C++ -*- -------------------------------//
// Copyright Celeritas contributors: see top-level COPYRIGHT file for details
// SPDX-License-Identifier: (Apache-2.0 OR MIT)
//---------------------------------------------------------------------------//
//! \file celeritas/track/detail/FillRngStateInitializer.cc
//---------------------------------------------------------------------------//
#include "FillRngStateInitializer.hh"

#include "corecel/random/engine/SplitMix64.hh"

namespace celeritas
{
namespace detail
{

//---------------------------------------------------------------------------//
//! Create and return the RNG state initializer specialized for XorWow.
CELER_FUNCTION
void setupRngInitializer(unsigned int seed,
unsigned int event_id,
unsigned int geant_track_id,
unsigned int geant_step_id,
XorwowRngEngine::RngStateInitializer_t& rng_init)
{
// Initialize SplitMix64 with the seed XORed with the track id
SplitMix64 rng(seed ^ geant_track_id);

// Fill first two state values
std::uint64_t val = rng();
rng_init.xorstate[0] = static_cast<XorwowUInt>(val);
rng_init.xorstate[1] = static_cast<XorwowUInt>(val >> 32);

// XOR with event id
rng.xor_state(event_id);
val = rng();
rng_init.xorstate[2] = static_cast<XorwowUInt>(val);
rng_init.xorstate[3] = static_cast<XorwowUInt>(val >> 32);

// XOR with step id
rng.xor_state(geant_step_id);
val = rng();
rng_init.xorstate[4] = static_cast<XorwowUInt>(val);
rng_init.weylstate = static_cast<XorwowUInt>(val >> 32);
}

//---------------------------------------------------------------------------//
//! Create and return the RNG state initializer specialized for Ranluxpp.
CELER_FUNCTION
void setupRngInitializer(unsigned int seed,
unsigned int event_id,
unsigned int geant_track_id,
unsigned int geant_step_id,
RanluxppRngEngine::RngStateInitializer_t& rng_init)
{
// Initialize SplitMix64 with the seed XORed with the track id
SplitMix64 rng(seed ^ geant_track_id);

// Fill first three state values
rng_init.value.number[0] = rng();
rng_init.value.number[1] = rng();
rng_init.value.number[2] = rng();

// XOR with event id and fill next three values
rng.xor_state(event_id);
rng_init.value.number[3] = rng();
rng_init.value.number[4] = rng();
rng_init.value.number[5] = rng();

// XOR with step id and fill next three values
rng.xor_state(geant_step_id);
rng_init.value.number[6] = rng();
rng_init.value.number[7] = rng();
rng_init.value.number[8] = rng();
}

//---------------------------------------------------------------------------//
} // namespace detail
} // namespace celeritas
35 changes: 35 additions & 0 deletions src/celeritas/track/detail/FillRngStateInitializer.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//------------------------------- -*- C++ -*- -------------------------------//
// Copyright Celeritas contributors: see top-level COPYRIGHT file for details
// SPDX-License-Identifier: (Apache-2.0 OR MIT)
//---------------------------------------------------------------------------//
//! \file celeritas/track/detail/FillRngStateInitializer.hh
//---------------------------------------------------------------------------//
#pragma once

#include "corecel/random/engine/RanluxppRngEngine.hh"
#include "corecel/random/engine/XorwowRngEngine.hh"

namespace celeritas
{
namespace detail
{

// Fill a XorwowRngEngine state initializer
CELER_FUNCTION
void fillRngStateInitializer(unsigned int seed,
unsigned int event_id,
unsigned int track_id,
unsigned int step_id,
XorwowRngEngine::RngStateInitializer_t& rng_init);

// Fill a RanluxppRngEngine state initializer
CELER_FUNCTION
void fillRngStateInitializer(unsigned int seed,
unsigned int event_id,
unsigned int track_id,
unsigned int step_id,
RanluxppRngEngine::RngStateInitializer_t& rng_init);

//---------------------------------------------------------------------------//
} // namespace detail
} // namespace celeritas
94 changes: 94 additions & 0 deletions src/celeritas/track/detail/ProcessPrimariesExecutor.hh
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,17 @@
#include "corecel/Assert.hh"
#include "corecel/Macros.hh"
#include "corecel/cont/Span.hh"
#include "corecel/random/engine/RanluxppRngEngine.hh"
#include "corecel/random/engine/RngEngine.hh"
#include "corecel/random/engine/SplitMix64.hh"
#include "corecel/random/engine/XorwowRngEngine.hh"
#include "celeritas/Quantities.hh"
#include "celeritas/Types.hh"
#include "celeritas/global/CoreTrackData.hh"
#include "celeritas/phys/ParticleData.hh"
#include "celeritas/phys/Primary.hh"

#include "FillRngStateInitializer.hh"
#include "../SimData.hh"
#include "../TrackInitData.hh"
#include "../Utils.hh"
Expand Down Expand Up @@ -45,6 +50,23 @@ struct ProcessPrimariesExecutor

// Create track initializers from primaries
inline CELER_FUNCTION void operator()(ThreadId tid) const;

private:
// Fill the RNG state initializer for the Xorwow engine
inline CELER_FUNCTION void fillRngStateInitializer(
unsigned int seed,
unsigned int event_id,
unsigned int geant_track_id,
unsigned int geant_step_id,
XorwowRngEngine::RngStateInitializer_t& rng_init) const;

// Fill the RNG state initializer for the Ranluxpp engine
void fillRngStateInitializer(
unsigned int seed,
unsigned int event_id,
unsigned int geant_track_id,
unsigned int geant_step_id,
RanluxppRngEngine::RngStateInitializer_t& rng_init) const;
};

//---------------------------------------------------------------------------//
Expand Down Expand Up @@ -72,11 +94,83 @@ CELER_FUNCTION void ProcessPrimariesExecutor::operator()(ThreadId tid) const
ti.particle.particle_id = primary.particle_id;
ti.particle.energy = primary.energy;

// Set the RNG state initializer appropriately dispatched on RNG type
this->fillRngStateInitializer(params->rng.get_seed(),
ti.sim.event_id.get(),
primary.geant_track_id,
primary.geant_step_count,
ti.rng);

// Store the initializer
size_type idx = counters->num_initializers - primaries.size() + tid.get();
state->init.initializers[ItemId<TrackInitializer>(idx)] = ti;
}

//---------------------------------------------------------------------------//
/*!
* Fill a XorwowRngEngine state initializer
*/
CELER_FUNCTION void ProcessPrimariesExecutor::fillRngStateInitializer(
unsigned int seed,
unsigned int event_id,
unsigned int geant_track_id,
unsigned int geant_step_id,
XorwowRngEngine::RngStateInitializer_t& rng_init) const
{
// Initialize SplitMix64 with the seed XORed with the track id
SplitMix64 rng(seed ^ geant_track_id);

// Fill first two state values
std::uint64_t val = rng();
rng_init.xorstate[0] = static_cast<XorwowUInt>(val);
rng_init.xorstate[1] = static_cast<XorwowUInt>(val >> 32);

// XOR with event id
rng.xor_state(event_id);
val = rng();
rng_init.xorstate[2] = static_cast<XorwowUInt>(val);
rng_init.xorstate[3] = static_cast<XorwowUInt>(val >> 32);

// XOR with step id
rng.xor_state(geant_step_id);
val = rng();
rng_init.xorstate[4] = static_cast<XorwowUInt>(val);
rng_init.weylstate = static_cast<XorwowUInt>(val >> 32);
}

//---------------------------------------------------------------------------//
/*!
* Fill a Ranluxpp state initializer
*/
CELER_FUNCTION
void ProcessPrimariesExecutor::fillRngStateInitializer(
unsigned int seed,
unsigned int event_id,
unsigned int geant_track_id,
unsigned int geant_step_id,
RanluxppRngEngine::RngStateInitializer_t& rng_init) const
{
// Initialize SplitMix64 with the seed XORed with the track id
SplitMix64 rng(seed ^ geant_track_id);

// Fill first three state values
rng_init.value.number[0] = rng();
rng_init.value.number[1] = rng();
rng_init.value.number[2] = rng();

// XOR with event id and fill next three values
rng.xor_state(event_id);
rng_init.value.number[3] = rng();
rng_init.value.number[4] = rng();
rng_init.value.number[5] = rng();

// XOR with step id and fill next three values
rng.xor_state(geant_step_id);
rng_init.value.number[6] = rng();
rng_init.value.number[7] = rng();
rng_init.value.number[8] = rng();
}

//---------------------------------------------------------------------------//
} // namespace detail
} // namespace celeritas
5 changes: 4 additions & 1 deletion src/celeritas/track/detail/ProcessSecondariesExecutor.hh
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,10 @@ ProcessSecondariesExecutor::operator()(TrackSlotId tid) const
// initialized in this slot
TrackId const track_id{sim.track_id()};

for (auto const& secondary : track.physics_step().secondaries())
for (unsigned int secondary_idx :
celeritas::range(track.physics_step().secondaries().size()))
{
auto secondary = track.physics_step().secondaries()[secondary_idx];
if (secondary)
{
CELER_ASSERT(secondary.energy > zero_quantity()
Expand All @@ -108,6 +110,7 @@ ProcessSecondariesExecutor::operator()(TrackSlotId tid) const
ti.geo.dir = secondary.direction;
ti.particle.particle_id = secondary.particle_id;
ti.particle.energy = secondary.energy;
ti.rng = track.rng().branch();
CELER_ASSERT(ti);

if (sim.track_id() == track_id && sim.status() != TrackStatus::alive
Expand Down
4 changes: 4 additions & 0 deletions src/corecel/random/data/RanluxppRngData.hh
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ struct RanluxppRngParamsDataImpl
RanluxppArray9 advance_sequence;

//// FUNCTIONS ////

//! Get the seed as a 64-bit unsigned integer
std::uint64_t get_seed() const { return seed; }

//! Whether the data is assigned.
explicit CELER_CONSTEXPR_FUNCTION operator bool() const
{
Expand Down
2 changes: 2 additions & 0 deletions src/corecel/random/data/RngData.hh
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ template<Ownership W, MemSpace M>
using RngParamsData = XorwowRngParamsData<W, M>;
template<Ownership W, MemSpace M>
using RngStateData = XorwowRngStateData<W, M>;
using RngStateInitializer = XorwowRngStateInitializer;
} // namespace celeritas
#elif (CELERITAS_CORE_RNG == CELERITAS_CORE_RNG_RANLUXPP)
# include "RanluxppRngData.hh"
Expand All @@ -37,6 +38,7 @@ template<Ownership W, MemSpace M>
using RngParamsData = RanluxppRngParamsData<W, M>;
template<Ownership W, MemSpace M>
using RngStateData = RanluxppRngStateData<W, M>;
using RngStateInitializer = RanluxppRngStateInitializer;
} // namespace celeritas
#endif
// IWYU pragma: end_exports
3 changes: 3 additions & 0 deletions src/corecel/random/data/XorwowRngData.hh
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ struct XorwowRngParamsData
return 8 * sizeof(XorwowUInt);
}

//! Retrieve the seed as a 64-bit unsigned integer
std::uint64_t get_seed() const { return seed[0]; }

//! Whether the data is assigned
explicit CELER_FUNCTION operator bool() const { return true; }

Expand Down
12 changes: 12 additions & 0 deletions src/corecel/random/engine/SplitMix64.hh
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ class SplitMix64
// Produce a random number
inline CELER_FUNCTION std::uint64_t operator()();

// XOR this state with another
inline CELER_FUNCTION void xor_state(std::uint64_t state);

private:
// SplitMix64 State
std::uint64_t state_;
Expand Down Expand Up @@ -58,5 +61,14 @@ CELER_FUNCTION std::uint64_t SplitMix64::operator()()
return z ^ (z >> 31);
}

//---------------------------------------------------------------------------//
/*!
* Perform a XOR operation of this state with another state.
*/
CELER_FUNCTION void SplitMix64::xor_state(std::uint64_t state)
{
state_ ^= state;
}

//---------------------------------------------------------------------------//
} // namespace celeritas
4 changes: 4 additions & 0 deletions test/celeritas/io/EventIOTestBase.cc
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,17 @@ void EventIOTestBase::write_test_event(Writer& write_event) const
Real3{1, 0, 0},
5.67e-9 * units::second,
EventId{0},
0,
0,
PrimaryId{}};
Primary proton{proton_id,
MevEnergy{2.34},
from_cm(Real3{3, 5, 8}),
Real3{0, 1, 0},
5.78e-9 * units::second,
EventId{0},
0,
0,
PrimaryId{}};
std::vector<Primary> primaries{gamma, proton, gamma, proton};
primaries[1].position = from_cm(Real3{-3, -4, 5});
Expand Down
Loading
Loading