Repository: pytorch
Issue: Model loaded in C++ runtime is not thread safe
Labels: module: cpp,triaged,module: sanitizers

WARNING: ThreadSanitizer: data race (pid=17) Read of size 8 at 0x7fd6718c2ea0 by thread T2:

```#0 std::__1::shared_ptr<at::CPUGenerator>::get() const external/clang/include/c++/v1/memory:3800:49 (libexternal_Spytorch_Slibaten.so+0x37dba2)
#1 at::detail::getDefaultCPUGenerator() external/pytorch/aten/src/ATen/CPUGenerator.cpp:27:26 (libexternal_Spytorch_Slibaten.so+0x37dba2)
#2 THFloatTensor_uniform external/pytorch/aten/src/TH/generic/THTensorRandom.cpp:81:73 (libexternal_Spytorch_Slibaten.so+0x1801ace)
#3 at::native::legacy::cpu::_th_uniform_(at::Tensor&, double, double, at::Generator*) bazel-out/k8-dbg-tsan/bin/external/pytorch/ATen/LegacyTHFunctionsCPU.cpp:9339:13 (libexternal_Spytorch_Slibaten.so+0x1a165cf)
#4 at::CPUType::(anonymous namespace)::uniform_(at::Tensor&, double, double, at::Generator*) bazel-out/k8-dbg-tsan/bin/external/pytorch/ATen/CPUType.cpp:2079:12 (libexternal_Spytorch_Slibaten.so+0x192487f)
#5 c10::detail::WrapRuntimeKernelFunctor_<at::Tensor& (*)(at::Tensor&, double, double, at::Generator*), at::Tensor&, c10::guts::typelist::typelist<at::Tensor&, double, double, at::Generator*> >::operator()(at::Tensor&, double, double, at::Generator*) external/pytorch/aten/src/ATen/core/boxing/kernel_lambda.h:23:14 (libexternal_Spytorch_Slibpytorch.so+0x1321734)
#6 c10::detail::wrap_kernel_functor_unboxed_<c10::detail::WrapRuntimeKernelFunctor_<at::Tensor& (*)(at::Tensor&, double, double, at::Generator*), at::Tensor&, c10::guts::typelist::typelist<at::Tensor&, double, double, at::Generator*> >, at::Tensor& (at::Tensor&, double, double, at::Generator*)>::call(c10::OperatorKernel*, at::Tensor&, double, double, at::Generator*) external/pytorch/aten/src/ATen/core/boxing/kernel_functor.h:262:14 (libexternal_Spytorch_Slibpytorch.so+0x1321734)
#7 at::Tensor& c10::KernelFunction::callUnboxed<at::Tensor&, at::Tensor&, double, double, at::Generator*>(c10::OperatorHandle const&, at::Tensor&, double, double, at::Generator*) const external/pytorch/aten/src/ATen/core/boxing/KernelFunction_impl.h:62:16 (libexternal_Spytorch_Slibpytorch.so+0x8d4c21)
#8 at::Tensor& c10::Dispatcher::callUnboxed<at::Tensor&, at::Tensor&, double, double, at::Generator*>(c10::OperatorHandle const&, at::Tensor&, double, double, at::Generator*) const external/pytorch/aten/src/ATen/core/dispatch/Dispatcher.h:179:26 (libexternal_Spytorch_Slibpytorch.so+0x954957)
#9 at::Tensor& c10::OperatorHandle::callUnboxed<at::Tensor&, at::Tensor&, double, double, at::Generator*>(at::Tensor&, double, double, at::Generator*) const external/pytorch/aten/src/ATen/core/dispatch/Dispatcher.h:154:41 (libexternal_Spytorch_Slibpytorch.so+0x954957)
#10 at::Tensor::uniform_(double, double, at::Generator*) const bazel-out/k8-dbg-tsan/bin/external/pytorch/ATen/core/TensorMethods.h:4653:15 (libexternal_Spytorch_Slibpytorch.so+0x954957)
#11 at::native::rand(c10::ArrayRef<long>, at::Generator*, c10::TensorOptions const&) external/pytorch/aten/src/ATen/native/TensorFactories.cpp:441:17 (libexternal_Spytorch_Slibaten.so+0x9155fb)
#12 at::native::rand(c10::ArrayRef<long>, c10::TensorOptions const&) external/pytorch/aten/src/ATen/native/TensorFactories.cpp:436:10 (libexternal_Spytorch_Slibaten.so+0x915572)
#13 at::TypeDefault::rand(c10::ArrayRef<long>, c10::TensorOptions const&) bazel-out/k8-dbg-tsan/bin/external/pytorch/ATen/TypeDefault.cpp:3284:12 (libexternal_Spytorch_Slibaten.so+0x1a80570)
#14 c10::detail::WrapRuntimeKernelFunctor_<at::Tensor (*)(c10::ArrayRef<long>, c10::TensorOptions const&), at::Tensor, c10::guts::typelist::typelist<c10::ArrayRef<long>, c10::TensorOptions const&> >::operator()(c10::ArrayRef<long>, c10::TensorOptions const&) external/pytorch/aten/src/ATen/core/boxing/kernel_lambda.h:23:14 (libexternal_Spytorch_Slibpytorch.so+0x132b8bd)
#15 c10::detail::wrap_kernel_functor_unboxed_<c10::detail::WrapRuntimeKernelFunctor_<at::Tensor (*)(c10::ArrayRef<long>, c10::TensorOptions const&), at::Tensor, c10::guts::typelist::typelist<c10::ArrayRef<long>, c10::TensorOptions const&> >, at::Tensor (c10::ArrayRef<long>, c10::TensorOptions const&)>::call(c10::OperatorKernel*, c10::ArrayRef<long>, c10::TensorOptions const&) external/pytorch/aten/src/ATen/core/boxing/kernel_functor.h:262:14 (libexternal_Spytorch_Slibpytorch.so+0x132b8bd)
#16 at::Tensor c10::KernelFunction::callUnboxed<at::Tensor, c10::ArrayRef<long>, c10::TensorOptions const&>(c10::OperatorHandle const&, c10::ArrayRef<long>, c10::TensorOptions const&) const external/pytorch/aten/src/ATen/core/boxing/KernelFunction_impl.h:62:16 (test_pytorch+0xd1fcb)
#17 at::Tensor c10::Dispatcher::callUnboxed<at::Tensor, c10::ArrayRef<long>, c10::TensorOptions const&>(c10::OperatorHandle const&, c10::ArrayRef<long>, c10::TensorOptions const&) const external/pytorch/aten/src/ATen/core/dispatch/Dispatcher.h:179:26 (test_pytorch+0xcf638)
#18 at::Tensor c10::OperatorHandle::callUnboxed<at::Tensor, c10::ArrayRef<long>, c10::TensorOptions const&>(c10::ArrayRef<long>, c10::TensorOptions const&) const external/pytorch/aten/src/ATen/core/dispatch/Dispatcher.h:154:41 (test_pytorch+0xcf638)
#19 at::rand(c10::ArrayRef<long>, c10::TensorOptions const&) bazel-out/k8-dbg-tsan/bin/external/pytorch/ATen/Functions.h:6638:15 (libros_Ssrc_Sa_Ulibtorch_Uuser_Sliba_Ulibtorch_Uuser.so+0x16794)
#20 torch::rand(c10::ArrayRef<long>, c10::TensorOptions const&)::'lambda'()::operator()() const bazel-out/k8-dbg-tsan/bin/external/pytorch/torch/csrc/autograd/generated/variable_factories.h:534:12 (libros_Ssrc_Sa_Ulibtorch_Uuser_Sliba_Ulibtorch_Uuser.so+0x16794)
#21 torch::rand(c10::ArrayRef<long>, c10::TensorOptions const&) bazel-out/k8-dbg-tsan/bin/external/pytorch/torch/csrc/autograd/generated/variable_factories.h:532:23 (libros_Ssrc_Sa_Ulibtorch_Uuser_Sliba_Ulibtorch_Uuser.so+0x12194)
#22 a_libtorch_user::ALibtorchUser::call_inference(int) ros/src/a_libtorch_user/src/ALibtorchUser.cpp:32:26 (libros_Ssrc_Sa_Ulibtorch_Uuser_Sliba_Ulibtorch_Uuser.so+0x10bf7)
#23 decltype(*(std::__1::forward<a_libtorch_user::ALibtorchUser*>(fp0)).*fp(std::__1::forward<int>(fp1))) std::__1::__invoke<void (a_libtorch_user::ALibtorchUser::*)(int), a_libtorch_user::ALibtorchUser*, int, void>(void (a_libtorch_user::ALibtorchUser::*&&)(int), a_libtorch_user::ALibtorchUser*&&, int&&) external/clang/include/c++/v1/type_traits:3471:1 (libros_Ssrc_Sa_Ulibtorch_Uuser_Sliba_Ulibtorch_Uuser.so+0x267ed)
#24 void std::__1::__thread_execute<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (a_libtorch_user::ALibtorchUser::*)(int), a_libtorch_user::ALibtorchUser*, int, 2ul, 3ul>(std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (a_libtorch_user::ALibtorchUser::*)(int), a_libtorch_user::ALibtorchUser*, int>&, std::__1::__tuple_indices<2ul, 3ul>) external/clang/include/c++/v1/thread:277:5 (libros_Ssrc_Sa_Ulibtorch_Uuser_Sliba_Ulibtorch_Uuser.so+0x267ed)
#25 void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (a_libtorch_user::ALibtorchUser::*)(int), a_libtorch_user::ALibtorchUser*, int> >(void*) external/clang/include/c++/v1/thread:287:5 (libros_Ssrc_Sa_Ulibtorch_Uuser_Sliba_Ulibtorch_Uuser.so+0x267ed)```

test.cpp
--------
void call_inference() {
    int batch_size = 100;
    torch::Tensor data = torch::rand({batch_size, 100, 30}).to(device);
    torch::Tensor h0 = torch::rand({1, batch_size, 256}).to(device);
    torch::Tensor c0 = torch::rand({1, batch_size, 256}).to(device);
    module.run_method("forward", data, h0, c0);
}
...
for (int32_t i = 0; i < n; i++) {
    std::thread t(&all_inference, i);
}
```

cc @yf225