c++ - Segmentation Fault calling MPI_Finalize() in c -
i running problem mpi_finalize. segmentation fault @ end of program when can mpi_finalize();, output:
a matrix = 48.3962 65.3245 15.0385 72.383 25.8898 46.0265 b matrix = 15.4881 50.6507 6.74602 71.0055 12.2209 77.5441 61.5452 31.5127 46.8515 89.4849 70.0342 57.3195 gather returned: 0 c matrix = 2252.46 8862.55 5400.1 6356.94 gather returned: 0 3593.88 9792.53 5305.12 8593.66 time=7.6e-05 seconds [dmc:13852] *** process received signal *** [dmc:13852] signal: segmentation fault (11) [dmc:13852] signal code: (128) [dmc:13852] failing @ address: (nil) [dmc:13852] [ 0] /lib64/libpthread.so.0(+0xf850)[0x7fcba45e8850] [dmc:13852] [ 1] /opt/asn/apps/openmpi_1.8.3_intel/lib/libopen-pal.so.6(opal_memory_ptmalloc2_int_free+0x1a9)[0x7fcba3b74a79] [dmc:13852] [ 2] /opt/asn/apps/openmpi_1.8.3_intel/lib/libopen-pal.so.6(opal_memory_ptmalloc2_free+0xad)[0x7fcba3b765fd] [dmc:13852] [ 3] /opt/asn/apps/openmpi_1.8.3_intel/lib/openmpi/mca_btl_openib.so(+0x27e14)[0x7fcb8f5cbe14] [dmc:13852] [ 4] /opt/asn/apps/openmpi_1.8.3_intel/lib/openmpi/mca_btl_openib.so(mca_btl_openib_finalize+0x484)[0x7fcb8f5b0724] [dmc:13852] [ 5] /opt/asn/apps/openmpi_1.8.3_intel/lib/libmpi.so.1(+0x8c246)[0x7fcba4d9e246] [dmc:13852] [ 6] /opt/asn/apps/openmpi_1.8.3_intel/lib/libopen-pal.so.6(mca_base_framework_close+0x63)[0x7fcba3b14ac3] [dmc:13852] [ 7] /opt/asn/apps/openmpi_1.8.3_intel/lib/libopen-pal.so.6(mca_base_framework_close+0x63)[0x7fcba3b14ac3] [dmc:13852] [ 8] /opt/asn/apps/openmpi_1.8.3_intel/lib/libmpi.so.1(ompi_mpi_finalize+0x60e)[0x7fcba4d5e21e] [dmc:13852] [ 9] ./mm_mult_mpi_gnu[0x4036ba] [dmc:13852] [10] /lib64/libc.so.6(__libc_start_main+0xe6)[0x7fcba427bc36] [dmc:13852] [11] ./mm_mult_mpi_gnu[0x402859] [dmc:13852] *** end of error message *** and here program:
using namespace std; #include <iostream> #include <iomanip> #include <sstream> #include <stdlib.h> #include <string.h> #include <sys/time.h> #include "mpi.h" #include <cmath> #define mx_sz 320 #define seed 2397 /* random number seed */ #define max_value 100.0 /* maximum size of array elements a, , b */ /* copied mpbench */ #define timer_clear (tv1.tv_sec = tv1.tv_usec = tv2.tv_sec = tv2.tv_usec = 0) #define timer_start gettimeofday(&tv1, (struct timezone*)0) #define timer_elapsed ((tv2.tv_usec-tv1.tv_usec)+((tv2.tv_sec-tv1.tv_sec)*1000000)) #define timer_stop gettimeofday(&tv2, (struct timezone*)0) struct timeval tv1,tv2; /* declaration facilitates creation of 2 dimensional dynamically allocated arrays (i.e. lxm array, mxn b array, , lxn c array). allows pointer arithmetic applied single data stream can dynamically allocated. address element @ row x, , column y use following notation: a(x,y),b(x,y), or c(x,y), respectively. note differs normal c notation if 2 dimensional array of a[x][y] still descriptive of data structure. */ float *a,*b,*c,*rbuf,*sbuf; #define a(i,j) *(a+i*dim_m+j) #define b(i,j) *(b+i*dim_n+j) #define c(i,j) *(c+i*dim_n+j) #define rbuf(i,j) *(rbuf+i*dim_m+j) #define sbuf(i,j) *(sbuf+i*dim_n+j) /* routine retrieve data size of numbers array command line or prompting user information */ void get_index_size(int argc,char *argv[],int *dim_l,int *dim_m,int *dim_n) { if(argc!=2 && argc!=4) { cout<<"usage: mm_mult_serial [l_dimension] <m_dimension n_dimmension>" << endl; exit(1); } else { if (argc == 2) { *dim_l = *dim_n = *dim_m = atoi(argv[1]); } else { *dim_l = atoi(argv[1]); *dim_m = atoi(argv[2]); *dim_n = atoi(argv[3]); } } if (*dim_l<=0 || *dim_n<=0 || *dim_m<=0) { cout<<"error: number of rows and/or columns must greater 0" << endl; exit(1); } } /* routine fills number matrix random data values between 0 , max_value simulates in way might happen if there single sequential data acquisition source such single file */ void fill_matrix(float *array,int dim_m,int dim_n) { int i,j; for(i=0;i<dim_m;i++) { (j=0;j<dim_n;j++) { array[i*dim_n+j]=drand48()*max_value; } } } /* routine outputs matrices screen */ void print_matrix(float *array,int dim_m,int dim_n) { int i,j; for(i=0;i<dim_m;i++) { (j=0;j<dim_n;j++) { cout << array[i*dim_n+j] << " "; } cout << endl; } } /* main routine: summation of number list */ int main( int argc, char *argv[]) { float dot_prod; int dim_l,dim_n,dim_m; int i,j,k; int id,p; int row_per_proc; int remain_rows; int error; mpi::status status; mpi::init(argc, argv); id = mpi::comm_world.get_rank(); p = mpi::comm_world.get_size(); if ( id == 0 ) { /* matrix sizes */ get_index_size(argc,argv,&dim_l,&dim_m,&dim_n); row_per_proc = ceil(float(dim_l)/p); if (dim_l%p > 0) { remain_rows = dim_l - (row_per_proc*(p-1)); } else { remain_rows = 0; } } // allocate space b in processes since shared b = new (nothrow) float[dim_m*dim_n]; if (b==0) { cout << "error: insufficient memory" << endl; mpi_finalize(); exit(1); } if (id == 0) { // allocate heap space , c = new (nothrow) float[dim_l*dim_m]; c = new (nothrow) float[row_per_proc*p*dim_n]; if (a==0 || c==0) { cout << "error: insufficient memory" << endl; mpi_finalize(); exit(1); } /* initialize numbers matrix random data */ srand48(seed); fill_matrix(a,dim_l,dim_m); fill_matrix(b,dim_m,dim_n); /* output numbers matrix */ cout << "a matrix =" << endl; print_matrix(a,dim_l,dim_m); cout << endl; cout << "b matrix =" << endl; print_matrix(b,dim_m,dim_n); cout << endl; } /* broadcast variables */ mpi_bcast(&p, 1, mpi_int, 0, mpi_comm_world); mpi_bcast(&dim_l, 1, mpi_int, 0, mpi_comm_world); mpi_bcast(&dim_m, 1, mpi_int, 0, mpi_comm_world); mpi_bcast(&dim_n, 1, mpi_int, 0, mpi_comm_world); mpi_bcast(&row_per_proc, 1, mpi_int, 0, mpi_comm_world); mpi_bcast(&remain_rows, 1, mpi_int, 0, mpi_comm_world); /* process 0 sends rows workers */ rbuf = new float[row_per_proc*dim_m]; mpi_scatter(a, row_per_proc*dim_m, mpi_float, rbuf, row_per_proc*dim_m, mpi_float, 0, mpi_comm_world); /* send matrix b other processes */ mpi_bcast(b, dim_m*dim_n, mpi_float, 0, mpi_comm_world); /* start recording execution time */ if (id == 0) { timer_clear; timer_start; } // multiply local part of matrix sbuf = new float[row_per_proc*dim_n]; (i=0; i<row_per_proc; i++) { (j=0; j<dim_n; j++) { dot_prod = 0.0; (k=0; k<dim_m; k++) { dot_prod += rbuf(i,k)*b(k,j); } sbuf(i,j) = dot_prod; } } // send calculated values process 0 error = mpi_gather(sbuf, row_per_proc*dim_n, mpi_float, c, row_per_proc*dim_n, mpi_float, 0, mpi_comm_world); cout << "gather returned: " << error << endl; if (id == 0) { /* stop recording execution time */ timer_stop; cout << "c matrix =" << endl; print_matrix(c,dim_l,dim_n); cout << endl; cout << "time=" << setprecision(8) << timer_elapsed/1000000.0 << " seconds" << endl; } // return allocated memory delete a; delete b; delete c; delete rbuf; delete sbuf; error = mpi_finalize(); cout << "finalize returned: " << error << endl; }
you creating a , c on rank 0:
if (id == 0) { // allocate heap space , c = new (nothrow) float[dim_l*dim_m]; c = new (nothrow) float[row_per_proc*p*dim_n]; therefore, should delete them on rank 0:
if (id == 0) { /* stop recording execution time */ timer_stop; cout << "c matrix =" << endl; print_matrix(c,dim_l,dim_n); cout << endl; cout << "time=" << setprecision(8) << timer_elapsed/1000000.0 << " seconds" << endl; delete a; delete c; } // return allocated memory delete b; delete rbuf; delete sbuf; additional note: calling mpi_finalize if allocation on rank 0 fails, better call mpi_abort in case, or broadcast result of check, notify processes of failure , allow proper termination. code right now, program might hang infinitely when running error.
Comments
Post a Comment