/* Should I cache some lines before inserting them into the matrix ? */ static int pmataddline(void*MM, int row, double dd, double vals[], int m){ plapackM* ctx=(plapackM*)MM; int info; double d_one=1.0*dd; DSDPFunctionBegin; vals[row]+=1.0e-11; /* vals[row]*=dd*(1.0 + 1.0e-10); */ info = PLA_API_axpy_matrix_to_global(m-row,1,&d_one, vals+row, m, ctx->AMat, row, row); DSDPCHKERR(info); DSDPFunctionReturn(0); }
static int pmataddelement(void* MM,int row, double shift){ plapackM* ctx=(plapackM*)MM; int info; double d_one=1.0; DSDPFunctionBegin; if (onrow(ctx,row)){ info = PLA_API_axpy_matrix_to_global(1,1,&d_one,&shift, ctx->global_size, ctx->AMat, row, row); DSDPCHKERR(info); } DSDPFunctionReturn(0); }
static int pmatadddiagonal(void*MM, double val[],int n){ plapackM* ctx=(plapackM*)MM; int row,info,m=ctx->global_size; double d_one=1.0; DSDPFunctionBegin; for (row=0;row<m;row++){ if (onrow(ctx,row)){ d_one=1.0; info = PLA_API_axpy_matrix_to_global(1,1,&d_one,val+row, ctx->global_size, ctx->AMat, row, row); DSDPCHKERR(info); } } DSDPFunctionReturn(0); }
static int pmatshiftdiagonal(void* MM,double shift){ plapackM* ctx=(plapackM*)MM; int info,row,m=ctx->global_size; double d_one=1.0,shift2; DSDPFunctionBegin; if (shift==0) return 0; info=PLA_API_begin();DSDPCHKERR(info); info=PLA_Obj_API_open(ctx->AMat);DSDPCHKERR(info); for (row=0;row<m;row++){ if (onrow(ctx,row)){ shift2=shift*10;d_one=1.0; info = PLA_API_axpy_matrix_to_global(1,1,&d_one, &shift2, ctx->global_size, ctx->AMat, row, row); DSDPCHKERR(info); } } info=PLA_Obj_API_close(ctx->AMat); DSDPCHKERR(info); info=PLA_API_end(); DSDPCHKERR(info); DSDPFunctionReturn(0); }
void create_problem( PLA_Obj A, PLA_Obj x, PLA_Obj b ) { PLA_Obj zero = NULL, one = NULL, A_cur = NULL, A11 = NULL; int size, me, nprocs, i, j, fill_blocksize, this_fill_blocksize, type_size; double d_one = 1.0, time; void *locA; void *local_buf; int local_m, local_n, local_ldim, local_stride, global_length; MPI_Datatype datatype; PLA_Obj_global_length( A, &size ); PLA_Obj_datatype ( A, &datatype ); MPI_Type_size ( datatype, &type_size); MPI_Comm_rank( MPI_COMM_WORLD, &me ); MPI_Comm_size( MPI_COMM_WORLD, &nprocs ); PLA_Create_constants_conf_to( A, NULL, &zero, &one ); srand48( me * 1793 ); PLA_Obj_local_length( A, &local_m ); PLA_Obj_local_width( A, &local_n ); PLA_Obj_local_buffer( A, (void **) &local_buf ); PLA_Obj_local_ldim( A, &local_ldim ); #define FILL_METHOD FILL_LOCAL_RANDOM #if FILL_METHOD /************************************************************************ Fill the matrices. NOTE: There are two versions of the fill routine in this file. The version directly below this comment simply fills the local portions of the matrix and vector with random numbers. To use this version, the line directly above this comment should read "#define FILL_METHOD FILL_LOCAL_RANDOM". The other version of the fill algorithm uses the PLAPACK Application Interface, which allows each processor to create a portion of the matrix or vector (regardless of the true location on the machine of that portion) and then submit the piece through a call to the PLAPACK API. To use this version of the algorithm, the line directly above this comment should read "#define FILL_METHOD FILL_THROUGH_API". The API version of the algorithm has a parameter called "fill_blocksize" that determines the width of the column blocks to be submitted to the matrix. The number of independent messages generated by the API is inversely proportional to the fill_blocksize, and significant network contention (or even deadlock on some systems) may occur if the fill_blocksize is taken too small. **********************************************************************/ for (j=0; j<local_n; j++ ) for (i=0; i<local_m; i++ ) if ( datatype == MPI_DOUBLE ) { ( (double *) local_buf )[ j*local_ldim + i ] = drand48() * 2.0 -1.0; } else if ( datatype == MPI_FLOAT ) { ( (float *) local_buf)[ j*local_ldim + i ] = (float) (drand48() * 2.0 -1.0); } else if ( datatype == MPI_DOUBLE_COMPLEX ) { ((PLA_DOUBLE_COMPLEX *)local_buf)[ j*local_ldim + i ].real = drand48() * 2.0 -1.0; ((PLA_DOUBLE_COMPLEX *)local_buf)[ j*local_ldim + i ].imaginary = drand48() * 2.0 -1.0; } else if ( datatype == MPI_COMPLEX ) { ((PLA_COMPLEX *)local_buf)[ j*local_ldim + i ].real = (float) drand48() * 2.0 -1.0; ((PLA_COMPLEX *)local_buf)[ j*local_ldim + i ].imaginary = (float) drand48() * 2.0 -1.0; } PLA_Obj_local_length( x, &local_m ); PLA_Obj_local_buffer( x, (void **) &local_buf ); PLA_Obj_local_stride( x, &local_stride ); for (i=0; i<local_m; i++ ) if ( datatype == MPI_DOUBLE ) { ((double*) local_buf)[ i*local_stride ] = drand48() * 2.0 -1.0; } else if ( datatype == MPI_FLOAT ) { ((float *)local_buf)[ i*local_stride ] = (float) (drand48() * 2.0 -1.0); } else if ( datatype == MPI_DOUBLE_COMPLEX ) { ((PLA_DOUBLE_COMPLEX *)local_buf)[ i*local_stride ].real = drand48() * 2.0 -1.0; ((PLA_DOUBLE_COMPLEX *)local_buf)[ i*local_stride ].imaginary = drand48() * 2.0 -1.0; } else if ( datatype == MPI_COMPLEX ) { ((PLA_COMPLEX *)local_buf)[ i*local_stride ].real = (float) drand48() * 2.0 -1.0; ((PLA_COMPLEX *)local_buf)[ i*local_stride ].imaginary = (float) drand48() * 2.0 -1.0; } #else /*********************************************************************************** Alternate version of the problem creation using the PLAPACK Application interface. To use, edit the line marked "PROBLEM CREATION METHOD" above to read "#define FILL_METHOD FILL_THROUGH_API". **********************************************************************************/ if ( 0 == me ) printf("Using PLAPACK application interface to create problem.\n"); MPI_Barrier ( MPI_COMM_WORLD); time = MPI_Wtime (); PLA_API_begin(); PLA_Obj_API_open(A); PLA_Obj_API_open(x); fill_blocksize = 10; locA = (void *) malloc( type_size * size * fill_blocksize ); for (j=me*fill_blocksize;j< size; j+=nprocs*fill_blocksize) { this_fill_blocksize = min( fill_blocksize, size - j); for (i=0; i < size*this_fill_blocksize; i++) { /* This loop determines the values to put into matrix */ if ( MPI_DOUBLE == datatype ) ((double *)locA)[i]=drand48() * 2.0 - 1.0; else if ( MPI_FLOAT == datatype ) ((float *)locA)[i]=drand48() * 2.0 - 1.0; else if ( MPI_DOUBLE_COMPLEX == datatype ) { ((double *)locA)[2*i]=drand48() * 2.0 - 1.0; ((double *)locA)[2*i+1]=drand48() * 2.0 - 1.0; } else if ( MPI_COMPLEX == datatype ) { ((float *)locA)[2*i]=drand48() * 2.0 - 1.0; ((float *)locA)[2*i+1]=drand48() * 2.0 - 1.0; } else printf("Unhandled datatype in create_problem().\n"); } PLA_API_axpy_matrix_to_global(size, this_fill_blocksize, &d_one, locA, size, A, 0, j ); } if (0==me) { /* processor zero alone fills the vector */ for (i=0; i<size; i++) if ( MPI_DOUBLE == datatype ) ((double *)locA)[i]=drand48() * 2.0 - 1.0; else if ( MPI_FLOAT == datatype ) ((float *)locA)[i]=drand48() * 2.0 - 1.0; else if ( MPI_DOUBLE_COMPLEX == datatype ) { ((double *)locA)[2*i]=drand48() * 2.0 - 1.0; ((double *)locA)[2*i+1]=drand48() * 2.0 - 1.0; } else if ( MPI_COMPLEX == datatype ) { ((float *)locA)[2*i]=drand48() * 2.0 - 1.0; ((float *)locA)[2*i+1]=drand48() * 2.0 - 1.0; } else printf("Unhandled datatype in create_problem().\n"); PLA_API_axpy_vector_to_global( size, &d_one, locA, 1, x, 0); } free( locA ); PLA_Obj_API_close(A); PLA_Obj_API_close(x); PLA_API_end(); MPI_Barrier ( MPI_COMM_WORLD); time = MPI_Wtime () - time; if ( 0 == me ) { printf("time for problem creation: %e seconds\n", time); } #endif /* Make A positive definite by adding a large value to the diagonal */ PLA_Obj_view_all( A, &A_cur ); PLA_Obj_global_length ( A, &global_length); while ( TRUE ){ PLA_Obj_global_length( A_cur, &size ); if ( 0 == size ) break; PLA_Obj_split_4( A_cur, 1, 1, &A11, PLA_DUMMY, PLA_DUMMY, &A_cur ); PLA_Obj_local_length( A11, &local_m ); PLA_Obj_local_width ( A11, &local_n ); if ( local_m == 1 && local_n == 1 ) { PLA_Obj_local_buffer( A11, (void **) &local_buf ); if ( datatype == MPI_DOUBLE ) *(double *)local_buf += (double) global_length; else if ( MPI_FLOAT == datatype ) *(float *)local_buf += (float) global_length; else if ( datatype == MPI_DOUBLE_COMPLEX){ ((double *)local_buf)[0] += (double) global_length; ((double *)local_buf)[1] = 0.0; } else if ( datatype == MPI_COMPLEX){ ((float *)local_buf)[0] += (float) global_length; ((float *)local_buf)[1] = 0.0; } else printf("Unhandled datatype in create_problem().\n"); } } if ( datatype == MPI_DOUBLE || datatype == MPI_FLOAT ) PLA_Symv( PLA_LOWER_TRIANGULAR, one, A, x, zero, b ); else PLA_Hemv( PLA_LOWER_TRIANGULAR, one, A, x, zero, b ); PLA_Obj_free( &zero ); PLA_Obj_free( &one ); PLA_Obj_free( &A_cur); PLA_Obj_free ( &A11); }