我使用openmp来并行化我的代码。我有一个原始数组:
A=[3,5,2,5,7,9,-4,6,7,-3,1,7,6,8,-1,2]
和标记数组:
M=[1,0,1,0,0,0,1,0,0,1,1,0,0,0,1,1]
使用数组M我可以压缩这个打包数组中的原始数组:
A=[3,2,-4,-3,1,-1,2]
我想使用多线程方法解决这个问题。图书馆' Thrust' for C ++解决了这个问题,但我无法为Fortran找到类似的工具。 是否有一个图书馆,比如“推力”和#39;对于C ++,我可以用来执行流压缩? 或者,是否有一种算法,我可以用fortran和openmp自己编写,以解决这个问题?
答案 0 :(得分:1)
是否有一个库,比如C ++的'推力',我可以用它来执行流压缩?
从Fortran调用推进例程应该不那么困难(如果你愿意写一点C ++代码)。此外,推力可以针对OMP后端而不是GPU后端。
或者,是否有一种算法我可以使用fortran和openmp自行编写,以解决这个问题?
基本并行流压缩算法如下。我们假设最初在数据数组中为每个元素分配了一个线程。
在M
阵列上执行parallel prefix sum (inclusive scan):
M=[1,0,1,0,0,0,1,0,0,1,1,0,0,0,1,1]
sM=[1,1,2,2,2,2,3,3,3,4,5,5,5,5,6,7]
然后每个线程将检查M
数组中的元素,如果该元素为非零,它会将A
数组中的相应元素复制到输出数组(我们称之为O
):
M=[1,0,1,0,0,0, 1,0,0, 1,1,0,0,0, 1,1]
sM=[1,1,2,2,2,2, 3,3,3, 4,5,5,5,5, 6,7]
A=[3,5,2,5,7,9,-4,6,7,-3,1,7,6,8,-1,2]
O=[3, 2, -4, -3,1, -1,2]
如果您在OMP中执行此操作,则在步骤1和步骤2之间需要OMP屏障。步骤2中的工作相对简单且完全独立,因此您可以使用OMP并行执行循环,并打破工作以任何你想要的方式。第1步将很复杂,我建议按照您和我链接的章节中提供的大纲进行操作。那里的OMP代码将需要各种障碍,但可以并行化。
正如评论中已经提到的,如果这是你想要并行化的唯一的工作,我不推荐使用GPU,因为将数据传输到GPU或从GPU传输数据的成本可能会超过您可能产生的任何并行执行时间的好处。但正如我已经提到的,推力可以针对OMP实现而不是GPU实现。值得一试。
关于来自fortran的推力,你需要的大部分是here。这无疑是CUDA fortran,但唯一的区别应该是不使用device属性,并使用thrust :: host_vector而不是thrust :: device_vector(至少,开始使用)。