Skip to content

Commit

Permalink
Implement ResourceInformationService
Browse files Browse the repository at this point in the history
  • Loading branch information
wddgit committed May 5, 2022
1 parent f62ece4 commit b4e04a9
Show file tree
Hide file tree
Showing 9 changed files with 262 additions and 0 deletions.
12 changes: 12 additions & 0 deletions FWCore/Framework/src/ScheduleItems.cc
Expand Up @@ -16,14 +16,18 @@
#include "FWCore/Framework/interface/SignallingProductRegistry.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "FWCore/ServiceRegistry/interface/ActivityRegistry.h"
#include "FWCore/ServiceRegistry/interface/Service.h"
#include "FWCore/ServiceRegistry/interface/ServiceRegistry.h"
#include "FWCore/Utilities/interface/BranchType.h"
#include "FWCore/Utilities/interface/GetPassID.h"
#include "FWCore/Utilities/interface/ResourceInformation.h"
#include "FWCore/Version/interface/GetReleaseVersion.h"

#include <memory>

#include <set>
#include <string>
#include <vector>

namespace edm {
ScheduleItems::ScheduleItems()
Expand Down Expand Up @@ -121,6 +125,14 @@ namespace edm {
}

std::shared_ptr<CommonParams> ScheduleItems::initMisc(ParameterSet& parameterSet) {
edm::Service<edm::ResourceInformation> resourceInformationService;
if (resourceInformationService.isAvailable()) {
auto const& selectedAccelerators =
parameterSet.getUntrackedParameter<std::vector<std::string>>("@selected_accelerators");
resourceInformationService->initializeAcceleratorTypes(selectedAccelerators);
resourceInformationService->lock();
}

act_table_ = std::make_unique<ExceptionToActionTable>(parameterSet);
std::string processName = parameterSet.getParameter<std::string>("@process_name");
processConfiguration_ = std::make_shared<ProcessConfiguration>(
Expand Down
16 changes: 16 additions & 0 deletions FWCore/Services/plugins/CPU.cc
Expand Up @@ -17,6 +17,7 @@
#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
#include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
#include "FWCore/Utilities/interface/CPUServiceBase.h"
#include "FWCore/Utilities/interface/ResourceInformation.h"

#include <iostream>
#include <sys/time.h>
Expand All @@ -25,6 +26,7 @@
#include <string>
#include <fstream>
#include <sstream>
#include <map>
#include <set>

#ifdef __linux__
Expand Down Expand Up @@ -139,6 +141,20 @@ namespace edm {

CPU::CPU(const ParameterSet &iPS, ActivityRegistry &iRegistry)
: reportCPUProperties_(iPS.getUntrackedParameter<bool>("reportCPUProperties")) {
edm::Service<edm::ResourceInformation> resourceInformationService;
if (resourceInformationService.isAvailable()) {
std::vector<std::pair<std::string, std::string>> info;
if (parseCPUInfo(info)) {
std::map<std::string, unsigned int> models;
for (const auto &entry : info) {
if (entry.first == "model name") {
++models[entry.second];
}
}
resourceInformationService->insertIntoModels(models);
}
}

iRegistry.watchPostEndJob(this, &CPU::postEndJob);
}

Expand Down
131 changes: 131 additions & 0 deletions FWCore/Services/plugins/ResourceInformationService.cc
@@ -0,0 +1,131 @@
// -*- C++ -*-
//
// Package: Services
// Class : ResourceInformationService
//
// Implementation:

/** \class edm::service::ResourceInformationService
\author W. David Dagenhart, created 29 April, 2022
*/

#include "FWCore/MessageLogger/interface/MessageLogger.h"
#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
#include "FWCore/ServiceRegistry/interface/ActivityRegistry.h"
#include "FWCore/ServiceRegistry/interface/ServiceMaker.h"
#include "FWCore/Utilities/interface/EDMException.h"
#include "FWCore/Utilities/interface/ResourceInformation.h"

#include <map>
#include <string>
#include <vector>

namespace edm {
namespace service {

class ResourceInformationService : public ResourceInformation {
public:
ResourceInformationService(ParameterSet const&, ActivityRegistry&);

static void fillDescriptions(ConfigurationDescriptions&);

std::vector<AcceleratorType> const& acceleratorTypes() const final;
std::map<std::string, unsigned int> const& models() const final;

void insertIntoModels(std::map<std::string, unsigned int> const& iModels) final;
void initializeAcceleratorTypes(std::vector<std::string> const& selectedAccelerators) final;
void lock() final;

void postBeginJob();

private:
std::vector<AcceleratorType> acceleratorTypes_;
std::map<std::string, unsigned int> models_;
bool locked_ = false;
bool verbose_;
};

ResourceInformationService::ResourceInformationService(ParameterSet const& pset, ActivityRegistry& iRegistry)
: verbose_(pset.getUntrackedParameter<bool>("verbose")) {
iRegistry.watchPostBeginJob(this, &ResourceInformationService::postBeginJob);
}

void ResourceInformationService::fillDescriptions(ConfigurationDescriptions& descriptions) {
ParameterSetDescription desc;
desc.addUntracked<bool>("verbose", false);
descriptions.add("ResourceInformationService", desc);
}

std::vector<ResourceInformation::AcceleratorType> const& ResourceInformationService::acceleratorTypes() const {
return acceleratorTypes_;
}
std::map<std::string, unsigned int> const& ResourceInformationService::models() const { return models_; }

void ResourceInformationService::insertIntoModels(std::map<std::string, unsigned int> const& iModels) {
if (locked_) {
// Only Services should call this function. Service construction is run serially.
// The lock provides thread safety and prevents modules from modifying models_.
throw edm::Exception(errors::LogicError)
<< "Attempt to add models after ResourceInformationService was locked ";
}
for (const auto& [key, value] : iModels) {
auto& count = models_[key];
count += value;
}
}

void ResourceInformationService::initializeAcceleratorTypes(std::vector<std::string> const& selectedAccelerators) {
if (locked_) {
// The lock provides thread safety and prevents modules from modifying acceleratorTypes_.
throw edm::Exception(errors::LogicError)
<< "Attempt to add models after ResourceInformationService was locked ";
}
for (auto const& selected : selectedAccelerators) {
// Test if the string begins with "gpu-"
if (selected.rfind("gpu-", 0) == 0) {
acceleratorTypes_.push_back(AcceleratorType::GPU);
break;
}
}
}

void ResourceInformationService::lock() { locked_ = true; }

void ResourceInformationService::postBeginJob() {
if (verbose_) {
LogAbsolute("ResourceInformation") << "ResourceInformationService";
LogAbsolute("ResourceInformation") << " models:";
if (models().empty()) {
LogAbsolute("ResourceInformation") << " None";
} else {
for (auto const& iter : models()) {
LogAbsolute("ResourceInformation") << " " << iter.first << " " << iter.second;
}
}

LogAbsolute("ResourceInformation") << " acceleratorTypes:";
if (acceleratorTypes().empty()) {
LogAbsolute("ResourceInformation") << " None";
} else {
for (auto const& iter : acceleratorTypes()) {
std::string acceleratorTypeString("unknown type");
if (iter == AcceleratorType::GPU) {
acceleratorTypeString = std::string("GPU");
}
LogAbsolute("ResourceInformation") << " " << acceleratorTypeString;
}
}
}
}

} // namespace service
} // namespace edm

using edm::service::ResourceInformationService;
using ResourceInformationMaker =
edm::serviceregistry::AllArgsMaker<edm::ResourceInformation, ResourceInformationService>;
DEFINE_FWK_SERVICE_MAKER(ResourceInformationService, ResourceInformationMaker);
5 changes: 5 additions & 0 deletions FWCore/Services/test/BuildFile.xml
Expand Up @@ -21,3 +21,8 @@
<use name="clhep"/>
<use name="FWCore/Services"/>
</bin>

<bin file="TestFWCoreServicesDriver.cpp" name="TestResourceInformationService">
<flags TEST_RUNNER_ARGS=" /bin/bash FWCore/Services/test test_resourceInformationService.sh"/>
<use name="FWCore/Utilities"/>
</bin>
16 changes: 16 additions & 0 deletions FWCore/Services/test/test_resourceInformationService.sh
@@ -0,0 +1,16 @@
#!/bin/bash

LOCAL_TEST_DIR=${CMSSW_BASE}/src/FWCore/Services/test
LOCAL_TMP_DIR=${CMSSW_BASE}/tmp/${SCRAM_ARCH}

function die { echo Failure $1: status $2 ; exit $2 ; }

pushd ${LOCAL_TMP_DIR}

cmsRun -p ${LOCAL_TEST_DIR}/test_resourceInformationService_cfg.py &> test_resourceInformationService.log || die "cmsRun test_resourceInformationService_cfg.py" $?

grep -A 1 "acceleratorTypes:" test_resourceInformationService.log | grep "GPU" || die "Check for existence of GPU acceleratorType" $?
grep -A 1 "models:" test_resourceInformationService.log | grep "None" && die "Check there is at least one model (not None)" 1
popd

exit 0
30 changes: 30 additions & 0 deletions FWCore/Services/test/test_resourceInformationService_cfg.py
@@ -0,0 +1,30 @@
# Test ResourceInformationService
# The shell script will examine its printout
import FWCore.ParameterSet.Config as cms

# This class is a hack just for the test to get
# 'gpu-foo' into @selected_accelerators
class ProcessAcceleratorTest(cms.ProcessAccelerator):
def __init__(self):
super(ProcessAcceleratorTest,self).__init__()
self._labels = ["test1", "gpu-foo", "test2"]
self._enabled = ["test1", "gpu-foo", "test2"]
def labels(self):
return self._labels
def enabledLabels(self):
return self._enabled

process = cms.Process("PROD")
process.add_(ProcessAcceleratorTest())

process.ResourceInformationService = cms.Service("ResourceInformationService",
verbose = cms.untracked.bool(True)
)
process.CPU = cms.Service("CPU")
process.options.accelerators = ["*"]

process.maxEvents = cms.untracked.PSet(
input = cms.untracked.int32(1)
)
process.source = cms.Source("EmptySource")

36 changes: 36 additions & 0 deletions FWCore/Utilities/interface/ResourceInformation.h
@@ -0,0 +1,36 @@
#ifndef FWCore_Utilities_ResourceInformation_h
#define FWCore_Utilities_ResourceInformation_h

/** \class edm::ResourceInformation
Description:
Usage:
\author W. David Dagenhart, created May 3, 2022
*/

#include <map>
#include <string>
#include <vector>

namespace edm {

class ResourceInformation {
public:
ResourceInformation();
ResourceInformation(ResourceInformation const&) = delete;
ResourceInformation const& operator=(ResourceInformation const&) = delete;
virtual ~ResourceInformation();

enum class AcceleratorType { GPU };

virtual std::vector<AcceleratorType> const& acceleratorTypes() const = 0;
virtual std::map<std::string, unsigned int> const& models() const = 0;

virtual void insertIntoModels(std::map<std::string, unsigned int> const& iModels) = 0;
virtual void initializeAcceleratorTypes(std::vector<std::string> const& selectedAccelerators) = 0;
virtual void lock() = 0;
};
} // namespace edm
#endif
4 changes: 4 additions & 0 deletions FWCore/Utilities/src/ResourceInformation.cc
@@ -0,0 +1,4 @@
#include "FWCore/Utilities/interface/ResourceInformation.h"

edm::ResourceInformation::ResourceInformation() {}
edm::ResourceInformation::~ResourceInformation() {}
12 changes: 12 additions & 0 deletions HeterogeneousCore/CUDAServices/src/CUDAService.cc
@@ -1,6 +1,8 @@
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <string>

#include <cuda.h>
#include <cuda_runtime.h>
Expand All @@ -10,6 +12,8 @@
#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
#include "FWCore/ServiceRegistry/interface/Service.h"
#include "FWCore/Utilities/interface/ResourceInformation.h"
#include "FWCore/Utilities/interface/ReusableObjectHolder.h"
#include "HeterogeneousCore/CUDAServices/interface/CUDAService.h"
#include "HeterogeneousCore/CUDAUtilities/interface/EventCache.h"
Expand Down Expand Up @@ -182,6 +186,8 @@ CUDAService::CUDAService(edm::ParameterSet const& config) : verbose_(config.getU
auto devRuntimeSyncDepth = limits.getUntrackedParameter<int>("cudaLimitDevRuntimeSyncDepth");
auto devRuntimePendingLaunchCount = limits.getUntrackedParameter<int>("cudaLimitDevRuntimePendingLaunchCount");

std::map<std::string, unsigned int> models;

for (int i = 0; i < numberOfDevices_; ++i) {
// read information about the compute device.
// see the documentation of cudaGetDeviceProperties() for more information.
Expand All @@ -191,6 +197,7 @@ CUDAService::CUDAService(edm::ParameterSet const& config) : verbose_(config.getU
if (verbose_) {
log << '\n';
}
++models[std::string(properties.name)];

// compute capabilities
computeCapabilities_.emplace_back(properties.major, properties.minor);
Expand Down Expand Up @@ -354,6 +361,11 @@ CUDAService::CUDAService(edm::ParameterSet const& config) : verbose_(config.getU
}
}

edm::Service<edm::ResourceInformation> resourceInformationService;
if (resourceInformationService.isAvailable()) {
resourceInformationService->insertIntoModels(models);
}

// Make sure the caching allocators and stream/event caches are constructed before declaring successful construction
if constexpr (cms::cuda::allocator::useCaching) {
cms::cuda::allocator::cachingAllocatorsConstruct();
Expand Down

0 comments on commit b4e04a9

Please sign in to comment.