caffe2 Tensor<CUDAContext> 赋值、构造或复制
caffe2 Tensor<CUDAContext> assignment, construction or copy
这是一个远景,如果您认为问题过于局限,请投票关闭。我在 caffe2 github repository, opened an issue asking the same question, opened another issue at the caffe2_ccp_tutorials repository because its author seems to understand it best, read the doxygen documentation on caffe2::Tensor and caffe2::CUDAContext 上搜索过,
甚至经历了 caffe2 source code,具体来说 tensor.h
、context_gpu.h
和 context_gpu.cc
.
我了解到目前caffe2 不允许将设备内存复制到张量。我愿意扩展图书馆并提出拉取请求以实现这一目标。我这样做的原因是我使用 cv::cuda::*
方法对设备内存进行所有图像预处理,因此我认为在 gpu 上进行预处理显然是一个问题,只能下载结果返回主机,然后将其从主机重新上传到网络到设备。
查看 Tensor<Context>
的构造函数,我可能只看到
template<class SrcContext , class ContextForCopy >
Tensor (const Tensor< SrcContext > &src, ContextForCopy *context)
可能会达到我想要的效果,但是我不知道如何设置<ContextForCopy>
然后用它来构建。
此外,我看到我可以用正确的尺寸构造张量,然后也许使用
template <typename T>
T* mutable_data()
我可以assign/copy数据。
数据本身存储在 std::vector<cv::cuda::GpuMat
中,因此我将不得不对其进行迭代,然后使用 cuda::PtrStepSz
or cuda::PtrStep
访问底层设备分配的数据。
这是我需要 copy/assign 到 caffe2::Tensor<CUDAContext>
.
中的相同数据
我一直在试图找出 Tensor<CPUContext>
在内部是如何被复制到 Tensor<CUDAContext>
的,因为我已经看到了它的例子,但我无法弄清楚,虽然我认为使用的方法是CopyFrom
。已经提到的常用示例,从 CPU 复制到 GPU:
TensorCPU tensor_cpu(...);
TensorCUDA tensor_cuda = workspace.CreateBlob("input")->GetMutable<TensorCUDA>();
tensor_cuda->ResizeLike(tensor_cpu);
tensor_cuda->ShareData(tensor_cpu);
我很惊讶还没有人 运行 完成这项任务,简短的搜索只产生一个 open issue 作者 (@peterneher) 或多或少地问同样的事情。
我已经弄明白了。
最简单的方法是告诉 OpenCV 使用哪个 内存位置。
这可以通过使用如下所示的 7th and 8th overload of the cv::cuda::GpuMat
constructor 来完成:
cv::cuda::GpuMat::GpuMat(int rows,
int cols,
int type,
void * data,
size_t step = Mat::AUTO_STEP
)
cv::cuda::GpuMat::GpuMat(Size size,
int type,
void * data,
size_t step = Mat::AUTO_STEP
)
这样做意味着 caffe2::TensorCUDA
已经预先声明并且 分配 :
std::vector<caffe2::TIndex> dims({1, 3, 224, 224});
caffe2::TensorCUDA tensor;
auto ptr = tensor.mutable_data<float>();
cv::cuda::GpuMat matrix(224, 224, CV_32F, ptr);
例如,使用 cv::cuda::split
处理 3 通道 BGR 浮点矩阵:
cv::cuda::GpuMat mfloat;
// TODO: put your BGR float data in `mfloat`
auto ptr = tensor.mutable_data<float>();
size_t width = mfloat.cols * mfloat.rows;
std::vector<cv::cuda::GpuMat> input_channels {
cv::cuda::GpuMat(mfloat.rows, mfloat.cols, CV_32F, &ptr[0]),
cv::cuda::GpuMat(mfloat.rows, mfloat.cols, CV_32F, &ptr[width]),
cv::cuda::GpuMat(mfloat.rows, mfloat.cols, CV_32F, &ptr[width * 2])
};
cv::cuda::split(mfloat, input_channels);
希望这对深入了解 Caffe2 的 C++ 端的任何人有所帮助。
注意 caffe2::Predictor
不适用于 caffe2::TensorCUDA
,您将不得不手动传播张量。
有关这方面的更多信息,the caffe2_cpp_tutorial mnist.cc.
这是一个远景,如果您认为问题过于局限,请投票关闭。我在 caffe2 github repository, opened an issue asking the same question, opened another issue at the caffe2_ccp_tutorials repository because its author seems to understand it best, read the doxygen documentation on caffe2::Tensor and caffe2::CUDAContext 上搜索过,
甚至经历了 caffe2 source code,具体来说 tensor.h
、context_gpu.h
和 context_gpu.cc
.
我了解到目前caffe2 不允许将设备内存复制到张量。我愿意扩展图书馆并提出拉取请求以实现这一目标。我这样做的原因是我使用 cv::cuda::*
方法对设备内存进行所有图像预处理,因此我认为在 gpu 上进行预处理显然是一个问题,只能下载结果返回主机,然后将其从主机重新上传到网络到设备。
查看 Tensor<Context>
的构造函数,我可能只看到
template<class SrcContext , class ContextForCopy >
Tensor (const Tensor< SrcContext > &src, ContextForCopy *context)
可能会达到我想要的效果,但是我不知道如何设置<ContextForCopy>
然后用它来构建。
此外,我看到我可以用正确的尺寸构造张量,然后也许使用
template <typename T>
T* mutable_data()
我可以assign/copy数据。
数据本身存储在 std::vector<cv::cuda::GpuMat
中,因此我将不得不对其进行迭代,然后使用 cuda::PtrStepSz
or cuda::PtrStep
访问底层设备分配的数据。
这是我需要 copy/assign 到 caffe2::Tensor<CUDAContext>
.
我一直在试图找出 Tensor<CPUContext>
在内部是如何被复制到 Tensor<CUDAContext>
的,因为我已经看到了它的例子,但我无法弄清楚,虽然我认为使用的方法是CopyFrom
。已经提到的常用示例,从 CPU 复制到 GPU:
TensorCPU tensor_cpu(...);
TensorCUDA tensor_cuda = workspace.CreateBlob("input")->GetMutable<TensorCUDA>();
tensor_cuda->ResizeLike(tensor_cpu);
tensor_cuda->ShareData(tensor_cpu);
我很惊讶还没有人 运行 完成这项任务,简短的搜索只产生一个 open issue 作者 (@peterneher) 或多或少地问同样的事情。
我已经弄明白了。
最简单的方法是告诉 OpenCV 使用哪个 内存位置。
这可以通过使用如下所示的 7th and 8th overload of the cv::cuda::GpuMat
constructor 来完成:
cv::cuda::GpuMat::GpuMat(int rows,
int cols,
int type,
void * data,
size_t step = Mat::AUTO_STEP
)
cv::cuda::GpuMat::GpuMat(Size size,
int type,
void * data,
size_t step = Mat::AUTO_STEP
)
这样做意味着 caffe2::TensorCUDA
已经预先声明并且 分配 :
std::vector<caffe2::TIndex> dims({1, 3, 224, 224});
caffe2::TensorCUDA tensor;
auto ptr = tensor.mutable_data<float>();
cv::cuda::GpuMat matrix(224, 224, CV_32F, ptr);
例如,使用 cv::cuda::split
处理 3 通道 BGR 浮点矩阵:
cv::cuda::GpuMat mfloat;
// TODO: put your BGR float data in `mfloat`
auto ptr = tensor.mutable_data<float>();
size_t width = mfloat.cols * mfloat.rows;
std::vector<cv::cuda::GpuMat> input_channels {
cv::cuda::GpuMat(mfloat.rows, mfloat.cols, CV_32F, &ptr[0]),
cv::cuda::GpuMat(mfloat.rows, mfloat.cols, CV_32F, &ptr[width]),
cv::cuda::GpuMat(mfloat.rows, mfloat.cols, CV_32F, &ptr[width * 2])
};
cv::cuda::split(mfloat, input_channels);
希望这对深入了解 Caffe2 的 C++ 端的任何人有所帮助。
注意 caffe2::Predictor
不适用于 caffe2::TensorCUDA
,您将不得不手动传播张量。
有关这方面的更多信息,the caffe2_cpp_tutorial mnist.cc.