Fortran 派生类型变量,其中包含 OpenMP 并行区域内具有共享属性的指针字段

Fortran derived type variable containing pointer fields with the shared attribute inside an OpenMP parallel region

提问人:user22593146 提问时间:9/19/2023 最后编辑:Vladimir F Героям славаuser22593146 更新时间:9/20/2023 访问量:34

问:

我有以下问题:我想访问存储在带有指针字段的派生类型中的数据。我希望派生类型的变量具有“shared”属性。运行代码时,我得到错误的结果。示例如下:

  1. 派生类型的说明:

    TYPE, PUBLIC :: T_CSR INTEGER(SIK) :: n
    INTEGER(SIK) :: nval
    REAL(SRK), POINTER :: a(:)
    INTEGER(SIK), POINTER :: ja(:)
    INTEGER(SIK), POINTER :: ia(:)
    INTEGER(SIK), POINTER :: diag(:)
    END TYPE T_CSR
    
  2. 派生类型的变量 -

    type (t_csr):: LU
    
  3. 代码:

    !$omp parallel do private (ij1, ij2, sum)
    do i = 2, n
      ij1 = LU%ia(i)
      ij2 = LU%diag(i) - 1
      sum = dot_product(LU%a(ij1:ij2), x_vek(LU%ja(ij1:ij2)))
      x_vek(i) = (b_vek(i) - sum)
    end do
    

在没有 openMP 或只有一个线程的 openMP 的情况下编译 - 正确的结果

使用 openMP 和 1 个以上的线程编译 - 不同的、错误的结果、偏离正确的预期结果

Fortran OpenMP 英特尔-Fortran

评论

0赞 PierU 9/19/2023
您有一个竞争条件,即在给定的迭代中,您正在读取一些可能在其他迭代中编写的元素。x_vek
0赞 PierU 9/19/2023
顺便说一句,如果你的代码是 LU 分解,则迭代相互依赖,无法并行化
0赞 user22593146 9/19/2023
谢谢!绝对是这样!这是LU分解,是不是意味着它根本无法并行化?或者有办法做到吗?
0赞 PierU 9/19/2023
当然存在用于 LU 分解的并行算法,但我很确定它们不是平凡的......经典的、“幼稚”的方式是内在的顺序。
1赞 Ian Bush 9/20/2023
如果您正在尝试编写一个并行 LU 分解/方程求解器,为什么不使用一个预先存在的库而不是编写自己的库呢?对于稀疏系统,有一个并行的直接(和迭代)求解器,为什么不使用其中之一呢?

答: 暂无答案