/*! Constructor for the data structure of CG vectors. @param[in] A the data structure that describes the problem matrix and its structure @param[out] data the data structure for CG vectors that will be allocated to get it ready for use in CG iterations */ inline void InitializeSparseCGData(SparseMatrix & A, CGData & data) { local_int_t nrow = A.localNumberOfRows; local_int_t ncol = A.localNumberOfColumns; InitializeVector(data.r, nrow); InitializeVector(data.z, ncol); InitializeVector(data.p, ncol); InitializeVector(data.Ap, nrow); return; }
int TestSymmetry(SparseMatrix & A, Vector & b, Vector & xexact, TestSymmetryData & testsymmetry_data) { local_int_t nrow = A.localNumberOfRows; local_int_t ncol = A.localNumberOfColumns; Vector x_ncol, y_ncol, z_ncol; InitializeVector(x_ncol, ncol); InitializeVector(y_ncol, ncol); InitializeVector(z_ncol, ncol); double t4 = 0.0; // Needed for dot-product call, otherwise unused testsymmetry_data.count_fail = 0; // Test symmetry of matrix // First load vectors with random values FillRandomVector(x_ncol); FillRandomVector(y_ncol); double xNorm2, yNorm2; double ANorm = 2 * 26.0; // Next, compute x'*A*y ComputeDotProduct(nrow, y_ncol, y_ncol, yNorm2, t4, A.isDotProductOptimized); int ierr = ComputeSPMV(A, y_ncol, z_ncol); // z_nrow = A*y_overlap if (ierr) HPCG_fout << "Error in call to SpMV: " << ierr << ".\n" << endl; double xtAy = 0.0; ierr = ComputeDotProduct(nrow, x_ncol, z_ncol, xtAy, t4, A.isDotProductOptimized); // x'*A*y if (ierr) HPCG_fout << "Error in call to dot: " << ierr << ".\n" << endl; // Next, compute y'*A*x ComputeDotProduct(nrow, x_ncol, x_ncol, xNorm2, t4, A.isDotProductOptimized); ierr = ComputeSPMV(A, x_ncol, z_ncol); // b_computed = A*x_overlap if (ierr) HPCG_fout << "Error in call to SpMV: " << ierr << ".\n" << endl; double ytAx = 0.0; ierr = ComputeDotProduct(nrow, y_ncol, z_ncol, ytAx, t4, A.isDotProductOptimized); // y'*A*x if (ierr) HPCG_fout << "Error in call to dot: " << ierr << ".\n" << endl; testsymmetry_data.depsym_spmv = std::fabs((long double) (xtAy - ytAx))/((xNorm2*ANorm*yNorm2 + yNorm2*ANorm*xNorm2) * (DBL_EPSILON)); if (testsymmetry_data.depsym_spmv > 1.0) ++testsymmetry_data.count_fail; // If the difference is > 1, count it wrong if (A.geom->rank==0) HPCG_fout << "Departure from symmetry (scaled) for SpMV abs(x'*A*y - y'*A*x) = " << testsymmetry_data.depsym_spmv << endl; // Test symmetry of symmetric Gauss-Seidel // Compute x'*Minv*y ierr = ComputeMG(A, y_ncol, z_ncol); // z_ncol = Minv*y_ncol if (ierr) HPCG_fout << "Error in call to MG: " << ierr << ".\n" << endl; double xtMinvy = 0.0; ierr = ComputeDotProduct(nrow, x_ncol, z_ncol, xtMinvy, t4, A.isDotProductOptimized); // x'*Minv*y if (ierr) HPCG_fout << "Error in call to dot: " << ierr << ".\n" << endl; // Next, compute z'*Minv*x ierr = ComputeMG(A, x_ncol, z_ncol); // z_ncol = Minv*x_ncol if (ierr) HPCG_fout << "Error in call to MG: " << ierr << ".\n" << endl; double ytMinvx = 0.0; ierr = ComputeDotProduct(nrow, y_ncol, z_ncol, ytMinvx, t4, A.isDotProductOptimized); // y'*Minv*x if (ierr) HPCG_fout << "Error in call to dot: " << ierr << ".\n" << endl; testsymmetry_data.depsym_mg = std::fabs((long double) (xtMinvy - ytMinvx))/((xNorm2*ANorm*yNorm2 + yNorm2*ANorm*xNorm2) * (DBL_EPSILON)); if (testsymmetry_data.depsym_mg > 1.0) ++testsymmetry_data.count_fail; // If the difference is > 1, count it wrong if (A.geom->rank==0) HPCG_fout << "Departure from symmetry (scaled) for MG abs(x'*Minv*y - y'*Minv*x) = " << testsymmetry_data.depsym_mg << endl; CopyVector(xexact, x_ncol); // Copy exact answer into overlap vector int numberOfCalls = 2; double residual = 0.0; for (int i=0; i< numberOfCalls; ++i) { ierr = ComputeSPMV(A, x_ncol, z_ncol); // b_computed = A*x_overlap if (ierr) HPCG_fout << "Error in call to SpMV: " << ierr << ".\n" << endl; if ((ierr = ComputeResidual(A.localNumberOfRows, b, z_ncol, residual))) HPCG_fout << "Error in call to compute_residual: " << ierr << ".\n" << endl; if (A.geom->rank==0) HPCG_fout << "SpMV call [" << i << "] Residual [" << residual << "]" << endl; } DeleteVector(x_ncol); DeleteVector(y_ncol); DeleteVector(z_ncol); return 0; }
int main(int argc, char *argv[]) { if (argc < 3) { printf("Invalid input parameters\n"); return 1; } int N = atoi(argv[1]); int NZ = atoi(argv[2]); char *mtxFileName = NULL; char *vecFileName = NULL; if (argc > 3 && argc < 6) { mtxFileName = argv[3]; vecFileName = argv[4]; } if ((NZ > N) || (N <= 0) || (NZ <= 0)) { printf("Incorrect arguments of main\n"); return 1; } crsMatrix A; double *x, *b, *bm; double timeM=0, timeM1=0, diff=0; if (ReadMatrix(A, mtxFileName) != 0) { GenerateRegularCRS(1, N, NZ, A); WriteMatrix(A, "mtx.txt"); } if (ReadVector(&x, N, vecFileName) != 0) { GenerateVector(2, N, &x); WriteVector(x, N, "vec.txt"); } InitializeVector(N, &b); Multiplicate(A, x, b, timeM); InitializeVector(N, &bm); SparseMKLMult(A, x, bm, timeM1); CompareVectors(b, bm, N, diff); if (diff < EPSILON) printf("OK\n"); else printf("not OK\n"); printf("%d %d\n", A.N, A.NZ); printf("%.3f %.3f\n", timeM, timeM1); FreeMatrix(A); FreeVector(&b); FreeVector(&bm); FreeVector(&x); return 0; }