Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 如何实现opencl内核管道_Linux_Opencl_Fpga_Hpc - Fatal编程技术网

Linux 如何实现opencl内核管道

Linux 如何实现opencl内核管道,linux,opencl,fpga,hpc,Linux,Opencl,Fpga,Hpc,我正在使用OpenCl进行我的项目。为了提高我的算法的性能,是否可以通过管道传输单个内核?如果内核由许多步骤组成,比如a、B、C,我希望a在完成它的部分后接受新数据并将其传递给B。我可以在它们之间创建通道,但我不知道如何进行详细操作 我可以在.cl文件中写A、B、C(3个内核)吗?但如何排队更改? 我正在使用AlteraSDK进行FPGA HPC开发。 谢谢。管道可以通过使用几个与通道相连的内核来实现。所有内核同时运行时,数据从一个内核传输到另一个内核: 此类管道的最基本示例是: channe

我正在使用OpenCl进行我的项目。为了提高我的算法的性能,是否可以通过管道传输单个内核?如果内核由许多步骤组成,比如a、B、C,我希望a在完成它的部分后接受新数据并将其传递给B。我可以在它们之间创建通道,但我不知道如何进行详细操作

我可以在.cl文件中写A、B、C(3个内核)吗?但如何排队更改? 我正在使用AlteraSDK进行FPGA HPC开发。
谢谢。

管道可以通过使用几个与通道相连的内核来实现。所有内核同时运行时,数据从一个内核传输到另一个内核:

此类管道的最基本示例是:

channel int foo_bar_channel;
channel float bar_baz_channel;

__kernel void foo(__global int* in) {
  for (int i = 0; i < 1024; ++i) {
    int value = in[i];
    value = clamp(value, 0, 255);                 // do some work
    write_channel_altera(foo_bar_channel, value); // send data to the next kernel
  }
}

__kernel void bar() {
  for (int i = 0; i < 1024; ++i) {
    int value = read_channel_altera(foo_bar_channel); // take data from foo
    float fvalue = (float) value;
    write_channel_altera(bar_baz_channel, value); // send data to the next kernel
  }
}

__kernel void baz(__global int* out) {
  for (int i = 0; i < 1024; ++i) {n
    float value = read_channel_altera(bar_baz_channel);
    float s = sin(value);
    out[i] = s;                                  // write result in the end
  }
}
与针对GPU的OpenCL编程不同,我们依赖于数据管道,因此NDRange内核不会给我们带来任何好处。使用单个工作项内核而不是NDRange内核,因此我们使用clEnqueueTask函数将它们排队。附加的内核属性(reqd_work_group_size)可用于标记单个工作项内核,为编译器提供一些优化空间

有关通道和内核属性的更多信息,请参阅《英特尔FPGA SDK for OpenCL编程指南》(具体请参见第1.6.4节“实现英特尔FPGA SDK for OpenCL通道扩展”):


“渠道”似乎是特定于供应商的。“管道”不应该是这样做的吗?(我是问,不是说;你显然比我更了解FPGA OpenCL)。嗨,非常感谢你回复安德鲁。因此,为了使不同的内核同时工作,我需要使用clEnqueueTask将内核排队,而不是使用EnqueueNDRange?并分别为我的所有内核创建我的内核和命令队列?编译器会自动为我的单个内核流水线吗?例如,对于(四舍五入=0;round@Dithermaster是的,管道是做同样事情的另一种方式FPGA它们与OpenCL 2.0管道规范不完全兼容,但正如您所提到的,它们在代码可移植性方面仍然很好。如果可移植性没有问题,管道和通道之间的区别主要在于语法。@HaominJ,将单个工作项内核(clEnqueueTask或clenqueendrange)排入全局工作大小的队列(1,1,1)会起作用。“循环是由编译器流水线(每轮接受新数据)还是逐轮执行(N轮后接受新数据)”-如果一个通道没有缓冲,那么在每次迭代中,数据都会传输到另一个内核。对于缓冲通道,它可以不同(见1.6.4.5.7)“使用深度通道属性实现缓冲通道”)
cl_queue foo_queue = clCreateCommandQueue(...);
cl_queue bar_queue = clCreateCommandQueue(...);
cl_queue baz_queue = clCreateCommandQueue(...);

clEnqueueTask(foo_queue, foo_kernel);
clEnqueueTask(bar_queue, bar_kernel);
clEnqueueTask(baz_queue, baz_kernel);

clFinish(baz_queue); // last kernel in our pipeline