如何在使用 GPU (C++) 时更改 Caffe2 中的 blob 值

How to change blob value in Caffe2 while using GPU (C++)

我正在尝试手动访问 blob 值并更改它。
我有一个名为“1conv1_w”的 blob,我通过以下方式访问它:

auto 1conv1_w = caffe2::TensorCPU((*workspace.GetBlob("1conv1_w")).Get<caffe2::TensorCPU>()).data<float>();

这将 return 指向 1conv1_w 的指针 float*。在 CPU 模式下,我可以使用

std::cout << *1conv1_w << std::endl

访问 Blob“1conv1_w”中的第一个值并修改该值。但是,当转为GPU模式时,会出现return错误,因为指针中没有值。如果我使用

auto 1conv1_w = caffe2::TensorCPU((*workspace.GetBlob("1conv1_w")).Get<caffe2::TensorCUDA>()).data<float>()[0];

然后我可以访问第一个值,但仍然无法访问 blob 中的其他值。
我想问题是因为在使用 GPU 时内存实际上是一个临时内存。该值在 CPU 和 GPU(可能是 memcpy)之间复制。当我使用 Get<caffe2::TensorCUDA>() 时,它只是将我想要的地址或值复制给我。因此,即使我更改此地址中的值,也不会影响保存在某处的实际值。

有没有人遇到同样的问题并且知道如何更改 blob 的实际值?

首先,您不能直接从 CPU 上下文访问 GPU 内存。您可以考虑为您的目的编写 CUDA 内核。如果您确实需要在 CPU 上执行此操作,那么您可以使用以下方法将数据从 GPU 获取到 CPU:

CPUContext context;
TensorCPU output;
auto& input = (*workspace.GetBlob("1conv1_w")).Get<TensorCUDA>();
output.ResizeLike(input);
context.CopyItems<CUDAContext, CPUContext>(
    input.meta(),
    input.size(),
    input.raw_data(),
    output.raw_mutable_data(input.meta()));

然后你可以修改CPU版本并以相同的类比方式将其放回GPU。