在 Fortran 中使用 Gatherv 处理二维数组

2023-12-08

我在不同进程上有许多大小 = (2,9) 的二维数组,我想在根进程上使用 MPI_Gatherv 将其连接到大小 = (2*nProcs,9) 的全局数组中。为此,我正在尝试调整这篇文章:使用 MPI_Gather 在 Fortran 中发送 2D 数组

但我确实理解他们在做什么,但我的例子不起作用:

program testing
    use mpi
    implicit none
    integer(4), allocatable :: local(:,:)
    integer(4), allocatable :: global(:,:), displs(:), counts(:)
    integer(4)              :: me, nProcs, ierr, i 
    integer(4), parameter   :: root = 3
    integer                 :: loc_size(2), glob_size(2), newtype, int_size, &
        resizedtype, starts(2)

    integer(kind=MPI_ADDRESS_KIND) :: extent, begin

    call MPI_Init(ierr)
    call MPI_Comm_rank(MPI_COMM_WORLD, me, ierr)
    call MPI_Comm_size(MPI_COMM_WORLD, nProcs, ierr)

    loc_size  = [2,9]
    glob_size = [2*nProcs, 9]
    starts    = [0, 0]

    allocate(local(loc_size(1),   loc_size(2)))
    allocate(global(glob_size(1), glob_size(2)))
    allocate(displs(nProcs))
    allocate(counts(nProcs))

    call create_loc(me, local)

    do i = 0,nProcs-1
        if(me ==  i) then
            call print_mtx(me, local)
        endif
        call MPI_Barrier(MPI_COMM_WORLD, ierr)
    enddo

    call MPI_Type_create_subarray(2, glob_size, loc_size, starts, &
        MPI_ORDER_FORTRAN, MPI_INTEGER4, &
        newtype, ierr)

    call MPI_Type_size(MPI_INTEGER4, int_size, ierr)
    extent =  2*9 *  int_size
    begin  =  0
    call MPI_Type_create_resized(newtype, begin, extent, resizedtype, ierr)
    call MPI_Type_commit(resizedtype, ierr)

    counts =  1

    do i =  1,nProcs
        displs(i) = (i-1) * 2 * 9 
    enddo

    call MPI_Gatherv(local, 2*9, MPI_INTEGER4, &
        global, counts, displs, resizedtype, &
        root, MPI_COMM_WORLD, ierr)

    if(me ==  root) then
        write (*,*) "##########################"
    endif
    call MPI_Barrier(MPI_COMM_WORLD, ierr)
    if(me ==  root) then
        call print_mtx(me, global)
    endif
    call MPI_Barrier(MPI_COMM_WORLD, ierr)
    call MPI_Finalize(ierr)

contains
    subroutine create_loc(me, arr)
        implicit none
        integer(4), intent(in)  :: me
        integer(4),allocatable  :: arr(:,:)
        integer(4)              :: i

        do i =  1,9
            arr(1,i) = 20 * me + i
            arr(2,i) = 20 * me + i + 10
        enddo
    end subroutine create_loc

    subroutine print_mtx(me, mtx)
        implicit none
        integer(4), intent(in)  :: me, mtx(:,:)
        integer(4)              :: i, j

        do i =  1,size(mtx,2)
            write (unit=6, fmt="(A,I2,A)", advance='no') '[',me, ']' 
            do j =  1,size(mtx,1)
                write(unit=6,fmt="(I,A)",advance='no') mtx(j,i), ";  "
            enddo
            write (*,*) " "
        enddo
        write (*,*) " "
    end subroutine print_mtx


end program testing

其输出:

[ 0]           1;            11;    
[ 0]           2;            12;    
[ 0]           3;            13;    
[ 0]           4;            14;    
[ 0]           5;            15;    
[ 0]           6;            16;    
[ 0]           7;            17;    
[ 0]           8;            18;    
[ 0]           9;            19;    

[ 1]          21;            31;    
[ 1]          22;            32;    
[ 1]          23;            33;    
[ 1]          24;            34;    
[ 1]          25;            35;    
[ 1]          26;            36;    
[ 1]          27;            37;    
[ 1]          28;            38;    
[ 1]          29;            39;    

[ 2]          41;            51;    
[ 2]          42;            52;    
[ 2]          43;            53;    
[ 2]          44;            54;    
[ 2]          45;            55;    
[ 2]          46;            56;    
[ 2]          47;            57;    
[ 2]          48;            58;    
[ 2]          49;            59;    

[ 3]          61;            71;    
[ 3]          62;            72;    
[ 3]          63;            73;    
[ 3]          64;            74;    
[ 3]          65;            75;    
[ 3]          66;            76;    
[ 3]          67;            77;    
[ 3]          68;            78;    
[ 3]          69;            79;    

 ##########################
[ 3]           1;            11;   -2111771071;         32765;   -2111771061;         32765;   -2111771047;         32765;    
[ 3]           2;            12;   -2111771013;         32765;   -2111770992;         32765;   -2111770934;         32765;    
[ 3]           3;            13;   -2111769952;         32765;   -2111769932;         32765;   -2111769910;         32765;    
[ 3]           4;            14;   -2111769772;         32765;   -2111769691;         32765;   -2111769647;         32765;    
[ 3]           5;            15;   -2111769585;         32765;   -2111769533;         32765;   -2111769511;         32765;    
[ 3]           6;            16;   -2111769426;         32765;   -2111769398;         32765;   -2111769319;         32765;    
[ 3]           7;            17;   -2111769242;         32765;   -2111769178;         32765;   -2111769145;         32765;    
[ 3]           8;            18;   -2111769061;         32765;   -2111768963;         32765;   -2111768932;         32765;    
[ 3]           9;            19;   -2111768793;         32765;   -2111768613;         32765;   -2111768596;         32765;    

由于第一个进程上的数组传递得很好,我最好的猜测是,它与位移有关,但我无法修复它。

在上面提到的帖子中,他们创建了一个像这样的新类型:

call MPI_Type_size(MPI_CHARACTER, charsize, ierr)
extent = localsize*charsize
begin  = 0
call MPI_Type_create_resized(newtype, begin, extent, resizedtype, ierr)
call MPI_Type_commit(resizedtype, ierr)

MPI_Type_create_resized 有什么作用以及为什么有必要?

他们设置范围 = localsize*charsize (不是 localsize**2*charsize)并且计数 = 1,但子数组是 3x3,而不是 3x1。他们怎么还在发送 3x3 矩阵?

如何修复我的示例程序?


您的程序有两个问题:

replace

extent =  2*9 *  int_size

with

extent =  2 *  int_size

并替换

displs(i) = (i-1) * 2 * 9 

with

displs(i) = (i-1)

你应该没事

 ##########################
[ 3]       1;        11;        21;        31;        41;        51;        61;        71;    
[ 3]       2;        12;        22;        32;        42;        52;        62;        72;    
[ 3]       3;        13;        23;        33;        43;        53;        63;        73;    
[ 3]       4;        14;        24;        34;        44;        54;        64;        74;    
[ 3]       5;        15;        25;        35;        45;        55;        65;        75;    
[ 3]       6;        16;        26;        36;        46;        56;        66;        76;    
[ 3]       7;        17;        27;        37;        47;        57;        67;        77;    
[ 3]       8;        18;        28;        38;        48;        58;        68;        78;    
[ 3]       9;        19;        29;        39;        49;        59;        69;        79;    

一般来说,我不认为MPI_Type_create_subarray非常适合分散/聚集,在这种情况下,您可以简单地使用MPI_Type_vector

call MPI_Type_vector(9, 2, 8, MPI_INTEGER4, newtype, ierr)

(注意,你仍然需要MPI_Type_create_resized)

最后但并非最不重要的一点是,你并不真正需要MPI_Gatherv here,

call MPI_Gather(local, 2*9, MPI_INTEGER4, &
    global, 1, resizedtype, &
    root, MPI_COMM_WORLD, ierr)

这里已经足够好了

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Fortran 中使用 Gatherv 处理二维数组 的相关文章

  • 在php中对带有特殊字符的多维数组进行排序

    我有一个多维数组 我按字母顺序排序 但问题是 带有丹麦语特殊字符 它们应该按该顺序排序 但不会按该顺序返回 这是我的数组 部分已删除 Array 0 gt Array Name gt John 1 gt Array Name gt Pate
  • 在 postgresql 9.4 或 9.5 中查询 json 对象的嵌套数组中的元素

    studentID 1 StudentName jhon Data schoolname school1 enrolmentInfo year 2015 info courseID csc213 school IT enrollmentda
  • 在 Numpy 中切片后确定结果数组的形状

    我很难理解在 numpy 中切片后如何确定结果数组的形状 例如 我使用以下简单代码 import numpy as np array np arange 27 reshape 3 3 3 slice1 array 1 2 1 slice2
  • 在 Postgres 中的数组字段上应用聚合函数?

    是否可以对整数 字段 或其他数字数组 中的所有值应用聚合 如 avg stddev CREATE TABLE widget measurement integer insert into widget measurement values
  • 大小为 8 的无效写入,C Valgrind,字符串数组

    我一直在使用 valgrind 和 gdb 但我不太明白问题是什么 它跳来跳去太多了 我无法在 gdb 中真正追踪它 而在 valgrind 中我没有足够的信息 这是我的 makeargv 函数 它将 strtok 输出的字符串放入数组中
  • 如何 grep 遍历数组,同时过滤掉匹配项?

    有没有一种快速简便的方法来 grep 遍历数组 找到满足某些测试的元素and从原始数组中删除这些 例如我想要 a 1 7 6 3 8 4 b grep filter gt 5 a now b 7 6 8 and a 1 3 4 换句话说 我
  • 这些双精度值如何精确到小数点后 20 位?

    当精度是一个问题时 我正在测试一些非常简单的等价错误 并希望以扩展双精度执行操作 这样我就知道答案在 19位数字中 然后以双精度执行相同的操作 其中第 16 位会有舍入误差 但不知何故 我的双精度算术保持了 19 位精度 当我在扩展双精度中
  • 在 Javascript 中创建数组

    我对 javascript 不太熟悉 并且在用 javascript 制作 2d 或者也许我可能需要 3d 数组时遇到了一些麻烦 我目前需要收集 2 条信息 一个 ID 和一个值 因此我创建了以下内容 var myArray var id
  • 将一维数组转换为二维数组[重复]

    这个问题在这里已经有答案了 我正在开发一个程序 我必须将文本文件中的值读入一维数组 我已经成功获取该一维数组中的数字 m1 1 2 3 4 5 6 7 8 9 但我希望数组是 m1 1 2 3 4 5 6 7 8 9 您可以使用此代码 co
  • C# 3维数组

    我想将 3 维数组中的 ARRAY 存储到buildingCostIds 中 但它说我必须有第三个数字 public static int buildingCost 0 1 2 5 5 5 public static void addBui
  • 给定一个零索引数组 & 该数组的平衡索引[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 给出一个由 N 个整数组成的零索引数组 A 该数组的平衡索引是任何整数 P 满足 0 P 例如 考虑以下由 N 8 个元素组成的数组
  • MPI 中的等级和进程有什么区别?

    MPI 中的等级和进程有什么区别 Here http www netlib org utk papers mpi book mpi book html是我学习所有 MPI 的资源 您可能会发现它很有用 至于你的问题 流程是正在运行的程序的实
  • 根据重复值对 PHP 数组进行排序

    我有一个包含重复值的数组 我想对数组进行排序 以便重复次数最多的值出现在行中的第一个 这是我的数组的示例 array 1 2 3 2 1 2 2 我想对该数组进行排序 以便它根据重复项的数量对自身进行排序 如下所示 array 2 1 3
  • 使用排序函数按 NSDates 对数组进行排序[重复]

    这个问题在这里已经有答案了 我有一个名为的模型类Event import Foundation import MapKit public class Event let id Int var title String let status
  • 使用 numpy 加速 for 循环

    下一个 for 循环如何使用 numpy 获得加速 我想这里可以使用一些奇特的索引技巧 但我不知道是哪一个 这里可以使用 einsum 吗 a 0 for i in range len b a numpy mean C d e f b i
  • 如何从 Adob​​e AIR 中的文件流获取字节数组?

    我阅读的内容有限 小 15 500 mb 文件 我需要能够将所有文件字节放入一个字节数组中 所以我有一个功能 Bindable public var ba ByteArray new ByteArray code protected fun
  • 你能向被劫持的 JavaScript 数组添加一个函数吗?

    这个问题与在 Javascript 中声明数组时应遵循哪些最佳实践 https stackoverflow com q 11500492 508537 假设有一个客户 我们就称他们为客户 D B 库珀 http en wikipedia o
  • $_POST 最大数组大小

    我有一个非常大的表单 有 gt 1000 个元素 它们已经嵌套在表单 html 结构中 foreach from result item item tr td td tr
  • 使用 calloc() 设置 char 数组,完成后还会“释放”数组

    我正在尝试设置一个字符串数组 在 C 语言中 使用 Linux 该数组将容纳 11 个字符串 静态长度 我最初将数组设置为 char Answers 10 100 但在我的代码中 我有一部分调用 fgets input sizeof inp
  • 它们是“相同的”吗?代码大战

    这是完整的问题描述 给定两个数组 a 和 b 编写一个函数 comp a b Clojure 中的 compSame a b 来检查这两个数组是否具有 相同 元素以及相同的重数 这里 相同 意味着 b 中的元素是 a 平方中的元素 无论顺序

随机推荐