OpenMP结构体内部数组设置task数据依赖编译报错如何解决
错误原因
- 你用到的
[起始索引:长度]是OpenMP的数组分段语法,该语法仅支持静态数组类型。你代码里的mat是double*类型的动态分配指针,不属于数组类型,编译器识别不了指针后的:符号,就会报错认为你漏写了]。 - 另外就算语法能过,你写的依赖范围本身逻辑也有问题:按行存储的扁平化矩阵里,单个分块不是连续的
BS*BS个元素,每一行之间间隔了ncols个元素,原写法圈定的依赖范围是错的,运行起来会有数据竞争。
修复方案
两种常用修复方式二选一即可:
方案1:用分块坐标做依赖标记(最简单,兼容所有支持task depend的OpenMP版本)
直接用分块的三维坐标i、j、k作为依赖标识,OpenMP会根据变量地址匹配依赖关系,完全满足分块矩阵乘法的依赖约束:
#pragma omp task depend(in: i, k) depend(in: k, j) depend(inout: i, j)
逻辑说明:
- 读取m1的
i行块 + k列块,依赖i、k - 读取m2的
k行块 + j列块,依赖k、j - 写入m3的
i行块 + j列块,依赖i、j
方案2:显式指定动态数组分段范围(需要OpenMP 4.5及以上版本)
把指针强转为变长数组指针,让编译器可以正常解析数组分段语法,同时修正依赖范围:
#pragma omp task depend(in: ((double (*)[m1->ncols])m1->mat)[i:BS][k:BS], ((double (*)[m2->ncols])m2->mat)[k:BS][j:BS]) \ depend(inout: ((double (*)[m3->ncols])m3->mat)[i:BS][j:BS])
内容的提问来源于stack exchange,提问作者Dresult
相关产品推荐
相关产品推荐

