这是一个长镜头,如果您认为问题过于局限,请投票关闭。我搜索了caffe2 github存储库,打开了an issue,问了同样的问题,在caffe2_ccp_tutorials存储库中打开了另一个问题,因为它的作者似乎最了解它,请阅读caffe2::Tensorcaffe2::CUDAContext上的doxygen文档,
甚至遍历了caffe2 source code,尤其是tensor.hcontext_gpu.hcontext_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/

10-13 08:28