257 if (TRITONSERVER_LogIsEnabled(TRITONSERVER_LOG_VERBOSE)) {
258 common::TritonJson::WriteBuffer buffer;
259 RETURN_IF_ERROR(ModelConfig().PrettyWrite(&buffer));
261 TRITONSERVER_LOG_VERBOSE,
262 (std::string(
"model configuration:\n") + buffer.Contents()).c_str());
268 common::TritonJson::Value inputs, outputs;
269 RETURN_IF_ERROR(ModelConfig().MemberAsArray(
"input", &inputs));
270 RETURN_IF_ERROR(ModelConfig().MemberAsArray(
"output", &outputs));
274 RETURN_ERROR_IF_FALSE(
275 inputs.ArraySize() == 2, TRITONSERVER_ERROR_INVALID_ARG,
276 std::string(
"model configuration must have 2 inputs"));
277 RETURN_ERROR_IF_FALSE(
278 outputs.ArraySize() ==
outputNames.size(), TRITONSERVER_ERROR_INVALID_ARG,
279 std::string(
"model configuration must have ") +
284 common::TritonJson::Value input_cells;
285 RETURN_IF_ERROR(inputs.IndexAsObject(0, &input_cells));
288 const char *input_cells_name;
289 size_t input_cells_len;
290 RETURN_IF_ERROR(input_cells.MemberAsString(
"name", &input_cells_name, &input_cells_len));
298 LOG_MESSAGE(TRITONSERVER_LOG_INFO,
299 (std::string(
"'traccc' backend: input tensor is '") +
303 std::string input_cells_dtype;
304 RETURN_IF_ERROR(input_cells.MemberAsString(
"data_type", &input_cells_dtype));
311 std::set<std::string> configured_outputs;
312 for (
size_t i = 0; i < outputs.ArraySize(); ++i) {
313 common::TritonJson::Value output;
314 RETURN_IF_ERROR(outputs.IndexAsObject(i, &output));
315 const char *output_name;
316 size_t output_name_len;
318 output.MemberAsString(
"name", &output_name, &output_name_len));
319 configured_outputs.emplace(output_name, output_name_len);
322 RETURN_ERROR_IF_FALSE(
323 configured_outputs.count(expected) == 1, TRITONSERVER_ERROR_INVALID_ARG,
324 std::string(
"model configuration is missing output '") + expected +
"'");
330 common::TritonJson::Value instance_groups;
331 if (ModelConfig().Find(
"instance_group", &instance_groups)) {
332 for (
size_t i = 0; i < instance_groups.ArraySize(); ++i) {
333 common::TritonJson::Value group;
334 RETURN_IF_ERROR(instance_groups.IndexAsObject(i, &group));
337 if (group.Find(
"count")) {
338 RETURN_IF_ERROR(group.MemberAsInt(
"count", &
count));
340 RETURN_ERROR_IF_FALSE(
341 count >= 0, TRITONSERVER_ERROR_INVALID_ARG,
342 std::string(
"instance_group count must not be negative"));
345 common::TritonJson::Value gpus;
346 if (group.Find(
"gpus", &gpus) && gpus.ArraySize() > 0) {
347 devices = gpus.ArraySize();
358 LOG_MESSAGE(TRITONSERVER_LOG_INFO,
359 (std::string(
"'traccc' backend: model configured with ") +
361 " instance(s), one event slot each").c_str());
558 TRITONBACKEND_ModelInstance*
instance, TRITONBACKEND_Request** requests,
559 const uint32_t request_count)
565 uint64_t exec_start_ns = 0;
566 SET_TIMESTAMP(exec_start_ns);
576 RETURN_IF_ERROR(TRITONBACKEND_ModelInstanceState(
577 instance,
reinterpret_cast<void**
>(&instance_state)));
583 cudaError_t err = cudaSetDevice(instance_state->DeviceId());
584 if (err != cudaSuccess)
586 return TRITONSERVER_ErrorNew(
587 TRITONSERVER_ERROR_INTERNAL,
588 (
"Failed to set CUDA device: " + std::string(cudaGetErrorString(err))).c_str());
602 std::vector<TRITONBACKEND_Response*> responses;
603 responses.reserve(request_count);
604 for (uint32_t
r = 0;
r < request_count; ++
r) {
605 TRITONBACKEND_Request* request = requests[
r];
607 RETURN_IF_ERROR(TRITONBACKEND_ResponseNew(&
response, request));
658 bool all_inputs_present =
true;
659 for (uint32_t
r = 0;
r < request_count; ++
r) {
660 for (
const std::string& name :
662 TRITONBACKEND_Input* input =
nullptr;
663 TRITONSERVER_Error* input_err =
664 TRITONBACKEND_RequestInput(requests[
r], name.c_str(), &input);
665 if (input_err !=
nullptr) {
666 all_inputs_present =
false;
667 RESPOND_AND_SET_NULL_IF_ERROR(&responses[
r], input_err);
673 BackendInputCollector collector(
674 requests, request_count, &responses, model_state->TritonMemoryManager(),
681 std::vector<std::pair<TRITONSERVER_MemoryType, int64_t>> allowed_input_types =
682 {{TRITONSERVER_MEMORY_CPU_PINNED, 0}, {TRITONSERVER_MEMORY_CPU, 0}};
684 const char *input_cells_buffer =
nullptr;
685 size_t input_cells_buffer_byte_size = 0;
686 TRITONSERVER_MemoryType input_cells_buffer_memory_type;
687 int64_t input_cells_buffer_memory_type_id;
689 const char *input_iov_buffer =
nullptr;
690 size_t input_iov_buffer_byte_size = 0;
691 TRITONSERVER_MemoryType input_iov_buffer_memory_type;
692 int64_t input_iov_buffer_memory_type_id;
694 if (all_inputs_present)
696 RESPOND_ALL_AND_SET_NULL_IF_ERROR(
697 responses, request_count,
698 collector.ProcessTensor(
700 0 , allowed_input_types, &input_cells_buffer,
701 &input_cells_buffer_byte_size, &input_cells_buffer_memory_type,
702 &input_cells_buffer_memory_type_id));
703 RESPOND_ALL_AND_SET_NULL_IF_ERROR(
704 responses, request_count,
705 collector.ProcessTensor(
707 0 , allowed_input_types, &input_iov_buffer,
708 &input_iov_buffer_byte_size, &input_iov_buffer_memory_type,
709 &input_iov_buffer_memory_type_id));
716 const bool need_cuda_input_sync = collector.Finalize();
717 if (need_cuda_input_sync)
720 TRITONSERVER_LOG_ERROR,
721 "'Traccc' backend: unexpected CUDA sync required by collector");
725 bool print_stats =
true;
731 uint64_t compute_start_ns = 0;
732 SET_TIMESTAMP(compute_start_ns);
735 bool run_succeeded =
false;
738 if (!all_inputs_present) {
739 throw std::runtime_error(
740 "request is missing the '" +
745 std::array<int64_t, iovSize> iov;
746 if (input_iov_buffer_byte_size !=
sizeof(iov)) {
747 throw std::runtime_error(
"'" +
iovInputName +
"' has the wrong size");
749 std::memcpy(iov.data(), input_iov_buffer,
sizeof(iov));
750 using number_type = EventIDBase::number_type;
751 const EventIDBase eventID(
752 static_cast<number_type
>(iov[0]), EventIDBase::UNDEFEVT,
753 static_cast<number_type
>(iov[2]),
static_cast<number_type
>(iov[3]),
754 static_cast<number_type
>(iov[1]));
756 reinterpret_cast<const uint8_t*
>(input_cells_buffer),
757 input_cells_buffer_byte_size, eventID,
758 static_cast<number_type
>(iov[4]), print_stats, traccc_result);
759 run_succeeded =
true;
761 catch (
const std::exception& e)
763 RESPOND_ALL_AND_SET_NULL_IF_ERROR(
764 responses, request_count,
765 TRITONSERVER_ErrorNew(TRITONSERVER_ERROR_INTERNAL, e.what()));
768 uint64_t compute_end_ns = 0;
769 SET_TIMESTAMP(compute_end_ns);
771 bool supports_first_dim_batching;
772 RESPOND_ALL_AND_SET_NULL_IF_ERROR(
773 responses, request_count,
774 model_state->SupportsFirstDimBatching(&supports_first_dim_batching));
784 BackendOutputResponder responder(
785 requests, request_count, &responses, model_state->TritonMemoryManager(),
786 supports_first_dim_batching,
false ,
789 auto output_proc_start = std::chrono::high_resolution_clock::now();
792 std::vector<std::vector<std::uint8_t>> output_bytes;
802 const auto sendCollection = [&](
const std::string& name,
803 const auto& collection) {
804 std::vector<std::uint8_t>& bytes = output_bytes.emplace_back();
806 std::vector<int64_t> shape = {
807 static_cast<int64_t
>(bytes.size())};
808 responder.ProcessTensor(
809 name.c_str(), TRITONSERVER_TYPE_UINT8, shape,
810 reinterpret_cast<const char*
>(bytes.data()),
811 TRITONSERVER_MEMORY_CPU, 0);
813 sendCollection(
"MEASUREMENTS", traccc_result.
measurements);
814 sendCollection(
"CLUSTERS", traccc_result.
clusters);
815 sendCollection(
"TRACKS", traccc_result.
tracks.tracks);
816 sendCollection(
"TRACK_STATES", traccc_result.
tracks.states);
821 auto output_proc_end = std::chrono::high_resolution_clock::now();
822 std::cout <<
"[TIMING] Output processing: "
823 << std::chrono::duration_cast<std::chrono::milliseconds>(
824 output_proc_end - output_proc_start).count()
825 <<
" ms" << std::endl;
834 const bool need_cuda_output_sync = responder.Finalize();
835 if (need_cuda_output_sync) {
837 TRITONSERVER_LOG_ERROR,
838 "'traccc' backend: unexpected CUDA sync required by responder");
846 TRITONBACKEND_ResponseSend(
847 response, TRITONSERVER_RESPONSE_COMPLETE_FINAL,
nullptr),
848 "failed to send response");
852 uint64_t exec_end_ns = 0;
853 SET_TIMESTAMP(exec_end_ns);
855#ifdef TRITON_ENABLE_STATS
860 size_t total_batch_size = 0;
861 if (!supports_first_dim_batching) {
862 total_batch_size = request_count;
864 for (uint32_t
r = 0;
r < request_count; ++
r)
866 auto& request = requests[
r];
867 TRITONBACKEND_Input* input =
nullptr;
869 TRITONBACKEND_RequestInputByIndex(request, 0 , &input),
870 "failed getting request input");
871 if (input !=
nullptr)
873 const int64_t* shape =
nullptr;
875 TRITONBACKEND_InputProperties(
876 input,
nullptr,
nullptr, &shape,
nullptr,
nullptr,
nullptr),
877 "failed getting input properties");
878 if (shape !=
nullptr)
880 total_batch_size += shape[0];
888 (void)compute_start_ns;
889 (void)compute_end_ns;
893for (uint32_t
r = 0;
r < request_count; ++
r)
895 auto& request = requests[
r];
897 #ifdef TRITON_ENABLE_STATS
899 TRITONBACKEND_ModelInstanceReportStatistics(
900 instance_state->TritonModelInstance(), request,
901 (responses[
r] !=
nullptr) , exec_start_ns,
902 compute_start_ns, compute_end_ns, exec_end_ns),
903 "failed reporting request statistics");
907 TRITONBACKEND_RequestRelease(request, TRITONSERVER_REQUEST_RELEASE_ALL),
908 "failed releasing request");
911#ifdef TRITON_ENABLE_STATS
914 TRITONBACKEND_ModelInstanceReportBatchStatistics(
915 instance_state->TritonModelInstance(), total_batch_size,
916 exec_start_ns, compute_start_ns, compute_end_ns, exec_end_ns),
917 "failed reporting batch request statistics");