00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifdef HAVE_CONFIG_H
00019
00020 #endif
00021
00022 #include <sys/time.h>
00023 #include <iostream>
00024 #include <cstdlib>
00025 #include <cassert>
00026 #include <unistd.h>
00027
00028 #include "Epetra_config.h"
00029
00030 #ifdef HAVE_MPI
00031 #include "mpi.h"
00032 #include "Epetra_MpiComm.h"
00033 #else
00034 #include "Epetra_SerialComm.h"
00035 #endif
00036
00037 #include "AztecOO.h"
00038 #include "Epetra_Map.h"
00039 #include "Epetra_Vector.h"
00040 #include "matrixmarket/mtxreader0.h"
00041 #include "matrixmarket/balancedmtxreader.h"
00042
00043 extern "C"
00044 {
00045 #include "pbe.h"
00046 }
00047
00048 double second()
00049 {
00050 struct timeval tv;
00051
00052 int info = gettimeofday(&tv, NULL);
00053 assert(info == 0);
00054 return tv.tv_sec + tv.tv_usec / 1e6;
00055 }
00056
00057 void usage(const Epetra_Comm& Comm, string err_msg)
00058 {
00059 if (Comm.MyPID() == 0) {
00060 cerr << err_msg << endl << endl;
00061 cerr << "Usage: trilinos_mtx_demo [-r reader_type] mtx_file" << endl;
00062 }
00063 #ifdef HAVE_MPI
00064 MPI_Finalize();
00065 #endif
00066 exit(1);
00067 }
00068
00069 int main(int argc, char *argv[])
00070 {
00071 #ifdef HAVE_MPI
00072 MPI_Init(&argc, &argv);
00073 Epetra_MpiComm Comm(MPI_COMM_WORLD);
00074 #else
00075 Epetra_SerialComm Comm;
00076 #endif
00077
00078 #ifdef __GNUC__
00079 std::set_terminate (__gnu_cxx::__verbose_terminate_handler);
00080 #endif
00081
00082 if (Comm.MyPID() == 0)
00083 cout << "running on " << Comm.NumProc() << " processor(s)..." << endl;
00084
00085 extern char *optarg;
00086 extern int optind;
00087
00088 int reader_type = 1;
00089
00090 int c;
00091 while ((c = getopt(argc, argv, "r:")) != -1) {
00092 switch (c) {
00093 case 'r':
00094 reader_type = atoi(optarg);
00095 if (!(reader_type == 1 || reader_type == 2))
00096 usage(Comm, "Unsupported reader");
00097 break;
00098 case ':':
00099 case '?':
00100 usage(Comm, "Unsupported option");
00101 break;
00102 }
00103 }
00104
00105 if (argc - optind != 1) {
00106 usage(Comm, "");
00107 }
00108
00109 string filename(argv[optind]);
00110
00111 if (access(filename.c_str(), R_OK)) {
00112 usage(Comm, "Unable to access matrix file.");
00113 }
00114
00115 const char* app_name = NULL;
00116 BaseMtxReader *reader = NULL;
00117 switch (reader_type) {
00118 case 1:
00119 reader = new MtxReader0(filename, Comm);
00120 app_name = "trilinos_trivial";
00121 break;
00122 case 2:
00123 reader = new BalancedMtxReader(filename, Comm);
00124 app_name = "trilinos_balanced";
00125 break;
00126 }
00127
00128 pbe_init(app_name, 4, 0, NULL);
00129 pbe_start(1, "whole_program");
00130
00131 pbe_start(2, "matrix_input");
00132 double t = second();
00133 Epetra_CrsMatrix* pA = reader->read();
00134 Epetra_CrsMatrix& A = *pA;
00135 t = second() - t;
00136 pbe_stop(2);
00137 cout << "Matrix read and distribution time: " << t << " seconds." << endl;
00138
00139 for (int p = 0; p < Comm.NumProc(); p ++) {
00140 if (Comm.MyPID() == p)
00141 cout << "processor " << p << ": " << A.NumMyNonzeros() << " non-zeros" << endl;
00142 Comm.Barrier();
00143 }
00144
00145
00146
00147
00148 Epetra_Vector b(A.RowMap());
00149 b.PutScalar(1.0);
00150
00151
00152 Epetra_Vector x(A.RowMap());
00153 x.PutScalar(0.0);
00154
00155 pbe_start(3, "solver_setup");
00156 t = second();
00157
00158 AztecOO::AztecOO solver(&A, &x, &b);
00159 solver.SetAztecOption(AZ_solver, AZ_bicgstab);
00160 solver.SetAztecOption(AZ_precond, AZ_Jacobi);
00161 solver.SetAztecOption(AZ_reorder, 1);
00162
00163 t = second() - t;
00164 pbe_stop(3);
00165 cout << "Solver setup time: " << t << " seconds." << endl;
00166
00167 t = second();
00168
00169
00170 pbe_start(4, "iteration");
00171 int stat = solver.Iterate(2000, 1e-8);
00172 assert(!stat);
00173 pbe_stop(4);
00174
00175 t = second() - t;
00176 cout << "Iteration time: " << t << " seconds." << endl;
00177
00178
00179 Epetra_Vector r(A.RowMap());
00180 A.Multiply(false, x, r);
00181 r.Update(1.0, b, -1.0);
00182
00183 double norm_r;
00184 r.Norm2(&norm_r);
00185
00186 if (Comm.MyPID() == 0)
00187 cout << "norm(b - A*x) = " << norm_r << endl;
00188
00189 cout << "Solver performed " << solver.NumIters() << " iterations." << endl
00190 << "Norm of true residual = " << solver.TrueResidual() << endl;
00191
00192 pbe_stop(1);
00193 pbe_dump();
00194 pbe_finalize(1);
00195
00196 delete reader;
00197
00198 #ifdef HAVE_MPI
00199 MPI_Finalize();
00200 #endif
00201 return EXIT_SUCCESS;
00202 }