首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SYCL中的使用障碍

SYCL中的使用障碍
EN

Stack Overflow用户
提问于 2019-10-17 16:24:40
回答 1查看 867关注 0票数 2

我用SYCL做矩阵乘法,并且有一个工作代码,其中我只使用parallel_for中的,而不是在 parallel_for.中使用nd_range 。现在,我想在其中使用障碍,据我所知,障碍只能与nd_range一起使用,对吗?我正在附加代码的一部分,请告诉我,如果没有nd_range就可以完成它,或者我应该使用nd_range做什么更改。谢谢

代码语言:javascript
复制
queue.submit([&](cl::sycl::handler &cgh) {
    auto A = A_sycl.get_access<cl::sycl::access::mode::read>(cgh);
    auto B = B_sycl.get_access<cl::sycl::access::mode::read>(cgh);
    auto C = C_sycl.get_access<cl::sycl::access::mode::write>(cgh);

    cgh.parallel_for<class test>(
        cl::sycl::range<2>(4, 4), [=](cl::sycl::id<2> id) {
        c_access[id] = A[id] * Y[id.get(1)];
    });

});
EN

回答 1

Stack Overflow用户

发布于 2019-10-18 10:52:56

使用nd_range可以显式指定本地范围。为了能够在内核中放置工作组屏障,还需要使用nd_item而不是 id 来访问更多的id位置和大小,例如全局和本地id、组范围和本地范围以及屏障同步原语。

然后,在完成对设备本地内存的读写(使用只使用设备的本地访问器)时,您可以放置一个屏障

然而,使用、range、id无法获得任何该功能。它只是为了简化命令组的设置和全局内存内核的编写,您希望运行库为您决定工作组大小,并且有一种简单的方法来索引您的工作项,而不是传统的OpenCL方法,即无论您的内核多么简单或复杂,都必须始终显式地定义NDRange (nd_range in SYCL)。

下面是一个简单的例子,假设您想要启动一个2D内核。

代码语言:javascript
复制
myQueue.submit([&](cl::sycl::handler& cgh) {
    auto A_ptr = A_buf.get_access<cl::sycl::access::mode::read>(cgh);
    auto B_ptr = B_buf.get_access<cl::sycl::access::mode::read_write>(cgh);
    auto C_ptr = C_buf.get_access<cl::sycl::access::mode::write>(cgh);
    // scratch/local memory for faster memory access to compute the results
    cl::sycl::accessor<int, 1, cl::sycl::access::mode::read_write,
                       cl::sycl::access::target::local>
        C_scratch(range<1>{size}, cgh);

    cgh.parallel_for<example_kernel>(
        cl::sycl::nd_range<2>(range<2>{size >> 3, size >> 3},   // 8, 8
                              range<2>{size >> 4, size >> 4}),  // 4, 4
        [=](cl::sycl::nd_item<2> item) {
          // get the 2D x and y indices
          const auto id_x = item.get_global_id(0);
          const auto id_y = item.get_global_id(1);
          // map the 2D x and y indices to a single linear,
          // 1D (kernel space) index
          const auto width =
              item.get_group_range(0) * item.get_local_range(0);
          // map the 2D x and y indices to a single linear,
          // 1D (work-group) index
          const auto index = id_x * width + id_y;
          // compute A_ptr * B_ptr into C_scratch
          C_scratch[index] = A_ptr[index] * B_ptr[index];
          // wait for result to be written (sync local memory read_write)
          item.barrier(cl::sycl::access::fence_space::local_space);
          // output result computed in local memory
          C_ptr[index] = C_scratch[index];
        });
  });

我使用主机数据和SYCL缓冲区的一维表示,这解释了从2D索引到单个线性一维索引的映射。

我希望这个解释有助于在你的案例中应用这些概念。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58437021

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档