第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在C中進行結(jié)構(gòu)化序列化并通過MPI進行傳輸

在C中進行結(jié)構(gòu)化序列化并通過MPI進行傳輸

莫回?zé)o 2019-11-29 10:38:24
我已經(jīng)定義了一個自定義結(jié)構(gòu),并希望使用MPI_Bsend(或MPI_Send)將其發(fā)送到另一個MPI進程。這是我的結(jié)構(gòu):struct car{  int shifts;  int topSpeed;}myCar;但是,除了基本類型,MPI似乎不支持復(fù)雜數(shù)據(jù)類型的直接“傳輸”,如上面的struct。我聽說我可能必須使用“序列化”。我應(yīng)該如何處理并將“ myCar”發(fā)送給進程5?
查看完整描述

3 回答

?
瀟湘沐

TA貢獻1816條經(jīng)驗 獲得超6個贊

耶利米是對的-MPI_Type_create_struct是前往此處的方法。


重要的是要記住,MPI是一個庫,而不是語言的內(nèi)置庫。因此它無法“看到”結(jié)構(gòu)將其自身序列化的樣子。因此,要發(fā)送復(fù)雜的數(shù)據(jù)類型,必須顯式定義其布局。在確實具有序列化支持的語言中,一組MPI包裝器可以方便地利用它。例如,mpi4py利用python的pickle透明地發(fā)送復(fù)雜的數(shù)據(jù)類型;但是在C語言中,您必須卷起袖子,自己動手做。


對于您的結(jié)構(gòu),它看起來像這樣:


#include <stdio.h>

#include <stdlib.h>

#include <mpi.h>

#include <stddef.h>


typedef struct car_s {

        int shifts;

        int topSpeed;

} car;


int main(int argc, char **argv) {


    const int tag = 13;

    int size, rank;


    MPI_Init(&argc, &argv);

    MPI_Comm_size(MPI_COMM_WORLD, &size);


    if (size < 2) {

        fprintf(stderr,"Requires at least two processes.\n");

        exit(-1);

    }


    /* create a type for struct car */

    const int nitems=2;

    int          blocklengths[2] = {1,1};

    MPI_Datatype types[2] = {MPI_INT, MPI_INT};

    MPI_Datatype mpi_car_type;

    MPI_Aint     offsets[2];


    offsets[0] = offsetof(car, shifts);

    offsets[1] = offsetof(car, topSpeed);


    MPI_Type_create_struct(nitems, blocklengths, offsets, types, &mpi_car_type);

    MPI_Type_commit(&mpi_car_type);


    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    if (rank == 0) {

        car send;

        send.shifts = 4;

        send.topSpeed = 100;


        const int dest = 1;

        MPI_Send(&send,   1, mpi_car_type, dest, tag, MPI_COMM_WORLD);


        printf("Rank %d: sent structure car\n", rank);

    }

    if (rank == 1) {

        MPI_Status status;

        const int src=0;


        car recv;


        MPI_Recv(&recv,   1, mpi_car_type, src, tag, MPI_COMM_WORLD, &status);

        printf("Rank %d: Received: shifts = %d topSpeed = %d\n", rank,

                 recv.shifts, recv.topSpeed);

    }


    MPI_Type_free(&mpi_car_type);

    MPI_Finalize();


    return 0;

}


查看完整回答
反對 回復(fù) 2019-11-29
?
慕少森

TA貢獻2019條經(jīng)驗 獲得超9個贊

盡管喬納森·杜爾西(Jonathan Dursi)的回答是正確的,但它過于復(fù)雜。MPI提供了更簡單,通用性更小的類型構(gòu)造函數(shù),更適合您的問題。MPI_Type_create_struct僅當您具有不同的基本類型(例如int和float)時才需要。


對于您的示例,存在幾種更好的解決方案:


假設(shè)兩個整數(shù)在連續(xù)的內(nèi)存區(qū)域中對齊(即,就像整數(shù)數(shù)組一樣),則根本不需要派生的數(shù)據(jù)類型。只需發(fā)送/接收兩個具有type MPI_INT變量的地址的type元素car即可用作發(fā)送/接收緩沖區(qū):


MPI_Send(&send, 2, MPI_INT, dest, tag, MPI_COMM_WORLD);

MPI_Recv(&recv, 2, MPI_INT, src, tag, MPI_COMM_WORLD, &status);

如果要使用派生的數(shù)據(jù)類型(例如,出于可讀性或樂趣),則可以使用MPI_Type_contiguous與數(shù)組相對應(yīng)的數(shù)據(jù)類型:


MPI_Type_contiguous(2, MPI_INT, &mpi_car_type);

如果兩個整數(shù)的對齊方式不同(很可能不是這種情況,但這是與機器相關(guān)的,并且MPI實現(xiàn)存在于許多不同的平臺上),則可以使用MPI_Type_indexed_block:它接受一組位移數(shù)組(如MPI_Type_create_struct),但是只有一個舊類型參數(shù),每個塊的塊長按定義為1:


MPI_Aint offsets[2];

offsets[0] = offsetof(car, shifts) ; //most likely going to be 0 

offsets[1] = offsetof(car, topSpeed);

MPI_Type_indexed_block(2, offsets, MPI_INT);

盡管其他解決方案在語義上是正確的,但它很難閱讀,并且可能會導(dǎo)致較大的性能損失。


查看完整回答
反對 回復(fù) 2019-11-29
?
四季花海

TA貢獻1811條經(jīng)驗 獲得超5個贊

int MPI_Send(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)

OpenMPI將發(fā)送count * sizeof(datatype)從開始的連續(xù)字節(jié),buf以允許發(fā)送類似int數(shù)組的內(nèi)容。例如,如果聲明一個10 int數(shù)組int arr[10],則可以使用


MPI_Send(arr, 10, MPI_INT, 1, 0, MPI_COMM_WORLD);

并收到類似的消息。由于buf是空指針,我們可以通過發(fā)送sizeof(my_struct)字節(jié)并在接收端將其強制轉(zhuǎn)換為結(jié)構(gòu)來濫用此結(jié)構(gòu)來發(fā)送結(jié)構(gòu)。這是一個例子:


#include "mpi.h"

#include <stdio.h>


typedef struct 

{

    char a;

    int b;

    short c;

} my_struct;



int main (int argc, char *argv[])

{

    int  numtasks, taskid;


    MPI_Init(&argc, &argv);

    MPI_Comm_rank(MPI_COMM_WORLD, &taskid);

    MPI_Comm_size(MPI_COMM_WORLD, &numtasks);



    if (taskid == 0) 

    {

        my_struct m;

        m.a = '!';

        m.b = 1234;

        m.c = 5678;


        MPI_Send(&m, sizeof(my_struct), MPI_CHAR, 1, 0, MPI_COMM_WORLD);

    }

    else 

    {

        my_struct m;

        MPI_Recv(&m, sizeof(my_struct), MPI_CHAR, 0, 0, MPI_COMM_WORLD, 

                 MPI_STATUS_IGNORE);

        printf("%c %d %d\n", m.a, m.b, m.c); 

    }


    MPI_Finalize();

}

由于C數(shù)組是連續(xù)存儲數(shù)據(jù)的,所以我們甚至可以像構(gòu)造m數(shù)組一樣發(fā)送結(jié)構(gòu)數(shù)組。因此,如果您有一個my_struct m_array[10],則可以發(fā)送(并以類似方式接收)


MPI_Send(m_array, sizeof(my_struct) * 10, MPI_CHAR, 1, 0, MPI_COMM_WORLD);


查看完整回答
反對 回復(fù) 2019-11-29
  • 3 回答
  • 0 關(guān)注
  • 666 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號