【问题标题】:How can I send columns in mpi4py using structs?如何使用结构在 mpi4py 中发送列?
【发布时间】:2023-01-02 23:11:04
【问题描述】:

所以我的目标是使用 mpi4py 将矩阵 A 的右列发送到另一个线程,它应该写入矩阵 B 的左列。因此我们从两个 numpy ndarrays int 开始,例如以下形式:

[[1,2,3]   [[0,0,0]
 [4,5,6]    [0,0,0]
 [7,7,9]],  [0,0,0]]

发送后,我希望它们如下所示:

[[1,2,3]   [[3,0,0]
 [4,5,6]    [6,0,0]
 [7,7,9]],  [9,0,0]]

一种方法是在 mpi4py 中使用结构。我不想将它们保存在缓冲区中,然后将其复制到矩阵中。

我尝试使用MPI.INT.Create_vector 来做到这一点。但无论我尝试什么,我似乎都没有得到正确的结构。我有一个测试脚本,我以mpirun -n 2 python3 mpi_type_tester.py开头:

import numpy as np
from mpi4py import MPI

comm = MPI.COMM_WORLD
world_size = comm.Get_size()
rank = comm.Get_rank()

# Size of my send and receive matrix
height = 3
width  = 3

# Variables used to define the struct
count = 3
blocklength = 1
stride = 3

# Int seemingly used to define how many of the structs are being sent?
sending_int = 1

# Here I define the struct with Create_vector:
column_type = MPI.INT.Create_vector(count = count,blocklength = blocklength,stride = stride)
column_type.Commit()


if rank == 0:
    send_array = np.arange(width*height).reshape(height,width)
    send_array += 1

    comm.Send([send_array,sending_int, column_type], dest = 1, tag = 0) 

    print(send_array)

if rank == 1:
    rec_array = np.zeros(width*height, dtype = int).reshape(height, width)
    comm.Recv([rec_array,sending_int,column_type], source = 0, tag = 0)

    print(rec_array)

当我现在改变countblocklengthstridesending_int时,它只是发送看似随机的东西。有人可以帮助我理解这一点,或者指出一些资源以便我理解Create_vector吗?

【问题讨论】:

    标签: python multithreading struct mpi mpi4py


    【解决方案1】:

    您需要密切注意您的数据具有相同的数据类型和大小,并且您告诉 MPI 发送所述大小的数据,例如 numpy 可能会使用 int32float32 如果它认为它不需要使用更大的类型,所以你必须明确你的数据类型。

    import numpy as np
    from mpi4py import MPI
    
    comm = MPI.COMM_WORLD
    world_size = comm.Get_size()
    rank = comm.Get_rank()
    
    height = 3
    width  = 3
    
    count = 3
    blocklength = 1
    stride = 3
    
    sending_int = 1
    
    # make sure you are sending exactly 64 bits per item.
    column_type = MPI.INT64_T.Create_vector(count = count,blocklength = blocklength,stride = stride)
    column_type.Commit()
    
    
    if rank == 0:
        # specify dtype
        send_array = np.arange(width*height,dtype=np.int64).reshape(height,width)
        send_array += 1
    
        comm.Send([send_array,sending_int, column_type], dest = 1, tag = 0)
    
        print(send_array)
    
    if rank == 1:
        rec_array = np.zeros(width*height, dtype = np.int64  # specify dtype
                             ).reshape(height, width)
        comm.Recv([rec_array,sending_int,column_type], source = 0, tag = 0)
    
        print(rec_array)
    

    我已经剥离了您的 cmets 并在指定数据类型的地方进行了评论。

    【讨论】:

      猜你喜欢
      • 2012-07-10
      • 2011-04-06
      • 1970-01-01
      • 2023-03-31
      • 2013-11-04
      • 1970-01-01
      • 2014-12-20
      • 2016-07-05
      • 2011-08-23
      相关资源
      最近更新 更多