apache / mxnet

Lightweight, Portable, Flexible Distributed/Mobile Deep Learning with Dynamic, Mutation-aware Dataflow Dep Scheduler; for Python, R, Julia, Scala, Go, Javascript and more
https://mxnet.apache.org
Apache License 2.0
20.79k stars 6.79k forks source link

TensorRT does not work on other GPUs except GPU0 #17855

Open SayHiRay opened 4 years ago

SayHiRay commented 4 years ago

Description

I followed this official tutorial to perform inference with TensorRT. It works fine when I bind the model on GPU0. However, it reports engine.cpp (212) - Cudnn Error in configure: 7 (CUDNN_STATUS_MAPPING_ERROR) error when I run the model on GPU1. Although an output is still given after the inference is done, the value of the output consists of all zeros and is different from the one run on GPU0.

Error Message

[2020-03-17 12:36:39 ERROR] engine.cpp (212) - Cudnn Error in configure: 7 (CUDNN_STATUS_MAPPING_ERROR) [2020-03-17 12:36:39 ERROR] engine.cpp (212) - Cudnn Error in configure: 7 (CUDNN_STATUS_MAPPING_ERROR)

To Reproduce

In my case I can use the example below to reproduce the error:

import mxnet as mx
from mxnet.gluon.model_zoo import vision
import os

ctx = mx.gpu(1)
batch_shape = (1, 3, 224, 224)
resnet18 = vision.resnet18_v2(pretrained=True)
resnet18.hybridize()
resnet18.forward(mx.nd.zeros(batch_shape))
resnet18.export('resnet18_v2')
sym, arg_params, aux_params = mx.model.load_checkpoint('resnet18_v2', 0)

trt_sym = sym.get_backend_symbol('TensorRT')
arg_params, aux_params = mx.contrib.tensorrt.init_tensorrt_params(trt_sym, arg_params, aux_params)

executor = trt_sym.simple_bind(ctx=ctx, data=batch_shape,
                               grad_req='null')

inp = mx.nd.zeros(batch_shape)
y_gen = executor.forward(is_train=False, data=inp)
print(y_gen)

What have you tried to solve it?

I tried to check GPU usage using nvidia-smi when running the python script above. It seems that Both GPU1 and GPU0 are used during the process. Looks like some operators are still allocated in GPU0 (especially the TensorRT0 Op).

Environment

We recommend using our script for collecting the diagnositc information. Run the following command and paste the outputs below:

curl --retry 10 -s https://raw.githubusercontent.com/dmlc/gluon-nlp/master/tools/diagnose.py | python

----------Python Info----------
Version      : 3.7.3
Compiler     : GCC 7.3.0
Build        : ('default', 'Mar 27 2019 22:11:17')
Arch         : ('64bit', '')
------------Pip Info-----------
Version      : 19.0.3
Directory    : /data/yangruizhi/anaconda3/lib/python3.7/site-packages/pip
----------MXNet Info-----------
Version      : 2.0.0
Directory    : /data/yangruizhi/mxnet/python/mxnet
Num GPUs     : 4
Hashtag not found. Not installed from pre-built package.
----------System Info----------
Platform     : Linux-4.9.70-040970-generic-x86_64-with-debian-stretch-sid
system       : Linux
node         : jja-gpu154
release      : 4.9.70-040970-generic
version      : #201712161132 SMP Sat Dec 16 16:33:52 UTC 2017
----------Hardware Info----------
machine      : x86_64
processor    : x86_64
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                32
On-line CPU(s) list:   0-31
Thread(s) per core:    2
Core(s) per socket:    8
Socket(s):             2
NUMA node(s):          2
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 85
Model name:            Intel(R) Xeon(R) Silver 4110 CPU @ 2.10GHz
Stepping:              4
CPU MHz:               2101.000
CPU max MHz:           2101.0000
CPU min MHz:           800.0000
BogoMIPS:              4201.52
Virtualization:        VT-x
L1d cache:             32K
L1i cache:             32K
L2 cache:              1024K
L3 cache:              11264K
NUMA node0 CPU(s):     0-7,16-23
NUMA node1 CPU(s):     8-15,24-31
Flags:                 fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch epb intel_pt tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm cqm mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local dtherm ida arat pln pts pku ospke
----------Network Test----------
Setting timeout: 10
Timing for MXNet: https://github.com/apache/incubator-mxnet, DNS: 0.0144 sec, LOAD: 1.2143 sec.
Timing for GluonNLP GitHub: https://github.com/dmlc/gluon-nlp, DNS: 0.0004 sec, LOAD: 1.0289 sec.
Timing for GluonNLP: http://gluon-nlp.mxnet.io, DNS: 0.0005 sec, LOAD: 0.0264 sec.
Timing for D2L: http://d2l.ai, DNS: 0.0004 sec, LOAD: 0.0120 sec.
Timing for D2L (zh-cn): http://zh.d2l.ai, DNS: 0.0002 sec, LOAD: 0.0466 sec.
Timing for FashionMNIST: https://repo.mxnet.io/gluon/dataset/fashion-mnist/train-labels-idx1-ubyte.gz, DNS: 0.0002 sec, LOAD: 0.6016 sec.
Timing for PYPI: https://pypi.python.org/pypi/pip, DNS: 0.0045 sec, LOAD: 0.0767 sec.
Timing for Conda: https://repo.continuum.io/pkgs/free/, DNS: 0.0003 sec, LOAD: 0.0386 sec.
SayHiRay commented 4 years ago

Would really appreciate it if you could take a look at this. Thanks a ton for your time! @KellenSunderland @marcoabreu @Caenorst

TristonC commented 4 years ago

It seems the onnx-trt not setting the device properly. @SayHiRay If you accept a dirty workaround try replace ctx = mx.gpu(1) with these:

from ctypes import cdll, c_char_p
libcudart = cdll.LoadLibrary('libcudart.so')
libcudart.cudaGetErrorString.restype = c_char_p
def cudaSetDevice(device_idx):
    ret = libcudart.cudaSetDevice(device_idx)
    if ret != 0:
        error_string = libcudart.cudaGetErrorString(ret)
        raise RuntimeError("cudaSetDevice: " + error_string)

device_id = 1
cudaSetDevice(device_id)
ctx = mx.gpu(device_id)
TristonC commented 4 years ago

@Caenorst Looks like the TRTCreateState function in src/operator/subgraph/tensorrt/tensorrt.cc file not passing the ctx to the TRT. Add

CUDA_CALL(cudaSetDevice(ctx.dev_id));

to the top of this function will fix this issue, but not sure it is a good fix.

SayHiRay commented 4 years ago

It seems the onnx-trt not setting the device properly. @SayHiRay If you accept a dirty workaround try replace ctx = mx.gpu(1) with these:

from ctypes import cdll, c_char_p
libcudart = cdll.LoadLibrary('libcudart.so')
libcudart.cudaGetErrorString.restype = c_char_p
def cudaSetDevice(device_idx):
    ret = libcudart.cudaSetDevice(device_idx)
    if ret != 0:
        error_string = libcudart.cudaGetErrorString(ret)
        raise RuntimeError("cudaSetDevice: " + error_string)

device_id = 1
cudaSetDevice(device_id)
ctx = mx.gpu(device_id)

@TristonC Thanks for the workaround. It works great!