这是一个长镜头,如果您认为问题过于局限,请投票关闭。我搜索了caffe2 github存储库,打开了an issue,问了同样的问题,在caffe2_ccp_tutorials存储库中打开了另一个问题,因为它的作者似乎最了解它,请阅读caffe2::Tensor和caffe2::CUDAContext上的doxygen文档,
甚至遍历了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()
我可以分配/复制数据。
数据本身存储在
std::vector<cv::cuda::GpuMat
中,因此我将不得不对其进行迭代,然后使用 cuda::PtrStepSz
or cuda::PtrStep
来访问基础设备分配的数据。那就是我需要复制/分配到
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 channel 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。
关于c++ - caffe2 Tensor <CUDAContext>赋值,构造或复制,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45484051/