Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.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
Opencl 向量化我的标量函数_Opencl_Vectorization - Fatal编程技术网

Opencl 向量化我的标量函数

Opencl 向量化我的标量函数,opencl,vectorization,Opencl,Vectorization,假设我想计算一个升余弦。我可以有一个宏来定义cos(x)(0.5f+0.5f*cos(x)),但是为了我的问题,我想把它变成一个函数,如下所示: float cos_raised(float x) { return 0.5f + 0.5f * cos(x); } float{N:} cos_raised_float{N:}(float{N:} x) { return 0.5f + 0.5f * cos(x); } 这可以很好地工作,但只有一个浮点输入,当它可以很容易地矢量化时

假设我想计算一个升余弦。我可以有一个宏来定义cos(x)(0.5f+0.5f*cos(x)),但是为了我的问题,我想把它变成一个函数,如下所示:

float cos_raised(float x)
{
    return 0.5f + 0.5f * cos(x);
}
float{N:} cos_raised_float{N:}(float{N:} x)
{
    return 0.5f + 0.5f * cos(x);
}
这可以很好地工作,但只有一个浮点输入,当它可以很容易地矢量化时。如何正确地对其进行矢量化,并使其接受float2/3/4/8/16作为输入和输出,而不复制函数体(这是一个简单的示例,但对于更复杂的函数,我需要知道这一点)


编辑:我想我是在问如何生成gentype函数?但是,仅仅键入
gentype
是行不通的。

IIRC:遗憾的是,“gentype”是一个仅存在于OpenCL文档中的概念,它实际上不是一种允许您自己创建泛型/模板式函数的语言功能。这意味着没有简单的方法来做你想做的事情,你可能需要使用一些预处理器的魔法来最小化代码重复。例如,请参阅此SO线程:它提供了比我更多的知识。

如果编译器在进行矢量化之前将所有函数调用内联,那么您就可以完成所有设置。顺便说一句,矢量化可能只在CPU执行时需要,因为现在大多数GPU都是标量的。

由于OpenCL内核是在运行时编译的,您可以在内核的开头添加额外的代码行。我会使用一个模板函数(例如,存储在单独的文本文件中),如下所示:

float cos_raised(float x)
{
    return 0.5f + 0.5f * cos(x);
}
float{N:} cos_raised_float{N:}(float{N:} x)
{
    return 0.5f + 0.5f * cos(x);
}

因为我更熟悉Python,所以我使用它的语法在字符串中指定占位符,即
{N:}
。您必须为主机代码的语言找到类似的东西。此后,只需在2、3、4、8和16之间建立一个循环,每次填写
{N:}
。这将为您提供五个需要添加到内核代码开头的额外字符串。不利的一面是,您必须想出一些方法,在主内核代码中指明所有这些生成的函数应该插入的位置。它们需要出现在所有
#pragma XXX:enable
语句之后。之后,您的内核可以调用任何版本,例如
cos\u-raised\u-float4

内核中会有一个
cos\u-raised
版本,还是多个版本,即同时有一个
float2
和一个
float4
版本?如果总是只有一个版本,那么在构建内核时定义几个宏就行了。什么宏?我的意思是,让你的内核只在
float cos_-rised(floatN x)
的版本上使用,但是你不知道在你的程序实际运行之前,floatN将是什么。此场景适用于将所有函数矢量化以使用相同的矢量宽度,但仅在运行时定义矢量宽度的情况。如果是这种情况,您可以使用
clBuildProgram
options
参数,并传递类似
“-D floatN=float2”
的内容。这样,您的代码中就有一个单一版本的函数,它可以处理
floatN
中的任何类型。这够了吗?哦,我明白了。这是一个有趣的想法,但还不够笼统,因为我可能想把它混在一起。怎么做?因为它只是用float4输入cos_raised(),无法编译。对不起,我不理解你的问题。请再说一遍,我准备好了吗?我该怎么做才能让它像这样工作?因为它不会编译。对不起,我误读了。如果希望函数的版本采用向量类型,则需要编写每个版本。