CMS 3D CMS Logo

TritonClient.cc
Go to the documentation of this file.
10 
11 #include "grpc_client.h"
12 #include "grpc_service.pb.h"
13 #include "model_config.pb.h"
14 
15 #include "google/protobuf/text_format.h"
16 #include "google/protobuf/io/zero_copy_stream_impl.h"
17 
18 #include <algorithm>
19 #include <cmath>
20 #include <exception>
21 #include <experimental/iterator>
22 #include <fcntl.h>
23 #include <sstream>
24 #include <string>
25 #include <utility>
26 #include <tuple>
27 
28 namespace tc = triton::client;
29 
30 namespace {
31  grpc_compression_algorithm getCompressionAlgo(const std::string& name) {
32  if (name.empty() or name.compare("none") == 0)
33  return grpc_compression_algorithm::GRPC_COMPRESS_NONE;
34  else if (name.compare("deflate") == 0)
35  return grpc_compression_algorithm::GRPC_COMPRESS_DEFLATE;
36  else if (name.compare("gzip") == 0)
37  return grpc_compression_algorithm::GRPC_COMPRESS_GZIP;
38  else
39  throw cms::Exception("GrpcCompression")
40  << "Unknown compression algorithm requested: " << name << " (choices: none, deflate, gzip)";
41  }
42 
43  std::vector<std::shared_ptr<tc::InferResult>> convertToShared(const std::vector<tc::InferResult*>& tmp) {
44  std::vector<std::shared_ptr<tc::InferResult>> results;
45  results.reserve(tmp.size());
46  std::transform(tmp.begin(), tmp.end(), std::back_inserter(results), [](tc::InferResult* ptr) {
47  return std::shared_ptr<tc::InferResult>(ptr);
48  });
49  return results;
50  }
51 } // namespace
52 
53 //based on https://github.com/triton-inference-server/server/blob/v2.3.0/src/clients/c++/examples/simple_grpc_async_infer_client.cc
54 //and https://github.com/triton-inference-server/server/blob/v2.3.0/src/clients/c++/perf_client/perf_client.cc
55 
57  : SonicClient(params, debugName, "TritonClient"),
58  batchMode_(TritonBatchMode::Rectangular),
59  manualBatchMode_(false),
60  verbose_(params.getUntrackedParameter<bool>("verbose")),
61  useSharedMemory_(params.getUntrackedParameter<bool>("useSharedMemory")),
62  compressionAlgo_(getCompressionAlgo(params.getUntrackedParameter<std::string>("compression"))) {
63  options_.emplace_back(params.getParameter<std::string>("modelName"));
64  //get appropriate server for this model
66  const auto& server =
67  ts->serverInfo(options_[0].model_name_, params.getUntrackedParameter<std::string>("preferredServer"));
68  serverType_ = server.type;
69  edm::LogInfo("TritonDiscovery") << debugName_ << " assigned server: " << server.url;
70  //enforce sync mode for fallback CPU server to avoid contention
71  //todo: could enforce async mode otherwise (unless mode was specified by user?)
75 
76  //connect to the server
78  tc::InferenceServerGrpcClient::Create(&client_, server.url, false, server.useSsl, server.sslOptions),
79  "TritonClient(): unable to create inference context",
80  isLocal_);
81 
82  //set options
83  options_[0].model_version_ = params.getParameter<std::string>("modelVersion");
84  options_[0].client_timeout_ = params.getUntrackedParameter<unsigned>("timeout");
85  //convert to microseconds
86  const auto& timeoutUnit = params.getUntrackedParameter<std::string>("timeoutUnit");
87  unsigned conversion = 1;
88  if (timeoutUnit == "seconds")
89  conversion = 1e6;
90  else if (timeoutUnit == "milliseconds")
91  conversion = 1e3;
92  else if (timeoutUnit == "microseconds")
93  conversion = 1;
94  else
95  throw cms::Exception("Configuration") << "Unknown timeout unit: " << timeoutUnit;
96  options_[0].client_timeout_ *= conversion;
97 
98  //get fixed parameters from local config
99  inference::ModelConfig localModelConfig;
100  {
101  const std::string localModelConfigPath(params.getParameter<edm::FileInPath>("modelConfigPath").fullPath());
102  int fileDescriptor = open(localModelConfigPath.c_str(), O_RDONLY);
103  if (fileDescriptor < 0)
104  throw TritonException("LocalFailure")
105  << "TritonClient(): unable to open local model config: " << localModelConfigPath;
106  google::protobuf::io::FileInputStream localModelConfigInput(fileDescriptor);
107  localModelConfigInput.SetCloseOnDelete(true);
108  if (!google::protobuf::TextFormat::Parse(&localModelConfigInput, &localModelConfig))
109  throw TritonException("LocalFailure")
110  << "TritonClient(): unable to parse local model config: " << localModelConfigPath;
111  }
112 
113  //check batch size limitations (after i/o setup)
114  //triton uses max batch size = 0 to denote a model that does not support native batching (using the outer dimension)
115  //but for models that do support batching (native or otherwise), a given event may set batch size 0 to indicate no valid input is present
116  //so set the local max to 1 and keep track of "no outer dim" case
117  maxOuterDim_ = localModelConfig.max_batch_size();
118  noOuterDim_ = maxOuterDim_ == 0;
120  //propagate batch size
121  setBatchSize(1);
122 
123  //compare model checksums to remote config to enforce versioning
124  inference::ModelConfigResponse modelConfigResponse;
125  TRITON_THROW_IF_ERROR(client_->ModelConfig(&modelConfigResponse, options_[0].model_name_, options_[0].model_version_),
126  "TritonClient(): unable to get model config",
127  isLocal_);
128  inference::ModelConfig remoteModelConfig(modelConfigResponse.config());
129 
130  std::map<std::string, std::array<std::string, 2>> checksums;
131  size_t fileCounter = 0;
132  for (const auto& modelConfig : {localModelConfig, remoteModelConfig}) {
133  const auto& agents = modelConfig.model_repository_agents().agents();
134  auto agent = std::find_if(agents.begin(), agents.end(), [](auto const& a) { return a.name() == "checksum"; });
135  if (agent != agents.end()) {
136  const auto& params = agent->parameters();
137  for (const auto& [key, val] : params) {
138  // only check the requested version
139  if (key.compare(0, options_[0].model_version_.size() + 1, options_[0].model_version_ + "/") == 0)
140  checksums[key][fileCounter] = val;
141  }
142  }
143  ++fileCounter;
144  }
145  std::vector<std::string> incorrect;
146  for (const auto& [key, val] : checksums) {
147  if (checksums[key][0] != checksums[key][1])
148  incorrect.push_back(key);
149  }
150  if (!incorrect.empty())
151  throw TritonException("ModelVersioning") << "The following files have incorrect checksums on the remote server: "
152  << triton_utils::printColl(incorrect, ", ");
153 
154  //get model info
155  inference::ModelMetadataResponse modelMetadata;
156  TRITON_THROW_IF_ERROR(client_->ModelMetadata(&modelMetadata, options_[0].model_name_, options_[0].model_version_),
157  "TritonClient(): unable to get model metadata",
158  isLocal_);
159 
160  //get input and output (which know their sizes)
161  const auto& nicInputs = modelMetadata.inputs();
162  const auto& nicOutputs = modelMetadata.outputs();
163 
164  //report all model errors at once
165  std::stringstream msg;
166  std::string msg_str;
167 
168  //currently no use case is foreseen for a model with zero inputs or outputs
169  if (nicInputs.empty())
170  msg << "Model on server appears malformed (zero inputs)\n";
171 
172  if (nicOutputs.empty())
173  msg << "Model on server appears malformed (zero outputs)\n";
174 
175  //stop if errors
176  msg_str = msg.str();
177  if (!msg_str.empty())
178  throw cms::Exception("ModelErrors") << msg_str;
179 
180  //setup input map
181  std::stringstream io_msg;
182  if (verbose_)
183  io_msg << "Model inputs: "
184  << "\n";
185  for (const auto& nicInput : nicInputs) {
186  const auto& iname = nicInput.name();
187  auto [curr_itr, success] = input_.emplace(std::piecewise_construct,
188  std::forward_as_tuple(iname),
189  std::forward_as_tuple(iname, nicInput, this, ts->pid()));
190  auto& curr_input = curr_itr->second;
191  if (verbose_) {
192  io_msg << " " << iname << " (" << curr_input.dname() << ", " << curr_input.byteSize()
193  << " b) : " << triton_utils::printColl(curr_input.shape()) << "\n";
194  }
195  }
196 
197  //allow selecting only some outputs from server
198  const auto& v_outputs = params.getUntrackedParameter<std::vector<std::string>>("outputs");
199  std::unordered_set s_outputs(v_outputs.begin(), v_outputs.end());
200 
201  //setup output map
202  if (verbose_)
203  io_msg << "Model outputs: "
204  << "\n";
205  for (const auto& nicOutput : nicOutputs) {
206  const auto& oname = nicOutput.name();
207  if (!s_outputs.empty() and s_outputs.find(oname) == s_outputs.end())
208  continue;
209  auto [curr_itr, success] = output_.emplace(std::piecewise_construct,
210  std::forward_as_tuple(oname),
211  std::forward_as_tuple(oname, nicOutput, this, ts->pid()));
212  auto& curr_output = curr_itr->second;
213  if (verbose_) {
214  io_msg << " " << oname << " (" << curr_output.dname() << ", " << curr_output.byteSize()
215  << " b) : " << triton_utils::printColl(curr_output.shape()) << "\n";
216  }
217  if (!s_outputs.empty())
218  s_outputs.erase(oname);
219  }
220 
221  //check if any requested outputs were not available
222  if (!s_outputs.empty())
223  throw cms::Exception("MissingOutput")
224  << "Some requested outputs were not available on the server: " << triton_utils::printColl(s_outputs);
225 
226  //print model info
227  std::stringstream model_msg;
228  if (verbose_) {
229  model_msg << "Model name: " << options_[0].model_name_ << "\n"
230  << "Model version: " << options_[0].model_version_ << "\n"
231  << "Model max outer dim: " << (noOuterDim_ ? 0 : maxOuterDim_) << "\n";
232  edm::LogInfo(fullDebugName_) << model_msg.str() << io_msg.str();
233  }
234 }
235 
237  //by default: members of this class destroyed before members of base class
238  //in shared memory case, TritonMemResource (member of TritonData) unregisters from client_ in its destructor
239  //but input/output objects are member of base class, so destroyed after client_ (member of this class)
240  //therefore, clear the maps here
241  input_.clear();
242  output_.clear();
243 }
244 
246  unsigned oldBatchSize = batchSize();
248  manualBatchMode_ = true;
249  //this allows calling setBatchSize() and setBatchMode() in either order consistently to change back and forth
250  //includes handling of change from ragged to rectangular if multiple entries already created
251  setBatchSize(oldBatchSize);
252 }
253 
256  manualBatchMode_ = false;
257 }
258 
259 unsigned TritonClient::nEntries() const { return !input_.empty() ? input_.begin()->second.entries_.size() : 0; }
260 
262 
263 bool TritonClient::setBatchSize(unsigned bsize) {
265  if (bsize > maxOuterDim_) {
266  throw TritonException("LocalFailure")
267  << "Requested batch size " << bsize << " exceeds server-specified max batch size " << maxOuterDim_ << ".";
268  return false;
269  } else {
270  outerDim_ = bsize;
271  //take min to allow resizing to 0
273  return true;
274  }
275  } else {
276  resizeEntries(bsize);
277  outerDim_ = 1;
278  return true;
279  }
280 }
281 
283  if (entry > nEntries())
284  //addEntry(entry) extends the vector to size entry+1
285  addEntry(entry - 1);
286  else if (entry < nEntries()) {
287  for (auto& element : input_) {
288  element.second.entries_.resize(entry);
289  }
290  for (auto& element : output_) {
291  element.second.entries_.resize(entry);
292  }
293  }
294 }
295 
297  for (auto& element : input_) {
298  element.second.addEntryImpl(entry);
299  }
300  for (auto& element : output_) {
301  element.second.addEntryImpl(entry);
302  }
303  if (entry > 0) {
305  outerDim_ = 1;
306  }
307 }
308 
310  if (!manualBatchMode_)
312  for (auto& element : input_) {
313  element.second.reset();
314  }
315  for (auto& element : output_) {
316  element.second.reset();
317  }
318 }
319 
320 template <typename F>
322  //caught exceptions will be propagated to edm::WaitingTaskWithArenaHolder
323  CMS_SA_ALLOW try {
324  call();
325  return true;
326  }
327  //TritonExceptions are intended/expected to be recoverable, i.e. retries should be allowed
328  catch (TritonException& e) {
329  e.convertToWarning();
330  finish(false);
331  return false;
332  }
333  //other exceptions are not: execution should stop if they are encountered
334  catch (...) {
335  finish(false, std::current_exception());
336  return false;
337  }
338 }
339 
340 void TritonClient::getResults(const std::vector<std::shared_ptr<tc::InferResult>>& results) {
341  for (unsigned i = 0; i < results.size(); ++i) {
342  const auto& result = results[i];
343  for (auto& [oname, output] : output_) {
344  //set shape here before output becomes const
345  if (output.variableDims()) {
346  std::vector<int64_t> tmp_shape;
348  result->Shape(oname, &tmp_shape), "getResults(): unable to get output shape for " + oname, false);
349  if (!noOuterDim_)
350  tmp_shape.erase(tmp_shape.begin());
351  output.setShape(tmp_shape, i);
352  }
353  //extend lifetime
354  output.setResult(result, i);
355  //compute size after getting all result entries
356  if (i == results.size() - 1)
357  output.computeSizes();
358  }
359  }
360 }
361 
362 //default case for sync and pseudo async
364  //undo previous signal from TritonException
365  if (tries_ > 0) {
367  ts->notifyCallStatus(true);
368  }
369 
370  //in case there is nothing to process
371  if (batchSize() == 0) {
372  //call getResults on an empty vector
373  std::vector<std::shared_ptr<tc::InferResult>> empty_results;
374  getResults(empty_results);
375  finish(true);
376  return;
377  }
378 
379  //set up input pointers for triton (generalized for multi-request ragged batching case)
380  //one vector<InferInput*> per request
381  unsigned nEntriesVal = nEntries();
382  std::vector<std::vector<triton::client::InferInput*>> inputsTriton(nEntriesVal);
383  for (auto& inputTriton : inputsTriton) {
384  inputTriton.reserve(input_.size());
385  }
386  for (auto& [iname, input] : input_) {
387  for (unsigned i = 0; i < nEntriesVal; ++i) {
388  inputsTriton[i].push_back(input.data(i));
389  }
390  }
391 
392  //set up output pointers similarly
393  std::vector<std::vector<const triton::client::InferRequestedOutput*>> outputsTriton(nEntriesVal);
394  for (auto& outputTriton : outputsTriton) {
395  outputTriton.reserve(output_.size());
396  }
397  for (auto& [oname, output] : output_) {
398  for (unsigned i = 0; i < nEntriesVal; ++i) {
399  outputsTriton[i].push_back(output.data(i));
400  }
401  }
402 
403  //set up shared memory for output
404  auto success = handle_exception([&]() {
405  for (auto& element : output_) {
406  element.second.prepare();
407  }
408  });
409  if (!success)
410  return;
411 
412  // Get the status of the server prior to the request being made.
413  inference::ModelStatistics start_status;
414  success = handle_exception([&]() {
415  if (verbose())
416  start_status = getServerSideStatus();
417  });
418  if (!success)
419  return;
420 
421  if (mode_ == SonicMode::Async) {
422  //non-blocking call
423  success = handle_exception([&]() {
424  TRITON_THROW_IF_ERROR(client_->AsyncInferMulti(
425  [start_status, this](std::vector<tc::InferResult*> resultsTmp) {
426  //immediately convert to shared_ptr
427  const auto& results = convertToShared(resultsTmp);
428  //check results
429  for (auto ptr : results) {
430  auto success = handle_exception([&]() {
431  TRITON_THROW_IF_ERROR(
432  ptr->RequestStatus(), "evaluate(): unable to get result(s)", isLocal_);
433  });
434  if (!success)
435  return;
436  }
437 
438  if (verbose()) {
439  inference::ModelStatistics end_status;
440  auto success = handle_exception([&]() { end_status = getServerSideStatus(); });
441  if (!success)
442  return;
443 
444  const auto& stats = summarizeServerStats(start_status, end_status);
446  }
447 
448  //check result
449  auto success = handle_exception([&]() { getResults(results); });
450  if (!success)
451  return;
452 
453  //finish
454  finish(true);
455  },
456  options_,
457  inputsTriton,
458  outputsTriton,
459  headers_,
461  "evaluate(): unable to launch async run",
462  isLocal_);
463  });
464  if (!success)
465  return;
466  } else {
467  //blocking call
468  std::vector<tc::InferResult*> resultsTmp;
469  success = handle_exception([&]() {
471  client_->InferMulti(&resultsTmp, options_, inputsTriton, outputsTriton, headers_, compressionAlgo_),
472  "evaluate(): unable to run and/or get result",
473  isLocal_);
474  });
475  //immediately convert to shared_ptr
476  const auto& results = convertToShared(resultsTmp);
477  if (!success)
478  return;
479 
480  if (verbose()) {
481  inference::ModelStatistics end_status;
482  success = handle_exception([&]() { end_status = getServerSideStatus(); });
483  if (!success)
484  return;
485 
486  const auto& stats = summarizeServerStats(start_status, end_status);
487  reportServerSideStats(stats);
488  }
489 
490  success = handle_exception([&]() { getResults(results); });
491  if (!success)
492  return;
493 
494  finish(true);
495  }
496 }
497 
499  std::stringstream msg;
500 
501  // https://github.com/triton-inference-server/server/blob/v2.3.0/src/clients/c++/perf_client/inference_profiler.cc
502  const uint64_t count = stats.success_count_;
503  msg << " Inference count: " << stats.inference_count_ << "\n";
504  msg << " Execution count: " << stats.execution_count_ << "\n";
505  msg << " Successful request count: " << count << "\n";
506 
507  if (count > 0) {
508  auto get_avg_us = [count](uint64_t tval) {
509  constexpr uint64_t us_to_ns = 1000;
510  return tval / us_to_ns / count;
511  };
512 
513  const uint64_t cumm_avg_us = get_avg_us(stats.cumm_time_ns_);
514  const uint64_t queue_avg_us = get_avg_us(stats.queue_time_ns_);
515  const uint64_t compute_input_avg_us = get_avg_us(stats.compute_input_time_ns_);
516  const uint64_t compute_infer_avg_us = get_avg_us(stats.compute_infer_time_ns_);
517  const uint64_t compute_output_avg_us = get_avg_us(stats.compute_output_time_ns_);
518  const uint64_t compute_avg_us = compute_input_avg_us + compute_infer_avg_us + compute_output_avg_us;
519  const uint64_t overhead =
520  (cumm_avg_us > queue_avg_us + compute_avg_us) ? (cumm_avg_us - queue_avg_us - compute_avg_us) : 0;
521 
522  msg << " Avg request latency: " << cumm_avg_us << " usec"
523  << "\n"
524  << " (overhead " << overhead << " usec + "
525  << "queue " << queue_avg_us << " usec + "
526  << "compute input " << compute_input_avg_us << " usec + "
527  << "compute infer " << compute_infer_avg_us << " usec + "
528  << "compute output " << compute_output_avg_us << " usec)" << std::endl;
529  }
530 
531  if (!debugName_.empty())
532  edm::LogInfo(fullDebugName_) << msg.str();
533 }
534 
535 TritonClient::ServerSideStats TritonClient::summarizeServerStats(const inference::ModelStatistics& start_status,
536  const inference::ModelStatistics& end_status) const {
537  TritonClient::ServerSideStats server_stats;
538 
539  server_stats.inference_count_ = end_status.inference_count() - start_status.inference_count();
540  server_stats.execution_count_ = end_status.execution_count() - start_status.execution_count();
541  server_stats.success_count_ =
542  end_status.inference_stats().success().count() - start_status.inference_stats().success().count();
543  server_stats.cumm_time_ns_ =
544  end_status.inference_stats().success().ns() - start_status.inference_stats().success().ns();
545  server_stats.queue_time_ns_ = end_status.inference_stats().queue().ns() - start_status.inference_stats().queue().ns();
546  server_stats.compute_input_time_ns_ =
547  end_status.inference_stats().compute_input().ns() - start_status.inference_stats().compute_input().ns();
548  server_stats.compute_infer_time_ns_ =
549  end_status.inference_stats().compute_infer().ns() - start_status.inference_stats().compute_infer().ns();
550  server_stats.compute_output_time_ns_ =
551  end_status.inference_stats().compute_output().ns() - start_status.inference_stats().compute_output().ns();
552 
553  return server_stats;
554 }
555 
556 inference::ModelStatistics TritonClient::getServerSideStatus() const {
557  if (verbose_) {
558  inference::ModelStatisticsResponse resp;
559  TRITON_THROW_IF_ERROR(client_->ModelInferenceStatistics(&resp, options_[0].model_name_, options_[0].model_version_),
560  "getServerSideStatus(): unable to get model statistics",
561  isLocal_);
562  return *(resp.model_stats().begin());
563  }
564  return inference::ModelStatistics{};
565 }
566 
567 //for fillDescriptions
569  edm::ParameterSetDescription descClient;
570  fillBasePSetDescription(descClient);
571  descClient.add<std::string>("modelName");
572  descClient.add<std::string>("modelVersion", "");
573  descClient.add<edm::FileInPath>("modelConfigPath");
574  //server parameters should not affect the physics results
575  descClient.addUntracked<std::string>("preferredServer", "");
576  descClient.addUntracked<unsigned>("timeout");
577  descClient.ifValue(edm::ParameterDescription<std::string>("timeoutUnit", "seconds", false),
578  edm::allowedValues<std::string>("seconds", "milliseconds", "microseconds"));
579  descClient.addUntracked<bool>("useSharedMemory", true);
580  descClient.addUntracked<std::string>("compression", "");
581  descClient.addUntracked<std::vector<std::string>>("outputs", {});
582  iDesc.add<edm::ParameterSetDescription>("Client", descClient);
583 }
bool verbose() const
Definition: TritonClient.h:43
ParameterDescriptionNode * ifValue(ParameterDescription< T > const &switchParameter, std::unique_ptr< ParameterDescriptionCases< T >> cases)
void getResults(const std::vector< std::shared_ptr< triton::client::InferResult >> &results)
const std::string & pid() const
#define CMS_SA_ALLOW
unsigned maxOuterDim_
Definition: TritonClient.h:73
bool setBatchSize(unsigned bsize)
bool noOuterDim_
Definition: TritonClient.h:75
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
~TritonClient() override
void notifyCallStatus(bool status) const
void addEntry(unsigned entry)
bool verbose
bool manualBatchMode_
Definition: TritonClient.h:78
TritonBatchMode batchMode() const
Definition: TritonClient.h:42
void setMode(SonicMode mode)
std::unique_ptr< triton::client::InferenceServerGrpcClient > client_
Definition: TritonClient.h:86
TritonClient(const edm::ParameterSet &params, const std::string &debugName)
Definition: TritonClient.cc:56
std::string debugName_
void finish(bool success, std::exception_ptr eptr=std::exception_ptr{})
ServerSideStats summarizeServerStats(const inference::ModelStatistics &start_status, const inference::ModelStatistics &end_status) const
TritonBatchMode
Definition: TritonClient.h:19
void resetBatchMode()
TritonServerType serverType_
Definition: TritonClient.h:81
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
bool handle_exception(F &&call)
key
prepare the HTCondor submission files and eventually submit them
grpc_compression_algorithm compressionAlgo_
Definition: TritonClient.h:83
#define TRITON_THROW_IF_ERROR(X, MSG, NOTIFY)
Definition: triton_utils.h:78
ParameterDescriptionBase * add(U const &iLabel, T const &value)
static void fillBasePSetDescription(edm::ParameterSetDescription &desc, bool allowRetry=true)
void resizeEntries(unsigned entry)
inference::ModelStatistics getServerSideStatus() const
Log< level::Info, false > LogInfo
triton::client::Headers headers_
Definition: TritonClient.h:84
unsigned nEntries() const
void conversion(EventAux const &from, EventAuxiliary &to)
Definition: EventAux.cc:9
unsigned long long uint64_t
Definition: Time.h:13
tuple msg
Definition: mps_check.py:286
unsigned outerDim_
Definition: TritonClient.h:74
unsigned batchSize() const
void evaluate() override
void setBatchMode(TritonBatchMode batchMode)
Server serverInfo(const std::string &model, const std::string &preferred="") const
double a
Definition: hdecay.h:121
void reportServerSideStats(const ServerSideStats &stats) const
void reset() override
std::string fullDebugName_
results
Definition: mysort.py:8
const std::string & fullPath() const
Definition: FileInPath.cc:144
Definition: output.py:1
static void fillPSetDescription(edm::ParameterSetDescription &iDesc)
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:163
TritonBatchMode batchMode_
Definition: TritonClient.h:77
std::string printColl(const C &coll, const std::string &delim=", ")
Definition: triton_utils.cc:10
tmp
align.sh
Definition: createJobs.py:716
std::vector< triton::client::InferOptions > options_
Definition: TritonClient.h:88
if(threadIdxLocalY==0 &&threadIdxLocalX==0)
Definition: server.py:1
unsigned transform(const HcalDetId &id, unsigned transformCode)