c++ - ComputeLibrary CLTensor 数据传输

标签 c++ arm opencl mali

我正在将 ARM ComputeLibrary 集成到一个项目中。

这不是我所熟悉的语义的 API,但我正在研究文档和示例。

目前,我正在尝试将 std::vector 的内容复制到 CLTensor。然后使用ARMCL GEMM操作。

我一直在构建一个 MWE,如下所示,目的是让矩阵乘法正常工作。

为了从标准 C++ std::vectorstd::ifstream 获取输入数据,我正在尝试基于迭代器的方法,基于 this example shown in the docs .

但是,我一直遇到段错误。

an example of sgemm 在源代码中使用 CLTensor,这也是我从中汲取灵感的地方。但是,它从 Numpy 数组获取输入数据,因此目前为止不相关。

我不确定在 ARMCL 中 CLTensorTensor 是否有不相交的方法。但我觉得它们是一个通用接口(interface)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;
}

最佳答案

您错过的部分(无可否认,在文档中可以更好地解释!)是您需要映射/取消映射 OpenCL 缓冲区,以便 CPU 可以访问它们。

如果你看一下 fill_random_tensor (这是在 cl_sgemm example 中使用的内容,您已调用 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

希望对你有帮助

关于c++ - ComputeLibrary CLTensor 数据传输,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53779230/

相关文章:

c++ - 使用 opencl 将软件渲染到 opengl 2d View

opengl - 想法 : how to interactively render large image series using GPU-based direct volume rendering

c++ - opengl - 每个三角形的独特颜色

c++ - 是否有一个函数可以添加到 C++ 堆栈的底部?

c - 在为arm进行交叉编译时,是否有特定的编译器标志来使用gcc同步内置函数?

c - 为内联汇编创建常量池的正确方法是什么?

c++ - 为什么很多 OpenCL 示例是用 C++ 而不是用 C 编写的?

C++:搜索 std::set 指向类的指针

c++ - 如果同时运行 GPU 密集光流算法,为什么会得到损坏的结果?

assembly - ARM Cortex M 中的 ISB 指令