C MPI-программа, вызывающая фортрановские сбои - PullRequest
1 голос
/ 08 апреля 2019

Я успешно запрограммировал умножение матрицы на матрицу на одном узле, и теперь моя цель - связать эту программу для параллельного выполнения на узлах кластера.

Основная работа модифицирует код из исходного кодаScalapack Netlib с изменением исходного кода (ScaLAPACK) с частичным вычислением умножения матрицы на матрицу (в данном случае dgemm_) по моей программе (mydgemm).

Здесь исходный код - это программа на С, но все подпрограммы в этой программе вызывают подпрограмму на Фортране (например, dgemm_ - это язык Фортрана), а моя программа (mydgemm) - это программа на Си.

После изменения я могу выполнить успешно с одним узлом с любым размером матрицы, но когда я запускаю с 4 узлами (с размером матрицы больше 200) -> Ошибка передачи данных между узлами(MPI).

Это ошибка:

*BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES

PID 69754 RUNNING AT localhost.localdomain

EXIT CODE: 11

CLEANING UP REMAINING PROCESSES

YOU CAN IGNORE THE BELOW CLEANUP MESSAGES* 

Я просто использую MPI в основной функции для создания случайной матрицы на каждом узле (присоединение следующего) - с подпрограммой называется new_pdgemm (...).(Я изменил код внутри new-pdgemm).

Внутри mydgemm.c, я использую OMP для параллельного выполнения, и этот код выполняется в ядре.

  • Может дать мнеруководство или идея для решения моей проблемы?

  • Как вы думаете, проблема в том, что Fortran - главный столбец, а C - главный ряд?

  • Илимне нужно изменить mydgemm.c на mydgemm.f (это действительно сложно и, может быть, я не могу это сделать)?

Мой код:

int main(int argc, char **argv) {
   int i, j, k;
/************  MPI ***************************/
   int myrank_mpi, nprocs_mpi;
   MPI_Init( &argc, &argv);
   MPI_Comm_rank(MPI_COMM_WORLD, &myrank_mpi);
   MPI_Comm_size(MPI_COMM_WORLD, &nprocs_mpi);
/************  BLACS ***************************/
   int ictxt, nprow, npcol, myrow, mycol,nb;
   int info,itemp;
   int _ZERO=0,_ONE=1;
     int M=20000;
     int K=20000;
     int N=20000;
   nprow = 2; npcol = 2; 
     nb=1200;

   Cblacs_pinfo( &myrank_mpi, &nprocs_mpi ) ;
   Cblacs_get( -1, 0, &ictxt );
   Cblacs_gridinit( &ictxt, "Row", nprow, npcol );
   Cblacs_gridinfo( ictxt, &nprow, &npcol, &myrow, &mycol );
   //printf("myrank = %d\n",myrank_mpi);


   int rA = numroc_( &M, &nb, &myrow, &_ZERO, &nprow );
   int cA = numroc_( &K, &nb, &mycol, &_ZERO, &npcol );
   int rB = numroc_( &K, &nb, &myrow, &_ZERO, &nprow );
   int cB = numroc_( &N, &nb, &mycol, &_ZERO, &npcol );
   int rC = numroc_( &M, &nb, &myrow, &_ZERO, &nprow );
   int cC = numroc_( &N, &nb, &mycol, &_ZERO, &npcol );

   double *A = (double*) malloc(rA*cA*sizeof(double));
   double *B = (double*) malloc(rB*cB*sizeof(double));
   double *C = (double*) malloc(rC*cC*sizeof(double));

   int descA[9],descB[9],descC[9];

     descinit_(descA, &M,   &K,   &nb,  &nb,  &_ZERO, &_ZERO, &ictxt, &rA,  &info);
     descinit_(descB, &K,   &N,   &nb,  &nb,  &_ZERO, &_ZERO, &ictxt, &rB,  &info);
     descinit_(descC, &M,   &N,   &nb,  &nb,  &_ZERO, &_ZERO, &ictxt, &rC,  &info);

   double alpha = 1.0; double beta = 1.0;   
    double start, end, flops;
     srand(time(NULL)*myrow+mycol);
     #pragma simd
     for (j=0; j<rA*cA; j++)
     {
         A[j]=((double)rand()-(double)(RAND_MAX)*0.5)/(double)(RAND_MAX);
    //   printf("A in myrank: %d\n",myrank_mpi);
     }
//   printf("A: %d\n",myrank_mpi);
     #pragma simd
     for (j=0; j<rB*cB; j++)
     {
         B[j]=((double)rand()-(double)(RAND_MAX)*0.5)/(double)(RAND_MAX);
     }
     #pragma simd
     for (j=0; j<rC*cC; j++)
     {
         C[j]=((double)rand()-(double)(RAND_MAX)*0.5)/(double)(RAND_MAX);
     }
     MPI_Barrier(MPI_COMM_WORLD);

  start=MPI_Wtime();

    new_pdgemm ("N", "N", &M , &N , &K , &alpha, A , &_ONE, &_ONE , descA , B , &_ONE, &_ONE , descB , &beta , C , &_ONE, &_ONE , descC );
MPI_Barrier(MPI_COMM_WORLD);
     end=MPI_Wtime();

     if (myrow==0 && mycol==0)
     {
        flops = 2 * (double) M * (double) N * (double) K / (end-start) / 1e9;
    /*   printf("This is value: %d\t%d\t%d\t%d\t%d\t%d\t\n",rA,cA,rB,cB,rC,cC);
        printf("%f\t%f\t%f\n", A[4], B[6], C[3]);*/
         printf("%f Gflops\n", flops);
     }
   Cblacs_gridexit( 0 );
   MPI_Finalize();
   free(A);
   free(B);
   free(C);
   return 0;
}

1 Ответ

0 голосов
/ 10 апреля 2019

ОК, это не совсем ответ, но это слишком долго для комментария, и я все равно хочу форматирование, которое вам даст ответ.

Так что я исправил ошибку с помощью blacs_gridexit, который я отметил в комментариях, а именно сделал параметр ictxt в соответствии с описанием процедуры. Затем я заменил вашу рутину стандартным pdgemm. Однажды я внес эти изменения и сократил размер матрицы до 2000 * 2000, чтобы уместить на своем ноутбуке. Затем код выполняется успешно, по крайней мере, в том смысле, что он не сообщает об ошибке и дает своего рода разумную страницу GFlopage. Так что мне подсказывает, что либо

  • В коде есть ошибка, которую вы не можете показать нам
  • Есть проблема с вашей реализацией MPI, blacs, pblas и / или Scalapack

Таким образом, я бы переустановил используемые вами библиотеки, убедившись, что они соответствуют используемому вами компилятору, и выполнил тесты, поставляемые с библиотеками, а также включил заголовочные файлы, которые вы пропустили в своем коде (DON 'T, это очень важно!) Если это сработает, я бы сказал, что это связано с ошибкой в ​​вашем коде По какой причине вы не можете показать это?

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

ian-admin@agon ~/work/stack/mpi $ cat stack.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "mpi.h"

int main(void) {
   int i, j, k;
/************  MPI ***************************/
   int myrank_mpi, nprocs_mpi;
   MPI_Init( NULL, NULL);
   MPI_Comm_rank(MPI_COMM_WORLD, &myrank_mpi);
   MPI_Comm_size(MPI_COMM_WORLD, &nprocs_mpi);
/************  BLACS ***************************/
   int ictxt, nprow, npcol, myrow, mycol,nb;
   int info,itemp;
   int _ZERO=0,_ONE=1;
     int M=2000;
     int K=2000;
     int N=2000;
   nprow = 2; npcol = 2; 
     nb=1200;


   Cblacs_pinfo( &myrank_mpi, &nprocs_mpi ) ;
   Cblacs_get( -1, 0, &ictxt );
   Cblacs_gridinit( &ictxt, "Row", nprow, npcol );
   Cblacs_gridinfo( ictxt, &nprow, &npcol, &myrow, &mycol );
   //printf("myrank = %d\n",myrank_mpi);


   int rA = numroc_( &M, &nb, &myrow, &_ZERO, &nprow );
   int cA = numroc_( &K, &nb, &mycol, &_ZERO, &npcol );
   int rB = numroc_( &K, &nb, &myrow, &_ZERO, &nprow );
   int cB = numroc_( &N, &nb, &mycol, &_ZERO, &npcol );
   int rC = numroc_( &M, &nb, &myrow, &_ZERO, &nprow );
   int cC = numroc_( &N, &nb, &mycol, &_ZERO, &npcol );

   double *A = (double*) malloc(rA*cA*sizeof(double));
   double *B = (double*) malloc(rB*cB*sizeof(double));
   double *C = (double*) malloc(rC*cC*sizeof(double));

   int descA[9],descB[9],descC[9];

     descinit_(descA, &M,   &K,   &nb,  &nb,  &_ZERO, &_ZERO, &ictxt, &rA,  &info);
     descinit_(descB, &K,   &N,   &nb,  &nb,  &_ZERO, &_ZERO, &ictxt, &rB,  &info);
     descinit_(descC, &M,   &N,   &nb,  &nb,  &_ZERO, &_ZERO, &ictxt, &rC,  &info);

   double alpha = 1.0; double beta = 1.0;   
    double start, end, flops;
     srand(time(NULL)*myrow+mycol);
     #pragma simd
     for (j=0; j<rA*cA; j++)
     {
         A[j]=((double)rand()-(double)(RAND_MAX)*0.5)/(double)(RAND_MAX);
    //   printf("A in myrank: %d\n",myrank_mpi);
     }
//   printf("A: %d\n",myrank_mpi);
     #pragma simd
     for (j=0; j<rB*cB; j++)
     {
         B[j]=((double)rand()-(double)(RAND_MAX)*0.5)/(double)(RAND_MAX);
     }
     #pragma simd
     for (j=0; j<rC*cC; j++)
     {
         C[j]=((double)rand()-(double)(RAND_MAX)*0.5)/(double)(RAND_MAX);
     }
     MPI_Barrier(MPI_COMM_WORLD);

  start=MPI_Wtime();

    pdgemm_ ("N", "N", &M , &N , &K , &alpha, A , &_ONE, &_ONE , descA , B , &_ONE, &_ONE , descB , &beta , C , &_ONE, &_ONE , descC );
MPI_Barrier(MPI_COMM_WORLD);
     end=MPI_Wtime();

     if (myrow==0 && mycol==0)
     {
        flops = 2 * (double) M * (double) N * (double) K / (end-start) / 1e9;
    /*   printf("This is value: %d\t%d\t%d\t%d\t%d\t%d\t\n",rA,cA,rB,cB,rC,cC);
        printf("%f\t%f\t%f\n", A[4], B[6], C[3]);*/
         printf("%f Gflops\n", flops);
     }
   Cblacs_gridexit( ictxt );
   MPI_Finalize();
   free(A);
   free(B);
   free(C);
   return 0;
}
ian-admin@agon ~/work/stack/mpi $ mpicc -g stack.c /home/ian-admin/Downloads/scalapack-2.0.2/libscalapack.a -llapack -lblas -lgfortran
stack.c: In function ‘main’:
stack.c:24:4: warning: implicit declaration of function ‘Cblacs_pinfo’ [-Wimplicit-function-declaration]
    Cblacs_pinfo( &myrank_mpi, &nprocs_mpi ) ;
    ^~~~~~~~~~~~
stack.c:25:4: warning: implicit declaration of function ‘Cblacs_get’ [-Wimplicit-function-declaration]
    Cblacs_get( -1, 0, &ictxt );
    ^~~~~~~~~~
stack.c:26:4: warning: implicit declaration of function ‘Cblacs_gridinit’ [-Wimplicit-function-declaration]
    Cblacs_gridinit( &ictxt, "Row", nprow, npcol );
    ^~~~~~~~~~~~~~~
stack.c:27:4: warning: implicit declaration of function ‘Cblacs_gridinfo’ [-Wimplicit-function-declaration]
    Cblacs_gridinfo( ictxt, &nprow, &npcol, &myrow, &mycol );
    ^~~~~~~~~~~~~~~
stack.c:31:13: warning: implicit declaration of function ‘numroc_’ [-Wimplicit-function-declaration]
    int rA = numroc_( &M, &nb, &myrow, &_ZERO, &nprow );
             ^~~~~~~
stack.c:44:6: warning: implicit declaration of function ‘descinit_’ [-Wimplicit-function-declaration]
      descinit_(descA, &M,   &K,   &nb,  &nb,  &_ZERO, &_ZERO, &ictxt, &rA,  &info);
      ^~~~~~~~~
stack.c:72:5: warning: implicit declaration of function ‘pdgemm_’ [-Wimplicit-function-declaration]
     pdgemm_ ("N", "N", &M , &N , &K , &alpha, A , &_ONE, &_ONE , descA , B , &_ONE, &_ONE , descB , &beta , C , &_ONE, &_ONE , descC );
     ^~~~~~~
stack.c:83:4: warning: implicit declaration of function ‘Cblacs_gridexit’ [-Wimplicit-function-declaration]
    Cblacs_gridexit( ictxt );
    ^~~~~~~~~~~~~~~
/usr/bin/ld: warning: libgfortran.so.3, needed by //usr/lib/liblapack.so, may conflict with libgfortran.so.5
ian-admin@agon ~/work/stack/mpi $ mpirun -np 4 --oversubscribe ./a.out 
9.424291 Gflops
...