2015-01-11 3 views
3

У меня проблема с динамическим распределением массивов.MPI динамически распределенные массивы

Этот код, если я использую статическое распределение, работает без проблем ...

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

    int size, rank; 

    MPI_Status status; 

    MPI_Init(&argc, &argv); 
    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
    MPI_Comm_size(MPI_COMM_WORLD, &size); 
    int lowerBound = 0, upperBound = 0, dimArrayTemp, x, z; 
    int dimBulk = size - 1, nPart, cnt; 


    FILE *pf; 
    pf = fopen("in.txt","r"); 
    int array_value = fscanf(pf,"%d",&array_value); 
    float ins_array_value; 

    float *arrayTemp, *bulkSum,*s,*a; 

    arrayTemp =(float*)malloc(array_value*sizeof(float)); 
    bulkSum = (float*)malloc(array_value*sizeof(float)); 
    s =(float*) malloc(array_value*sizeof(float)); 
    a =(float*) malloc(array_value*sizeof(float)); 

    int j=0; 

    while(!feof(pf)){ 
     fscanf(pf,"%f",&ins_array_value); 
     a[j] = ins_array_value; 
     j++; 
    } 
    fclose(pf); 

    float presum, valFinal; 

    if(size <= array_value){ 
     if (rank == MASTER){ 
      nPart = array_value/size; 
      int countPair; 
      if((array_value % size) != 0){ 
       countPair = 0; 
      } 
      for (int i = 0; i < size; i++){ 

       if(i == 0){ 
        lowerBound = upperBound; 
        upperBound += nPart - 1; 
       } 
       else{ 
        lowerBound += nPart; 
        upperBound += nPart; 
        if(countPair == 0 && i == size - 1) 
         upperBound = array_value - 1; 
       } 
       dimArrayTemp = upperBound - lowerBound; 
       //float arrayTemp[dimArrayTemp]; 
       for(x = lowerBound, z = 0; x <= upperBound; x++, z++){ 
        arrayTemp[z] = a[x]; 
       } 
       if (i > 0){ 
        //send array size 
        MPI_Send(&z,1,MPI_INT,i,0,MPI_COMM_WORLD); 
        //send value array 
        MPI_Send(arrayTemp,z,MPI_INT,i,1,MPI_COMM_WORLD); 
       } 
       else{ 

        for (int h = 1;h <= dimArrayTemp; h++) 
         arrayTemp[h] = arrayTemp[h-1] + arrayTemp[h]; 
        bulkSum[0] = arrayTemp[dimArrayTemp]; 
        for (int h = 0; h <= dimArrayTemp; h++) 
         s[h] = arrayTemp[h]; 
       } 

      }  
     } 
     else{ 
       //recieve array size 
      MPI_Recv(&z,1,MPI_INT,0,0,MPI_COMM_WORLD, &status); 

      MPI_Recv(arrayTemp,z,MPI_INT,0,1,MPI_COMM_WORLD,&status); 
      for(int h = 1; h < z; h++){ 
       arrayTemp[h] = arrayTemp[h-1] + arrayTemp[h]; 
       presum = arrayTemp[h]; 
      } 


      MPI_Send(&presum,1,MPI_INT,0,1,MPI_COMM_WORLD); 
     } 

     //MPI_Barrier(MPI_COMM_WORLD); 
     if (rank == MASTER){ 

      for (int i = 1; i<size;i++){ 
       MPI_Recv(&presum,1,MPI_INT,i,1,MPI_COMM_WORLD,&status); 
       bulkSum[i] = presum; 
      } 
      for (int i = 0; i<=dimBulk; i++){ 
       bulkSum[i] = bulkSum[i-1] +bulkSum[i]; 
      } 
      for(int i = 0; i<dimBulk;i++){ 
       valFinal = bulkSum[i]; 
       cnt = i+1; 
       MPI_Send(&valFinal,1,MPI_INT,cnt,1,MPI_COMM_WORLD); 
      } 
     } 
     else{ 

      MPI_Recv(&valFinal,1,MPI_INT,0,1,MPI_COMM_WORLD,&status); 
      for(int i = 0; i<z;i++){ 
       arrayTemp[i] = arrayTemp[i] + valFinal; 
      } 
      MPI_Send(arrayTemp,z,MPI_INT,0,1,MPI_COMM_WORLD); 
     } 

     if(rank == MASTER){ 
      for(int i =1;i<size;i++){ 
       MPI_Recv(arrayTemp,z,MPI_INT,i,1,MPI_COMM_WORLD,&status); 
       for(int v=0, w =dimArrayTemp+1 ;v<z;v++, w++){ 
        s[w] = arrayTemp[v]; 
       } 
       dimArrayTemp += z; 
      } 
      int count = 0; 
      for(int c = 0;c<array_value;c++){ 
       printf("s[%d] = %f \n",count++,s[c]); 
      } 

     } 
    } 
    else{ 
     printf("ERROR!!!\t number of procs (%d) is higher than array size(%d)!\n", size, array_value); 
     //fflush(stdout); 
     MPI_Finalize(); 
    } 
    free(arrayTemp); 
    free(s); 
    free(a); 
    free(bulkSum); 
    MPI_Finalize(); 
    return 0; 
} 

Это особая декларация массивов:

float *arrayTemp, *bulkSum,*s,*a; 

arrayTemp =(float*)malloc(array_value*sizeof(float)); 
bulkSum = (float*)malloc(array_value*sizeof(float)); 
s =(float*) malloc(array_value*sizeof(float)); 
a =(float*) malloc(array_value*sizeof(float)); 

Любых идеи?

EDIT: Я удаляю ссылку для массивов в MPI_Send(); и MPI_Recv(); и хозяин условий, возникает одна и та же ошибка: процесс выходит из сигнала 6 (прерывается).

+1

Обратите внимание, что вы используете 'MPI_INT' везде в своем коде, даже при отправке и получении значений' float'! Кроме того, эта строка неверна: 'int array_value = fscanf (pf,"% d ", & array_value);'. Возвращаемое значение 'fscanf' - это количество назначенных входных элементов и не должно быть присвоено' array_value'. –

ответ

3

Это очень распространенная ошибка новобранец. Часто можно увидеть руководства MPI, где переменные передаются по адресам на вызовы MPI, например. MPI_Send(&a, ...);. Адрес -оператора (&) используется для получения адреса переменной и этот адрес передается MPI в качестве буферной области для операции. В то время как & возвращает адрес фактического хранилища данных для скалярных переменных и массивов, когда применяется к указателям, он возвращает адрес, в котором хранится адрес, на который указывает.

Самое простое решение не придерживаться следующего правила: не использовать & с массивами или динамически распределяемой памяти, например:

int a; 
MPI_Send(&a, ...); 

но

int a[10]; 
MPI_Send(a, ...); 

и

int *a = malloc(10 * sizeof(int)); 
MPI_Send(a, ...); 

Кроме того, как отмечено @talonmies, вы выделяете массивы только в основном процессе. Вы должны удалить условие, связанное с вызовами распределения.

+0

Буферы также не динамически распределяются на любых узлах коммуникатора, кроме основного. – talonmies

+0

Хорошая добыча! Честно говоря, у меня был только поверхностный взгляд на код. –

-3

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