C++ 阵列火并行块和

C++ 阵列火并行块和,c++,parallel-processing,sum,opencl,arrayfire,C++,Parallel Processing,Sum,Opencl,Arrayfire,我想做的是: 我在第一(行)维中有一个“扩展”数组。例如,我有一个1080行1920列的图像。此扩展数组为(8*1080)行和1920列,8表示“行块”大小。 我想做的是制作一个大小为8x1的新阵列。 这个新数组将保存第i个(i=0到7)处每个块的总和 在上面的示例中,新阵列的第一个元素(i=0)将是扩展阵列中这些像素的总和(线性索引,按列): 0,8(因为8是第二个块的第一个元素),16(第三个块) 另一个例子是第二个元素: 1、9、17 我认为这是可以并行的?我正在尝试解决这个问题,但我无法

我想做的是: 我在第一(行)维中有一个“扩展”数组。例如,我有一个1080行1920列的图像。此扩展数组为(8*1080)行和1920列,8表示“行块”大小。 我想做的是制作一个大小为8x1的新阵列。 这个新数组将保存第i个(i=0到7)处每个块的总和

在上面的示例中,新阵列的第一个元素(i=0)将是扩展阵列中这些像素的总和(线性索引,按列):

0,8(因为8是第二个块的第一个元素),16(第三个块)

另一个例子是第二个元素:

1、9、17

我认为这是可以并行的?我正在尝试解决这个问题,但我无法解决,我尝试了gfor,但找不到一种方法来解决,arrayfire不可能吗?感谢您的帮助

我曾尝试使用gfor,但无法解决问题

下面是我尝试过的一些代码:rx是8x1(p_平方_1=8) rx_all是扩展的(p_平方*行、列)数组。 注:我使用seq“+”运算符,因为如果我尝试写入“I+p_平方_1”,则会出现不一致性,我认为……这是我的错误,但我找不到向seq对象添加值的其他方法)

af::阵列rx(p_平方_1,1);
gfor(af::序列i,行*列*(p_平方_1-1)){
rx(i)=af::sum(rx_all(i.operator+((const int)p_平方_1));
}
af::eval(rx);

cout我认为您可以通过执行
af::moddims
af::sum
来实现这一点

阵列img_扩展(1080*811920);
阵列img_扩展的img_整形=moddims(img_扩展的,8120*1080);
数组结果=和(img_扩展_整形,1);
moddims调用将数组重塑为8x(1920*1080)数组,然后对第二个维度执行求和

优化布局 如果你把1920面作为主要尺寸,你可以获得更好的性能。这不仅将匹配CPU内存中的图像布局,避免在与GPU之间的传输时进行转置,而且经过整形的阵列将具有更大的第一维度,因此它将具有更好的GPU利用率

array img_expanded(1920, 1080*8);

array img_expanded_reshaped = moddims(img_expanded, 1920*1080, 8);
array result = sum(img_expanded_reshaped, 0);

这需要你重构的不仅仅是代码的这一部分。

非常感谢,这帮助很大,我没有想到使用moddims,这是一个非常方便的函数。但是有一个问题,上面的代码可能不能100%准确地求和吗?总数是正确的,但8个和中的每一个都略有不同,因此我认为这与精度和准确性无关(我使用浮点数,但根本没有小数部分,数字类似于1268.0、650.0等)。浮点运算总是会有舍入错误。由于在GPU上执行操作的顺序未定义,因此值将略有不同。检查执行求和的
af::array
的类型。它可能处理整数值,然后将它们转换为浮点值。打印函数也可能会截断这些值。好的,谢谢您的澄清!我还有一个关于gfor结构的问题,我可以发表一篇新的帖子吗?最好在我们的松弛频道上处理这些问题。
array img_expanded(1920, 1080*8);

array img_expanded_reshaped = moddims(img_expanded, 1920*1080, 8);
array result = sum(img_expanded_reshaped, 0);