Я пытаюсь вручную получить доступ к значению BLOB-объектов и изменить его.
У меня есть блоб с именем «1conv1_w», и я получаю к нему доступ:
auto 1conv1_w = caffe2::TensorCPU((*workspace.GetBlob("1conv1_w")).Get<caffe2::TensorCPU>()).data<float>();
это вернет указатель float*
1conv1_w. В режиме CPU я могу использовать
std::cout << *1conv1_w << std::endl
чтобы получить доступ к первому значению в Blob «1conv1_w», а также изменить значение. Однако при переходе в режим графического процессора это приведет к ошибке, поскольку в указателе нет значения. Если я использую
auto 1conv1_w = caffe2::TensorCPU((*workspace.GetBlob("1conv1_w")).Get<caffe2::TensorCUDA>()).data<float>()[0];
Затем я могу получить доступ к первому значению, но все еще не могу получить доступ к другому значению в BLOB-объекте.
Я предполагаю, что проблема в том, что при использовании графического процессора память фактически является временной памятью. Значение копируется между CPU и GPU (вероятно, memcpy). Когда я использую Get<caffe2::TensorCUDA>()
это просто скопировать адрес или значение, которое я хочу для меня. Так что даже если я изменю значение в этом адресе, это не повлияет на фактическое значение, сохраненное где-либо.
Кто-нибудь сталкивается с той же проблемой и знает, как изменить фактическое значение капли?
Прежде всего, вы не можете получить доступ к памяти GPU прямо из контекста процессора. Вы можете написать ядро CUDA для своих целей. Если вам действительно нужно сделать это на процессоре, то вы можете получить данные из 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()));
Затем вы можете изменить версию ЦП и вернуть ее обратно в графический процессор аналогичным образом.
Других решений пока нет …