From 570a026668355e166e722bef6f36ed5e9b66cd54 Mon Sep 17 00:00:00 2001 From: Maximilian Reininghaus <maximilian.reininghaus@kit.edu> Date: Mon, 24 Sep 2018 13:29:03 +0200 Subject: [PATCH] basic interface for RNG --- Framework/CMakeLists.txt | 1 + Framework/Random/CMakeLists.txt | 49 +++++++++++++++++++++++++++++++++ Framework/Random/RNGManager.cc | 24 ++++++++++++++++ Framework/Random/RNGManager.h | 44 +++++++++++++++++++++++++++++ Framework/Random/testRandom.cc | 26 +++++++++++++++++ 5 files changed, 144 insertions(+) create mode 100644 Framework/Random/CMakeLists.txt create mode 100644 Framework/Random/RNGManager.cc create mode 100644 Framework/Random/RNGManager.h create mode 100644 Framework/Random/testRandom.cc diff --git a/Framework/CMakeLists.txt b/Framework/CMakeLists.txt index 836d67110..a60b8f06a 100644 --- a/Framework/CMakeLists.txt +++ b/Framework/CMakeLists.txt @@ -6,3 +6,4 @@ add_subdirectory (Logging) add_subdirectory (StackInterface) add_subdirectory (ProcessSequence) add_subdirectory (Cascade) +add_subdirectory (Random) diff --git a/Framework/Random/CMakeLists.txt b/Framework/Random/CMakeLists.txt new file mode 100644 index 000000000..3c1947d25 --- /dev/null +++ b/Framework/Random/CMakeLists.txt @@ -0,0 +1,49 @@ + +set ( + CORSIKArandom_SOURCES + RNGManager.cc + ) + +set ( + CORSIKArandom_HEADERS + RNGManager.h + ) + +set ( + CORSIKArandom_NAMESPACE + corsika/random + ) + +add_library (CORSIKArandom STATIC ${CORSIKArandom_SOURCES}) +CORSIKA_COPY_HEADERS_TO_NAMESPACE (CORSIKArandom ${CORSIKArandom_NAMESPACE} ${CORSIKArandom_HEADERS}) + +target_include_directories ( + CORSIKArandom + PUBLIC + $<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include> + $<INSTALL_INTERFACE:include/> + ) + +# target dependencies on other libraries (also the header onlys) +# none + +install ( + TARGETS CORSIKArandom + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + PUBLIC_HEADER DESTINATION include/${CORSIKArandom_NAMESPACE} + ) + + +# -------------------- +# code unit testing +add_executable (testRandom testRandom.cc) + +target_link_libraries ( + testRandom + CORSIKArandom + CORSIKAthirdparty # for catch2 + ) + +add_test (NAME testRandom COMMAND testRandom) + diff --git a/Framework/Random/RNGManager.cc b/Framework/Random/RNGManager.cc new file mode 100644 index 000000000..01bc247b4 --- /dev/null +++ b/Framework/Random/RNGManager.cc @@ -0,0 +1,24 @@ +#include <corsika/random/RNGManager.h> + +void corsika::random::RNGManager::RegisterRandomStream(std::string const& pStreamName) { + corsika::random::RNG rng; + + if (auto const& it = seeds.find(pStreamName); it != seeds.end()) { + rng.seed(it->second); + } + + rngs[pStreamName] = std::move(rng); +} + +corsika::random::RNG& corsika::random::RNGManager::GetRandomStream(std::string const& pStreamName) { + return rngs.at(pStreamName); +} + +std::stringstream corsika::random::RNGManager::dumpState() const { + std::stringstream buffer; + for (auto const& [streamName, rng] : rngs) { + buffer << '"' << streamName << "\" = \"" << rng << '"' << std::endl; + } + + return buffer; +} diff --git a/Framework/Random/RNGManager.h b/Framework/Random/RNGManager.h new file mode 100644 index 000000000..52e53cd75 --- /dev/null +++ b/Framework/Random/RNGManager.h @@ -0,0 +1,44 @@ +#ifndef _include_RNGManager_h_ +#define _include_RNGManager_h_ + +#include <map> +#include <random> +#include <sstream> +#include <string> + +/*! + * With this class modules can register streams of random numbers. + */ + +namespace corsika::random { + + using RNG = std::mt19937; //!< the actual RNG type that will be used + + class RNGManager { + std::map<std::string, RNG> rngs; + std::map<std::string, std::seed_seq> seeds; + + public: + /*! + * This function is to be called by a module requiring a random-number + * stream during its initialization. + * + * \throws sth. when stream \a pModuleName is already registered + */ + void RegisterRandomStream(std::string const& pStreamName); + + /*! + * returns the pre-stored stream of given name \a pStreamName if + * available + */ + RNG& GetRandomStream(std::string const& pStreamName); + + /*! + * dumps the names and states of all registered random-number streams + * into a std::stringstream. + */ + std::stringstream dumpState() const; + }; + +} // namespace Random +#endif diff --git a/Framework/Random/testRandom.cc b/Framework/Random/testRandom.cc new file mode 100644 index 000000000..f2d6fcdca --- /dev/null +++ b/Framework/Random/testRandom.cc @@ -0,0 +1,26 @@ +#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one + // cpp file +#include <catch2/catch.hpp> + +#include <corsika/random/RNGManager.h> +#include <iostream> + +using namespace corsika::random; + +SCENARIO("random-number streams can be registered and retrieved") { + GIVEN("a RNGManager") { + RNGManager rngManager; + + WHEN("a sequence is registered by name") { + rngManager.RegisterRandomStream("stream_A"); + + THEN("the sequence can be retrieved") { + REQUIRE_NOTHROW(rngManager.GetRandomStream("stream_A")); + } + + THEN("an unknown sequence cannot be retrieved") { + REQUIRE_THROWS(rngManager.GetRandomStream("stream_UNKNOWN")); + } + } + } +} -- GitLab