Skip to content
Snippets Groups Projects
Commit c1c4326a authored by Julien Maurer's avatar Julien Maurer
Browse files

Merge branch 'cherry-pick-0865f88d-22.0' into '22.0'

Sweeping !57115 from master to 22.0.
RootUtils: add TRandomTLS class

See merge request !57182
parents f1c2f685 1be2e9cc
No related branches found
No related tags found
4 merge requests!69091Fix correlated smearing bug in JER in JetUncertainties in 22.0,!58791DataQualityConfigurations: Modify L1Calo config for web display,!572112022-10-03: daily merge of 22.0 into master,!57182Sweeping !57115 from master to 22.0. RootUtils: add TRandomTLS class
# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration # Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
# Declare the package name: # Declare the package name:
atlas_subdir( RootUtils ) atlas_subdir( RootUtils )
...@@ -61,5 +61,11 @@ atlas_add_test( WithRootErrorHandler_test ...@@ -61,5 +61,11 @@ atlas_add_test( WithRootErrorHandler_test
INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
LINK_LIBRARIES ${ROOT_LIBRARIES} RootUtils ) LINK_LIBRARIES ${ROOT_LIBRARIES} RootUtils )
atlas_add_test( TRandomTLS_test
SOURCES test/TRandomTLS_test.cxx
INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
LINK_LIBRARIES ${ROOT_LIBRARIES} CxxUtils RootUtils
POST_EXEC_SCRIPT nopost.sh )
# Install files from the package: # Install files from the package:
atlas_install_python_modules( python/*.py POST_BUILD_CMD ${ATLAS_FLAKE8} ) atlas_install_python_modules( python/*.py POST_BUILD_CMD ${ATLAS_FLAKE8} )
/*
* Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration.
*/
/**
* @file RootUtils/TRandomTLS.h
* @author Frank Winklmeier
* @date Sept, 2022
* @brief Thread-local TRandom generator.
*/
#ifndef ROOTUTILS_TRANDOMTLS_H
#define ROOTUTILS_TRANDOMTLS_H
#include <atomic>
#include "Rtypes.h"
#include "boost/thread/tss.hpp"
namespace RootUtils {
/**
* Thread-local TRandom generator.
*
* This class provides a thread-local TRandom instance of type T.
* For each new instance/thread the seed is incremented to ensure
* independent random numbers.
*/
template <class T>
class TRandomTLS {
public:
/**
* Constructor
*
* @param seed The seed of the first TRandom instance. Additional instances
* are created with the seed incremented by one. If the seed is 0,
* it will not be incremented as ROOT then uses a time-based seed.
*/
TRandomTLS(UInt_t seed = 4357) : m_seed(seed) {}
/// Destructor
~TRandomTLS() = default;
/// Get thread-specific TRandom
T* get() const;
T* operator->() const { return get(); }
T& operator*() const { return *get(); }
private:
/// Thread-local TRandom
mutable boost::thread_specific_ptr<T> m_rand_tls;
/// TRandom seed (incremented for each new instance/thread)
mutable std::atomic<UInt_t> m_seed;
};
//
// Inline methods
//
template <class T>
inline T* TRandomTLS<T>::get() const
{
T* random = m_rand_tls.get();
if (!random) {
random = new T(m_seed > 0 ? m_seed++ : 0);
m_rand_tls.reset(random);
}
return random;
}
} // namespace RootUtils
#endif
/*
* Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration.
*/
#undef NDEBUG
#include "CxxUtils/checker_macros.h"
#include "RootUtils/TRandomTLS.h"
#include "TRandom3.h"
#include <cassert>
#include <iostream>
#include <mutex>
#include <set>
#include <thread>
/// Helper class
struct Test {
void rnd() const
{
const int v = m_rnd->Integer(1000);
std::scoped_lock lock(m_mutex);
m_values.insert(v);
}
RootUtils::TRandomTLS<TRandom3> m_rnd;
mutable std::mutex m_mutex;
mutable std::set<int> m_values ATLAS_THREAD_SAFE;
};
void test_compilation()
{
RootUtils::TRandomTLS<TRandom3> rnd(42);
rnd->Rndm();
(*rnd).Rndm();
assert(rnd.get());
}
void test_unique()
{
Test test;
std::vector<std::thread> threads;
constexpr int Nthreads = 4;
// Launch threads and wait
for (size_t i = 0; i < Nthreads; i++) {
threads.emplace_back(&Test::rnd, &test);
}
for (auto& th : threads) th.join();
// Each thread should have created a unique random number
assert(test.m_values.size() == Nthreads);
for (int v : test.m_values) {
std::cout << v << std::endl;
}
}
int main()
{
test_compilation();
test_unique();
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment