Control

These options manage trade-offs between performance and memory usage, and other parameters that affect the simulation results without changing the physics.

struct Control

Set up control/tuning parameters that do not affect physics.

Defaults:

  • device_debug: absent unless device is enabled

  • optical_capacity: absent unless optical physics is enabled

  • track_order: init_charge on GPU, none on CPU

Public Members

StateCapacity capacity

Per-process state sizes.

std::optional<StateCapacity> optical_capacity

Per-process state sizes for optical tracking loop.

size_type num_streams = {}

Number of streams.

std::optional<TrackOrder> track_order

Track sorting and initialization.

std::optional<DeviceDebug> device_debug

Debug options for device.

bool warm_up = {false}

Perform a no-op step at the beginning to improve timing measurements.

unsigned int seed = {}

Random number generator seed.

struct DeviceDebug

When using GPU, change execution options that make it easier to debug.

Defaults:

  • sync_stream: false unless timers.diagnostics.action is true.

Public Members

bool default_stream = {false}

Launch all kernels on the default stream.

std::optional<bool> sync_stream

Synchronize the stream after every kernel launch.

struct StateCapacity

Set up per-process state/buffer capacities.

Increasing these values increases resource requirements with the trade-off of (usually!) improving performance. A larger number of tracks in flight means improved performance on GPU because the standard kernel size increases, but it also means higher memory usage because of the larger number of full states. More initializers are necessary for more (and higher-energy) tracks when lots of particles are in flight and producing new child particles. More secondaries may be necessary if physical processes that produce many daughters (e.g., atomic relaxation or Bertini cascade) are active. The number of events in flight primarily increases the number of active tracks, possible initializers, and produced secondaries (NOTE: see #1233 ). Finally, the number of primaries is the maximum number of pending tracks from an external application before running a kernel to construct initializers and execute the stpeping loop.

Capacities are defined as the number per application process (task): this means that in a multithreaded context it implies “strong scaling” (i.e., the allocations are divided among threads), and in a multiprocess context it implies “weak scaling” (the problem size grows with the number of processes). In other words, if used in a multithread “event-parallel” context, each state gets the specified tracks divided by the number of threads. When used in MPI parallel (e.g., one process per GPU), each process rank has tracks total threads.

Defaults:

  • secondary: twice the number of track slots.

    Todo:

    Split this into “core” state capacity and “optical” state capacity? Core contains events and secondaries .

    Instead of a special value events=0, make a variant or something more descriptive?

    Some of these parameters will be more automated in the future.

Note

The primaries was previously named auto_flush .

Note

Previously, SetupOptions and celer-g4 treated these quantities as “per stream” whereas celer-sim used “per process”.

Public Members

size_type primaries = {}

Maximum number of primaries that can be buffered before stepping.

size_type initializers = {}

Maximum number of queued primaries+secondaries.

size_type tracks = {}

Maximum number of track slots to be simultaneously stepped.

std::optional<size_type> secondaries

Maximum number of secondaries created per step.

size_type events = {0}

Maximum number of simultaneous events (zero for Geant4 integration)