Skip to content

Commit

Permalink
Add configure-time CELERITAS_OPENMP switch to change threading (cel…
Browse files Browse the repository at this point in the history
…eritas-project#1222)

* Comment cmake config

* Add cmake for openmp

* Switch openmp pragmas based on configure flag

* Fix ccache key for ultralite builds

* Update warning message in accel

* Overwrite tags

* Address review feedback

* Escape macros for launcher
  • Loading branch information
sethrj committed May 7, 2024
1 parent a8c69d2 commit 12c9dbe
Show file tree
Hide file tree
Showing 14 changed files with 80 additions and 27 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build-ultralite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
uses: actions/cache@v4
with:
path: ${{env.CCACHE_DIR}}
key: ccache-ultralite-${{github.run_id}}
key: ccache-ultralite-ubuntu-${{github.run_id}}
restore-keys: |
ccache-ultralite
- name: Zero ccache stats
Expand Down Expand Up @@ -80,7 +80,7 @@ jobs:
uses: actions/cache@v4
with:
path: ${{env.CCACHE_DIR}}
key: ccache-ultralite-${{github.run_id}}
key: ccache-ultralite-windows-${{github.run_id}}
restore-keys: |
ccache-ultralite
- name: Zero ccache stats
Expand Down
54 changes: 45 additions & 9 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -80,16 +80,31 @@ cmake_dependent_option(CELERITAS_TEST_VERBOSE
# CELERITAS CORE IMPLEMENTATION OPTIONS
#----------------------------------------------------------------------------#

# CELERITAS_CORE_RNG: random number generator selection
if(CELERITAS_USE_CUDA OR CELERITAS_USE_HIP)
set(CELERITAS_MAX_BLOCK_SIZE 256
CACHE STRING "Threads-per-block launch bound for Celeritas action kernels"
)
else()
set(CELERITAS_MAX_BLOCK_SIZE 0)
endif()

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# CELERITAS_CORE_RNG
# Random number generator selection
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
celeritas_setup_option(CELERITAS_CORE_RNG xorwow)
celeritas_setup_option(CELERITAS_CORE_RNG cuRAND CELERITAS_USE_CUDA)
celeritas_setup_option(CELERITAS_CORE_RNG hipRAND CELERITAS_USE_HIP)
# TODO: allow wrapper to standard library RNG when not building for device?
# TODO: add wrapper to standard library RNG when not building for device?
# TODO: add ranluxpp?
# TODO: maybe even add wrapper to Geant4 RNG??
celeritas_define_options(CELERITAS_CORE_RNG
"Celeritas runtime random number generator")

# CELERITAS_CORE_GEO: runtime geometry selection
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# CELERITAS_CORE_GEO
# Runtime geometry selection
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if(CELERITAS_USE_VecGeom AND NOT CELERITAS_USE_HIP)
set(_allow_vecgeom TRUE)
else()
Expand All @@ -98,7 +113,7 @@ else()
message(SEND_ERROR "VecGeom core geometry is incompatible with HIP")
endif()
endif()
if(CELERITAS_USE_Geant4 AND NOT (CELERITAS_USE_HIP OR CELERITAS_USE_CUDA OR CELERITAS_USE_OpenMP))
if(CELERITAS_USE_Geant4 AND NOT (CELERITAS_USE_HIP OR CELERITAS_USE_CUDA OR CELERITAS_OPENMP))
set(_allow_g4 TRUE)
else()
if(CELERITAS_CORE_GEO STREQUAL "Geant4")
Expand All @@ -111,14 +126,26 @@ celeritas_setup_option(CELERITAS_CORE_GEO ORANGE)
celeritas_setup_option(CELERITAS_CORE_GEO Geant4 _allow_g4)
celeritas_define_options(CELERITAS_CORE_GEO "Celeritas runtime geometry")

if(CELERITAS_USE_CUDA OR CELERITAS_USE_HIP)
set(CELERITAS_MAX_BLOCK_SIZE 256
CACHE STRING "Threads-per-block launch bound for Celeritas action kernels"
)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# CELERITAS_OPENMP
# Thread parallelism
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

if(CELERITAS_USE_OpenMP)
set(_disable_openmp FALSE)
else()
set(CELERITAS_MAX_BLOCK_SIZE 0)
set(_disable_openmp TRUE)
endif()

celeritas_setup_option(CELERITAS_OPENMP disabled _disable_openmp)
celeritas_setup_option(CELERITAS_OPENMP event CELERITAS_USE_OpenMP)
celeritas_setup_option(CELERITAS_OPENMP track CELERITAS_USE_OpenMP)
celeritas_define_options(CELERITAS_OPENMP "Celeritas OpenMP parallelism")

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# CELERITAS_UNITS
# Unit system for celeritas runtime
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if(CELERITAS_CORE_GEO STREQUAL Geant4)
set(_allow_single_prec FALSE)
else()
Expand All @@ -131,6 +158,10 @@ celeritas_setup_option(CELERITAS_UNITS CLHEP)
celeritas_define_options(CELERITAS_UNITS
"Native unit system for Celeritas")

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# CELERITAS_REAL_TYPE
# Precision for real numbers
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
celeritas_setup_option(CELERITAS_REAL_TYPE double)
celeritas_setup_option(CELERITAS_REAL_TYPE float)
celeritas_define_options(CELERITAS_REAL_TYPE
Expand Down Expand Up @@ -269,6 +300,11 @@ endif()

if(CELERITAS_USE_Geant4 AND NOT Geant4_FOUND)
find_package(Geant4 REQUIRED)
if(CELERITAS_OPENMP STREQUAL "track" AND Geant4_multithreaded_FOUND)
message(WARNING "Track-level OpenMP will conflict with MT runs of geant4:"
"consider setting CELERITAS_OPENMP to \"event\" or disabling OpenMP"
)
endif()
endif()

if(CELERITAS_USE_HepMC3)
Expand Down
2 changes: 1 addition & 1 deletion app/celer-sim/Runner.cc
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ namespace
size_type calc_num_streams(RunnerInput const& inp, size_type num_events)
{
size_type num_threads = 1;
#if CELERITAS_USE_OPENMP
#if CELERITAS_OPENMP == CELERITAS_OPENMP_EVENT
if (!inp.merge_events)
{
# pragma omp parallel
Expand Down
2 changes: 1 addition & 1 deletion app/celer-sim/celer-sim.cc
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ void run(std::istream* is, std::shared_ptr<OutputRegistry> output)
CELER_LOG(status) << "Transporting " << run_stream.num_events()
<< " on " << num_streams << " threads";
MultiExceptionHandler capture_exception;
#ifdef _OPENMP
#if CELERITAS_OPENMP == CELERITAS_OPENMP_EVENT
# pragma omp parallel for
#endif
for (size_type event = 0; event < run_stream.num_events(); ++event)
Expand Down
2 changes: 1 addition & 1 deletion scripts/ci/run-ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ if [ -f "${_ENV_SCRIPT}" ]; then
fi

# Fetch tags for version provenance
git fetch --tags
git fetch -f --tags

# Clean older builds from jenkins *BEFORE* setting up presets
git clean -fxd
Expand Down
7 changes: 4 additions & 3 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@ set(CELERITAS_USE_VECGEOM ${CELERITAS_USE_VecGeom})
# Start counter from 1 because undefined config have the implicit value of 0 in
# the C preprocessor, so any unavailable options (e.g. CELERITAS_USE_CURAND
# when HIP is in use) will implicitly be zero.
celeritas_generate_option_config(CELERITAS_CORE_RNG)
celeritas_generate_option_config(CELERITAS_CORE_GEO)
celeritas_generate_option_config(CELERITAS_UNITS)
celeritas_generate_option_config(CELERITAS_CORE_RNG)
celeritas_generate_option_config(CELERITAS_OPENMP)
celeritas_generate_option_config(CELERITAS_REAL_TYPE)
celeritas_generate_option_config(CELERITAS_UNITS)
celeritas_configure_file("celeritas_config.h.in" "celeritas_config.h" @ONLY)

#----------------------------------------------------------------------------#
Expand All @@ -47,7 +48,7 @@ endif()

set(CELERITAS_CMAKE_STRINGS)
set(CELERITAS_BUILD_TYPE ${CMAKE_BUILD_TYPE})
foreach(_var BUILD_TYPE HOSTNAME REAL_TYPE CORE_GEO CORE_RNG UNITS)
foreach(_var BUILD_TYPE HOSTNAME REAL_TYPE UNITS OPENMP CORE_GEO CORE_RNG)
set(_var "CELERITAS_${_var}")
string(TOLOWER "${_var}" _lower)
string(APPEND CELERITAS_CMAKE_STRINGS
Expand Down
5 changes: 3 additions & 2 deletions src/accel/LocalTransporter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,12 @@ LocalTransporter::LocalTransporter(SetupOptions const& options,
<< params.Params()->max_streams() << ")");

// Check that OpenMP and Geant4 threading models don't collide
if (CELERITAS_USE_OPENMP && !celeritas::device()
if (CELERITAS_OPENMP == CELERITAS_OPENMP_TRACK && !celeritas::device()
&& G4Threading::IsMultithreadedApplication())
{
auto msg = CELER_LOG_LOCAL(warning);
msg << "Using multithreaded Geant4 with Celeritas OpenMP";
msg << "Using multithreaded Geant4 with Celeritas track-level OpenMP "
"parallelism";
if (std::string const& nt_str = celeritas::getenv("OMP_NUM_THREADS");
!nt_str.empty())
{
Expand Down
3 changes: 2 additions & 1 deletion src/celeritas/global/ActionLauncher.hh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//---------------------------------------------------------------------------//
#pragma once

#include "celeritas_config.h"
#include "corecel/Assert.hh"
#include "corecel/Types.hh"
#include "corecel/sys/MultiExceptionHandler.hh"
Expand Down Expand Up @@ -34,7 +35,7 @@ void launch_action(ExplicitActionInterface const& action,
F&& execute_thread)
{
MultiExceptionHandler capture_exception;
#ifdef _OPENMP
#if defined(_OPENMP) && CELERITAS_OPENMP == CELERITAS_OPENMP_TRACK
# pragma omp parallel for
#endif
for (size_type i = 0; i < num_threads; ++i)
Expand Down
4 changes: 3 additions & 1 deletion src/celeritas/track/detail/TrackSortUtils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,9 @@ void count_tracks_per_action(
std::fill(offsets.begin(), offsets.end(), ThreadId{});
auto const size = states.size();
// if get_action(0) != get_action(1), get_action(0) never gets initialized
#pragma omp parallel for
#if CELERITAS_OPENMP == CELERITAS_OPENMP_TRACK
# pragma omp parallel for
#endif
for (size_type i = 1; i < size; ++i)
{
ActionId current_action = get_action(ThreadId{i});
Expand Down
5 changes: 4 additions & 1 deletion src/celeritas/user/detail/SimpleCaloImpl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//---------------------------------------------------------------------------//
#include "SimpleCaloImpl.hh"

#include "celeritas_config.h"
#include "corecel/Types.hh"
#include "corecel/sys/MultiExceptionHandler.hh"
#include "corecel/sys/ThreadId.hh"
Expand All @@ -27,7 +28,9 @@ void simple_calo_accum(HostRef<StepStateData> const& step,
CELER_EXPECT(step && calo);
MultiExceptionHandler capture_exception;
SimpleCaloExecutor execute{step, calo};
#pragma omp parallel for
#if CELERITAS_OPENMP == CELERITAS_OPENMP_TRACK
# pragma omp parallel for
#endif
for (ThreadId::size_type i = 0; i < step.size(); ++i)
{
CELER_TRY_HANDLE(execute(ThreadId{i}), capture_exception);
Expand Down
2 changes: 2 additions & 0 deletions src/celeritas_config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@

@CELERITAS_UNITS_CONFIG@

@CELERITAS_OPENMP_CONFIG@

@CELERITAS_CORE_GEO_CONFIG@

@CELERITAS_CORE_RNG_CONFIG@
Expand Down
13 changes: 10 additions & 3 deletions src/corecel/math/Atomics.hh
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ namespace celeritas
//---------------------------------------------------------------------------//
/*!
* Add to a value, returning the original value.
*
* Note that on CPU, this assumes the atomic add is being done in with \em
* track-level parallelism rather than \em event-level because these utilities
* are meant for "kernel" code.
*
* \warning Multiple events must not use this function to simultaneously modify
* shared data.
*/
template<class T>
CELER_FORCEINLINE_FUNCTION T atomic_add(T* address, T value)
Expand All @@ -28,7 +35,7 @@ CELER_FORCEINLINE_FUNCTION T atomic_add(T* address, T value)
#else
CELER_EXPECT(address);
T initial;
# ifdef _OPENMP
# if defined(_OPENMP) && CELERITAS_OPENMP == CELERITAS_OPENMP_TRACK
# pragma omp atomic capture
# endif
{
Expand Down Expand Up @@ -78,7 +85,7 @@ CELER_FORCEINLINE_FUNCTION T atomic_min(T* address, T value)
#else
CELER_EXPECT(address);
T initial;
# ifdef _OPENMP
# if defined(_OPENMP) && CELERITAS_OPENMP == CELERITAS_OPENMP_TRACK
# pragma omp atomic capture
# endif
{
Expand All @@ -101,7 +108,7 @@ CELER_FORCEINLINE_FUNCTION T atomic_max(T* address, T value)
#else
CELER_EXPECT(address);
T initial;
# ifdef _OPENMP
# if defined(_OPENMP) && CELERITAS_OPENMP == CELERITAS_OPENMP_TRACK
# pragma omp atomic capture
# endif
{
Expand Down
2 changes: 1 addition & 1 deletion src/corecel/sys/MultiExceptionHandler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ MultiExceptionHandler::~MultiExceptionHandler()
*/
void MultiExceptionHandler::operator()(std::exception_ptr p)
{
#ifdef _OPENMP
#if CELERITAS_OPENMP == CELERITAS_OPENMP_TRACK
# pragma omp critical(MultiExceptionHandler)
#endif
{
Expand Down
2 changes: 1 addition & 1 deletion src/geocel/rasterize/RaytraceImager.t.hh
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ void RaytraceImager<G>::launch_raytrace_kernel(
size_type const num_threads = geo_states.size();

MultiExceptionHandler capture_exception;
#ifdef _OPENMP
#if CELERITAS_OPENMP == CELERITAS_OPENMP_TRACK
# pragma omp parallel for
#endif
for (size_type i = 0; i < num_threads; ++i)
Expand Down

0 comments on commit 12c9dbe

Please sign in to comment.