Skip to content

Commit 8333598

Browse files
authored
Merge pull request #5 from hls-fpga-machine-learning/kjp/kelvin
DeepCalo Support (squashed)
2 parents 3ff89cf + 46785ff commit 8333598

File tree

9 files changed

+462
-20
lines changed

9 files changed

+462
-20
lines changed

TensorRT/interface/TRTClient.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,18 @@
1313
#include "request_grpc.h"
1414

1515
namespace nic = nvidia::inferenceserver::client;
16+
namespace ni = nvidia::inferenceserver;
17+
18+
using ModelInfo = std::pair<std::string, int64_t>;
19+
20+
struct ServerSideStats {
21+
uint64_t request_count;
22+
uint64_t cumm_time_ns;
23+
uint64_t queue_time_ns;
24+
uint64_t compute_time_ns;
25+
26+
std::map<ModelInfo, ServerSideStats> composing_models_stat;
27+
};
1628

1729
template <typename Client>
1830
class TRTClient : public Client {
@@ -47,6 +59,22 @@ class TRTClient : public Client {
4759
//helper for common ops
4860
void setup();
4961

62+
void ReportServerSideState(const ServerSideStats& stats);
63+
void SummarizeServerStats(
64+
const ModelInfo model_info,
65+
const std::map<std::string, ni::ModelStatus>& start_status,
66+
const std::map<std::string, ni::ModelStatus>& end_status,
67+
ServerSideStats* server_stats);
68+
void SummarizeServerModelStats(
69+
const std::string& model_name, const int64_t model_version,
70+
const ni::ModelStatus& start_status, const ni::ModelStatus& end_status,
71+
ServerSideStats* server_stats);
72+
73+
void GetServerSideStatus(std::map<std::string, ni::ModelStatus>* model_status);
74+
void GetServerSideStatus(
75+
ni::ServerStatus& server_status, const ModelInfo model_info,
76+
std::map<std::string, ni::ModelStatus>* model_status);
77+
5078
//members
5179
std::string url_;
5280
unsigned timeout_;
@@ -55,8 +83,12 @@ class TRTClient : public Client {
5583
unsigned ninput_;
5684
unsigned noutput_;
5785
std::unique_ptr<nic::InferContext> context_;
86+
std::unique_ptr<nic::ServerStatusContext> server_ctx_;
5887
std::shared_ptr<nic::InferContext::Input> nicinput_;
88+
89+
std::map<std::string, ni::ModelStatus> start_status, end_status;
5990
};
91+
6092
typedef TRTClient<SonicClientSync<std::vector<float>>> TRTClientSync;
6193
typedef TRTClient<SonicClientPseudoAsync<std::vector<float>>> TRTClientPseudoAsync;
6294
typedef TRTClient<SonicClientAsync<std::vector<float>>> TRTClientAsync;
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#include <vector>
2+
#include <map>
3+
#include <sstream>
4+
#include <string>
5+
#include <iostream>
6+
#include <fstream>
7+
8+
#include <stdio.h>
9+
10+
#include "SonicCMS/Core/interface/SonicEDProducer.h"
11+
#include "SonicCMS/TensorRT/interface/TRTClient.h"
12+
#include "FWCore/Framework/interface/Event.h"
13+
#include "FWCore/ParameterSet/interface/ParameterSet.h"
14+
#include "FWCore/Framework/interface/EventSetup.h"
15+
#include "FWCore/Framework/interface/Frameworkfwd.h"
16+
#include "FWCore/Framework/interface/MakerMacros.h"
17+
#include "FWCore/MessageLogger/interface/MessageLogger.h"
18+
19+
template <typename Client>
20+
class DeepCaloProducer : public SonicEDProducer<Client>
21+
{
22+
public:
23+
//needed because base class has dependent scope
24+
using typename SonicEDProducer<Client>::Input;
25+
using typename SonicEDProducer<Client>::Output;
26+
explicit DeepCaloProducer(edm::ParameterSet const& cfg) :
27+
SonicEDProducer<Client>(cfg),
28+
topN_(cfg.getParameter<unsigned>("topN")),
29+
binDataPath_(cfg.getParameter<std::string>("binDataPath"))
30+
{
31+
//for debugging
32+
this->setDebugName("DeepCaloProducer");
33+
34+
// Load the bin data
35+
std::streampos fileSize;
36+
std::ifstream file(binDataPath_, std::ios::binary);
37+
38+
if(file.is_open()){
39+
file.unsetf(std::ios::skipws);
40+
41+
// Get the size of the file
42+
file.seekg(0, std::ios::end);
43+
fileSize = file.tellg();
44+
file.seekg(0, std::ios::beg);
45+
46+
imageData_.reserve(fileSize/sizeof(float));
47+
48+
for (size_t i = 0; i < imageData_.capacity(); i++)
49+
{
50+
float f;
51+
file.read(reinterpret_cast<char*>(&f), sizeof(float));
52+
imageData_.push_back(f);
53+
}
54+
file.close();
55+
} else throw cms::Exception("MissingInputFile") << "Could not read the file: " << binDataPath_;
56+
57+
imageID_ = 0;
58+
imageN_ = imageData_.size() / (56*11*4);
59+
}
60+
void acquire(edm::Event const& iEvent, edm::EventSetup const& iSetup, Input& iInput) override {
61+
auto ninput = client_.ninput();
62+
auto batchSize = client_.batchSize();
63+
iInput = Input(ninput*batchSize, 0.f);
64+
65+
if (imageID_ + batchSize >= imageN_)
66+
imageID_ = 0;
67+
68+
unsigned int start = imageID_*56*11*4;
69+
unsigned int end = start + batchSize*56*11*4;
70+
71+
iInput = std::vector<float>(imageData_.begin() + start, imageData_.begin() + end);
72+
73+
imageID_ += batchSize;
74+
}
75+
void produce(edm::Event& iEvent, edm::EventSetup const& iSetup, Output const& iOutput) override {
76+
findTopN(iOutput);
77+
}
78+
~DeepCaloProducer() override {}
79+
80+
private:
81+
using SonicEDProducer<Client>::client_;
82+
//Just putting something in for the hell of it
83+
void findTopN(const Output& scores) const {
84+
auto dim = client_.noutput();
85+
for(unsigned i0 = 0; i0 < client_.batchSize(); i0++) {
86+
//match score to type by index, then put in largest-first map
87+
std::map<float,std::string,std::greater<float>> score_map;
88+
for(unsigned i = 0; i < (unsigned)dim; ++i){
89+
std::stringstream pSS; pSS << "Dummy Channel " << i;
90+
score_map.emplace(scores[i0*dim+i],pSS.str());
91+
}
92+
//get top n
93+
std::stringstream msg;
94+
msg << "Scores:\n";
95+
unsigned counter = 0;
96+
for(const auto& item: score_map){
97+
msg << item.second << " : " << item.first << "\n";
98+
++counter;
99+
if(counter>=topN_) break;
100+
}
101+
edm::LogInfo("DeepCaloProducer") << msg.str();
102+
}
103+
}
104+
105+
unsigned topN_;
106+
unsigned int imageID_;
107+
unsigned int imageN_;
108+
std::string binDataPath_;
109+
std::vector<float> imageData_;
110+
};
111+
112+
typedef DeepCaloProducer<TRTClientSync> DeepCaloProducerSync;
113+
typedef DeepCaloProducer<TRTClientAsync> DeepCaloProducerAsync;
114+
typedef DeepCaloProducer<TRTClientPseudoAsync> DeepCaloProducerPseudoAsync;
115+
116+
DEFINE_FWK_MODULE(DeepCaloProducerSync);
117+
DEFINE_FWK_MODULE(DeepCaloProducerAsync);
118+
DEFINE_FWK_MODULE(DeepCaloProducerPseudoAsync);

TensorRT/plugins/JetImageProducer.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ class JetImageProducer : public SonicEDProducer<Client>
5555

5656
// create a jet image for the leading jet in the event
5757
// 224 x 224 image which is centered at the jet axis and +/- 1 unit in eta and phi
58-
std::vector<float> img(client_.ninput(),0.f);
58+
std::vector<float> img(client_.ninput()*client_.batchSize(),0.f);
59+
5960
const unsigned npix = 224;
6061
float pixel_width = 2./float(npix);
6162

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
from FWCore.ParameterSet.VarParsing import VarParsing
2+
import FWCore.ParameterSet.Config as cms
3+
import os, sys, json
4+
5+
options = VarParsing("analysis")
6+
options.register("address", "ailab01.fnal.gov", VarParsing.multiplicity.singleton, VarParsing.varType.string)
7+
#options.register("address", "prp-gpu-1.t2.ucsd.edu", VarParsing.multiplicity.singleton, VarParsing.varType.string)
8+
#options.register("address", "18.4.112.82", VarParsing.multiplicity.singleton, VarParsing.varType.string)
9+
options.register("port", 8001, VarParsing.multiplicity.singleton, VarParsing.varType.int)
10+
options.register("timeout", 30, VarParsing.multiplicity.singleton, VarParsing.varType.int)
11+
options.register("params", "", VarParsing.multiplicity.singleton, VarParsing.varType.string)
12+
options.register("threads", 1, VarParsing.multiplicity.singleton, VarParsing.varType.int)
13+
options.register("streams", 0, VarParsing.multiplicity.singleton, VarParsing.varType.int)
14+
options.register("batchsize", 1, VarParsing.multiplicity.singleton, VarParsing.varType.int)
15+
options.register("modelname","deepcalo_e", VarParsing.multiplicity.singleton, VarParsing.varType.string)
16+
options.register("mode", "Async", VarParsing.multiplicity.singleton, VarParsing.varType.string)
17+
options.parseArguments()
18+
19+
if len(options.params)>0:
20+
with open(options.params,'r') as pfile:
21+
pdict = json.load(pfile)
22+
options.address = pdict["address"]
23+
options.port = int(pdict["port"])
24+
print("server = "+options.address+":"+str(options.port))
25+
26+
# check mode
27+
allowed_modes = {
28+
"Async": "DeepCaloProducerAsync",
29+
"Sync": "DeepCaloProducerSync",
30+
"PseudoAsync": "DeepCaloProducerPseudoAsync",
31+
}
32+
if options.mode not in allowed_modes:
33+
raise ValueError("Unknown mode: "+options.mode)
34+
35+
process = cms.Process('imageTest')
36+
37+
#--------------------------------------------------------------------------------
38+
# Import of standard configurations
39+
#================================================================================
40+
process.load('FWCore/MessageService/MessageLogger_cfi')
41+
process.load('Configuration/StandardSequences/GeometryDB_cff')
42+
process.load('Configuration/StandardSequences/MagneticField_38T_cff')
43+
44+
process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff")
45+
process.GlobalTag.globaltag = cms.string('100X_upgrade2018_realistic_v10')
46+
47+
process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(options.maxEvents) )
48+
process.source = cms.Source("PoolSource",
49+
#fileNames = cms.untracked.vstring('file:../../Core/data/store_mc_RunIISpring18MiniAOD_BulkGravTohhTohbbhbb_narrow_M-2000_13TeV-madgraph_MINIAODSIM_100X_upgrade2018_realistic_v10-v1_30000_24A0230C-B530-E811-ADE3-14187741120B.root')
50+
fileNames = cms.untracked.vstring(['file:../../Core/data/skim.root']*100),
51+
duplicateCheckMode = cms.untracked.string('noDuplicateCheck')
52+
)
53+
54+
55+
if len(options.inputFiles)>0: process.source.fileNames = options.inputFiles
56+
57+
################### EDProducer ##############################
58+
process.DeepCaloProducer = cms.EDProducer(allowed_modes[options.mode],
59+
topN = cms.uint32(5),
60+
#binDataPath = cms.string("../../Core/data/image0_1000.bin"),
61+
binDataPath = cms.string("../../Core/data/deepcalo_all.bin"),
62+
Client = cms.PSet(
63+
ninput = cms.uint32(56*11*4),
64+
noutput = cms.uint32(1),
65+
batchSize = cms.uint32(options.batchsize),
66+
address = cms.string(options.address),
67+
port = cms.uint32(options.port),
68+
timeout = cms.uint32(options.timeout),
69+
modelName = cms.string(options.modelname),
70+
)
71+
)
72+
73+
# Let it run
74+
process.p = cms.Path(
75+
process.DeepCaloProducer
76+
)
77+
78+
process.MessageLogger.cerr.FwkReport.reportEvery = 500
79+
keep_msgs = ['TRTClient','DeepCaloProducer']
80+
for msg in keep_msgs:
81+
process.MessageLogger.categories.append(msg)
82+
setattr(process.MessageLogger.cerr,msg,
83+
cms.untracked.PSet(
84+
optionalPSet = cms.untracked.bool(True),
85+
limit = cms.untracked.int32(10000000),
86+
)
87+
)
88+
89+
if options.threads>0:
90+
if not hasattr(process,"options"):
91+
process.options = cms.untracked.PSet()
92+
process.options.numberOfThreads = cms.untracked.uint32(options.threads)
93+
process.options.numberOfStreams = cms.untracked.uint32(options.streams if options.streams>0 else 0)
94+
95+
process.Timing = cms.Service("Timing",
96+
summaryOnly = cms.untracked.bool(True),
97+
useJobReport = cms.untracked.bool(True)
98+
)

TensorRT/python/HcalTest_mc_cfg.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646

4747
process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(options.maxEvents) )
4848
process.source = cms.Source("PoolSource",
49-
fileNames = cms.untracked.vstring('file:../../Core/data/store_mc_RunIISpring18MiniAOD_BulkGravTohhTohbbhbb_narrow_M-2000_13TeV-madgraph_MINIAODSIM_100X_upgrade2018_realistic_v10-v1_30000_24A0230C-B530-E811-ADE3-14187741120B.root')
49+
fileNames = cms.untracked.vstring('/store/user/pedrok/sonic/store_mc_RunIISpring18MiniAOD_BulkGravTohhTohbbhbb_narrow_M-2000_13TeV-madgraph_MINIAODSIM_100X_upgrade2018_realistic_v10-v1_30000_24A0230C-B530-E811-ADE3-14187741120B.root')
5050
)
5151

5252
if len(options.inputFiles)>0: process.source.fileNames = options.inputFiles

TensorRT/python/jetImageTest_mc_cfg.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
options.register("threads", 1, VarParsing.multiplicity.singleton, VarParsing.varType.int)
1212
options.register("streams", 0, VarParsing.multiplicity.singleton, VarParsing.varType.int)
1313
options.register("batchsize", 10, VarParsing.multiplicity.singleton, VarParsing.varType.int)
14-
#options.register("modelname","resnet50_netdef", VarParsing.multiplicity.singleton, VarParsing.varType.string)
15-
options.register("modelname","resnet50_ensemble", VarParsing.multiplicity.singleton, VarParsing.varType.string)
14+
options.register("modelname","resnet50_netdef", VarParsing.multiplicity.singleton, VarParsing.varType.string)
15+
#options.register("modelname","resnet50_ensemble", VarParsing.multiplicity.singleton, VarParsing.varType.string)
1616
options.register("mode","Async", VarParsing.multiplicity.singleton, VarParsing.varType.string)
1717
options.parseArguments()
1818

@@ -46,7 +46,8 @@
4646

4747
process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(options.maxEvents) )
4848
process.source = cms.Source("PoolSource",
49-
fileNames = cms.untracked.vstring('file:../../Core/data/store_mc_RunIISpring18MiniAOD_BulkGravTohhTohbbhbb_narrow_M-2000_13TeV-madgraph_MINIAODSIM_100X_upgrade2018_realistic_v10-v1_30000_24A0230C-B530-E811-ADE3-14187741120B.root')
49+
fileNames = cms.untracked.vstring(['file:store_mc_RunIISpring18MiniAOD_BulkGravTohhTohbbhbb_narrow_M-2000_13TeV-madgraph_MINIAODSIM_100X_upgrade2018_realistic_v10-v1_30000_24A0230C-B530-E811-ADE3-14187741120B.root']*50),
50+
duplicateCheckMode = cms.untracked.string('noDuplicateCheck')
5051
)
5152

5253
if len(options.inputFiles)>0: process.source.fileNames = options.inputFiles
@@ -57,8 +58,8 @@
5758
topN = cms.uint32(5),
5859
imageList = cms.string("../../Core/data/imagenet_classes.txt"),
5960
Client = cms.PSet(
60-
ninput = cms.uint32(15),
61-
noutput = cms.uint32(1),
61+
ninput = cms.uint32(224*224*3),
62+
noutput = cms.uint32(1000),
6263
batchSize = cms.uint32(options.batchsize),
6364
address = cms.string(options.address),
6465
port = cms.uint32(options.port),
@@ -72,7 +73,7 @@
7273
process.jetImageProducer
7374
)
7475

75-
process.MessageLogger.cerr.FwkReport.reportEvery = 1
76+
process.MessageLogger.cerr.FwkReport.reportEvery = 500
7677
keep_msgs = ['JetImageProducer','TRTClient']
7778
for msg in keep_msgs:
7879
process.MessageLogger.categories.append(msg)
@@ -88,3 +89,8 @@
8889
process.options = cms.untracked.PSet()
8990
process.options.numberOfThreads = cms.untracked.uint32(options.threads)
9091
process.options.numberOfStreams = cms.untracked.uint32(options.streams if options.streams>0 else 0)
92+
93+
process.Timing = cms.Service("Timing",
94+
summaryOnly = cms.untracked.bool(True),
95+
useJobReport = cms.untracked.bool(True)
96+
)

TensorRT/python/process_result.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import pickle
2+
3+
domain_name = "mit"
4+
5+
with open(domain_name+"_result.txt") as f:
6+
content = f.readlines()
7+
# you may also want to remove whitespace characters like `\n` at the end of each line
8+
content = [x.strip() for x in content]
9+
10+
output_time = []
11+
remote_time = []
12+
client_time = []
13+
14+
for line in content:
15+
this_line = line.split()
16+
if (len(this_line) == 0):
17+
continue
18+
if (this_line[0] == "Remote"):
19+
remote_time.append(int(this_line[-1]))
20+
if (this_line[0] == "Client"):
21+
client_time.append(int(this_line[-1]))
22+
if (this_line[0] == "Output"):
23+
output_time.append(int(this_line[-1]))
24+
25+
result_dic = {}
26+
27+
result_dic["Remote"] = remote_time
28+
result_dic["Output"] = output_time
29+
result_dic["Client"] = client_time
30+
31+
with open(domain_name+'_result.pkl', 'wb') as handle:
32+
pickle.dump(result_dic, handle, protocol=pickle.HIGHEST_PROTOCOL)

0 commit comments

Comments
 (0)