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
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
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
00634 if (numprocs != 2) return(0);
00635
00636
00637
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
00645
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
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
00678
00679
00680
00681
00682
00683
00684
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
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