Передача структуры в MPI в C

#c #mpi

#c #mpi

Вопрос:

Я пытаюсь создать пользовательский тип данных для MPI и передать структуру d_type из корневого процесса в другие процессы, но я получаю ошибку сегментации и следующую ошибку. Позже я хочу создать вектор структуры, а затем передать этот вектор из корневого процесса в другие процессы.

Недопустимый ключ MIT-MAGIC-COOKIE-1[blackbirdx-H170-Gaming-3:11787] *** Обрабатывать принятый сигнал ***

[blackbirdx-H170-Gaming-3:11787] Сигнал: Ошибка сегментации (11)

[blackbirdx-H170-Gaming-3:11787] Код сигнала: Адрес не сопоставлен (1)

[blackbirdx-H170-Gaming-3:11787] Сбой по адресу: 0x7ffd2daa9dd8

[blackbirdx-H170-Gaming-3:11788] *** Обработать полученный сигнал ***

[blackbirdx-H170-Gaming-3:11789] *** Обработать принятый сигнал ***

[blackbirdx-H170-Gaming-3:11789] Сигнал: ошибка сегментации (11)

[blackbirdx-H170-Gaming-3:11789] Код сигнала: Адрес не сопоставлен (1)

[blackbirdx-H170-Gaming-3:11789] Сбой по адресу: 0x7ffd2daa9dd8

 #include <iostream>
#define HAVE_STRUCT_TIMESPEC
#include <mpi.h>
#include <time.h>
#include <queue>
#include <string>
#include <sstream>
#include <fstream>
#include <thread>  
#include <chrono> 
#include <vector>
using namespace std;
struct d_type{
    string timestamp;
    int lightpostID;
    int carTraffic;
};
class trafficData
{
public:
    string timestamp;
    int lightpostID;
    int carTraffic;

    trafficData(string timestamp, int lightpostID, int carTraffic);
};

trafficData::trafficData(string timestamp, int lightpostID, int carTraffic)
{
    this->timestamp = timestamp;
    this->lightpostID = lightpostID;
    this->carTraffic = carTraffic;
}
#define TRAFFIC_LIGHTS 5 
#define SIMULATION_TIME 3
#define MASTER_RANK 0
MPI_Status status;
#define CLASS_MASTER 1
#define CLASS_WORKER 2
int counter =0;
void generateTraffic();
// Read into queue.
void dataProducer();
// Read data from queue and sort it into list.
void dataConsume();
queue<trafficData> dataQueue;
vector<trafficData> sortedTraffic;
vector<trafficData> hourlyTraffic;
vector<string> movementLog;

int main(int argc, char *argv[])
{
    int sizeCommunicator,rankProcess,idProcess,offsetTotal;
    int offsetRow,workProcess,remainder,whole_part;
    int message_tag;
    MPI_Init(amp;argc, amp;argv);
    MPI_Comm_size(MPI_COMM_WORLD, amp;sizeCommunicator);
    MPI_Comm_rank(MPI_COMM_WORLD, amp;rankProcess);
    if(sizeCommunicator < 2){
        MPI_Abort(MPI_COMM_WORLD, 1);
    }
    MPI_Datatype string_dt;
    MPI_Type_contiguous(6, MPI_CHAR, amp;string_dt);
    MPI_Type_commit(amp;string_dt);
    
    MPI_Datatype traffic_type;
    const int nitems=3;
    int blocklengths[nitems] = {1,1,1};
    const MPI_Aint displacements[nitems] = { offsetof(d_type, timestamp), offsetof(d_type, lightpostID), offsetof(d_type, carTraffic) };
    MPI_Datatype types[nitems] = {  string_dt ,MPI_INT, MPI_INT};
    MPI_Type_create_struct(nitems, blocklengths, displacements, types, amp;traffic_type);
    MPI_Type_commit(amp;traffic_type);
    MPI_Barrier(MPI_COMM_WORLD);

    if(rankProcess == MASTER_RANK) {
        workProcess = sizeCommunicator - 1;
        string str="11:55";
        d_type buffer;
        buffer.timestamp="11:00";
        buffer.lightpostID=1;
        buffer.carTraffic=500;
    
        message_tag = CLASS_MASTER;
            for(idProcess = 1; idProcess <= workProcess; idProcess    ){
              MPI_Send(amp;buffer, 1, traffic_type, idProcess, message_tag, MPI_COMM_WORLD);
            }
        message_tag = CLASS_WORKER;
            for(idProcess = 1; idProcess <= workProcess; idProcess   ){
                MPI_Recv(amp;str[0], 1, string_dt, idProcess, message_tag, MPI_COMM_WORLD, amp;status);
                cout<<str<<endl;
            }
    }
    if(rankProcess != MASTER_RANK){
        string str;
        d_type data;
        message_tag = CLASS_MASTER;
        MPI_Recv(amp;data, 1, traffic_type, MASTER_RANK, message_tag, MPI_COMM_WORLD, amp;status);

        
       //cout<<data.timestamp<<endl;
        // cout<<str<<endl;
        str="gone";
        message_tag = CLASS_WORKER;
        MPI_Send(amp;str[0], 1, string_dt, MASTER_RANK, message_tag, MPI_COMM_WORLD);
    }
    MPI_Barrier(MPI_COMM_WORLD);
    MPI_Finalize();
    return 0;
}
  

Комментарии:

1. Я не использовал MPI , но где указание на то, что он может работать с типами, которые не являются POD и / или не поддаются тривиальному копированию? Ваши переменные-члены struct имеют std::string значение, что делает их не-POD и не поддающимися тривиальному копированию. Я бы подумал, что вам нужно использовать C структуры, совместимые с макетом.

2. вы не можете использовать std::string и создавать свой производный тип данных так, как если бы это был char[6]

3. Рассмотрите возможность использования Boost. MPI для передачи типов данных C . Сам MPI имеет только C API, который ничего не знает о классах.

4. std::string является самой структурой, содержащей указатель на кучу. Невозможно определить единый тип данных, производный от MPI, который работает со многими экземплярами std::string , потому что указатель кучи отличается в каждом экземпляре.