ComputeLibrary CLTensor передача данных

Я работаю над интеграцией ARM ComputeLibrary в проект.

Это не API, семантика которого мне знакома, но я работаю над документами и примерами.

В данный момент я пытаюсь скопировать содержимое std::vector к CLTensor, Затем используйте операцию ARMCL GEMM.

Я строил MWE, показанный ниже, с целью заставить матричное умножение работать.

Чтобы получить входные данные из стандартного C ++ std::vector, или же std::ifstreamЯ пытаюсь подход, основанный на итераторе, основанный на этот пример показан в документах.

Тем не менее, я продолжаю получать segfault.

Есть пример sgemm с помощью CLTensor в источнике, который также является источником вдохновения. Однако он получает свои входные данные из массивов Numpy, поэтому не имеет значения до этого момента.

Я не уверен в ARMCL, если CLTensor а также Tensor есть непересекающиеся методы. Но я чувствую, что они имеют общий интерфейс ITensor, Тем не менее, я не смог найти эквивалентный пример, который использует CLTensor вместо Tensor для этого метода на основе итератора.

Вы можете увидеть мой код, с которым я работаю ниже, который завершается ошибкой в ​​строке 64 (*reinterpret_cast..). Я не совсем уверен, какие операции он выполняет, но я предполагаю, что у нас есть итератор ARMCL input_it который увеличивается n * m раз, каждая итерация устанавливает значение CLTensor по этому адресу к соответствующему входному значению. reinterpret_cast это просто, чтобы типы играли вместе?

Я считаю, что мои объекты Iterator и Window в порядке, но не уверены.

#include "arm_compute/core/Types.h"#include "arm_compute/runtime/CL/CLFunctions.h"#include "arm_compute/runtime/CL/CLScheduler.h"#include "arm_compute/runtime/CL/CLTuner.h"#include "utils/Utils.h"
namespace armcl = arm_compute;
namespace armcl_utils = arm_compute::utils;

int main(int argc, char *argv[])
{
int n = 3;
int m = 2;
int p = 4;

std::vector<float> src_a = {2, 1,
6, 4,
2, 3};
std::vector<float> src_b = {5, 2, 1, 6,
3, 7, 4, 1};
std::vector<float> c_targets = {13, 11, 6, 13,
42, 40, 22, 40,
19, 25, 14, 15};

// Provides global access to a CL context and command queue.
armcl::CLTuner tuner{};
armcl::CLScheduler::get().default_init(&tuner);

armcl::CLTensor a{}, b{}, c{};
float alpha = 1;
float beta = 0;
// Initialize the tensors dimensions and type:
const armcl::TensorShape shape_a(m, n);
const armcl::TensorShape shape_b(p, m);
const armcl::TensorShape shape_c(p, n);
a.allocator()->init(armcl::TensorInfo(shape_a, 1, armcl::DataType::F32));
b.allocator()->init(armcl::TensorInfo(shape_b, 1, armcl::DataType::F32));
c.allocator()->init(armcl::TensorInfo(shape_c, 1, armcl::DataType::F32));

// configure sgemm
armcl::CLGEMM sgemm{};
sgemm.configure(&a, &b, nullptr, &c, alpha, beta);

// // Allocate the input / output tensors:
a.allocator()->allocate();
b.allocator()->allocate();
c.allocator()->allocate();

// // Fill the input tensor:
// // Simplest way: create an iterator to iterate through each element of the input tensor:
armcl::Window input_window;
armcl::Iterator input_it(&a, input_window);
input_window.use_tensor_dimensions(shape_a);

std::cout << " Dimensions of the input's iterator:\n";
std::cout << " X = [start=" << input_window.x().start() << ", end=" << input_window.x().end() << ", step=" << input_window.x().step() << "]\n";
std::cout << " Y = [start=" << input_window.y().start() << ", end=" << input_window.y().end() << ", step=" << input_window.y().step() << "]\n";// // Iterate through the elements of src_data and copy them one by one to the input tensor:
execute_window_loop(input_window, [&](const armcl::Coordinates & id)
{
std::cout << "Setting item [" << id.x() << "," << id.y() << "]\n";
*reinterpret_cast<float *>(input_it.ptr()) = src_a[id.y() * m + id.x()]; //
},
input_it);

//  armcl_utils::init_sgemm_output(dst, src0, src1, armcl::DataType::F32);

// Configure function

// Allocate all the images
//  src0.allocator()->import_memory(armcl::Memory(&a));
//src0.allocator()->allocate();
//src1.allocator()->allocate();

// dst.allocator()->allocate();

// armcl_utils::fill_random_tensor(src0, -1.f, 1.f);
// armcl_utils::fill_random_tensor(src1, -1.f, 1.f);

// Dummy run for CLTuner
//sgemm.run();

std::vector<float> lin_c(n * p);

return 0;
}

0

Решение

Часть, которую вы пропустили (что, по общему признанию, могло бы быть лучше объяснено в документации!), Заключается в том, что вам нужно отобразить / снять отображение буферов OpenCL, чтобы сделать их доступными для ЦП.

Если вы посмотрите внутрь fill_random_tensor (что используется в пример cl_sgemm тебе позвонили tensor.map();

Так что если вы map() ваш буфер перед созданием итератора, тогда я считаю, что он должен работать:

a.map();
input_it(&a, input_window);
execute_window_loop(...)
{
}
a.unmap(); //Don't forget to unmap the buffer before using it on the GPU

Надеюсь это поможет

2

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

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

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