2015-01-13 2 views
5

का उपयोग कर गतिशील आकार के साथ गतिशील सरणी भेजें ओपनएमपीआई: मैं रूट नोड पर एक फ़ाइल पढ़ना चाहता हूं और उस फ़ाइल की सामग्री को अन्य सभी नोड्स पर भेजना चाहता हूं। मैं पाया है MPI_Bcast करता है कि कि:MPI_Bcast

int MPI_Bcast(void *buffer, int count, MPI_Datatype datatype, 
    int root, MPI_Comm comm) 

सभी उदाहरण है कि मैं पाया है count मूल्य पहले से ही ज्ञात है, लेकिन मेरे मामले में, गिनती मूल्य मुख्य रूप से जड़ पर जाना जाता है। अन्य examples कहते हैं कि MPI_Bcast का एक ही कॉल अन्य नोड्स पर डेटा पुनर्प्राप्त करता है।

मैं इस जोड़ दिया है:

typedef short Descriptor[128]; 
MPI_Datatype descriptorType; 
MPI_Type_contiguous(sizeof(Descriptor), MPI_SHORT, &descriptorType); 
MPI_Type_commit(&descriptorType); 



if(world_rank == 0) { 
    struct stat finfo; 

    if(stat(argv[1], &finfo) == 0) { 
     querySize = finfo.st_size/sizeof(Descriptor); 
    } 

{ 
    //read binary query 
    queryDescriptors = new Descriptor[querySize]; 
    fstream qFile(argv[1], ios::in | ios::binary); 
    qFile.read((char*)queryDescriptors, querySize*sizeof(Descriptor)); 
    qFile.close(); 

    } 
} 

    MPI_Bcast((void*)&querySize, 1, MPI_INT, 0, MPI_COMM_WORLD); 
    if (world_rank != 0) 
    { 
     queryDescriptors = new Descriptor[querySize]; 
    } 
    MPI_Bcast((void*)queryDescriptors, querySize, descriptorType, 0, MPI_COMM_WORLD); 

जब मैं इसे इस तरह कहते हैं: mpirun -np 2 ./mpi_hello_world यह ठीक काम करता है, लेकिन जब मैं एक से अधिक से कॉल करने, मैं इस मिल:

mpi_hello_world: malloc.c:3096: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' failed. 
mpi_hello_world: malloc.c:3096: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' failed. 
+2

तो दो प्रसारण, गिनती के साथ पहले, बफर सामग्री के साथ दूसरा मुद्दा: यह MPI_Type_contiguous(sizeof(Descriptor), MPI_CHAR, &descriptorType); यहाँ तुम्हारा के आधार पर कोड का एक टुकड़ा है कि चाल करना चाहिए है होना चाहिए। –

+0

आप सही हैं, यह एक समाधान है। मैं सोच रहा था कि ऐसी परिस्थितियों के लिए एमपीआई में एक तंत्र है या नहीं। – AlexandruC

+0

ऐसा नहीं है कि मुझे पता है, लेकिन मेरे एमपीआई थोड़ा जंगली हो रहा है। –

उत्तर

2

यदि qFile.read(...)if(rank==0){} परीक्षण में संलग्न नहीं है, तो सभी प्रक्रियाएं फ़ाइल को पढ़ेगी। और queryDescriptors = new Descriptor[querySize]; को सभी प्रक्रियाओं के लिए पहले MPI_Bcast() के बाद कॉल किया जाना चाहिए 0: इससे पहले, querySize इन प्रक्रियाओं पर व्यर्थ है।

प्रक्रिया 0 करना होगा:

  • आइटम्स की संख्या को पढ़ने के
  • आवंटित
  • सरणी
  • आइटम
  • सरणी

अन्य प्रसारण की संख्या प्रसारित पढ़ प्रक्रियाओं को अवश्य:

होना चाहिए
  • मदों की संख्या प्राप्त
  • आवंटित
  • सरणी

यहाँ प्राप्त कैसे नाव की एक सरणी पढ़ सकते हैं और गतिशील आवंटन का उपयोग करने का एक उदाहरण है:

#include <stdio.h> 
#include <iostream> 
#include <fstream> 

#include <mpi.h> 
using namespace std; 

int main (int argc, char *argv[]) 
{ 
    int rank; 
    int size; 

    MPI_Init(&argc, &argv); 

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

    if(rank == 0) 
    { 
     //creating the file 
     ofstream myfile; 
     myfile.open ("example.txt", ios::out |ios::binary); 
     int nbitem=42; 
     myfile.write((char*)&nbitem,sizeof(int)); 

     float a=0; 
     for(int i=0;i<nbitem;i++){ 
      myfile.write((char*)&a,sizeof(float)); 
      a+=2; 
     } 
     myfile.close();  
    } 


    //now reading the file 
    int nbitemread=0; 
    float* buffer; 
    if(rank==0){ 
     ifstream file ("example.txt", ios::in |ios::binary); 
     file.read ((char*)&nbitemread, sizeof(int)); 
     buffer=new float[nbitemread]; 
     file.read ((char*)buffer,nbitemread* sizeof(float)); 
     file.close(); 
     //communication 
     MPI_Bcast(&nbitemread, 1, MPI_INT, 0, MPI_COMM_WORLD); 
     MPI_Bcast(buffer, nbitemread, MPI_FLOAT, 0, MPI_COMM_WORLD); 
    }else{ 

     MPI_Bcast(&nbitemread, 1, MPI_INT, 0, MPI_COMM_WORLD); 
     //nbitemread is meaningfull now 
     buffer=new float[nbitemread]; 
     MPI_Bcast(buffer, nbitemread, MPI_FLOAT, 0, MPI_COMM_WORLD); 

    } 

    //printing... 
    cout<<"on rank "<<rank<<" rode "<<buffer[nbitemread/2]<<" on position "<<nbitemread/2<<endl; 

    delete[] buffer; 
    MPI_Finalize(); 

    return 0; 
} 

इसे mpiCC main.cpp -o main के साथ संकलित करें और mpirun -np 2 main

द्वारा चलाएं

आपके कोड में एक और मुद्दा MPI_Type_contiguous(sizeof(Descriptor), MPI_SHORT, &descriptorType); है।

#include <stdio.h> 
#include <iostream> 
#include <fstream> 

#include <sys/types.h> 
#include <sys/stat.h> 
#include <unistd.h> 

#include <mpi.h> 
using namespace std; 

int main (int argc, char *argv[]) 
{ 
    int world_rank; 
    int size; 

    MPI_Init(&argc, &argv); 

    MPI_Comm_size(MPI_COMM_WORLD, &size); 
    MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); 

    int querySize; 


    typedef short Descriptor[128]; 
    MPI_Datatype descriptorType; 
    MPI_Type_contiguous(sizeof(Descriptor), MPI_CHAR, &descriptorType); 
    MPI_Type_commit(&descriptorType); 


    Descriptor* queryDescriptors; 


    if(world_rank == 0) { 
     struct stat finfo; 

     if(stat(argv[1], &finfo) == 0) { 
      cout<<"st_size "<<finfo.st_size<<" descriptor "<<sizeof(Descriptor)<< endl; 
      querySize = finfo.st_size/sizeof(Descriptor); 
      cout<<"querySize "<<querySize<<endl; 
     }else{ 
      cout<<"stat error"<<endl; 
     } 

     { 
      //read binary query 
      queryDescriptors = new Descriptor[querySize]; 
      fstream qFile(argv[1], ios::in | ios::binary); 
      qFile.read((char*)queryDescriptors, querySize*sizeof(Descriptor)); 
      qFile.close(); 

     } 
    } 

    MPI_Bcast((void*)&querySize, 1, MPI_INT, 0, MPI_COMM_WORLD); 
    if (world_rank != 0) 
    { 
     queryDescriptors = new Descriptor[querySize]; 
    } 
    MPI_Bcast((void*)queryDescriptors, querySize, descriptorType, 0, MPI_COMM_WORLD); 

    cout<<"on rank "<<world_rank<<" rode "<<queryDescriptors[querySize/2][12]<<" on position "<<querySize/2<<endl; 

    delete[] queryDescriptors; 

    MPI_Finalize(); 

    return 0; 
} 
+0

मुझे खेद है कि इसका उल्लेख नहीं है, लेकिन मैं ज्यादातर वही करता हूं। मैं mpiC++ और mpirun -np 3 मुख्य – AlexandruC

+0

का उपयोग करता हूं मैंने अपने प्रश्न में और कोड जोड़ा है। फ़्रांस अमर रहे! – AlexandruC

+0

मुझे आश्चर्य है कि यह एक मुद्दा है क्योंकि मैं इसे एक नोड पर चला रहा हूं? – AlexandruC