0

I am trying to manually access blobs value and change it.
I have a blob called "1conv1_w" and I access it by:

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

this will return a pointer float* to 1conv1_w. In CPU mode, I can use

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

to access the first value within Blob "1conv1_w" as well as modify the value. However, when turn into GPU mode, this will return error because there is no value within the pointer. If I use

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

Then I can access the first value but still cannot access other value within the blob.
I guess the problem is because while using GPU the memory is actually a temporary memory. The value is copied between CPU and GPU (probably memcpy). When I use Get<caffe2::TensorCUDA>() it just copy the address or value I want to me. So even I change the value in this address it will not affect the actual value saved in somewhere.

Does anyone face the same problem and know how to change the actual value of the blob?

吳順成
  • 13
  • 1
  • 4

1 Answers1

0

First of all you cannot access GPU memory straight forward from CPU context. You may consider writing CUDA kernel for your purpose. If you really need to do it on CPU then you can get data from GPU to CPU with:

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

Then you can modify CPU version and put it back to GPU in the same analogical way.

  • Hey, thanks for your answer. I found that the best way to do it is to write a caffe2 operator to do it. But the approach you provided is also a possible way to do it, i.e. overwrite the blob value in device. – 吳順成 Jun 01 '18 at 20:37