test/MatrixMatrix/cxx_main.cpp

Go to the documentation of this file.
00001 
00002 #include <string.h>
00003 #include <stdio.h>
00004 #include <iostream>
00005 #include <fstream>
00006 
00007 #include <Epetra_ConfigDefs.h>
00008 
00009 #ifdef EPETRA_MPI
00010 #include <mpi.h>
00011 #include <Epetra_MpiComm.h>
00012 #endif
00013 
00014 #include <Epetra_SerialComm.h>
00015 #include <Epetra_Time.h>
00016 #include <Epetra_Import.h>
00017 #include <Epetra_Map.h>
00018 #include <Epetra_LocalMap.h>
00019 #include <Epetra_CrsGraph.h>
00020 #include <Epetra_CrsMatrix.h>
00021 #include <Epetra_Vector.h>
00022 #include <EpetraExt_MatrixMatrix.h>
00023 
00024 #include <EpetraExt_BlockMapIn.h>
00025 #include <EpetraExt_CrsMatrixIn.h>
00026 #include <EpetraExt_RowMatrixOut.h>
00027 
00028 namespace EpetraExt {
00029 extern
00030 Epetra_Map* find_rows_containing_cols(const Epetra_CrsMatrix& M,
00031                                       const Epetra_Map* colmap);
00032 }
00033 
00034 int read_input_file(Epetra_Comm& Comm,
00035                     const char* input_file_name,
00036                     const char**& filenames,
00037                     int& numfiles,
00038                     int& numfilenames_allocated);
00039 
00040 int read_matrix_file_names(Epetra_Comm& Comm,
00041                            const char* input_file_name,
00042                            char*& A_file,
00043                            bool& transA,
00044                            char*& B_file,
00045                            bool& transB,
00046                            char*& C_file);
00047 
00048 int broadcast_name(Epetra_Comm& Comm, const char*& name);
00049 
00050 int create_maps(Epetra_Comm& Comm,
00051                 const char* input_file_name,
00052                 Epetra_Map*& row_map,
00053                 Epetra_Map*& col_map,
00054                 Epetra_Map*& range_map,
00055                 Epetra_Map*& domain_map);
00056 
00057 int read_matrix(const char* filename,
00058                 Epetra_Comm& Comm,
00059                 const Epetra_Map* rowmap,
00060                 Epetra_Map* colmap,
00061                 const Epetra_Map* rangemap,
00062                 const Epetra_Map* domainmap,
00063                 Epetra_CrsMatrix*& mat);
00064 
00065 int run_test(Epetra_Comm& Comm,
00066              const char* filename,
00067              bool result_mtx_to_file=false,
00068              bool verbose=false);
00069 
00070 int two_proc_test(Epetra_Comm& Comm,
00071                   bool verbose=false);
00072 
00073 int test_find_rows(Epetra_Comm& Comm);
00074 
00075 Epetra_CrsMatrix* create_epetra_crsmatrix(int numProcs,
00076                                           int localProc,
00077                                           int local_n);
00078 
00079 int time_matrix_matrix_multiply(Epetra_Comm& Comm,
00080                                 bool verbose);
00081 
00083 //Global variable!!!!
00084 char* path;
00086 
00087 int main(int argc, char** argv) {
00088 
00089 #ifdef EPETRA_MPI
00090   MPI_Init(&argc,&argv);
00091   Epetra_MpiComm Comm(MPI_COMM_WORLD);
00092 #else
00093   Epetra_SerialComm Comm;
00094 #endif
00095 
00096   bool write_result_mtx = false;
00097   bool verbose = false;
00098   int write = 0;
00099   bool path_specified = false;
00100   char* input_file = NULL;
00101   bool input_file_specified = false;
00102 
00103   if (Comm.MyPID()==0) {
00104     for(int ii=0; ii<argc; ++ii) {
00105       if (!strcmp("-write_result", argv[ii])) write_result_mtx = true;
00106       if (!strcmp("-v", argv[ii])) verbose = true;
00107       if (!strcmp("-i", argv[ii])) {
00108         input_file = argv[ii+1];
00109         input_file_specified = true;
00110       }
00111       if (!strcmp("-d",argv[ii])) {
00112         path = argv[ii+1];
00113         path_specified = true;
00114       }
00115     }
00116     write = write_result_mtx ? 1 : 0;
00117   }
00118 #ifdef EPETRA_MPI
00119   MPI_Bcast(&write, 1, MPI_INT, 0, MPI_COMM_WORLD);
00120   if (write) write_result_mtx = true;
00121 #endif
00122 
00123   if (!path_specified) {
00124     path = new char[32];
00125     sprintf(path, "%s", ".");
00126   }
00127 
00128   int err = two_proc_test(Comm, verbose);
00129   if (err != 0) {
00130     std::cout << "two_proc_test returned err=="<<err<<std::endl;
00131     return(err);
00132   }
00133 
00134   if (!input_file_specified) {
00135     input_file = new char[64];
00136     sprintf(input_file, "%s", "infiles");
00137   }
00138 
00139   const char** filenames = NULL;
00140   int numfiles = 0;
00141   int numfilenames_allocated = 0;
00142 
00143   err = read_input_file(Comm, input_file,
00144                         filenames, numfiles, numfilenames_allocated);
00145   if (err != 0) {
00146     if (path_specified) path_specified = false;
00147     sprintf(path, "%s", "./MatrixMatrix");
00148     read_input_file(Comm, input_file,
00149                     filenames, numfiles, numfilenames_allocated);
00150   }
00151 
00152   err = test_find_rows(Comm);
00153   if (err != 0) {
00154     std::cout << "test_find_rows returned err=="<<err<<endl;
00155     return(err);
00156   }
00157 
00158   for(int i=0; i<numfiles; ++i) {
00159     err = run_test(Comm, filenames[i], write_result_mtx, verbose);
00160     delete [] filenames[i];
00161     if (err != 0) break;
00162   }
00163 
00164   for(int j=numfiles; j<numfilenames_allocated; ++j) {
00165     delete [] filenames[j];
00166   }
00167 
00168   delete [] filenames;
00169 
00170   if (!input_file_specified) delete [] input_file;
00171   if (!path_specified) delete [] path;
00172 
00173   err = time_matrix_matrix_multiply(Comm, verbose);
00174 
00175 #ifdef EPETRA_MPI
00176   MPI_Finalize();
00177 #endif
00178 
00179   return(err);
00180 }
00181 
00182 int test_find_rows(Epetra_Comm& Comm)
00183 {
00184   int numprocs = Comm.NumProc();
00185   int localproc = Comm.MyPID();
00186   int numlocalrows = 2;
00187   int numglobalrows = numprocs*numlocalrows;
00188   Epetra_Map rowmap(numlocalrows*numprocs, 0, Comm);
00189   Epetra_CrsMatrix matrix(Copy, rowmap, numglobalrows);
00190 
00191   int err = 0;
00192   int* cols = new int[numglobalrows];
00193   double*vals = new double[numglobalrows];
00194 
00195   for(int j=0; j<numglobalrows; ++j) {
00196     cols[j] = j;
00197     vals[j] = 1.0;
00198   }
00199 
00200   Epetra_Map colmap(-1, numglobalrows, cols, 0, Comm);
00201 
00202   for(int i=0; i<numlocalrows; ++i) {
00203     int row = localproc*numlocalrows+i;
00204     err = matrix.InsertGlobalValues(row, 1, &(vals[i]), &row);
00205     if (err != 0) {
00206       return(err);
00207     }
00208   }
00209 
00210   err = matrix.FillComplete();
00211   if (err != 0) {
00212     return(err);
00213   }
00214 
00215   Epetra_Map* map_rows = EpetraExt::find_rows_containing_cols(matrix,
00216                     &colmap);
00217 
00218   if (map_rows->NumMyElements() != numglobalrows) {
00219     return(-1);
00220   }
00221 
00222   delete map_rows;
00223   delete [] cols;
00224   delete [] vals;
00225 
00226   return(0);
00227 }
00228 
00229 int expand_name_list(const char* newname,
00230                      const char**& names,
00231                      int& alloc_len,
00232                      int& num_names)
00233 {
00234   int offset = num_names;
00235   if (offset >= alloc_len) {
00236     int alloc_increment = 8;
00237     const char** newlist = new const char*[alloc_len+alloc_increment];
00238     for(int i=0; i<offset; ++i) {
00239       newlist[i] = names[i];
00240     }
00241     delete [] names;
00242     names = newlist;
00243     alloc_len += alloc_increment;
00244     for(int i=offset; i<alloc_len; ++i) {
00245       names[i] = NULL;
00246     }
00247   }
00248 
00249   names[offset] = newname;
00250   ++num_names;
00251   return(0);
00252 }
00253 
00254 int broadcast_name(Epetra_Comm& Comm, const char*& name)
00255 {
00256   if (Comm.NumProc() < 2) return(0);
00257 
00258 #ifdef EPETRA_MPI
00259   int len;
00260   int localProc = Comm.MyPID();
00261   if (localProc == 0) {
00262     len = (int)strlen(name)+1;
00263     
00264     MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD);
00265     MPI_Bcast((void*)name, len, MPI_CHAR, 0, MPI_COMM_WORLD);
00266   }
00267   else {
00268     MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD);
00269     name = new char[len];
00270     MPI_Bcast((void*)name, len, MPI_CHAR, 0, MPI_COMM_WORLD);
00271   }
00272 
00273 #endif
00274   return(0);
00275 }
00276 
00277 int read_input_file(Epetra_Comm& Comm,
00278                     const char* input_file_name,
00279                     const char**& filenames,
00280                     int& numfiles,
00281                     int& numfilenames_allocated)
00282 {
00283   int local_err = 0, global_err = 0;
00284   ifstream* infile = NULL;
00285   int pathlen = path != 0 ? (int)strlen(path): 0;
00286 
00287   if (Comm.MyPID() == 0) {
00288     char* full_name = NULL;
00289     int filenamelen = input_file_name != 0 ? (int)strlen(input_file_name) : 0;
00290 
00291     full_name = new char[pathlen+filenamelen+2];
00292     if (path != 0) {
00293       sprintf(full_name, "%s/%s",path,input_file_name);
00294     }
00295     else {
00296       sprintf(full_name, "%s", input_file_name);
00297     }
00298 
00299     infile = new ifstream(full_name);
00300     if (!(*infile)) {
00301       local_err = -1;
00302       delete infile;
00303     }
00304     delete [] full_name;
00305   }
00306 
00307   Comm.SumAll(&local_err, &global_err, 1);
00308 
00309   if (global_err != 0) {
00310     return(global_err);
00311   }
00312 
00313 
00314   if (Comm.MyPID() == 0) {
00315     int linelen = 512;
00316     char* line = NULL;
00317 
00318     ifstream& ifile = *infile;
00319     while(!ifile.eof()) {
00320       line = new char[pathlen+1+linelen];
00321       if (pathlen>0) {
00322         sprintf(line,"%s/",path);
00323         ifile.getline(&(line[pathlen+1]), linelen);
00324       }
00325       else {
00326         ifile.getline(line, linelen);
00327       }
00328 
00329       if (ifile.fail()) {
00330   delete [] line;
00331         break;
00332       }
00333       if (strchr(line, '#') == NULL) {
00334         expand_name_list(line, filenames, numfilenames_allocated, numfiles);
00335       }
00336       else {
00337         delete [] line;
00338       }
00339     }
00340 
00341 #ifdef EPETRA_MPI
00342     MPI_Bcast(&numfiles, 1, MPI_INT, 0, MPI_COMM_WORLD);
00343 #endif
00344     for(int i=0; i<numfiles; ++i) {
00345       broadcast_name(Comm, filenames[i]);
00346     }
00347 
00348     delete infile;
00349   }
00350   else {
00351 #ifdef EPETRA_MPI
00352     MPI_Bcast(&numfiles, 1, MPI_INT, 0, MPI_COMM_WORLD);
00353 #endif
00354     filenames = new const char*[numfiles];
00355     numfilenames_allocated = numfiles;
00356     for(int i=0; i<numfiles; ++i) {
00357       broadcast_name(Comm, filenames[i]);
00358     }
00359   }
00360   
00361   return(0);
00362 }
00363 
00364 int run_test(Epetra_Comm& Comm,
00365              const char* filename,
00366              bool result_mtx_to_file,
00367              bool verbose)
00368 {
00369   char* A_file = NULL;
00370   char AT[3]; AT[0] = '^'; AT[1] = 'T'; AT[2] = '\0';
00371   char* B_file = NULL;
00372   char BT[3]; BT[0] = '^'; BT[1] = 'T'; BT[2] = '\0';
00373   char* C_file = NULL;
00374   bool transA, transB;
00375 
00376   int err = read_matrix_file_names(Comm, filename, A_file, transA,
00377                                    B_file, transB, C_file);
00378   if (err != 0) {
00379     std::cout << "Error, read_matrix_file_names returned " << err << std::endl;
00380     return(err);
00381   }
00382 
00383   if (!transA) AT[0] = '\0';
00384   if (!transB) BT[0] = '\0';
00385 
00386   int localProc = Comm.MyPID();
00387 
00388   if (localProc == 0 && verbose) {
00389     std::cout << "Testing C=A"<<AT<<"*B"<<BT<< "; A:" << A_file
00390               << ", B:" << B_file << ", C:" << C_file << std::endl;
00391   }
00392 
00393   Epetra_CrsMatrix* A = NULL;
00394   Epetra_CrsMatrix* B = NULL;
00395   Epetra_CrsMatrix* C = NULL;
00396   Epetra_CrsMatrix* C_check = NULL;
00397 
00398   Epetra_Map* A_row_map = NULL;
00399   Epetra_Map* A_col_map = NULL;
00400   Epetra_Map* A_range_map = NULL;
00401   Epetra_Map* A_domain_map = NULL;
00402   err = create_maps(Comm, A_file, A_row_map, A_col_map, A_range_map, A_domain_map);
00403   if (err != 0) {
00404     std::cout << "create_maps A returned err=="<<err<<std::endl;
00405     return(err);
00406   }
00407 
00408   Epetra_Map* B_row_map = NULL;
00409   Epetra_Map* B_col_map = NULL;
00410   Epetra_Map* B_range_map = NULL;
00411   Epetra_Map* B_domain_map = NULL;
00412   err = create_maps(Comm, B_file, B_row_map, B_col_map, B_range_map, B_domain_map);
00413   if (err != 0) {
00414     std::cout << "create_maps A returned err=="<<err<<std::endl;
00415     return(err);
00416   }
00417 
00418   err = read_matrix(A_file, Comm, A_row_map, A_col_map,
00419                     A_range_map, A_domain_map, A);
00420   delete [] A_file;
00421   if (err != 0) {
00422     std::cout << "read_matrix A returned err=="<<err<<std::endl;
00423     return(err);
00424   }
00425 
00426   err = read_matrix(B_file, Comm, B_row_map, B_col_map,
00427                     B_range_map, B_domain_map, B);
00428   delete [] B_file;
00429   if (err != 0) {
00430     std::cout << "read_matrix B returned err=="<<err<<std::endl;
00431     return(-1);
00432   }
00433 
00434   const Epetra_Map* rowmap = transA ? &(A->DomainMap()) : &(A->RowMap());
00435 
00436   C = new Epetra_CrsMatrix(Copy, *rowmap, 1);
00437 
00438   err = EpetraExt::MatrixMatrix::Multiply(*A, transA, *B, transB, *C);
00439   if (err != 0) {
00440     std::cout << "err "<<err<<" from MatrixMatrix::Multiply"<<std::endl;
00441     return(err);
00442   }
00443 
00444 //  std::cout << "A: " << *A << std::endl << "B: "<<*B<<std::endl<<"C: "<<*C<<std::endl;
00445   if (result_mtx_to_file) {
00446     EpetraExt::RowMatrixToMatrixMarketFile("result.mtx", *C);
00447   }
00448 
00449   Epetra_Map* Cck_row_map = NULL;
00450   Epetra_Map* Cck_col_map = NULL;
00451   Epetra_Map* Cck_range_map = NULL;
00452   Epetra_Map* Cck_domain_map = NULL;
00453   err = create_maps(Comm, C_file, Cck_row_map, Cck_col_map,
00454                     Cck_range_map, Cck_domain_map);
00455   if (err != 0) {
00456     std::cout << "create_maps C returned err=="<<err<<std::endl;
00457     return(err);
00458   }
00459 
00460   err = read_matrix(C_file, Comm, Cck_row_map, Cck_col_map,
00461                      Cck_range_map, Cck_domain_map, C_check);
00462   delete [] C_file;
00463   if (err != 0) {
00464     std::cout << "read_matrix C returned err=="<<err<<std::endl;
00465     return(-1);
00466   }
00467 
00468   EpetraExt::MatrixMatrix::Add(*C, false, -1.0, *C_check, 1.0);
00469 
00470   double inf_norm = C_check->NormInf();
00471 
00472   int return_code = 0;
00473 
00474   if (inf_norm < 1.e-13) {
00475     if (localProc == 0 && verbose) {
00476       std::cout << "Test Passed" << std::endl;
00477     }
00478   }
00479   else {
00480     return_code = -1;
00481     if (localProc == 0) {
00482       std::cout << "Test Failed, inf_norm = " << inf_norm << std::endl;
00483     }
00484   }
00485 
00486   delete A;
00487   delete B;
00488   delete C;
00489   delete C_check;
00490 
00491   delete A_row_map;
00492   delete A_col_map;
00493   delete A_range_map;
00494   delete A_domain_map;
00495 
00496   delete B_row_map;
00497   delete B_col_map;
00498   delete B_range_map;
00499   delete B_domain_map;
00500 
00501   delete Cck_row_map;
00502   delete Cck_col_map;
00503   delete Cck_range_map;
00504   delete Cck_domain_map;
00505 
00506   return(return_code);
00507 }
00508 
00509 int read_matrix_file_names(Epetra_Comm& Comm,
00510                            const char* input_file_name,
00511                            char*& A_file,
00512                            bool& transA,
00513                            char*& B_file,
00514                            bool& transB,
00515                            char*& C_file)
00516 {
00517   int pathlen = path!=0 ? (int)strlen(path) : 0;
00518 
00519   if (Comm.MyPID()==0) {
00520     ifstream infile(input_file_name);
00521     if (!infile) {
00522       std::cout << "error opening input file " << input_file_name << std::endl;
00523       return(-1);
00524     }
00525 
00526     int linelen = 512;
00527     char line[512];
00528 
00529     infile.getline(line, linelen);
00530     if (!infile.eof()) {
00531       if (strchr(line, '#') == NULL) {
00532         A_file = new char[pathlen+strlen(line)+2];
00533         sprintf(A_file, "%s/%s",path,line);
00534       }
00535     }
00536 
00537     infile.getline(line, linelen);
00538     if (!infile.eof()) {
00539       if (!strcmp(line, "TRANSPOSE")) {
00540         transA = true;
00541       }
00542       else transA = false;
00543     }
00544 
00545     infile.getline(line, linelen);
00546     if (!infile.eof()) {
00547       if (strchr(line, '#') == NULL) {
00548         B_file = new char[pathlen+strlen(line)+2];
00549         sprintf(B_file, "%s/%s",path,line);
00550       }
00551     }
00552 
00553     infile.getline(line, linelen);
00554     if (!infile.eof()) {
00555       if (!strcmp(line, "TRANSPOSE")) {
00556         transB = true;
00557       }
00558       else transB = false;
00559     }
00560 
00561     infile.getline(line, linelen);
00562     if (!infile.eof()) {
00563       if (strchr(line, '#') == NULL) {
00564         C_file = new char[pathlen+strlen(line)+2];
00565         sprintf(C_file, "%s/%s", path, line);
00566       }
00567     }
00568 
00569     broadcast_name(Comm, (const char*&)A_file);
00570     broadcast_name(Comm, (const char*&)B_file);
00571     broadcast_name(Comm, (const char*&)C_file);
00572 #ifdef EPETRA_MPI
00573     int len = transA ? 1 : 0;
00574     MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD);
00575     len = transB ? 1 : 0;
00576     MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD);
00577 #endif
00578   }
00579   else {
00580     broadcast_name(Comm, (const char*&)A_file);
00581     broadcast_name(Comm, (const char*&)B_file);
00582     broadcast_name(Comm, (const char*&)C_file);
00583 #ifdef EPETRA_MPI
00584     int len = 0;
00585     MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD);
00586     transA = len==1 ? true : false;
00587     MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD);
00588     transB = len==1 ? true : false;
00589 #endif
00590   }
00591 
00592   return(0);
00593 }
00594 
00595 int create_maps(Epetra_Comm& Comm,
00596                 const char* input_file_name,
00597                 Epetra_Map*& row_map,
00598                 Epetra_Map*& col_map,
00599                 Epetra_Map*& range_map,
00600                 Epetra_Map*& domain_map)
00601 {
00602   return( EpetraExt::MatrixMarketFileToBlockMaps(input_file_name,
00603                                          Comm,
00604                                          (Epetra_BlockMap*&)row_map,
00605                                          (Epetra_BlockMap*&)col_map,
00606                                          (Epetra_BlockMap*&)range_map,
00607                                          (Epetra_BlockMap*&)domain_map)
00608   );
00609 }
00610 
00611 int read_matrix(const char* filename,
00612                 Epetra_Comm& Comm,
00613                 const Epetra_Map* rowmap,
00614                 Epetra_Map* colmap,
00615                 const Epetra_Map* rangemap,
00616                 const Epetra_Map* domainmap,
00617                 Epetra_CrsMatrix*& mat)
00618 {
00619   (void)Comm;
00620   int err = EpetraExt::MatrixMarketFileToCrsMatrix(filename, *rowmap, *colmap,
00621                                                    *rangemap, *domainmap, mat);
00622 
00623   return(err);
00624 }
00625 
00626 int two_proc_test(Epetra_Comm& Comm,
00627                   bool verbose)
00628 {
00629   (void)verbose;
00630   int thisproc = Comm.MyPID();
00631   int numprocs = Comm.NumProc();
00632 
00633   //only run this test on 2 procs
00634   if (numprocs != 2) return(0);
00635 
00636   //set up a row-map with 2 global elements,
00637   //1 on each proc.
00638   int numGlobalRows = 2;
00639   int numMyRows = 1;
00640   int myrow = 3;
00641   if (thisproc == 1) myrow = 7;
00642   Epetra_Map rowmap(numGlobalRows, numMyRows, &myrow, 0, Comm);
00643 
00644   //set up a domain-map with columns 0 - 4 on proc 0,
00645   //and columns 5 - 9 on proc 1.
00646   int numGlobalCols = 10;
00647   int numMyCols = 5;
00648   int* mycols = new int[numGlobalCols];
00649   int i;
00650   for(i=0; i<numGlobalCols; ++i) {
00651     mycols[i] = i;
00652   }
00653 
00654   Epetra_Map domainmap(numGlobalCols, numMyCols, &(mycols[thisproc*numMyCols]),
00655                        0, Comm);
00656 
00657   //now create matrices A, B and C with rowmap.
00658   Epetra_CrsMatrix A(Copy, rowmap, 10);
00659   Epetra_CrsMatrix B(Copy, rowmap, 10);
00660   Epetra_CrsMatrix C(Copy, rowmap, 10);
00661 
00662   double* coefs = new double[numGlobalCols];
00663   for(i=0; i<numGlobalCols; ++i) {
00664     coefs[i] = 1.0*i;
00665   }
00666 
00667   int err = A.InsertGlobalValues(myrow, numGlobalCols, coefs, mycols);
00668 
00669   err += B.InsertGlobalValues(myrow, numMyCols, &(coefs[thisproc*numMyCols]),
00670                        &(mycols[thisproc*numMyCols]));
00671 
00672   err += A.FillComplete(domainmap, rowmap);
00673   err += B.FillComplete(domainmap, rowmap);
00674 
00675   err += EpetraExt::MatrixMatrix::Multiply(A, false, B, true, C);
00676 
00677   //cout << "two_proc_test, A: "<<endl;
00678   //cout << A << endl;
00679 
00680   //cout << "two_proc_test, B: "<<endl;
00681   //cout << B << endl;
00682 
00683   //cout << "two_proc_test, C: "<<endl;
00684   //cout << C << endl;
00685 
00686   if (C.NumGlobalNonzeros() != 4) {
00687     err += 1;
00688   }
00689 
00690   delete [] coefs;
00691   delete [] mycols;
00692 
00693   return(err);
00694 }
00695 
00696 int time_matrix_matrix_multiply(Epetra_Comm& Comm, bool verbose)
00697 {
00698   int localn = 30000/Comm.NumProc();
00699 
00700   Epetra_CrsMatrix* A = create_epetra_crsmatrix(Comm.NumProc(),
00701                                                 Comm.MyPID(),
00702                                                 localn);
00703 
00704   Epetra_CrsMatrix* C = new Epetra_CrsMatrix(Copy, A->RowMap(), 0);
00705 
00706   Epetra_Time timer(Comm);
00707   double start_time = timer.WallTime();
00708 
00709   int err = EpetraExt::MatrixMatrix::Multiply(*A, false, *A, false, *C);
00710 
00711   int globaln = localn*Comm.NumProc();
00712   if (verbose) {
00713     std::cout << "size: " << globaln << "x"<<globaln<<", C = A*A, time: "
00714        << timer.WallTime()-start_time << std::endl;
00715   }
00716 
00717   C->FillComplete();
00718 
00719   start_time = timer.WallTime();
00720 
00721   err = EpetraExt::MatrixMatrix::Multiply(*A, false, *A, false, *C);
00722 
00723   if (verbose) {
00724     std::cout << "size: " << globaln << "x"<<globaln<<", C = A*A, time: "
00725        << timer.WallTime()-start_time << " (C already Filled)\n" <<std::endl;
00726   }
00727 
00728   delete C;
00729 
00730   C = new Epetra_CrsMatrix(Copy, A->RowMap(), 0);
00731 
00732   start_time = timer.WallTime();
00733 
00734   err = EpetraExt::MatrixMatrix::Multiply(*A, false, *A, true, *C);
00735 
00736   if (verbose) {
00737     std::cout << "size: " << globaln << "x"<<globaln<<", C = A*A^T, time: "
00738        << timer.WallTime()-start_time << std::endl;
00739   }
00740 
00741   C->FillComplete();
00742 
00743   start_time = timer.WallTime();
00744 
00745   err = EpetraExt::MatrixMatrix::Multiply(*A, false, *A, true, *C);
00746 
00747   if (verbose) {
00748     std::cout << "size: " << globaln << "x"<<globaln<<", C = A*A^T, time: "
00749        << timer.WallTime()-start_time << " (C already Filled)\n" <<std::endl;
00750   }
00751 
00752   delete C;
00753 
00754   C = new Epetra_CrsMatrix(Copy, A->RowMap(), 0);
00755 
00756   start_time = timer.WallTime();
00757 
00758   err = EpetraExt::MatrixMatrix::Multiply(*A, true, *A, false, *C);
00759 
00760   if (verbose) {
00761     std::cout << "size: " << globaln << "x"<<globaln<<", C = A^T*A, time: "
00762        << timer.WallTime()-start_time << std::endl;
00763   }
00764 
00765   C->FillComplete();
00766 
00767   start_time = timer.WallTime();
00768 
00769   err = EpetraExt::MatrixMatrix::Multiply(*A, true, *A, false, *C);
00770 
00771   if (verbose) {
00772     std::cout << "size: " << globaln << "x"<<globaln<<", C = A^T*A, time: "
00773        << timer.WallTime()-start_time << " (C already Filled)\n"<<std::endl;
00774   }
00775 
00776   delete C;
00777 
00778   C = new Epetra_CrsMatrix(Copy, A->RowMap(), 0);
00779 
00780   start_time = timer.WallTime();
00781 
00782   err = EpetraExt::MatrixMatrix::Multiply(*A, true, *A, true, *C);
00783 
00784   if (verbose) {
00785     std::cout << "size: " << globaln << "x"<<globaln<<", C = A^T*A^T, time: "
00786        << timer.WallTime()-start_time << std::endl;
00787   }
00788 
00789   C->FillComplete();
00790 
00791   start_time = timer.WallTime();
00792 
00793   err = EpetraExt::MatrixMatrix::Multiply(*A, true, *A, true, *C);
00794 
00795   if (verbose) {
00796     std::cout << "size: " << globaln << "x"<<globaln<<", C = A^T*A^T, time: "
00797        << timer.WallTime()-start_time << " (C already Filled)\n" <<std::endl;
00798   }
00799 
00800   delete C;
00801 
00802   delete A;
00803 
00804   return(err);
00805 }
00806 
00807 Epetra_CrsMatrix* create_epetra_crsmatrix(int numProcs,
00808                                           int localProc,
00809                                           int local_n)
00810 {
00811   (void)localProc;
00812 #ifdef EPETRA_MPI
00813   Epetra_MpiComm comm(MPI_COMM_WORLD);
00814 #else
00815   Epetra_SerialComm comm;
00816 #endif
00817   int global_num_rows = numProcs*local_n;
00818 
00819   Epetra_Map rowmap(global_num_rows, local_n, 0, comm);
00820 
00821   int nnz_per_row = 9;
00822   Epetra_CrsMatrix* matrix =
00823     new Epetra_CrsMatrix(Copy, rowmap, nnz_per_row);
00824 
00825   // Add  rows one-at-a-time
00826   double negOne = -1.0;
00827   double posTwo = 2.0;
00828   for (int i=0; i<local_n; i++) {
00829     int GlobalRow = matrix->GRID(i);
00830     int RowLess1 = GlobalRow - 1;
00831     int RowPlus1 = GlobalRow + 1;
00832     int RowLess5 = GlobalRow - 5;
00833     int RowPlus5 = GlobalRow + 5;
00834     int RowLess9 = GlobalRow - 9;
00835     int RowPlus9 = GlobalRow + 9;
00836     int RowLess24 = GlobalRow - 24;
00837     int RowPlus24 = GlobalRow + 24;
00838     int RowLess48 = GlobalRow - 48;
00839     int RowPlus48 = GlobalRow + 48;
00840 
00841     if (RowLess48>=0) {
00842       matrix->InsertGlobalValues(GlobalRow, 1, &negOne, &RowLess48);
00843     }
00844     if (RowLess24>=0) {
00845       matrix->InsertGlobalValues(GlobalRow, 1, &negOne, &RowLess24);
00846     }
00847     if (RowLess9>=0) {
00848       matrix->InsertGlobalValues(GlobalRow, 1, &negOne, &RowLess9);
00849     }
00850     if (RowLess5>=0) {
00851       matrix->InsertGlobalValues(GlobalRow, 1, &negOne, &RowLess5);
00852     }
00853     if (RowLess1>=0) {
00854       matrix->InsertGlobalValues(GlobalRow, 1, &negOne, &RowLess1);
00855     }
00856     if (RowPlus1<global_num_rows) {
00857       matrix->InsertGlobalValues(GlobalRow, 1, &negOne, &RowPlus1);
00858     }
00859     if (RowPlus5<global_num_rows) {
00860       matrix->InsertGlobalValues(GlobalRow, 1, &negOne, &RowPlus5);
00861     }
00862     if (RowPlus9<global_num_rows) {
00863       matrix->InsertGlobalValues(GlobalRow, 1, &negOne, &RowPlus9);
00864     }
00865     if (RowPlus24<global_num_rows) {
00866       matrix->InsertGlobalValues(GlobalRow, 1, &negOne, &RowPlus24);
00867     }
00868     if (RowPlus48<global_num_rows) {
00869       matrix->InsertGlobalValues(GlobalRow, 1, &negOne, &RowPlus48);
00870     }
00871 
00872     matrix->InsertGlobalValues(GlobalRow, 1, &posTwo, &GlobalRow);
00873   }
00874 
00875   int err = matrix->FillComplete();
00876   if (err != 0) {
00877     std::cout << "create_epetra_matrix: error in matrix.FillComplete()"
00878        <<std::endl;
00879   }
00880 
00881   return(matrix);
00882 }
00883 

Generated on Thu Sep 18 12:31:57 2008 for EpetraExt Package Browser (Single Doxygen Collection) by doxygen 1.3.9.1