Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-06-17 01:30:27

0001 // -*- C++ -*-
0002 //
0003 // Package:     Services
0004 // Class  :     ResourceInformationService
0005 //
0006 // Implementation:
0007 
0008 /** \class edm::service::ResourceInformationService
0009 
0010 \author W. David Dagenhart, created 29 April, 2022
0011 
0012 */
0013 
0014 #include "FWCore/AbstractServices/interface/ResourceInformation.h"
0015 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0016 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0017 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0018 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0019 #include "FWCore/ServiceRegistry/interface/ActivityRegistry.h"
0020 #include "FWCore/Utilities/interface/EDMException.h"
0021 
0022 #include <string>
0023 #include <vector>
0024 
0025 namespace edm {
0026   namespace service {
0027 
0028     class ResourceInformationService : public ResourceInformation {
0029     public:
0030       ResourceInformationService(ParameterSet const&, ActivityRegistry&);
0031 
0032       static void fillDescriptions(ConfigurationDescriptions&);
0033 
0034       HardwareResourcesDescription hardwareResourcesDescription() const final;
0035 
0036       std::vector<std::string> const& selectedAccelerators() const final;
0037       std::vector<std::string> const& cpuModels() const final;
0038       std::vector<std::string> const& gpuModels() const final;
0039 
0040       bool hasGpuNvidia() const final;
0041 
0042       std::string const& nvidiaDriverVersion() const final;
0043       int cudaDriverVersion() const final;
0044       int cudaRuntimeVersion() const final;
0045 
0046       // Same as cpuModels except in a single string with models separated by ", "
0047       std::string const& cpuModelsFormatted() const final;
0048       double cpuAverageSpeed() const final;
0049 
0050       void setSelectedAccelerators(std::vector<std::string> const& selectedAccelerators) final;
0051       void setCPUModels(std::vector<std::string> const&) final;
0052       void setGPUModels(std::vector<std::string> const&) final;
0053 
0054       void setNvidiaDriverVersion(std::string const&) final;
0055       void setCudaDriverVersion(int) final;
0056       void setCudaRuntimeVersion(int) final;
0057 
0058       void setCpuModelsFormatted(std::string const&) final;
0059       void setCpuAverageSpeed(double) final;
0060 
0061       void postBeginJob();
0062 
0063     private:
0064       void throwIfLocked() const;
0065 
0066       std::vector<std::string> selectedAccelerators_;
0067       std::vector<std::string> cpuModels_;
0068       std::vector<std::string> gpuModels_;
0069 
0070       std::string nvidiaDriverVersion_;
0071       int cudaDriverVersion_ = 0;
0072       int cudaRuntimeVersion_ = 0;
0073 
0074       std::string cpuModelsFormatted_;
0075       double cpuAverageSpeed_ = 0;
0076 
0077       bool hasGpuNvidia_ = false;
0078       bool locked_ = false;
0079       bool verbose_;
0080     };
0081 
0082     ResourceInformationService::ResourceInformationService(ParameterSet const& pset, ActivityRegistry& iRegistry)
0083         : verbose_(pset.getUntrackedParameter<bool>("verbose")) {
0084       iRegistry.watchPostBeginJob(this, &ResourceInformationService::postBeginJob);
0085     }
0086 
0087     void ResourceInformationService::fillDescriptions(ConfigurationDescriptions& descriptions) {
0088       ParameterSetDescription desc;
0089       desc.addUntracked<bool>("verbose", false);
0090       descriptions.add("ResourceInformationService", desc);
0091     }
0092 
0093     HardwareResourcesDescription ResourceInformationService::hardwareResourcesDescription() const {
0094       // It is important to have this function defined in a plugin
0095       // library. It expands the CMS_MICRO_ARCH macro, and loading the
0096       // library via plugin mechanism rather than as a dependence of
0097       // another library has the best chance to capture the best
0098       // microarchitecture that scram decided to use
0099 
0100       HardwareResourcesDescription ret;
0101       ret.microarchitecture = CMS_MICRO_ARCH;  // macro expands to string literal
0102       ret.cpuModels = cpuModels();
0103       ret.selectedAccelerators = selectedAccelerators();
0104       ret.gpuModels = gpuModels();
0105       return ret;
0106     }
0107 
0108     std::vector<std::string> const& ResourceInformationService::selectedAccelerators() const {
0109       return selectedAccelerators_;
0110     }
0111 
0112     std::vector<std::string> const& ResourceInformationService::cpuModels() const { return cpuModels_; }
0113 
0114     std::vector<std::string> const& ResourceInformationService::gpuModels() const { return gpuModels_; }
0115 
0116     bool ResourceInformationService::hasGpuNvidia() const { return hasGpuNvidia_; }
0117 
0118     std::string const& ResourceInformationService::nvidiaDriverVersion() const { return nvidiaDriverVersion_; }
0119 
0120     int ResourceInformationService::cudaDriverVersion() const { return cudaDriverVersion_; }
0121 
0122     int ResourceInformationService::cudaRuntimeVersion() const { return cudaRuntimeVersion_; }
0123 
0124     std::string const& ResourceInformationService::cpuModelsFormatted() const { return cpuModelsFormatted_; }
0125 
0126     double ResourceInformationService::cpuAverageSpeed() const { return cpuAverageSpeed_; }
0127 
0128     void ResourceInformationService::setSelectedAccelerators(std::vector<std::string> const& selectedAccelerators) {
0129       if (!locked_) {
0130         selectedAccelerators_ = selectedAccelerators;
0131         locked_ = true;
0132       }
0133     }
0134 
0135     void ResourceInformationService::setCPUModels(std::vector<std::string> const& val) {
0136       throwIfLocked();
0137       cpuModels_ = val;
0138     }
0139 
0140     void ResourceInformationService::setGPUModels(std::vector<std::string> const& val) {
0141       throwIfLocked();
0142       gpuModels_ = val;
0143     }
0144 
0145     void ResourceInformationService::setNvidiaDriverVersion(std::string const& val) {
0146       throwIfLocked();
0147       nvidiaDriverVersion_ = val;
0148       hasGpuNvidia_ = true;
0149     }
0150 
0151     void ResourceInformationService::setCudaDriverVersion(int val) {
0152       throwIfLocked();
0153       cudaDriverVersion_ = val;
0154       hasGpuNvidia_ = true;
0155     }
0156 
0157     void ResourceInformationService::setCudaRuntimeVersion(int val) {
0158       throwIfLocked();
0159       cudaRuntimeVersion_ = val;
0160       hasGpuNvidia_ = true;
0161     }
0162 
0163     void ResourceInformationService::setCpuModelsFormatted(std::string const& val) {
0164       throwIfLocked();
0165       cpuModelsFormatted_ = val;
0166     }
0167 
0168     void ResourceInformationService::setCpuAverageSpeed(double val) {
0169       throwIfLocked();
0170       cpuAverageSpeed_ = val;
0171     }
0172 
0173     void ResourceInformationService::throwIfLocked() const {
0174       if (locked_) {
0175         // Only Services should modify ResourceInformationService. Service construction is run serially.
0176         // The lock provides thread safety and prevents modules from modifying ResourceInformationService.
0177         throw edm::Exception(errors::LogicError)
0178             << "Attempt to modify member data after ResourceInformationService was locked ";
0179       }
0180     }
0181 
0182     void ResourceInformationService::postBeginJob() {
0183       if (verbose_) {
0184         LogAbsolute("ResourceInformation") << "ResourceInformationService";
0185         LogAbsolute("ResourceInformation") << "    cpu models:";
0186         if (cpuModels().empty()) {
0187           LogAbsolute("ResourceInformation") << "        None";
0188         } else {
0189           for (auto const& iter : cpuModels()) {
0190             LogAbsolute("ResourceInformation") << "        " << iter;
0191           }
0192         }
0193         LogAbsolute("ResourceInformation") << "    gpu models:";
0194         if (gpuModels().empty()) {
0195           LogAbsolute("ResourceInformation") << "        None";
0196         } else {
0197           for (auto const& iter : gpuModels()) {
0198             LogAbsolute("ResourceInformation") << "        " << iter;
0199           }
0200         }
0201 
0202         LogAbsolute("ResourceInformation") << "    selectedAccelerators:";
0203         if (selectedAccelerators().empty()) {
0204           LogAbsolute("ResourceInformation") << "        None";
0205         } else {
0206           for (auto const& iter : selectedAccelerators()) {
0207             LogAbsolute("ResourceInformation") << "        " << iter;
0208           }
0209         }
0210         LogAbsolute("ResourceInformation") << "    nvidiaDriverVersion: " << nvidiaDriverVersion();
0211         LogAbsolute("ResourceInformation") << "    cudaDriverVersion: " << cudaDriverVersion();
0212         LogAbsolute("ResourceInformation") << "    cudaRuntimeVersion: " << cudaRuntimeVersion();
0213         LogAbsolute("ResourceInformation") << "    cpuModelsFormatted: " << cpuModelsFormatted();
0214         LogAbsolute("ResourceInformation") << "    cpuAverageSpeed: " << cpuAverageSpeed();
0215       }
0216     }
0217 
0218   }  // namespace service
0219 }  // namespace edm
0220 
0221 #include "FWCore/ServiceRegistry/interface/ServiceMaker.h"
0222 
0223 using edm::service::ResourceInformationService;
0224 using ResourceInformationMaker =
0225     edm::serviceregistry::AllArgsMaker<edm::ResourceInformation, ResourceInformationService>;
0226 DEFINE_FWK_SERVICE_MAKER(ResourceInformationService, ResourceInformationMaker);