diff --git a/src/Applications/src/gundamFitter.cxx b/src/Applications/src/gundamFitter.cxx index 0cf08d0f..727b3052 100644 --- a/src/Applications/src/gundamFitter.cxx +++ b/src/Applications/src/gundamFitter.cxx @@ -121,31 +121,28 @@ int main(int argc, char** argv){ LogWarning << "Using GPU parallelization." << std::endl; } - GundamGlobals::setIsForceCpuCalculation(clParser.isOptionTriggered("forceDirect")); + Cache::Manager::setIsForceCpuCalculation(clParser.isOptionTriggered("forceDirect")); bool useCache = false; #ifdef GUNDAM_USING_CACHE_MANAGER useCache = Cache::Manager::HasGPU(true); #endif if (clParser.isOptionTriggered("usingCacheManager")) { - int values = clParser.getNbValueSet("usingCacheManager"); - if (values < 1) useCache = not useCache; - else if ("on" == clParser.getOptionVal("usingCacheManager",0)) useCache = true; - else if ("off" == clParser.getOptionVal("usingCacheManager",0)) useCache = false; - else { - LogThrow("Invalid --cache-manager argument: must be empty, 'on' or 'off'"); - } + int values = clParser.getNbValueSet("usingCacheManager"); + if (values < 1) useCache = not useCache; + else if ("on" == clParser.getOptionVal("usingCacheManager",0)) useCache = true; + else if ("off" == clParser.getOptionVal("usingCacheManager",0)) useCache = false; + else { + LogThrow("Invalid --cache-manager argument: must be empty, 'on' or 'off'"); + } } - if (clParser.isOptionTriggered("usingGpu")) useCache = true; + useCache = clParser.isOptionTriggered("usingGpu"); #ifdef GUNDAM_USING_CACHE_MANAGER - GundamGlobals::setIsCacheManagerEnabled(useCache); - if (not useCache) { - LogWarning << "Cache::Manager enabled but turned off for job" - << std::endl; - } + Cache::Manager::SetIsEnabled(useCache); + LogWarningIf(not useCache) << "Cache::Manager enabled but turned off for job" << std::endl; #else - LogThrowIf(useCache, "GUNDAM compiled without Cache::Manager"); + LogThrowIf(useCache, "GUNDAM compiled without Cache::Manager"); #endif // inject parameter config? diff --git a/src/CacheManager/include/CacheManager.h b/src/CacheManager/include/CacheManager.h index 1dda52f2..2dc6e782 100644 --- a/src/CacheManager/include/CacheManager.h +++ b/src/CacheManager/include/CacheManager.h @@ -51,27 +51,87 @@ class Parameter; /// Manage the cache calculations on the GPU. This will work even when there /// isn't a GPU, but it's really slow on the CPU. This is a singleton. class Cache::Manager { + +private: + // Holds static members of the CacheManager in one place + struct Parameters{ + + // You get one guess... + Manager* fSingleton{nullptr}; + + // By default, the use of CacheManager is set to false. This parameter replaces the ones that + // was present in GundamGlobals.h + // This parameter should be set in the front-end applications + bool fIsEnabled{false}; + + // Enabled printouts when moving data between host and device + bool fEnableDebugPrintouts{false}; + + // forceCpuCalculation allows to also do the propagation of parameters with the CPU + // routine in order to check the accuracy of the CacheManager computation + bool fForceCpuCalculation{false}; + + // Set to true when the cache needs an update. + bool fUpdateRequired{true}; + + // Keep track of the state of the CacheManager + bool fIsCacheManagerBuilt{false}; + + // Pointers to the Propagator member the CacheManger has to take care of + SampleSet* fSampleSetPtr{nullptr}; + EventDialCache* fEventDialCachePtr{nullptr}; + // A map between the fit parameter pointers and the parameter index used + // by the fitter. + std::map ParameterMap{}; + + // Keep track of when we want to get back from the GPU once the propagation is complete + bool fIsHistContentCopyEnabled{false}; + bool fIsEventWeightCopyEnabled{false}; + + /// Declare all of the actual GPU caches here. There is one GPU, so this + /// is the ONE place that everything is collected together. + std::vector fSampleHistFillerList{}; + std::vector fEventWeightFillerList{}; + + // Time monitoring + GenericToolbox::Time::AveragedTimer<10> cacheFillTimer; + GenericToolbox::Time::AveragedTimer<10> pullFromDeviceTimer; + + }; + + // instance defined in cpp file + static Parameters fParameters; + public: + + // static setters + static void SetIsEnabled(bool enable_){ fParameters.fIsEnabled = enable_; } + static void setIsForceCpuCalculation(bool enable_){ fParameters.fForceCpuCalculation = enable_; } + + // static getters + static bool isCacheManagerEnabled(){ return fParameters.fIsEnabled; } + static bool isForceCpuCalculation(){ return fParameters.fForceCpuCalculation; } + // Get the pointer to the cache manager. This will be a nullptr if the // cache is not being used. - static Manager* Get() {return fSingleton;} + static Manager* Get(){ return fParameters.fSingleton; } /// Fill the cache for the current iteration. This needs to be called /// before the cached weights can be used. This is used in Propagator.cpp. static bool Fill(); /// Dedicated setter for fUpdateRequired flag - static void SetUpdateRequired(bool isUpdateRequired_){ fUpdateRequired = isUpdateRequired_; }; + static void SetUpdateRequired(bool isUpdateRequired_){ fParameters.fUpdateRequired = isUpdateRequired_; }; /// Set addresses of the Propagator objects the CacheManager should take care of - static void SetSampleSetPtr(SampleSet& sampleSet_){ fSampleSetPtr = &sampleSet_; } - static void SetEventDialSetPtr(EventDialCache& eventDialCache_){ fEventDialCachePtr = &eventDialCache_; } - static void SetIsHistContentCopyEnabled(bool fIsHistContentCopyEnabled_){ fIsHistContentCopyEnabled = fIsHistContentCopyEnabled_; } - static void SetIsEventWeightCopyEnabled(bool fIsEventWeightCopyEnabled_){ fIsEventWeightCopyEnabled = fIsEventWeightCopyEnabled_; } - static void SetEnableDebugPrintouts(bool fEnableDebugPrintouts_){ fEnableDebugPrintouts = fEnableDebugPrintouts_; } + static void SetSampleSetPtr(SampleSet& sampleSet_){ fParameters.fSampleSetPtr = &sampleSet_; } + static void SetEventDialSetPtr(EventDialCache& eventDialCache_){ fParameters.fEventDialCachePtr = &eventDialCache_; } + static void SetIsHistContentCopyEnabled(bool fIsHistContentCopyEnabled_){ fParameters.fIsHistContentCopyEnabled = fIsHistContentCopyEnabled_; } + static void SetIsEventWeightCopyEnabled(bool fIsEventWeightCopyEnabled_){ fParameters.fIsEventWeightCopyEnabled = fIsEventWeightCopyEnabled_; } + static void SetEnableDebugPrintouts(bool fEnableDebugPrintouts_){ fParameters.fEnableDebugPrintouts = fEnableDebugPrintouts_; } - static const GenericToolbox::Time::AveragedTimer<10>& GetCacheFillTimer() { return cacheFillTimer; } - static const GenericToolbox::Time::AveragedTimer<10>& GetPullFromDeviceTimer() { return pullFromDeviceTimer; } + static const GenericToolbox::Time::AveragedTimer<10>& GetCacheFillTimer() { return fParameters.cacheFillTimer; } + static const GenericToolbox::Time::AveragedTimer<10>& GetPullFromDeviceTimer() { return fParameters.pullFromDeviceTimer; } /// Build the cache and load it into the device. This is used in /// Propagator.cpp to fill the constants needed to for the calculations. @@ -109,10 +169,12 @@ class Cache::Manager { static bool CopyEventWeights(); static bool CopyHistogramsContent(); - static bool IsBuilt(){ return fIsCacheManagerBuilt; } + static bool IsBuilt(){ return fParameters.fIsCacheManagerBuilt; } private: + + // Hold the configuration that will be used to construct the manager // (singleton). This information was originally passed as arguments to // the constructor, but it became to complex and prone to mistakes since @@ -184,28 +246,7 @@ class Cache::Manager { }; // This is a singleton, so the constructor is private. - Manager(const Cache::Manager::Configuration& config); - static Manager* fSingleton; // You get one guess... - static bool fUpdateRequired; // Set to true when the cache needs an update. - - // A map between the fit parameter pointers and the parameter index used - // by the fitter. - static std::map ParameterMap; - - /// Declare all of the actual GPU caches here. There is one GPU, so this - /// is the ONE place that everything is collected together. - - /// pointers to the corresponding Propagator structure - static bool fEnableDebugPrintouts; - static SampleSet* fSampleSetPtr; - static EventDialCache* fEventDialCachePtr; - static std::vector fSampleHistFillerList; - static std::vector fEventWeightFillerList; - static bool fIsHistContentCopyEnabled; - static bool fIsEventWeightCopyEnabled; - static bool fIsCacheManagerBuilt; - static GenericToolbox::Time::AveragedTimer<10> cacheFillTimer; - static GenericToolbox::Time::AveragedTimer<10> pullFromDeviceTimer; + explicit Manager(const Cache::Manager::Configuration& config); /// The cache for parameter weights (on the GPU). std::unique_ptr fParameterCache; diff --git a/src/CacheManager/src/CacheManager.cpp b/src/CacheManager/src/CacheManager.cpp index 805ad6c7..1b372524 100644 --- a/src/CacheManager/src/CacheManager.cpp +++ b/src/CacheManager/src/CacheManager.cpp @@ -40,19 +40,8 @@ #include -bool Cache::Manager::fEnableDebugPrintouts{false}; -Cache::Manager* Cache::Manager::fSingleton = nullptr; -bool Cache::Manager::fUpdateRequired = true; -std::map Cache::Manager::ParameterMap; -SampleSet* Cache::Manager::fSampleSetPtr{nullptr}; -EventDialCache* Cache::Manager::fEventDialCachePtr{nullptr}; -bool Cache::Manager::fIsHistContentCopyEnabled{false}; -bool Cache::Manager::fIsEventWeightCopyEnabled{false}; -bool Cache::Manager::fIsCacheManagerBuilt{false}; -std::vector Cache::Manager::fSampleHistFillerList{}; -std::vector Cache::Manager::fEventWeightFillerList{}; -GenericToolbox::Time::AveragedTimer<10> Cache::Manager::cacheFillTimer{}; -GenericToolbox::Time::AveragedTimer<10> Cache::Manager::pullFromDeviceTimer{}; +// static definitions +Cache::Manager::Parameters Cache::Manager::fParameters{}; Cache::Manager::Manager(const Cache::Manager::Configuration& config) { LogInfo << "Creating cache manager" << std::endl; @@ -187,9 +176,9 @@ bool Cache::Manager::HasGPU(bool dump) { } bool Cache::Manager::Build() { - if (not GundamGlobals::isCacheManagerEnabled()) return false; + if( not isCacheManagerEnabled() ){ return false; } - if( fSampleSetPtr == nullptr or fEventDialCachePtr == nullptr ){ + if( fParameters.fSampleSetPtr == nullptr or fParameters.fEventDialCachePtr == nullptr ){ LogError << "fSampleSetPtr or fEventDialCachePtr not set." << std::endl; LogThrow("Can't Build()"); } @@ -204,7 +193,7 @@ bool Cache::Manager::Build() { // but be sure). The map is between the address of the parameter, and the // index of the parameter and is needed since the dials only contain a // pointer to the parameter. - Cache::Manager::ParameterMap.clear(); + fParameters.ParameterMap.clear(); /// Keep track of which parameters are used. This also provides a count /// of the parameters. @@ -212,7 +201,7 @@ bool Cache::Manager::Build() { int dialErrorCount = 0; // This should *stay* zero. std::map useCount; - for (EventDialCache::CacheEntry& elem : fEventDialCachePtr->getCache()) { + for (EventDialCache::CacheEntry& elem : fParameters.fEventDialCachePtr->getCache()) { if (elem.event->getIndices().bin < 0) { LogThrow("Caching event that isn't used"); } @@ -270,7 +259,7 @@ bool Cache::Manager::Build() { } else if (dialType.find("Tabulated") == 0) { ++config.tabulated; - Tabulated* tabDial = dynamic_cast(dial); + auto* tabDial = dynamic_cast(dial); LogThrowIf(tabDial == nullptr, "Tabulated dial is not a Tabulated dial"); // Add a place holder for this table. This will be filled // with the offset to the table when the weighting is built. @@ -303,7 +292,7 @@ bool Cache::Manager::Build() { // Count the total number of histogram cells. config.histBins = 0; - for(const Sample& sample : fSampleSetPtr->getSampleList() ){ + for(const Sample& sample : fParameters.fSampleSetPtr->getSampleList() ){ int cells = sample.getHistogram().getNbBins(); // GetNcells() of TH1D LogInfo << "Add histogram for " << sample.getName() << " with " << cells @@ -403,16 +392,15 @@ bool Cache::Manager::Build() { // Try to allocate the Cache::Manager memory (including for the GPU if // it's being used). - if (!Cache::Manager::Get() - && GundamGlobals::isCacheManagerEnabled()) { + if( Cache::Manager::Get() == nullptr and isCacheManagerEnabled() ){ LogInfo << "Creating the Cache::Manager" << std::endl; if (!Cache::Manager::HasCUDA()) { LogInfo << " GPU Not enabled with Cache::Manager" << std::endl; } try { - fSingleton = new Manager(config); - LogThrowIf(not fSingleton, "CacheManager Not allocated"); + fParameters.fSingleton = new Manager(config); + LogThrowIf(not fParameters.fSingleton, "CacheManager Not allocated"); } catch (...) { LogError << "Did not allocated cache manager" << std::endl; @@ -430,7 +418,7 @@ bool Cache::Manager::Build() { Cache::Manager::RequireUpdate(); - fIsCacheManagerBuilt = true; + fParameters.fIsCacheManagerBuilt = true; return true; } @@ -457,11 +445,11 @@ bool Cache::Manager::Update() { int usedResults = 0; - fEventWeightFillerList.clear(); - fEventWeightFillerList.reserve( fEventDialCachePtr->getCache().size() ); + fParameters.fEventWeightFillerList.clear(); + fParameters.fEventWeightFillerList.reserve( fParameters.fEventDialCachePtr->getCache().size() ); // Add the dials in the EventDialCache to the internal cache. - for (EventDialCache::CacheEntry& elem : fEventDialCachePtr->getCache()) { + for (EventDialCache::CacheEntry& elem : fParameters.fEventDialCachePtr->getCache()) { // Skip events that are not in a bin. if (elem.event->getIndices().bin < 0) continue; Event& event = *elem.event; @@ -469,7 +457,7 @@ bool Cache::Manager::Update() { // event in the cache. int resultIndex = usedResults++; - fEventWeightFillerList.emplace_back( elem.event, resultIndex ); + fParameters.fEventWeightFillerList.emplace_back( elem.event, resultIndex ); // Get the initial value for this event and save it. double initialEventWeight = event.getWeights().base; @@ -480,7 +468,7 @@ bool Cache::Manager::Update() { DialInputBuffer* dialInputs = dialElem.dialInterface->getInputBufferRef(); - // Make sure all of the used parameters are in the parameter + // Make sure all the used parameters are in the parameter // map. for (std::size_t i = 0; i < dialInputs->getBufferSize(); ++i) { // Find the index (or allocate a new one) for the dial @@ -488,10 +476,10 @@ bool Cache::Manager::Update() { const Parameter* fp = &(dialElem.dialInterface->getInputBufferRef() ->getParameter(i)); - auto parMapIt = Cache::Manager::ParameterMap.find(fp); - if (parMapIt == Cache::Manager::ParameterMap.end()) { - Cache::Manager::ParameterMap[fp] - = int(Cache::Manager::ParameterMap.size()); + auto parMapIt = fParameters.ParameterMap.find(fp); + if (parMapIt == fParameters.ParameterMap.end()) { + fParameters.ParameterMap[fp] + = int(fParameters.ParameterMap.size()); } } @@ -500,7 +488,7 @@ bool Cache::Manager::Update() { const Parameter* fp = &(dialInputs->getParameter(i)); auto& bounds = dialInputs->getMirrorEdges(i); if( not std::isnan(bounds.minValue) ){ - int parIndex = Cache::Manager::ParameterMap[fp]; + int parIndex = fParameters.ParameterMap[fp]; Cache::Manager::Get()->GetParameterCache() .SetLowerMirror(parIndex, bounds.minValue); Cache::Manager::Get()->GetParameterCache() @@ -513,7 +501,7 @@ bool Cache::Manager::Update() { const Parameter* fp = &(dialInputs->getParameter(i)); const DialResponseSupervisor* resp = dialElem.dialInterface->getResponseSupervisorRef(); - int parIndex = Cache::Manager::ParameterMap[fp]; + int parIndex = fParameters.ParameterMap[fp]; double minResponse = 0.0; if (std::isfinite(resp->getMinResponse())) { minResponse = resp->getMinResponse(); @@ -527,105 +515,96 @@ bool Cache::Manager::Update() { // Add the dial information to the appropriate caches int dialUsed = 0; - const DialBase* baseDial = dialElem.dialInterface->getDialBaseRef(); - const Norm* normDial = dynamic_cast(baseDial); + auto* baseDial = dialElem.dialInterface->getDialBaseRef(); + auto* normDial = dynamic_cast(baseDial); if (normDial) { ++dialUsed; const Parameter* fp = &(dialInputs->getParameter(0)); - int parIndex = Cache::Manager::ParameterMap[fp]; + int parIndex = fParameters.ParameterMap[fp]; Cache::Manager::Get() ->fNormalizations ->ReserveNorm(resultIndex,parIndex); } - const CompactSpline* compactSpline - = dynamic_cast(baseDial); + auto* compactSpline = dynamic_cast(baseDial); if (compactSpline) { ++dialUsed; const Parameter* fp = &(dialInputs->getParameter(0)); - int parIndex = Cache::Manager::ParameterMap[fp]; + int parIndex = fParameters.ParameterMap[fp]; Cache::Manager::Get() ->fCompactSplines ->AddSpline(resultIndex,parIndex, baseDial->getDialData()); } - const MonotonicSpline* monotonicSpline - = dynamic_cast(baseDial); + auto* monotonicSpline = dynamic_cast(baseDial); if (monotonicSpline) { ++dialUsed; const Parameter* fp = &(dialInputs->getParameter(0)); - int parIndex = Cache::Manager::ParameterMap[fp]; + int parIndex = fParameters.ParameterMap[fp]; Cache::Manager::Get() ->fMonotonicSplines ->AddSpline(resultIndex,parIndex, baseDial->getDialData()); } - const UniformSpline* uniformSpline - = dynamic_cast(baseDial); + auto* uniformSpline = dynamic_cast(baseDial); if (uniformSpline) { ++dialUsed; const Parameter* fp = &(dialInputs->getParameter(0)); - int parIndex = Cache::Manager::ParameterMap[fp]; + int parIndex = fParameters.ParameterMap[fp]; Cache::Manager::Get() ->fUniformSplines ->AddSpline(resultIndex,parIndex, baseDial->getDialData()); } - const GeneralSpline* generalSpline - = dynamic_cast(baseDial); + auto* generalSpline = dynamic_cast(baseDial); if (generalSpline) { ++dialUsed; const Parameter* fp = &(dialInputs->getParameter(0)); - int parIndex = Cache::Manager::ParameterMap[fp]; + int parIndex = fParameters.ParameterMap[fp]; Cache::Manager::Get() ->fGeneralSplines ->AddSpline(resultIndex,parIndex, baseDial->getDialData()); } - const LightGraph* lightGraph - = dynamic_cast(baseDial); + auto* lightGraph = dynamic_cast(baseDial); if (lightGraph) { ++dialUsed; const Parameter* fp = &(dialInputs->getParameter(0)); - int parIndex = Cache::Manager::ParameterMap[fp]; + int parIndex = fParameters.ParameterMap[fp]; Cache::Manager::Get() ->fGraphs ->AddGraph(resultIndex,parIndex, baseDial->getDialData()); } - const Bilinear* bilinear - = dynamic_cast(baseDial); + auto* bilinear = dynamic_cast(baseDial); if (bilinear) { ++dialUsed; const Parameter* fp1 = &(dialInputs->getParameter(0)); - int parIndex1 = Cache::Manager::ParameterMap[fp1]; + int parIndex1 = fParameters.ParameterMap[fp1]; const Parameter* fp2 = &(dialInputs->getParameter(1)); - int parIndex2 = Cache::Manager::ParameterMap[fp2]; + int parIndex2 = fParameters.ParameterMap[fp2]; Cache::Manager::Get() ->fBilinear ->AddData(resultIndex,parIndex1,parIndex2, baseDial->getDialData()); } - const Bicubic* bicubic - = dynamic_cast(baseDial); + auto* bicubic = dynamic_cast(baseDial); if (bicubic) { ++dialUsed; const Parameter* fp1 = &(dialInputs->getParameter(0)); - int parIndex1 = Cache::Manager::ParameterMap[fp1]; + int parIndex1 = fParameters.ParameterMap[fp1]; const Parameter* fp2 = &(dialInputs->getParameter(1)); - int parIndex2 = Cache::Manager::ParameterMap[fp2]; + int parIndex2 = fParameters.ParameterMap[fp2]; Cache::Manager::Get() ->fBicubic ->AddData(resultIndex,parIndex1,parIndex2, baseDial->getDialData()); } - const Shift* shift - = dynamic_cast(baseDial); + auto* shift = dynamic_cast(baseDial); if (shift) { ++dialUsed; initialEventWeight *= shift->evalResponse(DialInputBuffer()); } - const Tabulated* tabulated - = dynamic_cast(baseDial); + auto* tabulated = dynamic_cast(baseDial); if (tabulated) { ++dialUsed; Cache::Manager::Get() @@ -674,8 +653,8 @@ bool Cache::Manager::Update() { LogThrow("Probable problem putting dials in cache"); } - fSampleHistFillerList.clear(); - fSampleHistFillerList.reserve( fSampleSetPtr->getSampleList().size() ); + fParameters.fSampleHistFillerList.clear(); + fParameters.fSampleHistFillerList.reserve( fParameters.fSampleSetPtr->getSampleList().size() ); // Add the histogram cells to the cache. THIS CODE IS SUSPECT SINCE IT IS // SAVING ADDRESSES OF CLASS FIELDS. This *will* be OK since the fields @@ -683,18 +662,18 @@ bool Cache::Manager::Update() { // but is officially "dangerous". LogInfo << "Add this histogram cells to the cache." << std::endl; int nextHist = 0; - for(Sample& sample : fSampleSetPtr->getSampleList() ) { + for(Sample& sample : fParameters.fSampleSetPtr->getSampleList() ) { LogInfo << "Fill cache for " << sample.getName() << " with " << sample.getEventList().size() << " events" << std::endl; int thisHistIndexOffset = nextHist; - fSampleHistFillerList.emplace_back( &sample.getHistogram(), thisHistIndexOffset ); + fParameters.fSampleHistFillerList.emplace_back( &sample.getHistogram(), thisHistIndexOffset ); int cells = sample.getHistogram().getNbBins(); nextHist += cells; - for( auto& eventFiller : fEventWeightFillerList ){ + for( auto& eventFiller : fParameters.fEventWeightFillerList ){ if( eventFiller.getEventPtr()->getIndices().sample == sample.getIndex() ){ Cache::Manager::Get()->GetHistogramsCache().SetEventIndex( eventFiller.getValueIndex(), @@ -710,8 +689,8 @@ bool Cache::Manager::Update() { } // If the event weight cap has been set, then pass it along - if (fEventDialCachePtr->getGlobalEventReweightCap().isEnabled) { - double cap = fEventDialCachePtr->getGlobalEventReweightCap().maxReweight; + if (fParameters.fEventDialCachePtr->getGlobalEventReweightCap().isEnabled) { + double cap = fParameters.fEventDialCachePtr->getGlobalEventReweightCap().maxReweight; if (std::isfinite(cap)) { Cache::Manager::Get() ->GetHistogramsCache().SetMaximumEventWeight(cap); @@ -728,7 +707,7 @@ bool Cache::Manager::Update() { bool Cache::Manager::Fill() { Cache::Manager* cache = Cache::Manager::Get(); if (!cache) return false; - if (fUpdateRequired) { + if (fParameters.fUpdateRequired) { LogError << "Fill while an update is required" << std::endl; LogThrow("Fill while an update is required"); } @@ -739,10 +718,10 @@ bool Cache::Manager::Fill() { static bool printed = false; if (printed) break; printed = true; - for (auto& par : Cache::Manager::ParameterMap ) { + for (auto& par : fParameters.ParameterMap ) { // This produces a crazy amount of output. LogInfo << "FILL: " << par.second - << "/" << Cache::Manager::ParameterMap.size() + << "/" << fParameters.ParameterMap.size() << " " << par.first->getParameterValue() << " (" << par.first->getFullTitle() << ")" << " enabled: " << par.first->isEnabled() @@ -752,7 +731,7 @@ bool Cache::Manager::Fill() { #endif cache->GetWeightsCache().Invalidate(); cache->GetHistogramsCache().Invalidate(); - for (auto& par : Cache::Manager::ParameterMap ) { + for (auto& par : fParameters.ParameterMap ) { if (not par.first->isEnabled()) { LogWarning << "WARNING: Disabled parameter: " << par.first->getFullTitle() @@ -775,13 +754,13 @@ bool Cache::Manager::PropagateParameters(){ bool isSuccess{false}; { - auto s{cacheFillTimer.scopeTime()}; + auto s{fParameters.cacheFillTimer.scopeTime()}; // if disabled, leave if( Cache::Manager::Get() == nullptr ){ return false; } // update the cache if necessary - if( fUpdateRequired ){ Cache::Manager::Update(); } + if( fParameters.fUpdateRequired ){ Cache::Manager::Update(); } // do the propagation on the device isSuccess = Cache::Manager::Fill(); @@ -791,15 +770,15 @@ bool Cache::Manager::PropagateParameters(){ // now everything is on the device, what info do we need on the CPU? { - auto s{pullFromDeviceTimer.scopeTime()}; + auto s{fParameters.pullFromDeviceTimer.scopeTime()}; // do we need to copy every event weight to the CPU structures ? - if( Cache::Manager::fIsEventWeightCopyEnabled ){ + if( fParameters.fIsEventWeightCopyEnabled ){ Cache::Manager::CopyEventWeights(); } // do we need to copy bin content to the CPU structures ? - if( Cache::Manager::fIsHistContentCopyEnabled ){ + if( fParameters.fIsHistContentCopyEnabled ){ Cache::Manager::CopyHistogramsContent(); } } @@ -811,11 +790,11 @@ bool Cache::Manager::CopyEventWeights(){ if( not Cache::Manager::Get()->GetWeightsCache().IsResultValid() ){ // Trigger this update - if( fEnableDebugPrintouts ){ LogDebug << "Copy event weights from Device to Host" << std::endl; } + if( fParameters.fEnableDebugPrintouts ){ LogDebug << "Copy event weights from Device to Host" << std::endl; } Cache::Manager::Get()->GetWeightsCache().GetResult(0); } - for( auto& eventFiller : fEventWeightFillerList ){ + for( auto& eventFiller : fParameters.fEventWeightFillerList ){ eventFiller.copyCacheToCpu( Cache::Manager::Get()->GetWeightsCache().GetWeights().hostPtr() ); } @@ -830,13 +809,13 @@ bool Cache::Manager::CopyHistogramsContent(){ // _CacheManagerValue_ and _CacheManagerValid_ are inside the summed // index cache (a bit of evil coding here), and are updated by the // cache. The update is triggered by (*_CacheManagerUpdate_)(). - if( fEnableDebugPrintouts ){ LogDebug << "Copy bin contents from Device to Host" << std::endl; } + if( fParameters.fEnableDebugPrintouts ){ LogDebug << "Copy bin contents from Device to Host" << std::endl; } Cache::Manager::Get()->GetHistogramsCache().GetSum(0); Cache::Manager::Get()->GetHistogramsCache().GetSum2(0); } - for( auto& histFiller : fSampleHistFillerList ){ + for( auto& histFiller : fParameters.fSampleHistFillerList ){ histFiller.pullHistContent( Cache::Manager::Get()->GetHistogramsCache().GetSumsPointer(), Cache::Manager::Get()->GetHistogramsCache().GetSums2Pointer() @@ -847,8 +826,8 @@ bool Cache::Manager::CopyHistogramsContent(){ } int Cache::Manager::ParameterIndex(const Parameter* fp) { - auto parMapIt = Cache::Manager::ParameterMap.find(fp); - if (parMapIt == Cache::Manager::ParameterMap.end()) return -1; + auto parMapIt = fParameters.ParameterMap.find(fp); + if (parMapIt == fParameters.ParameterMap.end()) return -1; return parMapIt->second; } diff --git a/src/DatasetManager/include/DataDispenser.h b/src/DatasetManager/include/DataDispenser.h index 7b26f529..cab44214 100644 --- a/src/DatasetManager/include/DataDispenser.h +++ b/src/DatasetManager/include/DataDispenser.h @@ -101,8 +101,10 @@ class DataDispenser : public JsonBaseClass { // needed to check which variables need to be loaded const PlotGenerator* _plotGeneratorPtr_{nullptr}; + // multi-threading GenericToolbox::ParallelWorker _threadPool_{}; GenericToolbox::ParallelWorker _threadPoolEventLoad_{}; + GenericToolbox::NoCopyWrapper _mutex_{}; }; diff --git a/src/DatasetManager/src/DataDispenser.cpp b/src/DatasetManager/src/DataDispenser.cpp index a2fed12e..14ac6aee 100644 --- a/src/DatasetManager/src/DataDispenser.cpp +++ b/src/DatasetManager/src/DataDispenser.cpp @@ -1161,7 +1161,7 @@ void DataDispenser::loadEvent(int iThread_){ // Let's claim an index. Indices are shared among threads EventDialCache::IndexedCacheEntry *eventDialCacheEntry{nullptr}; { - std::unique_lock lock(GundamGlobals::getMutex()); + std::unique_lock lock(_mutex_); if( _parameters_.debugNbMaxEventsToLoad != 0 ){ // check if the limit has been reached diff --git a/src/DialDictionary/DialEngine/include/DialInputBuffer.h b/src/DialDictionary/DialEngine/include/DialInputBuffer.h index c94f737b..820b7c91 100644 --- a/src/DialDictionary/DialEngine/include/DialInputBuffer.h +++ b/src/DialDictionary/DialEngine/include/DialInputBuffer.h @@ -89,10 +89,6 @@ class DialInputBuffer { /// Simple printout function for debug info on error [[nodiscard]] std::string getSummary() const; - // Deprecated - [[deprecated("use getParameter()")]] [[nodiscard]] const Parameter& getFitParameter(int i=0) const { return getParameter(i); } - [[deprecated("use getParameterSet()")]] [[nodiscard]] const ParameterSet& getFitParameterSet(int i=0) const { return getParameterSet(i); } - private: /// Flag if the member can be still edited. bool _isInitialized_{false}; diff --git a/src/DialDictionary/DialEngine/include/EventDialCache.h b/src/DialDictionary/DialEngine/include/EventDialCache.h index fcacb590..1ca30677 100644 --- a/src/DialDictionary/DialEngine/include/EventDialCache.h +++ b/src/DialDictionary/DialEngine/include/EventDialCache.h @@ -10,8 +10,6 @@ #include "Event.h" #include "DialInterface.h" - -// DEV #include "GundamGlobals.h" #include "GenericToolbox.Wrappers.h" @@ -51,11 +49,7 @@ class EventDialCache{ bool *updateRequested{nullptr}; void update(){ // Reevaluate the dial if an update has been requested -#ifdef EVENT_DIAL_CACHE_SAFE_SLOW_INTERFACE - if( dialInterface->getInputBufferRef()->isDialUpdateRequested() ){ -#else if( *(this->updateRequested) ) { -#endif response = dialInterface->evalResponse(); } } @@ -155,7 +149,7 @@ class EventDialCache{ // returns the current index [[nodiscard]] size_t getFillIndex() const { return _fillIndex_; } - [[nodiscard]] const std::vector getIndexedCache() const { return _indexedCache_; } + [[nodiscard]] const std::vector& getIndexedCache() const { return _indexedCache_; } /// Provide the event dial cache. The event dial cache containes a /// CacheElem_t object for every dial applied to a physics event. The diff --git a/src/ParametersManager/include/ParameterSet.h b/src/ParametersManager/include/ParameterSet.h index 6773b96a..8c2a762b 100644 --- a/src/ParametersManager/include/ParameterSet.h +++ b/src/ParametersManager/include/ParameterSet.h @@ -167,14 +167,7 @@ class ParameterSet : public JsonBaseClass { /// not fix. This is true if the parameter should be in the stripped /// covariance matrix. static bool isValidCorrelatedParameter(const Parameter& par_); - - // Deprecated - [[deprecated("use getCustomParThrow()")]] [[nodiscard]] const std::vector& getCustomFitParThrow() const{ return getCustomParThrow(); } - [[deprecated("use isEnableEigenDecomp()")]] [[nodiscard]] bool isUseEigenDecompInFit() const{ return isEnableEigenDecomp(); } - [[deprecated("use moveParametersToPrior()")]] void moveFitParametersToPrior(){ moveParametersToPrior(); } - [[deprecated("use throwParameters()")]] void throwFitParameters( bool rethrowIfNotPhysical_ = true, double gain_ = 1){ throwParameters(rethrowIfNotPhysical_, gain_); } - [[deprecated]] [[nodiscard]] bool isUseOnlyOneParameterPerEvent() const{ return _useOnlyOneParameterPerEvent_; } - + // print void printConfiguration() const; diff --git a/src/Propagator/src/Propagator.cpp b/src/Propagator/src/Propagator.cpp index 15142333..a4d33a98 100644 --- a/src/Propagator/src/Propagator.cpp +++ b/src/Propagator/src/Propagator.cpp @@ -135,7 +135,7 @@ void Propagator::propagateParameters(){ // Only real parameters are propagated on the spectra -> need to convert the eigen to original if( _enableEigenToOrigInPropagate_ ){ _parManager_.convertEigenToOrig(); } usedCacheManager = Cache::Manager::PropagateParameters(); - if( usedCacheManager and not GundamGlobals::isForceCpuCalculation() ){ return; } + if( usedCacheManager and not Cache::Manager::isForceCpuCalculation() ){ return; } #endif this->reweightEvents(); this->refillHistograms(); diff --git a/src/StatisticalInference/Likelihood/src/LikelihoodInterface.cpp b/src/StatisticalInference/Likelihood/src/LikelihoodInterface.cpp index 4ec8819b..4bf04b08 100644 --- a/src/StatisticalInference/Likelihood/src/LikelihoodInterface.cpp +++ b/src/StatisticalInference/Likelihood/src/LikelihoodInterface.cpp @@ -345,7 +345,7 @@ void LikelihoodInterface::loadModelPropagator(){ }); #ifdef GUNDAM_USING_CACHE_MANAGER - if( GundamGlobals::isCacheManagerEnabled() ){ + if( Cache::Manager::isCacheManagerEnabled() ){ _modelPropagator_.initializeCacheManager(); } #endif diff --git a/src/Utils/include/GundamGlobals.h b/src/Utils/include/GundamGlobals.h index 56840800..754c5ff5 100644 --- a/src/Utils/include/GundamGlobals.h +++ b/src/Utils/include/GundamGlobals.h @@ -5,34 +5,36 @@ #ifndef GUNDAM_GUNDAM_GLOBALS_H #define GUNDAM_GUNDAM_GLOBALS_H -#include - class GundamGlobals{ public: // setters - static void setIsDebug( bool enable){ _isDebug_ = enable; } - static void setLightOutputMode(bool enable_){ _lightOutputModeEnabled_ = enable_; } - static void setIsCacheManagerEnabled( bool enable){ _useCacheManager_ = enable; } - static void setIsForceCpuCalculation( bool enable){ _forceCpuCalculation_ = enable; } - static void setNumberOfThreads(int nbCpuThreads_){ _nbCpuThreads_ = nbCpuThreads_; } + static void setIsDebug(bool enable_){ _parameters_.isDebug = enable_; } + static void setLightOutputMode(bool enable_){ _parameters_.lightOutputModeEnabled = enable_; } + static void setNumberOfThreads(int nbCpuThreads_){ _parameters_.nbCpuThreads = nbCpuThreads_; } // getters - static bool isDebug(){ return _isDebug_; } - static bool isLightOutputMode(){ return _lightOutputModeEnabled_; } - static bool isCacheManagerEnabled(){ return _useCacheManager_; } - static bool isForceCpuCalculation(){ return _forceCpuCalculation_; } - static int getNbCpuThreads(){ return _nbCpuThreads_; } - static std::mutex& getMutex(){ return _threadMutex_; } + static bool isDebug(){ return _parameters_.isDebug; } + static bool isLightOutputMode(){ return _parameters_.lightOutputModeEnabled; } + static int getNbCpuThreads(){ return _parameters_.nbCpuThreads; } private: - static bool _isDebug_; /* enable debug printouts for the config reading */ - static bool _useCacheManager_; /* enable the use of the cache manager in the propagator (mainly for GPU) */ - static bool _forceCpuCalculation_; /* force using CPU in the cache manager */ - static bool _lightOutputModeEnabled_; - static int _nbCpuThreads_; - static std::mutex _threadMutex_; + + struct Parameters{ + // Debug mode is set to enable extra printouts during runtime. + bool isDebug{false}; + + // Light output mode will disable the writing of objects in the output files. + // This makes the produced output .root file lighter. + bool lightOutputModeEnabled{false}; + + // how many parallel threads must be running during the + // compatible routines during runtime + int nbCpuThreads{1}; + }; + static Parameters _parameters_; + }; diff --git a/src/Utils/src/GundamGlobals.cpp b/src/Utils/src/GundamGlobals.cpp index e82dbfa5..0c4ff359 100644 --- a/src/Utils/src/GundamGlobals.cpp +++ b/src/Utils/src/GundamGlobals.cpp @@ -4,10 +4,6 @@ #include "GundamGlobals.h" -// statics -int GundamGlobals::_nbCpuThreads_{1}; -bool GundamGlobals::_useCacheManager_{false}; -bool GundamGlobals::_isDebug_{false}; -bool GundamGlobals::_forceCpuCalculation_{false}; -bool GundamGlobals::_lightOutputModeEnabled_{false}; -std::mutex GundamGlobals::_threadMutex_; +// static on global scope +GundamGlobals::Parameters GundamGlobals::_parameters_{}; +