dshin
(David Shin)
October 27, 2022, 5:26pm
1
I have a c++ process that constructs torch Tensor’s and writes their numerical values to datasets in an hdf5 file. It takes advantages of hdf5’s parallel write capabilities by using multiple threads, each of which writes to a part of the hdf5 file. After the file is written, a python process loads the hdf5 data and converts it into torch Tensor’s.
I am wondering if I can eliminate the hdf5 middleman here. When I google for phrases like “c++ pytorch write tensor disk”, I don’t see clear tutorials or examples of how to do this. Is this type of workflow supported? Where can I find clear documentation on this?
1 Like
Save C++:
auto tensor = torch::randn({ 1, 5 });
auto pickled = torch::pickle_save(tensor);
std::ofstream fout("input.pt", std::ios::out | std::ios::binary);
fout.write(pickled.data(), pickled.size());
fout.close();
Load python:
tensor = torch.load('input.pt')
From this GitHub thread:
opened 09:27AM - 10 May 19 UTC
closed 08:06AM - 23 Nov 19 UTC
high priority
oncall: jit
module: cpp
module: serialization
triaged
## 🐛 Bug
I don't manage to import a tensor saved in PyTorch from C++. Any hel… p on this is welcome 😄
## To Reproduce
Save a tensor to a file in python.
```python
>>> import torch
>>> torch.save(torch.tensor([1., 2., 3.]), "tensor.pt")
>>> torch.load("tensor.pt")
tensor([1., 2., 3.])
```
Build this small C++ program
```cpp
#include <torch/torch.h>
int main() {
torch::Tensor tensor;
torch::load(tensor, "tensor.pt");
std::cout << tensor << std::endl;
}
```
At runtime I get:
```
terminate called after throwing an instance of 'c10::Error'
what(): [enforce fail at inline_container.cc:137] . PytorchStreamReader failed reading zip archive: failed finding central directory
frame #0: std::function<std::string ()>::operator()() const + 0x11 (0x7f1da515e691 in /___/libtorch/lib/libc10.so)
frame #1: c10::ThrowEnforceNotMet(char const*, int, char const*, std::string const&, void const*) + 0x49 (0x7f1da515e4a9 in /__/libtorch/lib/libc10.so)
frame #2: caffe2::serialize::PyTorchStreamReader::valid(char const*) + 0x6b (0x7f1d9c69735b in /__/libtorch/lib/libcaffe2.so)
frame #3: caffe2::serialize::PyTorchStreamReader::init() + 0x9d (0x7f1d9c69912d in /___/libtorch/lib/libcaffe2.so)
frame #4: caffe2::serialize::PyTorchStreamReader::PyTorchStreamReader(std::unique_ptr<caffe2::serialize::ReadAdapterInterface, std::default_delete<caffe2::serialize::ReadAdapterInterface> >) + 0x3b (0x7f1d9c69ab8b in /__/libtorch/lib/libcaffe2.so)
frame #5: <unknown function> + 0xa9b5bf (0x7f1da5e125bf in /__/libtorch/lib/libtorch.so.1)
frame #6: torch::jit::load(std::unique_ptr<caffe2::serialize::ReadAdapterInterface, std::default_delete<caffe2::serialize::ReadAdapterInterface> >, c10::optional<c10::Device>, std::unordered_map<std::string, std::string, std::hash<std::string>, std::equal_to<std::string>, std::allocator<std::pair<std::string const, std::string> > >&) + 0x9a (0x7f1da5e15d2a in /__/libtorch/lib/libtorch.so.1)
frame #7: torch::jit::load(std::string const&, c10::optional<c10::Device>, std::unordered_map<std::string, std::string, std::hash<std::string>, std::equal_to<std::string>, std::allocator<std::pair<std::string const, std::string> > >&) + 0x68 (0x7f1da5e15ec8 in /___/libtorch/lib/libtorch.so.1)
frame #8: torch::serialize::InputArchive::load_from(std::string const&, c10::optional<c10::Device>) + 0x38 (0x7f1da604c058 in /___/libtorch/lib/libtorch.so.1)
frame #9: void torch::load<at::Tensor, char const (&) [10]>(at::Tensor&, char const (&) [10]) + 0x86 (0x55a502f5fe97 in ./load)
frame #10: main + 0x37 (0x55a502f5fb51 in ./load)
frame #11: __libc_start_main + 0xe7 (0x7f1d9a338b97 in /lib/x86_64-linux-gnu/libc.so.6)
frame #12: _start + 0x2a (0x55a502f5f96a in ./load)
[1] 30788 abort ./load
```
## Expected behavior
I would expect to be able to load a tensor from the PyTorch dump in the C++ program.
## Environment
PyTorch version: 1.1.0
Is debug build: No
CUDA used to build PyTorch: 9.0.176
OS: Ubuntu 18.04.2 LTS
GCC version: (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0
CMake version: version 3.10.2
Python version: 3.7
Is CUDA available: Yes
CUDA runtime version: 10.1.105
GPU models and configuration:
GPU 0: GeForce GTX TITAN X
GPU 1: GeForce GTX TITAN X
GPU 2: GeForce GTX TITAN X
GPU 3: GeForce GTX TITAN X
GPU 4: GeForce GTX TITAN X
GPU 5: GeForce GTX TITAN X
GPU 6: GeForce GTX TITAN X
GPU 7: GeForce GTX TITAN X
Nvidia driver version: 418.56
cuDNN version: Could not collect
Versions of relevant libraries:
[pip] msgpack-numpy==0.4.3.2
[pip] numpy==1.15.4
[pip] numpydoc==0.8.0
[pip] pytorch-nlp==0.4.1
[pip] torch==1.1.0
[pip] torchvision==0.2.2
[conda] blas 1.0 mkl
[conda] mkl 2018.0.3 1
[conda] mkl-service 1.1.2 py37h90e4bf4_5
[conda] mkl_fft 1.0.6 py37h7dd41cf_0
[conda] mkl_random 1.0.1 py37h4414c95_1
[conda] pytorch 1.1.0 py3.7_cuda9.0.176_cudnn7.5.1_0 pytorch
[conda] pytorch-nlp 0.4.1 pypi_0 pypi
[conda] torchvision 0.2.2 py_3 pytorch
## Additional context
I downloaded the C++ frontend from [https://download.pytorch.org/libtorch/nightly/cpu/libtorch-shared-with-deps-latest.zip](https://download.pytorch.org/libtorch/nightly/cpu/libtorch-shared-with-deps-latest.zip) yesterday.
3 Likes
dshin
(David Shin)
October 28, 2022, 8:35pm
3
Thanks, that works.
I also found this resource which shows usage of the torch::save()
API: LibTorch (PyTorch C++ Frontend) | Ye Shu
1 Like