caffe2 Tensor & lt; CUDAContext & gt; назначение, строительство или копия

Это долгий путь, если вы думаете, что вопрос слишком локализован, пожалуйста, проголосуйте, чтобы закрыть. Я искал на caffe2 github хранилище, открытое проблема задавая тот же вопрос, открыл еще один вопрос на caffe2_ccp_tutorials хранилище, потому что его автор, кажется, понимает это лучше, прочитайте документацию по Doxygen caffe2 :: Тензор а также caffe2 :: CUDAContext,
и даже прошел через 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) просит то же самое более или менее.

7

Решение

Мне удалось выяснить это.
Самый простой способ — рассказать OpenCV который расположение памяти для использования.
Это можно сделать с помощью 7-я и 8-я перегрузка cv::cuda::GpuMat конструктор показано ниже:

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);

Например, обработка 3-канальной плавающей матрицы BGR с использованием cv::cuda::split:

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);

Надеюсь, что это поможет любому, кто углубится в C ++ сторону Caffe2.

НОТА тот caffe2::Predictor не будет работать с caffe2::TensorCUDAвместо этого вам придется размножать тензор вручную.
Для получения дополнительной информации об этом, caffe2_cpp_tutorial mnist.cc.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]