You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过MPI收发包含二维数组的C语言结构体?

解决MPI收发含二维数组的C结构体问题

Hey there! Let's walk through how to send and receive that C struct with a 2D array using MPI. I see you've already made progress with serialization, so let's break down the approach and confirm the key steps that make this work.

方法1:手动序列化(你目前采用的方案)

手动序列化 involves unpacking the struct into basic data types for transmission, then reassembling them on the receiving end. Here's a breakdown of your modified code with key explanations:

typedef struct a_s { double array[3][3]; int err; } a;

int main(int argc, char** argv) {
    // Initialize the MPI environment
    MPI_Init(NULL, NULL);

    int rank, size;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    a my_data;
    // Rank 0 prepares the data to send
    if (rank == 0) {
        // Populate the 2D array
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                my_data.array[i][j] = i * 3.0 + j;
            }
        }
        my_data.err = 0;
        
        // Send the 2D array as a contiguous block of 9 doubles
        MPI_Send(my_data.array, 9, MPI_DOUBLE, 1, 0, MPI_COMM_WORLD);
        // Send the err integer separately
        MPI_Send(&my_data.err, 1, MPI_INT, 1, 1, MPI_COMM_WORLD);
    } 
    // Rank 1 receives and reassembles the data
    else if (rank == 1) {
        MPI_Recv(my_data.array, 9, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
        MPI_Recv(&my_data.err, 1, MPI_INT, 0, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
        
        // Verify the received data
        printf("Received 3x3 array:\n");
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                printf("%.1f ", my_data.array[i][j]);
            }
            printf("\n");
        }
        printf("Received error code: %d\n", my_data.err);
    }

    // Clean up MPI resources
    MPI_Finalize();
    return 0;
}

关键注意事项:

  • The 2D array array[3][3] is stored contiguously in memory, so we can treat it as a 1D array of 9 double values for transmission—no need to send each row individually.
  • Use distinct message tags (like 0 for the array and 1 for the error code) to avoid mixing up messages during reception.
  • Ensure the receiving order matches the sending order exactly to correctly reconstruct the struct.

方法2:自定义MPI数据类型(更简洁的替代方案)

If you want to avoid manual serialization, you can create a custom MPI datatype that matches your struct. This lets MPI handle the transmission as a single unit:

typedef struct a_s { double array[3][3]; int err; } a;

int main(int argc, char** argv) {
    MPI_Init(NULL, NULL);

    int rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    // Define custom MPI datatype for the struct
    MPI_Datatype MPI_A_STRUCT;
    MPI_Aint offsets[2];
    int blocklengths[2] = {9, 1}; // 9 doubles for the array, 1 int for err
    MPI_Datatype types[2] = {MPI_DOUBLE, MPI_INT};

    // Calculate offsets of each member in the struct
    offsets[0] = offsetof(a, array);
    offsets[1] = offsetof(a, err);

    // Create and commit the custom type
    MPI_Type_create_struct(2, blocklengths, offsets, types, &MPI_A_STRUCT);
    MPI_Type_commit(&MPI_A_STRUCT);

    a my_data;
    if (rank == 0) {
        // Populate data...
        MPI_Send(&my_data, 1, MPI_A_STRUCT, 1, 0, MPI_COMM_WORLD);
    } else if (rank == 1) {
        MPI_Recv(&my_data, 1, MPI_A_STRUCT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
        // Verify data...
    }

    // Free the custom datatype when done
    MPI_Type_free(&MPI_A_STRUCT);
    MPI_Finalize();
    return 0;
}

This approach is cleaner for complex structs, as you don't have to manage separate send/receive calls for each member. Both methods work reliably—pick whichever fits your code style better!

内容的提问来源于stack exchange,提问作者L. Hidalgo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:30:02