2017-09-17 5 views
0

ich an einem Projekt arbeite, wo ich wie dieseMPI abgeleiteten Datentyp für Eigen Array

eine Klasse mit Eigen Array erstellt
class Cartesian{ 
    public: 
     double x() const { return r_(0); } 
     double y() const { return r_(1); } 
     double z() const { return r_(2); } 
    private: 
     Eigen::Array3d r_; 
} 

Eigen::Array<Cartesian, Eigen::Dynamic, 1> Cart_Array(10); 

So, jetzt will ich Cart_Array mit MPI_Send von Proc 0 bis Proc 1. Was ist die schicken beste Art es zu tun? Ich möchte einen abgeleiteten MPI-Datentyp erstellen; z.B. Cart_Type, und dann zu senden, wie

MPI_Send(&Cart_Array, 10, Cart_Type, 1, TAG, MPI_COMM_WORLD). 

Ich weiß, wie MPI abgeleitete Typen für einfache Dinge zu schaffen MPI_Type_create_struct verwenden, etc. Aber ich weiß nicht, wie es für den Fall zu tun, ich zeigte. Bitte zeig es mir. Wenn möglich, möchte ich andere Bibliotheken wie Boost vermeiden.

EDITS:

fragte ich diese Frage, weil ich mit der Serialisierung Ansatz vermeiden wollte. Und das liegt daran, dass dies Teil eines großen Programms ist, das Effizienz betont.

Antwort

0

Sie sollten etwas wie unten tun. Serialisieren Sie einfach einen oder mehrere Cartesian in Vektor von Doppel, senden und empfangen Sie diese Doppel und Deserialise. Ich hoffe, dass das kompiliert wird, weil ich dies nur auf einer Maschine ohne MPI eingegeben habe. Ich habe kein Eigen installiert, aber Sie bekommen die Idee.

class Cartesian{ 
public: 
    double x() const { return r_(0); } 
    double y() const { return r_(1); } 
    double z() const { return r_(2); } 
    std::vector<double> const& r() const { return r_; }; 
    Cartesian* operator=(std::vector<double> const& r) {r_ = r;} 
private: 
    std::vector<double> r_; 
    //Eigen::Array3d r_; 
}; 

// Send vector of Cartesian 
void sendData(std::vector<Cartesian> const& v) { 
    std::vector<double> data; 
    for (auto const& i : v) { 
    data.insert(data.end(), v.r().begin(), v.r().end()); 
    } 
    MPI_Send(data.begin(), data.size(), MPI_DOUBLE, 0, 1, MPI_COMM_WORLD); 
} 

// Receive vector of Cartesian 
std::vector<Cartesian> recvData() { 

    int n; 
    MPI_Status status; 
    MPI_Probe(0, 0, MPI_COMM_WORLD, &status); // Incoming? 
    MPI_Get_count(&status, MPI_INT, &n); // Number of incoming 

    std::vector<Cartesian> v; 
    if (n>0) { 
    std::vector<double>(n); 
    MPI_Recv(n.begin(), n, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); 
    v.resize(n/3); 
    int i = 0; 
    for (auto i : v) { 
     i.r(*b.begin()+3*i); 
     ++i; 
    } 
    } 
    return v; 

} 

int main() { 

    MPI_Init(NULL, NULL); 

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

    std::vector<Cartesian> data; 
    if (rank == 0) { 
    data.resize(1000); 
    sendData(data); 
    } else { 
    data = recvData(); 
    } 

    MPI_Finalize(); 

} 
+0

Danke. Ich habe in meiner früheren Version des Codes tatsächlich die Serialisierung verwendet, aber es beinhaltet das Kopieren und Verschieben von Daten. Ich möchte abgeleiteten Datentyp verwenden, um zu hoffen, dass es effizienter sein könnte, da der Code, den ich zeigte, Teil eines großen High Performance Computation-Programms ist. Irgendein bestimmter Grund, warum Sie std :: vector anstelle von Eigen verwenden, außer Sie haben es nicht? – Bill

+0

Welche Netzwerkstruktur verwenden Sie? Wenn Sie nicht auf Infiniband sind, denken Sie nicht einmal über diese Route nach. Auch wenn ich Sie wäre, würde ich den Code profilieren und herausfinden, ob Sie nicht 0,001% optimieren. Ich bezweifle sehr, dass Sie im Vergleich zur Netzwerk- und Rechenzeit einen Wert auf die Serialisierung legen können. –

+0

Ich benutze den Code auf mehreren Plattformen, einige von ihnen verwenden Infiniband. Danke für Ihre Hilfe. – Bill