[英]caffe2 Tensor<CUDAContext> assignment, construction or copy
这是一个长镜头,如果您认为问题过于局限,请投票关闭。 我已经搜索了caffe2 github存储库,打开了一个问题,问了同样的问题,在caffe2_ccp_tutorials存储库中打开了另一个问题,因为它的作者似乎最了解它,阅读了caffe2 :: Tensor和caffe2 :: CUDAContext上的doxygen文档,甚至通过了caffe2 源代码 ,尤其是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
或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);
我很惊讶,还没有人完成这项任务,而简短的搜索仅产生一个未解决的问题 ,作者(@peterneher)或多或少地在问同样的事情。
我设法弄清楚了。 最简单的方法是告诉OpenCV使用哪个内存位置。 这可以通过使用cv::cuda::GpuMat
构造函数的第7和第8重载来完成,如下所示:
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
,而必须手动传播张量。 有关更多信息,请访问caffe2_cpp_tutorial mnist.cc 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.