11#include <grpc_client.h>
12#include <grpc_service.pb.h>
23namespace tc = triton::client;
26#define TRITON_CHECK(EXP) \
28 const tc::Error err = EXP; \
30 ATH_MSG_ERROR("Failed to execute: " << #EXP \
33 return StatusCode::FAILURE; \
44 static constexpr const char*
value =
"FP32";
48 static constexpr const char*
value =
"INT64";
52 static constexpr const char*
value =
"UINT8";
60 StatusCode
getClient(tc::InferenceServerGrpcClient*& client,
61 const std::string& url,
int port,
bool useSSL)
const {
63 thread_local std::unique_ptr<tc::InferenceServerGrpcClient> threadClient;
66 const std::string urlAndPort =
67 url +
":" + std::to_string(port);
71 &threadClient, urlAndPort,
verbose, useSSL));
73 ATH_MSG_INFO(
"Triton client created for url: " << urlAndPort);
75 client = threadClient.get();
77 return StatusCode::SUCCESS;
82 tc::Headers httpHeaders;
85 client.IsServerLive(&live, httpHeaders,
m_options->client_timeout_);
90 return tc::Error(
"Triton server is not live");
93 bool serverReady =
false;
94 err = client.IsServerReady(&serverReady, httpHeaders,
100 return tc::Error(
"Triton server is not ready");
103 bool modelReady =
false;
104 err = client.IsModelReady(&modelReady,
m_options->model_name_,
111 return tc::Error(
"Triton model " +
m_options->model_name_ +
" is not ready");
114 return tc::Error::Success;
118 retryDelayMs *= (1 << attempt);
119 if (retryDelayMs > 0) {
120 std::this_thread::sleep_for(std::chrono::milliseconds(retryDelayMs));
125 tc::InferenceServerGrpcClient& client,
126 const std::vector<tc::InferInput*>& rawInputs,
127 const int maxRetries,
const int retryDelayMs,
128 std::shared_ptr<tc::InferResult>& results)
const {
130 tc::Headers httpHeaders;
131 grpc_compression_algorithm compressionAlgorithm =
132 grpc_compression_algorithm::GRPC_COMPRESS_NONE;
135 for (
int attempt = 0; attempt <= maxRetries; ++attempt) {
137 tc::InferResult* rawResultPtr =
nullptr;
138 err = client.Infer(&rawResultPtr, *
m_options, rawInputs, {},
139 httpHeaders, compressionAlgorithm);
140 if (err.IsOk() && rawResultPtr !=
nullptr) {
141 results.reset(rawResultPtr);
142 err = results->RequestStatus();
143 }
else if (err.IsOk()) {
144 err = tc::Error(
"Triton synchronous inference returned no result");
147 using Promise_t = boost::fibers::promise<tc::InferResult*>;
148 using Future_t = boost::fibers::future<tc::InferResult*>;
150 Future_t future = promise.get_future();
151 auto callback = [&promise](tc::InferResult* resultPtr) {
152 promise.set_value(resultPtr);
154 err = client.AsyncInfer(callback, *
m_options, rawInputs, {},
155 httpHeaders, compressionAlgorithm);
157 results.reset(future.get());
159 if (results !=
nullptr) {
160 err = results->RequestStatus();
162 err = tc::Error(
"Triton asynchronous inference returned no "
169 return StatusCode::SUCCESS;
172 if (attempt == maxRetries) {
173 ATH_MSG_ERROR(
"Triton inference failed after " << (attempt + 1)
176 return StatusCode::FAILURE;
180 <<
" failed: " << err
185 return StatusCode::FAILURE;
188 template <
typename T>
190 const std::string& name,
const std::vector<int64_t>& shape,
191 const std::vector<T>& data,
192 std::vector<std::unique_ptr<tc::InferInput>>& inputs)
const {
195 tc::InferInput* rawInputPtr =
nullptr;
199 TRITON_CHECK(tc::InferInput::Create(&rawInputPtr, name, shape, dtype));
200 assert(rawInputPtr !=
nullptr);
208 std::unique_ptr<tc::InferInput> input{rawInputPtr};
209 TRITON_CHECK(input->AppendRaw(
reinterpret_cast<const uint8_t*
>(data.data()),
210 data.size() *
sizeof(T)));
212 inputs.push_back(std::move(input));
213 return StatusCode::SUCCESS;
216 template <
typename T>
218 const tc::InferResult& result,
219 std::vector<T>& outputVec)
const {
221 const uint8_t* rawData =
nullptr;
229 outputVec.resize(
size /
sizeof(T));
230 std::memcpy(outputVec.data(), rawData,
size);
231 return StatusCode::SUCCESS;
240 const IInterface* parent)
241 : base_class(
type, name, parent) {}
248 m_impl = std::make_unique<Impl>(name() +
"::Impl");
255 const IAlgTool* p =
dynamic_cast<const IAlgTool*
>(
this);
258 const IInterface* myParent =
nullptr;
259 while (p !=
nullptr) {
260 myParent = p->parent();
261 p =
dynamic_cast<const IAlgTool*
>(myParent);
265 m_impl->m_parentAsyncAlg =
267 if (
m_impl->m_parentAsyncAlg !=
nullptr) {
269 "Owned by an AthAsynchronousAlgorithm, using asynchronous inference");
272 "Not owned by an AthAsynchronousAlgorithm, not using asynchronous "
277 tc::InferenceServerGrpcClient* dummyClient =
nullptr;
281 tc::Error err =
m_impl->checkServerHealth(*dummyClient);
284 return StatusCode::FAILURE;
288 return StatusCode::SUCCESS;
298 std::vector<std::unique_ptr<tc::InferInput>> inputs;
299 inputs.reserve(inputData.size());
301 for (
auto& [inputName, inputInfo] : inputData) {
303 const std::vector<int64_t>& inputShape = inputInfo.first;
307 [&](
const auto& dataVec) {
308 using T = std::decay_t<
decltype(dataVec[0])>;
309 return m_impl->prepareInput<T>(inputName, inputShape, dataVec,
316 std::vector<tc::InferInput*> rawInputs;
317 for (
auto& input : inputs) {
318 rawInputs.push_back(input.get());
322 tc::InferenceServerGrpcClient* client =
nullptr;
324 assert(client !=
nullptr);
327 std::shared_ptr<tc::InferResult> results;
330 const int maxRetries = maxRetriesValue < 0 ? 0 : maxRetriesValue;
331 const int retryDelayMs = retryDelayMsValue < 0 ? 0 : retryDelayMsValue;
333 m_impl->runInference(*client, rawInputs, maxRetries, retryDelayMs,
335 assert(results !=
nullptr);
338 for (
auto& [outputName, outputInfo] : outputData) {
344 using T = std::decay_t<
decltype(dataVec[0])>;
345 return m_impl->extractOutput<T>(outputName, *results, dataVec);
351 return StatusCode::SUCCESS;
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
size_t size() const
Number of registered mappings.
An algorithm that can be suspended while work is offloaded to an accelerator.
AthMessaging(IMessageSvc *msgSvc, const std::string &name)
Constructor.
std::map< std::string, InferenceData > OutputDataMap
std::variant< std::vector< float >, std::vector< int64_t >, std::vector< uint8_t > > DataVariant
std::map< std::string, InferenceData > InputDataMap
static constexpr const char * value
static constexpr const char * value
static constexpr const char * value