Skip to content

Cannot run TensorRT session on another thread on a device other than the default one (0) #16274

Description

@JulienTheron

Describe the issue

Running a TensorRT session on device 1 works as long as you're using the same thread that created the session.
When running the session on another thread, the following errors occur:

2023-06-07 16:46:47.2457468 [E:onnxruntime:, tensorrt_execution_provider.h:73 onnxruntime::TensorrtLogger::log] [2023-06-07 20:46:47   ERROR] 1: [eltwise.cu::cuEltwise::dispatchOp::423] Error Code 1: Cuda Runtime (invalid resource handle)
2023-06-07 16:46:47.2492417 [E:onnxruntime:, sequential_executor.cc:514 onnxruntime::ExecuteKernel] Non-zero status code returned while running TRTKernel_graph_Model Name_5506887977754746303_0 node. Name:'TensorrtExecutionProvider_TRTKernel_graph_Model Name_5506887977754746303_0_0' Status Message: TensorRT EP execution context enqueue failed.

Using the CUDA EP instead works as expected, so this is something specific to the TensorRT EP.
This issue happens on ORT 1.14.1 and 1.15.0 (other versions untested).

To reproduce

Run this code on a machine which has at least 2 CUDA devices.
I included a simple model created in Python that adds two tensors.
Usage: model.onnx

#include <future>
#include <vector>

#include "onnxruntime_cxx_api.h"

using namespace Ort;
using namespace std;

int wmain(int argc, wchar_t* argv[])
{
  if (argc < 2)
    return -1;

  const int deviceId = 1;

  Env env;
  SessionOptions sessionOptions;
  OrtTensorRTProviderOptions tensorrtOptions = { .device_id = deviceId };
  sessionOptions.AppendExecutionProvider_TensorRT(tensorrtOptions);

  Session session(env, argv[1], sessionOptions);

  const vector<int64_t> shape { 1, 2, 2, 3 };

  vector inputBuffer1(12, 1.0f);
  vector inputBuffer2(12, 2.0f);

  auto memInfo = MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault);

  const char* inputNames[] = { "input1", "input2" };
  const Value inputValues[] =
  {
    Value::CreateTensor(memInfo, inputBuffer1.data(), inputBuffer1.size(), shape.data(), shape.size()),
    Value::CreateTensor(memInfo, inputBuffer2.data(), inputBuffer2.size(), shape.data(), shape.size())
  };

  const char* outputNames[] = { "output" };
  vector<float> outputBuffer(12);
  Value outputValues[] =
  {
    Value::CreateTensor(memInfo, outputBuffer.data(), outputBuffer.size(), shape.data(), shape.size())
  };

  auto fut = async(launch::async, [&]
  {
    session.Run(RunOptions(), inputNames, inputValues, size(inputNames), outputNames, outputValues, size(outputNames));
  });

  fut.get();

  return 0;
}

model.zip

Urgency

The workaround is to call cudaSetDevice(1) before session.Run. This is not ideal as the ONNX Runtime is supposed to hide these kind of implementation details to the user.

Platform

Windows

OS Version

22621.1702

ONNX Runtime Installation

Released Package

ONNX Runtime Version or Commit ID

Microsoft.ML.OnnxRuntime.Gpu 1.15.0

ONNX Runtime API

C++

Architecture

X64

Execution Provider

TensorRT

Execution Provider Library Version

TensorRT 8.6.1 CUDA 11.8 cuDNN 8.9.0

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    ep:CUDAissues related to the CUDA execution providerep:TensorRTissues related to TensorRT execution providerplatform:windowsissues related to the Windows platform

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions