.. _program_listing_file_include_flamegpu_simulation_RunPlanVector.h: Program Listing for File RunPlanVector.h ======================================== |exhale_lsh| :ref:`Return to documentation for file ` (``include/flamegpu/simulation/RunPlanVector.h``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #ifndef INCLUDE_FLAMEGPU_SIMULATION_RUNPLANVECTOR_H_ #define INCLUDE_FLAMEGPU_SIMULATION_RUNPLANVECTOR_H_ #include #include #include #include #include #include #include "flamegpu/simulation/RunPlan.h" #include "flamegpu/detail/StaticAssert.h" #include "flamegpu/detail/type_decode.h" #include "flamegpu/model/EnvironmentData.h" namespace flamegpu { class ModelDescription; class EnvironmentDescription; class RunPlanVector : private std::vector { friend class RunPlan; friend class detail::AbstractSimRunner; friend unsigned int CUDAEnsemble::simulate(const RunPlanVector& plans); public: explicit RunPlanVector(const ModelDescription &model, unsigned int initial_length); void setRandomSimulationSeed(uint64_t initial_seed, unsigned int step = 0); void setSteps(unsigned int steps); void setOutputSubdirectory(const std::string &subdir); template void setProperty(const std::string &name, const T value); template void setProperty(const std::string &name, const std::array &value); template void setProperty(const std::string &name, const flamegpu::size_type index, const T value); #ifdef SWIG template void setPropertyArray(const std::string &name, const std::vector &value); #endif template void setPropertyLerpRange(const std::string &name, T min, T max); template void setPropertyLerpRange(const std::string &name, flamegpu::size_type index, T min, T max); template void setPropertyStep(const std::string& name, T init, T step); template void setPropertyStep(const std::string& name, flamegpu::size_type index, T init, T step); void setRandomPropertySeed(uint64_t seed); uint64_t getRandomPropertySeed(); template void setPropertyUniformRandom(const std::string &name, const T min, const T max); template void setPropertyUniformRandom(const std::string &name, const flamegpu::size_type index, const T min, const T max); template void setPropertyNormalRandom(const std::string &name, const T mean, const T stddev); template void setPropertyNormalRandom(const std::string &name, flamegpu::size_type index, T mean, T stddev); template void setPropertyLogNormalRandom(const std::string &name, T mean, T stddev); template void setPropertyLogNormalRandom(const std::string &name, flamegpu::size_type index, T mean, T stddev); template void setPropertyRandom(const std::string &name, rand_dist &distribution); template void setPropertyRandom(const std::string &name, flamegpu::size_type index, rand_dist &distribution); #ifndef SWIG using std::vector::begin; using std::vector::end; using std::vector::size; using std::vector::operator[]; using std::vector::insert; using std::vector::at; #else // Can't get SWIG %import to use std::vector so manually implement the required items size_t size() const { return std::vector::size(); } RunPlan& operator[] (const size_t _Pos) { return std::vector::operator[](_Pos); } #endif RunPlanVector operator+(const RunPlan& rhs) const; RunPlanVector operator+(const RunPlanVector& rhs) const; RunPlanVector& operator+=(const RunPlan& rhs); RunPlanVector& operator+=(const RunPlanVector& rhs); RunPlanVector& operator*=(unsigned int rhs); RunPlanVector operator*(unsigned int rhs) const; bool operator==(const RunPlanVector& rhs) const; bool operator!=(const RunPlanVector &rhs) const; private: RunPlanVector(const std::shared_ptr> &environment, bool allow_0_steps); uint64_t randomPropertySeed; std::mt19937_64 rand; std::shared_ptr> environment; const bool allow_0_steps; }; template void RunPlanVector::setProperty(const std::string &name, const T value) { // Validation const auto it = environment->find(name); if (it == environment->end()) { THROW exception::InvalidEnvProperty("Environment description does not contain property '%s', " "in RunPlanVector::setProperty()\n", name.c_str()); } if (it->second.data.type != std::type_index(typeid(typename detail::type_decode::type_t))) { THROW exception::InvalidEnvPropertyType("Environment property '%s' type mismatch '%s' != '%s', " "in RunPlanVector::setProperty()\n", name.c_str(), it->second.data.type.name(), std::type_index(typeid(typename detail::type_decode::type_t)).name()); } if (it->second.data.elements != detail::type_decode::len_t) { THROW exception::InvalidEnvPropertyType("Environment property '%s' is an array with %u elements, array method should be used, " "in RunPlanVector::setProperty()\n", name.c_str(), it->second.data.elements); } for (auto &i : *this) { i.setProperty(name, value); } } template void RunPlanVector::setProperty(const std::string &name, const std::array &value) { // Validation const auto it = environment->find(name); if (it == environment->end()) { THROW exception::InvalidEnvProperty("Environment description does not contain property '%s', " "in RunPlanVector::setProperty()\n", name.c_str()); } if (it->second.data.type != std::type_index(typeid(typename detail::type_decode::type_t))) { THROW exception::InvalidEnvPropertyType("Environment property '%s' type mismatch '%s' != '%s', " "in RunPlanVector::setProperty()\n", name.c_str(), it->second.data.type.name(), std::type_index(typeid(typename detail::type_decode::type_t)).name()); } if (it->second.data.elements != N * detail::type_decode::len_t) { THROW exception::InvalidEnvPropertyType("Environment property array '%s' length mismatch %u != %u " "in RunPlanVector::setProperty()\n", name.c_str(), it->second.data.elements, N * detail::type_decode::len_t); } for (auto &i : *this) { i.setProperty(name, value); } } template void RunPlanVector::setProperty(const std::string &name, const flamegpu::size_type index, const T value) { // Validation const auto it = environment->find(name); if (it == environment->end()) { THROW exception::InvalidEnvProperty("Environment description does not contain property '%s', " "in RunPlanVector::setProperty()\n", name.c_str()); } if (it->second.data.type != std::type_index(typeid(typename detail::type_decode::type_t))) { THROW exception::InvalidEnvPropertyType("Environment property '%s' type mismatch '%s' != '%s', " "in RunPlanVector::setProperty()\n", name.c_str(), it->second.data.type.name(), std::type_index(typeid(typename detail::type_decode::type_t)).name()); } const unsigned int t_index = detail::type_decode::len_t * index + detail::type_decode::len_t; if (t_index > it->second.data.elements || t_index < index) { THROW exception::OutOfBoundsException("Environment property array index out of bounds " "in RunPlanVector::setProperty()\n"); } for (auto &i : *this) { i.setProperty(name, index, value); } } #ifdef SWIG template void RunPlanVector::setPropertyArray(const std::string &name, const std::vector &value) { // Validation const auto it = environment->find(name); if (it == environment->end()) { THROW exception::InvalidEnvProperty("Environment description does not contain property '%s', " "in RunPlanVector::setPropertyArray()\n", name.c_str()); } if (it->second.data.type != std::type_index(typeid(typename detail::type_decode::type_t))) { THROW exception::InvalidEnvPropertyType("Environment property '%s' type mismatch '%s' != '%s', " "in RunPlanVector::setPropertyArray()\n", name.c_str(), it->second.data.type.name(), std::type_index(typeid(typename detail::type_decode::type_t)).name()); } if (value.size() * detail::type_decode::len_t != it->second.data.elements) { THROW exception::InvalidEnvProperty("Environment property array length does not match the value provided, %u != %llu," "in RunPlanVector::setPropertyArray()\n", name.c_str(), value.size() * detail::type_decode::len_t, it->second.data.elements); } for (auto &i : *this) { i.setPropertyArray(name, value); } } #endif template void RunPlanVector::setPropertyLerpRange(const std::string &name, const T min, const T max) { // Validation if (this->size() < 2) { THROW exception::OutOfBoundsException("Unable to apply a property distribution a vector with less than 2 elements, " "in RunPlanVector::setPropertyLerpRange()\n"); } const auto it = environment->find(name); if (it == environment->end()) { THROW exception::InvalidEnvProperty("Environment description does not contain property '%s', " "in RunPlanVector::setPropertyLerpRange()\n", name.c_str()); } if (it->second.data.type != std::type_index(typeid(T))) { THROW exception::InvalidEnvPropertyType("Environment property '%s' type mismatch '%s' != '%s', " "in RunPlanVector::setPropertyLerpRange()\n", name.c_str(), it->second.data.type.name(), std::type_index(typeid(T)).name()); } if (it->second.data.elements != 1) { THROW exception::InvalidEnvPropertyType("Environment property '%s' is an array with %u elements, array method should be used, " "in RunPlanVector::setPropertyLerpRange()\n", name.c_str(), it->second.data.elements); } unsigned int ct = 0; for (auto &i : *this) { const double a = static_cast(ct++) / (this->size() - 1); double lerp = min * (1.0 - a) + max * a; if (std::numeric_limits::is_integer) lerp = round(lerp); const T lerp_t = static_cast(lerp); i.setProperty(name, lerp_t); } } template void RunPlanVector::setPropertyLerpRange(const std::string &name, const flamegpu::size_type index, const T min, const T max) { // Validation if (this->size() < 2) { THROW exception::OutOfBoundsException("Unable to apply a property distribution a vector with less than 2 elements, " "in RunPlanVector::setPropertyLerpRange()\n"); } const auto it = environment->find(name); if (it == environment->end()) { THROW exception::InvalidEnvProperty("Environment description does not contain property '%s', " "in RunPlanVector::setPropertyLerpRange()\n", name.c_str()); } if (it->second.data.type != std::type_index(typeid(T))) { THROW exception::InvalidEnvPropertyType("Environment property '%s' type mismatch '%s' != '%s', " "in RunPlanVector::setPropertyLerpRange()\n", name.c_str(), it->second.data.type.name(), std::type_index(typeid(T)).name()); } const unsigned int t_index = detail::type_decode::len_t * index + detail::type_decode::len_t; if (t_index > it->second.data.elements || t_index < index) { THROW exception::OutOfBoundsException("Environment property array index out of bounds " "in RunPlanVector::setPropertyLerpRange()\n"); } unsigned int ct = 0; for (auto &i : *this) { const double a = static_cast(ct++) / (this->size() - 1); double lerp = min * (1.0 - a) + max * a; if (std::numeric_limits::is_integer) lerp = round(lerp); const T lerp_t = static_cast(lerp); i.setProperty(name, index, lerp_t); } } template void RunPlanVector::setPropertyStep(const std::string& name, T init, const T step) { // Validation const auto it = environment->find(name); if (it == environment->end()) { THROW exception::InvalidEnvProperty("Environment description does not contain property '%s', " "in RunPlanVector::setPropertyStep()\n", name.c_str()); } if (it->second.data.type != std::type_index(typeid(T))) { THROW exception::InvalidEnvPropertyType("Environment property '%s' type mismatch '%s' != '%s', " "in RunPlanVector::setPropertyStep()\n", name.c_str(), it->second.data.type.name(), std::type_index(typeid(T)).name()); } if (it->second.data.elements != 1) { THROW exception::InvalidEnvPropertyType("Environment property '%s' is an array with %u elements, array method should be used, " "in RunPlanVector::setPropertyStep()\n", name.c_str(), it->second.data.elements); } for (auto& i : *this) { i.setProperty(name, init); init += step; } } template void RunPlanVector::setPropertyStep(const std::string& name, const flamegpu::size_type index, T init, const T step) { // Validation const auto it = environment->find(name); if (it == environment->end()) { THROW exception::InvalidEnvProperty("Environment description does not contain property '%s', " "in RunPlanVector::setPropertyStep()\n", name.c_str()); } if (it->second.data.type != std::type_index(typeid(T))) { THROW exception::InvalidEnvPropertyType("Environment property '%s' type mismatch '%s' != '%s', " "in RunPlanVector::setPropertyStep()\n", name.c_str(), it->second.data.type.name(), std::type_index(typeid(T)).name()); } const unsigned int t_index = detail::type_decode::len_t * index + detail::type_decode::len_t; if (t_index > it->second.data.elements || t_index < index) { throw exception::OutOfBoundsException("Environment property array index out of bounds " "in RunPlanVector::setPropertyStep()\n"); } for (auto& i : *this) { i.setProperty(name, index, init); init += step; } } template void RunPlanVector::setPropertyRandom(const std::string &name, rand_dist &distribution) { // Validation if (this->size() < 2) { THROW exception::OutOfBoundsException("Unable to apply a property distribution a vector with less than 2 elements, " "in RunPlanVector::setPropertyRandom()\n"); } const auto it = environment->find(name); if (it == environment->end()) { THROW exception::InvalidEnvProperty("Environment description does not contain property '%s', " "in RunPlanVector::setPropertyRandom()\n", name.c_str()); } if (it->second.data.type != std::type_index(typeid(T))) { THROW exception::InvalidEnvPropertyType("Environment property '%s' type mismatch '%s' != '%s', " "in RunPlanVector::setPropertyRandom()\n", name.c_str(), it->second.data.type.name(), std::type_index(typeid(T)).name()); } if (it->second.data.elements != 1) { THROW exception::InvalidEnvPropertyType("Environment property '%s' is an array with %u elements, array method should be used, " "in RunPlanVector::setPropertyRandom()\n", name.c_str(), it->second.data.elements); } for (auto &i : *this) { i.setProperty(name, static_cast(distribution(this->rand))); } } template void RunPlanVector::setPropertyRandom(const std::string &name, const flamegpu::size_type index, rand_dist &distribution) { // Validation if (this->size() < 2) { THROW exception::OutOfBoundsException("Unable to apply a property distribution a vector with less than 2 elements, " "in RunPlanVector::setPropertyRandom()\n"); } const auto it = environment->find(name); if (it == environment->end()) { THROW exception::InvalidEnvProperty("Environment description does not contain property '%s', " "in RunPlanVector::setPropertyRandom()\n", name.c_str()); } if (it->second.data.type != std::type_index(typeid(T))) { THROW exception::InvalidEnvPropertyType("Environment property '%s' type mismatch '%s' != '%s', " "in RunPlanVector::setPropertyRandom()\n", name.c_str(), it->second.data.type.name(), std::type_index(typeid(T)).name()); } const unsigned int t_index = detail::type_decode::len_t * index + detail::type_decode::len_t; if (t_index > it->second.data.elements || t_index < index) { THROW exception::OutOfBoundsException("Environment property array index out of bounds " "in RunPlanVector::setPropertyRandom()\n"); } for (auto &i : *this) { i.setProperty(name, index, static_cast(distribution(this->rand))); } } template void RunPlanVector::setPropertyUniformRandom(const std::string &name, const T min, const T max) { static_assert(detail::StaticAssert::_Is_IntType::value, "Invalid template argument for RunPlanVector::setPropertyUniformRandom(const std::string &name, T min, T max)"); std::uniform_int_distribution dist(min, max); setPropertyRandom(name, dist); } template void RunPlanVector::setPropertyUniformRandom(const std::string &name, const flamegpu::size_type index, const T min, const T max) { static_assert(detail::StaticAssert::_Is_IntType::value, "Invalid template argument for RunPlanVector::setPropertyUniformRandom(const std::string &name, flamegpu::size_type index, T min, T max)"); std::uniform_int_distribution dist(min, max); setPropertyRandom(name, index, dist); } template void RunPlanVector::setPropertyNormalRandom(const std::string &name, const T mean, const T stddev) { static_assert(detail::StaticAssert::_Is_RealType::value, "Invalid template argument for RunPlanVector::setPropertyNormalRandom(const std::string &name, T mean, T stddev)"); std::normal_distribution dist(mean, stddev); setPropertyRandom(name, dist); } template void RunPlanVector::setPropertyNormalRandom(const std::string &name, const flamegpu::size_type index, const T mean, const T stddev) { static_assert(detail::StaticAssert::_Is_RealType::value, "Invalid template argument for RunPlanVector::setPropertyNormalRandom(const std::string &name, flamegpu::size_type index, T mean, T stddev)"); std::normal_distribution dist(mean, stddev); setPropertyRandom(name, index, dist); } template void RunPlanVector::setPropertyLogNormalRandom(const std::string &name, const T mean, const T stddev) { static_assert(detail::StaticAssert::_Is_RealType::value, "Invalid template argument for RunPlanVector::setPropertyLogNormalRandom(const std::string &name, T mean, T stddev)"); std::lognormal_distribution dist(mean, stddev); setPropertyRandom(name, dist); } template void RunPlanVector::setPropertyLogNormalRandom(const std::string &name, const flamegpu::size_type index, const T mean, const T stddev) { static_assert(detail::StaticAssert::_Is_RealType::value, "Invalid template argument for RunPlanVector::setPropertyLogNormalRandom(const std::string &name, flamegpu::size_type index, T mean, T stddev)"); std::lognormal_distribution dist(mean, stddev); setPropertyRandom(name, index, dist); } template<> inline void RunPlanVector::setPropertyUniformRandom(const std::string &name, const float min, const float max) { std::uniform_real_distribution dist(min, max); setPropertyRandom(name, dist); } template<> inline void RunPlanVector::setPropertyUniformRandom(const std::string &name, const flamegpu::size_type index, const float min, const float max) { std::uniform_real_distribution dist(min, max); setPropertyRandom(name, index, dist); } template<> inline void RunPlanVector::setPropertyUniformRandom(const std::string &name, const double min, const double max) { std::uniform_real_distribution dist(min, max); setPropertyRandom(name, dist); } template<> inline void RunPlanVector::setPropertyUniformRandom(const std::string &name, const flamegpu::size_type index, const double min, const double max) { std::uniform_real_distribution dist(min, max); setPropertyRandom(name, index, dist); } template<> inline void RunPlanVector::setPropertyUniformRandom(const std::string &name, const char min, const char max) { std::uniform_int_distribution dist(min, max); setPropertyRandom(name, dist); } template<> inline void RunPlanVector::setPropertyUniformRandom(const std::string &name, const flamegpu::size_type index, const char min, const char max) { std::uniform_int_distribution dist(min, max); setPropertyRandom(name, index, dist); } template<> inline void RunPlanVector::setPropertyUniformRandom(const std::string &name, const unsigned char min, const unsigned char max) { std::uniform_int_distribution dist(min, max); setPropertyRandom(name, dist); } template<> inline void RunPlanVector::setPropertyUniformRandom(const std::string &name, const flamegpu::size_type index, const unsigned char min, const unsigned char max) { std::uniform_int_distribution dist(min, max); setPropertyRandom(name, index, dist); } template<> inline void RunPlanVector::setPropertyUniformRandom(const std::string &name, const signed char min, const signed char max) { std::uniform_int_distribution dist(min, max); setPropertyRandom(name, dist); } template<> inline void RunPlanVector::setPropertyUniformRandom(const std::string &name, const flamegpu::size_type index, const signed char min, const signed char max) { std::uniform_int_distribution dist(min, max); setPropertyRandom(name, index, dist); } } // namespace flamegpu #endif // INCLUDE_FLAMEGPU_SIMULATION_RUNPLANVECTOR_H_