Exemple #1
0
// prototype
int main(int argc, char *argv[]) {
#ifdef HAVE_MPI
  MPI_Init(&argc,&argv);
  Epetra_MpiComm Comm(MPI_COMM_WORLD);
#else
  Epetra_SerialComm Comm;
#endif

  if (Comm.MyPID()==0)
    cout << Epetra_Version() << endl << endl;

  cout << Comm << endl; // Print out process information
  // Get the number of global equations from the command line
  if (argc!=2) { 
    cout << "Usage: " << argv[0] << " number_of_equations" << endl;
    exit(1);
   }
  int NumGlobalElements = atoi(argv[1]);
  // Construct a Map that puts approximately the same number of 
  // equations on each processor.
  Epetra_Map Map(NumGlobalElements, 0, Comm);
  // Get update list and number of local equations from newly created Map.
  cout << Map << endl;
#ifdef UG_EX1_MPI
  MPI_Finalize() ;
#endif
return 0;
}
Exemple #2
0
int main(int argc, char *argv[])
{

  std::cout << Epetra_Version() << std::endl << std::endl;

  Epetra_SerialComm Comm;

  int NumElements = 1000;

  // Construct a Map with NumElements and index base of 0
  Epetra_Map Map(NumElements, 0, Comm);

  // Create x and b vectors
  Epetra_Vector x(Map);
  Epetra_Vector b(Map);

  b.Random();
  x.Update(2.0, b, 0.0); // x = 2*b

  double bnorm, xnorm;
  x.Norm2(&xnorm);
  b.Norm2(&bnorm);

  std::cout << "2 norm of x = " << xnorm << std::endl
       << "2 norm of b = " << bnorm << std::endl;

  return 0;
}
Exemple #3
0
int main(int argc, char *argv[])
{
  cout << Epetra_Version() << endl << endl;

  Teuchos::GlobalMPISession mpiSession(&argc,&argv);

  int NumElements = 1000;

  typedef double Scalar;

  Teuchos::RCP<const Epetra_Comm> epetra_comm;
  epetra_comm = Teuchos::rcp(new Epetra_SerialComm);

  // Construct a Map with NumElements and index base of 0
  Teuchos::RCP<const Epetra_Map> epetra_map;
  epetra_map = Teuchos::rcp(new Epetra_Map(NumElements, 0, *epetra_comm));
  // Construct a VectorSpace from the map
  Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> > epetra_vs;
  epetra_vs = Thyra::create_VectorSpace(epetra_map);
  

  // Create x and b vectors
  Teuchos::RCP<Thyra::VectorBase<Scalar> > b = Thyra::createMember(epetra_vs);
  Teuchos::RCP<Thyra::VectorBase<Scalar> > x = Thyra::createMember(epetra_vs);

  Thyra::randomize(0.0,1.0,&*b); // b = random
  Thyra::V_StV(&*x,2.0,*b); // x = 2*b

  double bnorm, xnorm;
  xnorm = Thyra::norm_2(*x);
  bnorm = Thyra::norm_2(*b);

  cout << "2 norm of x = " << xnorm << endl
       << "2 norm of b = " << bnorm << endl;

//  Test out error messages from bad pointer arithmetic
//  cout << "Element 0 of x = " << (&*x)[0] << endl; // bad error message
//  cout << "Element 0 of x = " << (*x)[0] << endl; // good error message
//  for (int i=1;i<=NumElements;++i)
//    cout << "Element " << i << " of x = " << Thyra::get_ele(*x,i) << endl;

// Test out get_Epetra_Vector:
//  Teuchos::RCP<Epetra_Vector> x_epetra = Thyra::get_Epetra_Vector(*epetra_map,x);
//  for (int i=0;i<NumElements;++i)
//    cout << "Element " << i << " of x = " << (*x_epetra)[i] << endl;

  return 0;
}
Exemple #4
0
int main(int argc, char *argv[]) {

  int ierr = 0, i;

#ifdef EPETRA_MPI

  // Initialize MPI

  MPI_Init(&argc,&argv);
  int rank; // My process ID

  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  Epetra_MpiComm Comm(MPI_COMM_WORLD);

#else

  int rank = 0;
  Epetra_SerialComm Comm;

#endif

#ifdef HAVE_EPETRA_TEUCHOS
  Teuchos::RCP<Teuchos::FancyOStream>
    fancyOut = Teuchos::VerboseObjectBase::getDefaultOStream();
  if (Comm.NumProc() > 1 ) {
    fancyOut->setShowProcRank(true);
    fancyOut->setOutputToRootOnly(-1);
  }
  std::ostream &out = *fancyOut;
#else
  std::ostream &out = std::cout;
#endif

  Comm.SetTracebackMode(0); // This should shut down any error tracing
  bool verbose = false;

  // Check if we should print results to standard out
  if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true;

  //  char tmp;
  //  if (rank==0) out << "Press any key to continue..."<< endl;
  //  if (rank==0) cin >> tmp;
  //  Comm.Barrier();

  int MyPID = Comm.MyPID();
  int NumProc = Comm.NumProc();

  if (verbose && MyPID==0)
    out << Epetra_Version() << endl << endl;

  if (verbose) out << Comm <<endl;

  bool verbose1 = verbose;

  // Redefine verbose to only print on PE 0
  if (verbose && rank!=0) verbose = false;

  int NumMyElements = 10000;
  int NumMyElements1 = NumMyElements; // Needed for localmap
  int NumGlobalElements = NumMyElements*NumProc+EPETRA_MIN(NumProc,3);
  if (MyPID < 3) NumMyElements++;
  int IndexBase = 0;
  int ElementSize = 7;

  // Test LocalMap constructor
  // and Petra-defined uniform linear distribution constructor

  if (verbose) out << "\n*********************************************************" << endl;
  if (verbose) out << "Checking Epetra_LocalMap(NumMyElements1, IndexBase, Comm)" << endl;
  if (verbose) out << "     and Epetra_BlockMap(NumGlobalElements, ElementSize, IndexBase, Comm)" << endl;
  if (verbose) out << "*********************************************************" << endl;

  Epetra_LocalMap *LocalMap = new Epetra_LocalMap(NumMyElements1, IndexBase,
                              Comm);
  Epetra_BlockMap * BlockMap = new Epetra_BlockMap(NumGlobalElements, ElementSize, IndexBase, Comm);
  EPETRA_TEST_ERR(VectorTests(*BlockMap, verbose),ierr);

  EPETRA_TEST_ERR(MatrixTests(*BlockMap, *LocalMap, verbose),ierr);

  delete BlockMap;

  // Test User-defined linear distribution constructor

  if (verbose) out << "\n*********************************************************" << endl;
  if (verbose) out << "Checking Epetra_BlockMap(NumGlobalElements, NumMyElements, ElementSize, IndexBase, Comm)" << endl;
  if (verbose) out << "*********************************************************" << endl;

  BlockMap = new Epetra_BlockMap(NumGlobalElements, NumMyElements, ElementSize, IndexBase, Comm);

  EPETRA_TEST_ERR(VectorTests(*BlockMap, verbose),ierr);

  EPETRA_TEST_ERR(MatrixTests(*BlockMap, *LocalMap, verbose),ierr);

  delete BlockMap;

  // Test User-defined arbitrary distribution constructor
  // Generate Global Element List.  Do in reverse for fun!

  int * MyGlobalElements = new int[NumMyElements];
  int MaxMyGID = (Comm.MyPID()+1)*NumMyElements-1+IndexBase;
  if (Comm.MyPID()>2) MaxMyGID+=3;
  for (i = 0; i<NumMyElements; i++) MyGlobalElements[i] = MaxMyGID-i;

  if (verbose) out << "\n*********************************************************" << endl;
  if (verbose) out << "Checking Epetra_BlockMap(NumGlobalElements, NumMyElements, MyGlobalElements,  ElementSize, IndexBase, Comm)" << endl;
  if (verbose) out << "*********************************************************" << endl;

  BlockMap = new Epetra_BlockMap(NumGlobalElements, NumMyElements, MyGlobalElements, ElementSize,
		      IndexBase, Comm);
  EPETRA_TEST_ERR(VectorTests(*BlockMap, verbose),ierr);

  EPETRA_TEST_ERR(MatrixTests(*BlockMap, *LocalMap, verbose),ierr);

  delete BlockMap;

  int * ElementSizeList = new int[NumMyElements];
  int NumMyEquations = 0;
  int NumGlobalEquations = 0;
  for (i = 0; i<NumMyElements; i++)
    {
      ElementSizeList[i] = i%6+2; // blocksizes go from 2 to 7
      NumMyEquations += ElementSizeList[i];
    }
  ElementSize = 7; // Set to maximum for use in checkmap
  NumGlobalEquations = Comm.NumProc()*NumMyEquations;

  // Adjust NumGlobalEquations based on processor ID
  if (Comm.NumProc() > 3)
    {
      if (Comm.MyPID()>2)
	NumGlobalEquations += 3*((NumMyElements)%6+2);
      else
	NumGlobalEquations -= (Comm.NumProc()-3)*((NumMyElements-1)%6+2);
    }

  if (verbose) out << "\n*********************************************************" << endl;
  if (verbose) out << "Checking Epetra_BlockMap(NumGlobalElements, NumMyElements, MyGlobalElements,  ElementSizeList, IndexBase, Comm)" << endl;
  if (verbose) out << "*********************************************************" << endl;

  BlockMap = new Epetra_BlockMap(NumGlobalElements, NumMyElements, MyGlobalElements, ElementSizeList,
		      IndexBase, Comm);
  EPETRA_TEST_ERR(VectorTests(*BlockMap, verbose),ierr);

  EPETRA_TEST_ERR(MatrixTests(*BlockMap, *LocalMap, verbose),ierr);

  // Test Copy constructor

  if (verbose) out << "\n*********************************************************" << endl;
  if (verbose) out << "Checking Epetra_BlockMap(*BlockMap)" << endl;
  if (verbose) out << "*********************************************************" << endl;

  Epetra_BlockMap * BlockMap1 = new Epetra_BlockMap(*BlockMap);

  EPETRA_TEST_ERR(VectorTests(*BlockMap, verbose),ierr);

  EPETRA_TEST_ERR(MatrixTests(*BlockMap, *LocalMap, verbose),ierr);

  delete [] ElementSizeList;
  delete [] MyGlobalElements;
  delete BlockMap;
  delete BlockMap1;


  // Test Petra-defined uniform linear distribution constructor

  if (verbose) out << "\n*********************************************************" << endl;
  if (verbose) out << "Checking Epetra_Map(NumGlobalElements, IndexBase, Comm)" << endl;
  if (verbose) out << "*********************************************************" << endl;

  Epetra_Map * Map = new Epetra_Map(NumGlobalElements, IndexBase, Comm);
  EPETRA_TEST_ERR(VectorTests(*Map, verbose),ierr);

  EPETRA_TEST_ERR(MatrixTests(*Map, *LocalMap, verbose),ierr);

  delete Map;

  // Test User-defined linear distribution constructor

  if (verbose) out << "\n*********************************************************" << endl;
  if (verbose) out << "Checking Epetra_Map(NumGlobalElements, NumMyElements, IndexBase, Comm)" << endl;
  if (verbose) out << "*********************************************************" << endl;

  Map = new Epetra_Map(NumGlobalElements, NumMyElements, IndexBase, Comm);

  EPETRA_TEST_ERR(VectorTests(*Map, verbose),ierr);

  EPETRA_TEST_ERR(MatrixTests(*Map, *LocalMap, verbose),ierr);

  delete Map;

  // Test User-defined arbitrary distribution constructor
  // Generate Global Element List.  Do in reverse for fun!

  MyGlobalElements = new int[NumMyElements];
  MaxMyGID = (Comm.MyPID()+1)*NumMyElements-1+IndexBase;
  if (Comm.MyPID()>2) MaxMyGID+=3;
  for (i = 0; i<NumMyElements; i++) MyGlobalElements[i] = MaxMyGID-i;

  if (verbose) out << "\n*********************************************************" << endl;
  if (verbose) out << "Checking Epetra_Map(NumGlobalElements, NumMyElements, MyGlobalElements,  IndexBase, Comm)" << endl;
  if (verbose) out << "*********************************************************" << endl;

  Map = new Epetra_Map(NumGlobalElements, NumMyElements, MyGlobalElements,
		      IndexBase, Comm);
  EPETRA_TEST_ERR(VectorTests(*Map, verbose),ierr);

  EPETRA_TEST_ERR(MatrixTests(*Map, *LocalMap, verbose),ierr);

  // Test Copy constructor

  if (verbose) out << "\n*********************************************************" << endl;
  if (verbose) out << "Checking Epetra_Map(*Map)" << endl;
  if (verbose) out << "*********************************************************" << endl;

  Epetra_Map Map1(*Map);

  EPETRA_TEST_ERR(VectorTests(*Map, verbose),ierr);

  EPETRA_TEST_ERR(MatrixTests(*Map, *LocalMap, verbose),ierr);

  delete [] MyGlobalElements;
  delete Map;

  if (verbose1)
    {
      // Test Vector MFLOPS for 2D Dot Product
      int M = 1;
      int K = 1000000;
      Epetra_Map Map2(-1, K, IndexBase, Comm);
      Epetra_LocalMap Map3(M, IndexBase, Comm);

      Epetra_Vector A(Map2);A.Random();
      Epetra_Vector B(Map2);B.Random();
      Epetra_Vector C(Map3);C.Random();

      // Test Epetra_Vector label
      const char* VecLabel = A.Label();
      const char* VecLabel1 = "Epetra::Vector";
      if (verbose) out << endl << endl <<"This should say " << VecLabel1 << ": " << VecLabel << endl << endl << endl;
      EPETRA_TEST_ERR(strcmp(VecLabel1,VecLabel),ierr);
      if (verbose) out << "Testing Assignment operator" << endl;

      double tmp1 = 1.00001* (double) (MyPID+1);
      double tmp2 = tmp1;
      A[1] = tmp1;
      tmp2 = A[1];
      out << "On PE "<< MyPID << "  A[1] should equal = " << tmp1;
      if (tmp1==tmp2) out << " and it does!" << endl;
      else out << " but it equals " << tmp2;

      Comm.Barrier();
	
      if (verbose) out << endl << endl << "Testing MFLOPs" << endl;
      Epetra_Flops counter;
      C.SetFlopCounter(counter);
      Epetra_Time mytimer(Comm);
      C.Multiply('T', 'N', 0.5, A, B, 0.0);
      double Multiply_time = mytimer.ElapsedTime();
      double Multiply_flops = C.Flops();
      if (verbose) out << "\n\nTotal FLOPs = " << Multiply_flops << endl;
      if (verbose) out << "Total Time  = " << Multiply_time << endl;
      if (verbose) out << "MFLOPs      = " << Multiply_flops/Multiply_time/1000000.0 << endl;

      Comm.Barrier();
	
      // Test Vector ostream operator with Petra-defined uniform linear distribution constructor
      // and a small vector

      Epetra_Map Map4(100, IndexBase, Comm);
      double * Dp = new double[100];
      for (i=0; i<100; i++)
	Dp[i] = i;
      Epetra_Vector D(View, Map4,Dp);
	
      if (verbose) out << "\n\nTesting ostream operator:  Multivector  should be 100-by-2 and print i,j indices"
	   << endl << endl;
      out << D << endl;

      if (verbose) out << "Traceback Mode value = " << D.GetTracebackMode() << endl;
      delete [] Dp;
    }

#ifdef EPETRA_MPI
  MPI_Finalize();
#endif

  return ierr;

}
Exemple #5
0
int main(int argc, char *argv[]) {

  int i, returnierr=0;

#ifdef EPETRA_MPI
  // Initialize MPI
  MPI_Init(&argc,&argv);
  Epetra_MpiComm Comm(MPI_COMM_WORLD);
#else
  Epetra_SerialComm Comm;
#endif

  // Uncomment to debug in parallel int tmp; if (Comm.MyPID()==0) cin >> tmp; Comm.Barrier();

  bool verbose = false;
  bool veryVerbose = false;

  // Check if we should print results to standard out
  if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true;

  // Check if we should print lots of results to standard out
  if (argc>2) if (argv[2][0]=='-' && argv[2][1]=='v') veryVerbose = true;

  if (verbose && Comm.MyPID()==0)
    std::cout << Epetra_Version() << std::endl << std::endl;

  if (!verbose) Comm.SetTracebackMode(0); // This should shut down any error traceback reporting

  if (verbose) std::cout << Comm << std::endl << std::flush;

  bool verbose1 = verbose;
  if (verbose) verbose = (Comm.MyPID()==0);

  bool veryVerbose1 = veryVerbose;
  if (veryVerbose) veryVerbose = (Comm.MyPID()==0);

  int NumMyElements = 100;
  if (veryVerbose1) NumMyElements = 10;
  NumMyElements += Comm.MyPID();
  int MaxNumMyElements = NumMyElements+Comm.NumProc()-1;
  int * ElementSizeList = new int[NumMyElements];
  long long * MyGlobalElements = new long long[NumMyElements];

  for (i = 0; i<NumMyElements; i++) {
    MyGlobalElements[i] = (Comm.MyPID()*MaxNumMyElements+i)*2;
    ElementSizeList[i] = i%6 + 2; // elementsizes go from 2 to 7
  }

  Epetra_BlockMap Map(-1LL, NumMyElements, MyGlobalElements, ElementSizeList,
		      0, Comm);

  delete [] ElementSizeList;
  delete [] MyGlobalElements;

  Epetra_MapColoring C0(Map);

  int * elementColors = new int[NumMyElements];

  int maxcolor = 24;
  int * colorCount = new int[maxcolor];
  int ** colorLIDs = new int*[maxcolor];
  for (i=0; i<maxcolor; i++) colorCount[i] = 0;
  for (i=0; i<maxcolor; i++) colorLIDs[i] = 0;

  int defaultColor = C0.DefaultColor();
  for (i=0; i<Map.NumMyElements(); i++) {
    assert(C0[i]==defaultColor);
    assert(C0(Map.GID64(i))==defaultColor);
    if (i%2==0) C0[i] = i%6+5+i%14; // cycle through 5...23 on even elements
    else C0(Map.GID64(i)) = i%5+1; // cycle through 1...5 on odd elements
    elementColors[i] = C0[i]; // Record color of ith element for use below
    colorCount[C0[i]]++; // Count how many of each color for checking below
  }
  
  if (veryVerbose)
    std::cout << "Original Map Coloring using element-by-element definitions" << std::endl;
  if (veryVerbose1)
    std::cout <<  C0 << std::endl;

  int numColors = 0;
  for (i=0; i<maxcolor; i++) 
    if (colorCount[i]>0) {
      numColors++;
      colorLIDs[i] = new int[colorCount[i]];
    }
  for (i=0; i<maxcolor; i++) colorCount[i] = 0;
  for (i=0; i<Map.NumMyElements(); i++) colorLIDs[C0[i]][colorCount[C0[i]]++] = i;

  

  int newDefaultColor = -1;
  Epetra_MapColoring C1(Map, elementColors, newDefaultColor);
  if (veryVerbose)
    std::cout << "Same Map Coloring using one-time construction" << std::endl;
  if (veryVerbose1)
    std::cout <<  C1 << std::endl;
  assert(C1.DefaultColor()==newDefaultColor);
  for (i=0; i<Map.NumMyElements(); i++) assert(C1[i]==C0[i]);

  Epetra_MapColoring C2(C1);
  if (veryVerbose)
    std::cout << "Same Map Coloring using copy constructor" << std::endl;
  if (veryVerbose1)
    std::cout <<  C1 << std::endl;
  for (i=0; i<Map.NumMyElements(); i++) assert(C2[i]==C0[i]);
  assert(C2.DefaultColor()==newDefaultColor);

  assert(numColors==C2.NumColors());

  for (i=0; i<maxcolor; i++) {
    int curNumElementsWithColor = C2.NumElementsWithColor(i);
    assert(colorCount[i]==curNumElementsWithColor);
    int * curColorLIDList = C2.ColorLIDList(i);
    if (curNumElementsWithColor==0) {
      assert(curColorLIDList==0);
    }
    else
      for (int j=0; j<curNumElementsWithColor; j++) assert(curColorLIDList[j]==colorLIDs[i][j]);
  }
  int curColor = 1;
  Epetra_Map * Map1 = C2.GenerateMap(curColor);
  Epetra_BlockMap * Map2 = C2.GenerateBlockMap(curColor);

  assert(Map1->NumMyElements()==colorCount[curColor]);
  assert(Map2->NumMyElements()==colorCount[curColor]);

  for (i=0; i<Map1->NumMyElements(); i++) {
    assert(Map1->GID64(i)==Map.GID64(colorLIDs[curColor][i]));
    assert(Map2->GID64(i)==Map.GID64(colorLIDs[curColor][i]));
    assert(Map2->ElementSize(i)==Map.ElementSize(colorLIDs[curColor][i]));
  }

  // Now test data redistribution capabilities


  Epetra_Map ContiguousMap(-1LL, Map.NumMyElements(), Map.IndexBase64(), Comm);
  // This vector contains the element sizes for the original map.
  Epetra_IntVector elementSizes(Copy, ContiguousMap, Map.ElementSizeList());
  Epetra_LongLongVector elementIDs(Copy, ContiguousMap, Map.MyGlobalElements64());
  Epetra_IntVector elementColorValues(Copy, ContiguousMap, C2.ElementColors());


  long long NumMyElements0 = 0;
  if (Comm.MyPID()==0) NumMyElements0 = Map.NumGlobalElements64();
  Epetra_Map CMap0(-1LL, NumMyElements0, Map.IndexBase64(), Comm);
  Epetra_Import importer(CMap0, ContiguousMap);
  Epetra_IntVector elementSizes0(CMap0);
  Epetra_LongLongVector elementIDs0(CMap0);
  Epetra_IntVector elementColorValues0(CMap0);
  elementSizes0.Import(elementSizes, importer, Insert);
  elementIDs0.Import(elementIDs, importer, Insert);
  elementColorValues0.Import(elementColorValues, importer, Insert);

  Epetra_BlockMap MapOnPE0(-1LL,NumMyElements0, elementIDs0.Values(), 
			   elementSizes0.Values(), Map.IndexBase64(), Comm);

  Epetra_Import importer1(MapOnPE0, Map);
  Epetra_MapColoring ColoringOnPE0(MapOnPE0);
  ColoringOnPE0.Import(C2, importer1, Insert);

  for (i=0; i<MapOnPE0.NumMyElements(); i++)
    assert(ColoringOnPE0[i]==elementColorValues0[i]);

  if (veryVerbose)
    std::cout << "Same Map Coloring on PE 0 only" << std::endl;
  if (veryVerbose1)
    std::cout <<  ColoringOnPE0 << std::endl;
  Epetra_MapColoring C3(Map);
  C3.Export(ColoringOnPE0, importer1, Insert);
  for (i=0; i<Map.NumMyElements(); i++) assert(C3[i]==C2[i]);
  if (veryVerbose)
    std::cout << "Same Map Coloring after Import/Export exercise" << std::endl;
  if (veryVerbose1)
    std::cout <<  ColoringOnPE0 << std::endl;
   
  
  if (verbose) std::cout << "Checked OK\n\n" << std::endl;

  if (verbose1) {
    if (verbose) std::cout << "Test ostream << operator" << std::endl << std::flush;
    std::cout << C0 << std::endl;
  }
	

  delete [] elementColors;
  for (i=0; i<maxcolor; i++) if (colorLIDs[i]!=0) delete [] colorLIDs[i];
  delete [] colorLIDs;
  delete [] colorCount;

  delete Map1;
  delete Map2;


#ifdef EPETRA_MPI
  MPI_Finalize();
#endif

  return returnierr;
}
Exemple #6
0
int main(int argc, char *argv[]) {
  int ierr = 0;
  int i;
  int forierr = 0;
  long long* Indices;
  bool debug = true;

#ifdef EPETRA_MPI

  // Initialize MPI

  MPI_Init(&argc,&argv);
  int rank; // My process ID

  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  Epetra_MpiComm Comm( MPI_COMM_WORLD );

#else

  int rank = 0;
  Epetra_SerialComm Comm;

#endif

  bool verbose = false;

  // Check if we should print results to standard out
  if(argc > 1) {
    if(argv[1][0]=='-' && argv[1][1]=='v') {
      verbose = true;
    }
  }

  if(verbose && rank == 0)
	cout << Epetra_Version() << endl << endl;

  //char tmp;
  //if (rank==0) cout << "Press any key to continue..."<< endl;
  //if (rank==0) cin >> tmp;
  //Comm.Barrier();

  Comm.SetTracebackMode(0); // This should shut down any error traceback reporting
  int MyPID = Comm.MyPID();
  int NumProc = Comm.NumProc();
  if(verbose) cout << "Processor "<<MyPID<<" of "<< NumProc << " is alive." << endl;

  bool verbose1 = verbose;

  // Redefine verbose to only print on PE 0
  if(verbose && rank != 0)
		verbose = false;

  int NumMyEquations = 5;
  long long NumGlobalEquations = NumMyEquations*NumProc+EPETRA_MIN(NumProc,3);
  if(MyPID < 3)
    NumMyEquations++;

  // Construct a Map that puts approximately the same Number of equations on each processor

  Epetra_Map& Map = *new Epetra_Map(NumGlobalEquations, NumMyEquations, 0LL, Comm);

  // Get update list and number of local equations from newly created Map
  long long* MyGlobalElements = new long long[Map.NumMyElements()];
  Map.MyGlobalElements(MyGlobalElements);

  // Create an integer vector NumNz that is used to build the Petra Matrix.
  // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation on this processor

  int* NumNz = new int[NumMyEquations];

  // We are building a tridiagonal matrix where each row has (-1 2 -1)
  // So we need 2 off-diagonal terms (except for the first and last equation)

  for(i=0; i<NumMyEquations; i++)
    if(MyGlobalElements[i]==0 || MyGlobalElements[i] == NumGlobalEquations-1)
      NumNz[i] = 1;
    else
      NumNz[i] = 2;

  // Create a Epetra_CrsGraph

  Epetra_CrsGraph& A = *new Epetra_CrsGraph(Copy, Map, NumNz);
  EPETRA_TEST_ERR(A.IndicesAreGlobal(),ierr);
  EPETRA_TEST_ERR(A.IndicesAreLocal(),ierr);

  // Add  rows one-at-a-time
  // Need some vectors to help
  // Off diagonal Values will always be -1

  Indices = new long long[2];
  int NumEntries;

  forierr = 0;
  for(i = 0; i < NumMyEquations; i++) {
    if(MyGlobalElements[i] == 0) {
			Indices[0] = 1;
			NumEntries = 1;
		}
    else if(MyGlobalElements[i] == NumGlobalEquations-1) {
			Indices[0] = NumGlobalEquations-2;
			NumEntries = 1;
		}
    else {
			Indices[0] = MyGlobalElements[i]-1;
			Indices[1] = MyGlobalElements[i]+1;
			NumEntries = 2;
		}
		forierr += !(A.InsertGlobalIndices(MyGlobalElements[i], NumEntries, Indices)==0);
		forierr += !(A.InsertGlobalIndices(MyGlobalElements[i], 1, MyGlobalElements+i)>0); // Put in the diagonal entry (should cause realloc)
  }
  EPETRA_TEST_ERR(forierr,ierr);
	//A.PrintGraphData(cout);
  delete[] Indices;

  // Finish up
  EPETRA_TEST_ERR(!(A.IndicesAreGlobal()),ierr);
  EPETRA_TEST_ERR(!(A.FillComplete()==0),ierr);
  EPETRA_TEST_ERR(!(A.IndicesAreLocal()),ierr);
  EPETRA_TEST_ERR(A.StorageOptimized(),ierr);

	A.OptimizeStorage();

  EPETRA_TEST_ERR(!(A.StorageOptimized()),ierr);
  EPETRA_TEST_ERR(A.UpperTriangular(),ierr);
  EPETRA_TEST_ERR(A.LowerTriangular(),ierr);

  if(verbose) cout << "\n*****Testing variable entry constructor\n" << endl;

  int NumMyNonzeros = 3 * NumMyEquations;
  if(A.LRID(0) >= 0)
		NumMyNonzeros--; // If I own first global row, then there is one less nonzero
  if(A.LRID(NumGlobalEquations-1) >= 0)
		NumMyNonzeros--; // If I own last global row, then there is one less nonzero

  EPETRA_TEST_ERR(check(A, NumMyEquations, NumGlobalEquations, NumMyNonzeros, 3*NumGlobalEquations-2,
												MyGlobalElements, verbose),ierr);
  forierr = 0;
  for(i = 0; i < NumMyEquations; i++)
		forierr += !(A.NumGlobalIndices(MyGlobalElements[i])==NumNz[i]+1);
  EPETRA_TEST_ERR(forierr,ierr);
  for(i = 0; i < NumMyEquations; i++)
		forierr += !(A.NumMyIndices(i)==NumNz[i]+1);
  EPETRA_TEST_ERR(forierr,ierr);

  if(verbose) cout << "NumIndices function check OK" << endl;

  delete &A;

  if(debug) Comm.Barrier();

  if(verbose) cout << "\n*****Testing constant entry constructor\n" << endl;

  Epetra_CrsGraph& AA = *new Epetra_CrsGraph(Copy, Map, 5);

  if(debug) Comm.Barrier();

  for(i = 0; i < NumMyEquations; i++)
		AA.InsertGlobalIndices(MyGlobalElements[i], 1, MyGlobalElements+i);

  // Note:  All processors will call the following Insert routines, but only the processor
  //        that owns it will actually do anything

  long long One = 1;
  if(AA.MyGlobalRow(0)) {
    EPETRA_TEST_ERR(!(AA.InsertGlobalIndices(0, 0, &One)==0),ierr);
  }
  else
		EPETRA_TEST_ERR(!(AA.InsertGlobalIndices(0, 1, &One)==-2),ierr);
  EPETRA_TEST_ERR(!(AA.FillComplete()==0),ierr);
  EPETRA_TEST_ERR(AA.StorageOptimized(),ierr);
  EPETRA_TEST_ERR(!(AA.UpperTriangular()),ierr);
  EPETRA_TEST_ERR(!(AA.LowerTriangular()),ierr);

  if(debug) Comm.Barrier();
  EPETRA_TEST_ERR(check(AA, NumMyEquations, NumGlobalEquations, NumMyEquations, NumGlobalEquations,
												MyGlobalElements, verbose),ierr);

  if(debug) Comm.Barrier();

  forierr = 0;
  for(i = 0; i < NumMyEquations; i++)
		forierr += !(AA.NumGlobalIndices(MyGlobalElements[i])==1);
  EPETRA_TEST_ERR(forierr,ierr);

  if(verbose) cout << "NumIndices function check OK" << endl;

  if(debug) Comm.Barrier();

  if(verbose) cout << "\n*****Testing copy constructor\n" << endl;

  Epetra_CrsGraph& B = *new Epetra_CrsGraph(AA);
  delete &AA;

  EPETRA_TEST_ERR(check(B, NumMyEquations, NumGlobalEquations, NumMyEquations, NumGlobalEquations,
												MyGlobalElements, verbose),ierr);

  forierr = 0;
  for(i = 0; i < NumMyEquations; i++)
		forierr += !(B.NumGlobalIndices(MyGlobalElements[i])==1);
  EPETRA_TEST_ERR(forierr,ierr);

  if(verbose) cout << "NumIndices function check OK" << endl;

  if(debug) Comm.Barrier();

  if(verbose) cout << "\n*****Testing post construction modifications\n" << endl;

  EPETRA_TEST_ERR(!(B.InsertGlobalIndices(0, 1, &One)==-2),ierr);
  delete &B;

  // Release all objects
  delete[] MyGlobalElements;
  delete[] NumNz;
  delete &Map;
			

  if (verbose1) {
    // Test ostream << operator (if verbose1)
    // Construct a Map that puts 2 equations on each PE

    int NumMyElements1 = 4;
    int NumMyEquations1 = NumMyElements1;
    long long NumGlobalEquations1 = NumMyEquations1*NumProc;

    Epetra_Map& Map1 = *new Epetra_Map(NumGlobalEquations1, NumMyElements1, 1LL, Comm);

    // Get update list and number of local equations from newly created Map
    long long* MyGlobalElements1 = new long long[Map1.NumMyElements()];
    Map1.MyGlobalElements(MyGlobalElements1);

    // Create an integer vector NumNz that is used to build the Petra Matrix.
    // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation on this processor

    int* NumNz1 = new int[NumMyEquations1];

    // We are building a tridiagonal matrix where each row has (-1 2 -1)
    // So we need 2 off-diagonal terms (except for the first and last equation)

    for(i = 0; i < NumMyEquations1; i++)
      if(MyGlobalElements1[i]==1 || MyGlobalElements1[i] == NumGlobalEquations1)
				NumNz1[i] = 1;
      else
				NumNz1[i] = 2;

    // Create a Epetra_Graph using 1-based arithmetic

    Epetra_CrsGraph& A1 = *new Epetra_CrsGraph(Copy, Map1, NumNz1);

    // Add  rows one-at-a-time
    // Need some vectors to help
    // Off diagonal Values will always be -1


    long long* Indices1 = new long long[2];
    int NumEntries1;

    forierr = 0;
    for(i = 0; i < NumMyEquations1; i++) {
			if(MyGlobalElements1[i]==1) {
				Indices1[0] = 2;
				NumEntries1 = 1;
			}
			else if(MyGlobalElements1[i] == NumGlobalEquations1) {
	    Indices1[0] = NumGlobalEquations1-1;
	    NumEntries1 = 1;
			}
			else {
				Indices1[0] = MyGlobalElements1[i]-1;
				Indices1[1] = MyGlobalElements1[i]+1;
				NumEntries1 = 2;
			}
			forierr += !(A1.InsertGlobalIndices(MyGlobalElements1[i], NumEntries1, Indices1)==0);
			forierr += !(A1.InsertGlobalIndices(MyGlobalElements1[i], 1, MyGlobalElements1+i)>0); // Put in the diagonal entry
    }
    EPETRA_TEST_ERR(forierr,ierr);
		
    // Finish up
    EPETRA_TEST_ERR(!(A1.FillComplete()==0),ierr);

    if(verbose) cout << "Print out tridiagonal matrix, each part on each processor. Index base is one.\n" << endl;
    cout << A1 << endl;

  // Release all objects
  delete[] NumNz1;
  delete[] Indices1;
  delete[] MyGlobalElements1;

  delete &A1;
  delete &Map1;
  }

	// Test copy constructor, op=, and reference-counting
	int tempierr = 0;
	if(verbose) cout << "\n*****Checking cpy ctr, op=, and reference counting." << endl;
	tempierr = checkCopyAndAssignment(Comm, verbose);
	EPETRA_TEST_ERR(tempierr, ierr);
	if(verbose && (tempierr == 0)) cout << "Checked OK." << endl;

	// Test shared-ownership code (not implemented yet)
	tempierr = 0;
	if(verbose) cout << "\n*****Checking shared-ownership tests." << endl;
	tempierr = checkSharedOwnership(Comm, verbose);
	EPETRA_TEST_ERR(tempierr, ierr);
	if(verbose && (tempierr == 0)) cout << "Checked OK." << endl;

			
#ifdef EPETRA_MPI
  MPI_Finalize() ;
#endif
/* end main */
	return(ierr);
}
int main(int argc, char *argv[])
{
  int ierr = 0;

#ifdef EPETRA_MPI

  // Initialize MPI

  MPI_Init(&argc, &argv);
  int rank; // My process ID

  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  Epetra_MpiComm Comm( MPI_COMM_WORLD );

#else

  int rank = 0;
  Epetra_SerialComm Comm;

#endif

  bool verbose = false;

  // Check if we should print results to standard out
  if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true;

  int verbose_int = verbose ? 1 : 0;
  Comm.Broadcast(&verbose_int, 1, 0);
  verbose = verbose_int==1 ? true : false;

  Comm.SetTracebackMode(0); // This should shut down any error traceback reporting
  int MyPID = Comm.MyPID();
  int NumProc = Comm.NumProc();

  if(verbose && MyPID==0)
    std::cout << Epetra_Version() << std::endl << std::endl;

  if (verbose) std::cout << "Processor "<<MyPID<<" of "<< NumProc
		    << " is alive."<< std::endl;

  // unused: bool verbose1 = verbose;

  // Redefine verbose to only print on PE 0
  if(verbose && rank!=0) 
    verbose = false;

  if (verbose) std::cout << "Test the memory management system of the class CrsMatrix (memory leak, invalid free)" << std::endl;

  //
  // Test 1: code initially proposed to illustrate bug #5499
  //
  
  if(Comm.NumProc() == 1) { // this is a sequential test

    if (verbose) std::cout << "* Using Copy, ColMap, Variable number of indices per row and Static profile (cf. bug #5499)." << std::endl;

    // Row Map
    Epetra_Map RowMap(2LL, 0LL, Comm);
    
    // ColMap  
    std::vector<long long> colids(2);
    colids[0]=0;
    colids[1]=1;
    Epetra_Map ColMap(-1LL, 2, &colids[0], 0LL, Comm);

    // NumEntriesPerRow
    std::vector<int> NumEntriesPerRow(2);
    NumEntriesPerRow[0]=2;
    NumEntriesPerRow[1]=2;
    
    // Test
    Epetra_CrsMatrix A(Copy, RowMap, ColMap, &NumEntriesPerRow[0], true);
    // Bug #5499 shows up because InsertGlobalValues() is not called (CrsMatrix::Values_ not allocated but freed)
    A.FillComplete();
    
  }

  //
  // Test 1 Bis: same as Test1, but without ColMap and variable number of indices per row. Does not seems to matter
  //
  
  if(Comm.NumProc() == 1) { // this is a sequential test

    if (verbose) std::cout << "* Using Copy, Fixed number of indices per row and Static profile" << std::endl;

    Epetra_Map RowMap(2LL, 0LL, Comm);

    // Test
    Epetra_CrsMatrix    A(Copy, RowMap, 1, true);
    // Bug #5499 shows up because InsertGlobalValues() is not called (CrsMatrix::Values_ not allocated but freed)
    A.FillComplete();
    
  }

  //
  // Test 2: same as Test 1 Bis but with one call to InsertGlobalValues.
  //

  if(Comm.NumProc() == 1) {

    if (verbose) std::cout << "* Using Copy, Fixed number of indices per row and Static profile + InsertGlobalValues()." << std::endl;

    Epetra_Map RowMap(2LL, 0LL, Comm);

    // Test
    Epetra_CrsMatrix    A(Copy, RowMap, 1, true);
    std::vector<long long>    Indices(1);
    std::vector<double> Values(1);
    Values[0] = 2;
    Indices[0] = 0;

    A.InsertGlobalValues(0, 1, &Values[0], &Indices[0]); // Memory leak if CrsMatrix::Values not freed

    A.FillComplete();

  }

  // 
  // Test 3: check if the patch is not introducing some obvious regression
  //

  if(Comm.NumProc() == 1) {
    
    if (verbose) std::cout << "* Using Copy, Fixed number of indices per row and Dynamic profile" << std::endl;
    
    Epetra_Map RowMap(2LL, 0LL, Comm);

    // Test
    Epetra_CrsMatrix    A(Copy, RowMap, 1, false);
    A.FillComplete();
    
  }

  // 
  // Test 4: idem but with one call to InsertGlobalValues.
  // 

  if(Comm.NumProc() == 1) {
    
    if (verbose) std::cout << "* Using Copy, Fixed number of indices per row and Dynamic profile + InsertGlobalValues()." << std::endl;
    
    Epetra_Map RowMap(2LL, 0LL, Comm);

    // Test
    Epetra_CrsMatrix    A(Copy, RowMap, 1, false);
    std::vector<long long>    Indices(1);
    std::vector<double> Values(1);
    Values[0] = 2;
    Indices[0] = 0;
    
    A.InsertGlobalValues(0, 1, &Values[0], &Indices[0]);
    A.FillComplete();
    
  }

  if(Comm.NumProc() == 1) {
    
    if (verbose) std::cout << "* Using Copy, Static Graph()." << std::endl;
    
    Epetra_Map RowMap(1LL, 0LL, Comm);

    // Test
    Epetra_CrsGraph    G(Copy, RowMap, 1);
    std::vector<long long>    Indices(1);
    Indices[0] = 0;
    G.InsertGlobalIndices(0, 1, &Indices[0]);
    G.FillComplete();
    
    Epetra_CrsMatrix    A(Copy, G);
    std::vector<double> Values(1);
    Values[0] = 2;
    A.ReplaceGlobalValues(0, 1, &Values[0], &Indices[0]);
    A.FillComplete();
    double norminf = A.NormInf();
    if (verbose) std::cout << "** Inf Norm of Matrix = " << norminf << "." << std::endl;
    std::cout << A << std::endl;

    
  }


  if(Comm.NumProc() == 1) {
    
    if (verbose) std::cout << "* Using Copy, Fixed number of indices per row and static profile + InsertGlobalValues() for a single row." << std::endl;
    
    Epetra_Map RowMap(1LL, 0LL, Comm);

    // Test
    Epetra_CrsMatrix    A(Copy, RowMap, 1, true);
    std::vector<long long>    Indices(1);
    std::vector<double> Values(1);
    Values[0] = 2;
    Indices[0] = 0;
    
    A.InsertGlobalValues(0, 1, &Values[0], &Indices[0]);
    A.FillComplete();
    
  }

  /*
    if (bool) {
    if (verbose) std::cout << std::endl << "tests FAILED" << std::endl << std::endl;
    }
    else {*/
  if (verbose) std::cout << std::endl << "tests PASSED" << std::endl << std::endl;
  /*    } */

#ifdef EPETRA_MPI
  MPI_Finalize();
#endif

  return ierr;
}
Exemple #8
0
int main(int argc, char *argv[])
{
  int ierr = 0, i;

#ifdef EPETRA_MPI

  // Initialize MPI

  MPI_Init(&argc,&argv);

  Epetra_MpiComm Comm( MPI_COMM_WORLD );

#else

  Epetra_SerialComm Comm;

#endif

  int MyPID = Comm.MyPID();
  int NumProc = Comm.NumProc();
  bool verbose = (MyPID==0);

  if (verbose)
    cout << Epetra_Version() << endl << endl;

  cout << Comm << endl;

  // Get the number of local equations from the command line
  if (argc!=2)
   {
     if (verbose) 
       cout << "Usage: " << argv[0] << " number_of_equations" << endl;
    std::exit(1);
   }
  long long NumGlobalElements = std::atoi(argv[1]);

  if (NumGlobalElements < NumProc)
      {
     if (verbose)
       cout << "numGlobalBlocks = " << NumGlobalElements 
	    << " cannot be < number of processors = " << NumProc << endl;
     std::exit(1);
      }

  // Construct a Map that puts approximately the same number of 
  // equations on each processor.

  Epetra_Map Map(NumGlobalElements, 0LL, Comm);
  
  // Get update list and number of local equations from newly created Map.

  int NumMyElements = Map.NumMyElements();

  std::vector<long long> MyGlobalElements(NumMyElements);
    Map.MyGlobalElements(&MyGlobalElements[0]);

  // Create an integer vector NumNz that is used to build the Petra Matrix.
  // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation 
  // on this processor

    std::vector<int> NumNz(NumMyElements);

  // We are building a tridiagonal matrix where each row has (-1 2 -1)
  // So we need 2 off-diagonal terms (except for the first and last equation)

  for (i=0; i<NumMyElements; i++)
    if (MyGlobalElements[i]==0 || MyGlobalElements[i] == NumGlobalElements-1)
      NumNz[i] = 2;
    else
      NumNz[i] = 3;

  // Create a Epetra_Matrix

  Epetra_CrsMatrix A(Copy, Map, &NumNz[0]);
  
  // Add  rows one-at-a-time
  // Need some vectors to help
  // Off diagonal Values will always be -1


  std::vector<double> Values(2);
  Values[0] = -1.0; Values[1] = -1.0;
  std::vector<long long> Indices(2);
  double two = 2.0;
  int NumEntries;
  
  for (i=0; i<NumMyElements; i++)
    {
    if (MyGlobalElements[i]==0)
      {
	Indices[0] = 1;
	NumEntries = 1;
      }
    else if (MyGlobalElements[i] == NumGlobalElements-1)
      {
	Indices[0] = NumGlobalElements-2;
	NumEntries = 1;
      }
    else
      {
	Indices[0] = MyGlobalElements[i]-1;
	Indices[1] = MyGlobalElements[i]+1;
	NumEntries = 2;
      }
     ierr = A.InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0]);
     assert(ierr==0);
     // Put in the diagonal entry
     ierr = A.InsertGlobalValues(MyGlobalElements[i], 1, &two, &MyGlobalElements[i]);
     assert(ierr==0);
    }
   
  // Finish up
  ierr = A.FillComplete();
  assert(ierr==0);

  // Create vectors for Power method


  // variable needed for iteration
  double lambda = 0.0;
  int niters = (int) NumGlobalElements*10;
  double tolerance = 1.0e-2;

  // Iterate
  Epetra_Flops counter;
  A.SetFlopCounter(counter);
  Epetra_Time timer(Comm);
  ierr += power_method(A, lambda, niters, tolerance, verbose);
  double elapsed_time = timer.ElapsedTime();
  double total_flops =counter.Flops();
  double MFLOPs = total_flops/elapsed_time/1000000.0;

  if (verbose) 
    cout << "\n\nTotal MFLOPs for first solve = " << MFLOPs << endl<< endl;

  // Increase diagonal dominance
  if (verbose) 
    cout << "\nIncreasing magnitude of first diagonal term, solving again\n\n"
		    << endl;

  if (A.MyGlobalRow(0)) {
    int numvals = A.NumGlobalEntries(0);
    std::vector<double> Rowvals(numvals);
    std::vector<long long> Rowinds(numvals);
    A.ExtractGlobalRowCopy(0, numvals, numvals, &Rowvals[0], &Rowinds[0]); // Get A[0,0]
    for (i=0; i<numvals; i++) if (Rowinds[i] == 0) Rowvals[i] *= 10.0;

    A.ReplaceGlobalValues(0, numvals, &Rowvals[0], &Rowinds[0]);
  }
 
  // Iterate (again)
  lambda = 0.0;
  timer.ResetStartTime();
  counter.ResetFlops();
  ierr += power_method(A, lambda, niters, tolerance, verbose);
  elapsed_time = timer.ElapsedTime();
  total_flops = counter.Flops();
  MFLOPs = total_flops/elapsed_time/1000000.0;

  if (verbose) 
    cout << "\n\nTotal MFLOPs for second solve = " << MFLOPs << endl<< endl;


  // Release all objects
#ifdef EPETRA_MPI
  MPI_Finalize() ;
#endif

/* end main
*/
return ierr ;
}
Exemple #9
0
int main(int argc, char *argv[]) {

  int ierr = 0;

#ifdef EPETRA_MPI
  MPI_Init(&argc,&argv);
  Epetra_MpiComm Comm(MPI_COMM_WORLD);
#else
  Epetra_SerialComm Comm;
#endif

//  Comm.SetTracebackMode(0); // This should shut down any error tracing
  bool verbose = false;

  // Check if we should print results to standard out
  if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true;

#ifdef EPETRA_MPI
  int localverbose = verbose ? 1 : 0;
  int globalverbose=0;
  MPI_Allreduce(&localverbose, &globalverbose, 1, MPI_INT, MPI_SUM,
		MPI_COMM_WORLD);
  verbose = (globalverbose>0);
#endif

  int MyPID = Comm.MyPID();
  int NumProc = Comm.NumProc(); 

  if (verbose && MyPID==0)
    cout << Epetra_Version() << endl << endl;

  if (verbose) cout << Comm <<endl;

  int NumMyElements = 4;
  long long NumGlobalElements = NumMyElements*NumProc;
  int IndexBase = 0;
  
  Epetra_Map Map(NumGlobalElements, NumMyElements, IndexBase, Comm);

  EPETRA_TEST_ERR( Drumm1(Map, verbose),ierr);

  EPETRA_TEST_ERR( Drumm2(Map, verbose),ierr);


  bool preconstruct_graph = false;

  EPETRA_TEST_ERR( four_quads(Comm, preconstruct_graph, verbose), ierr);

  preconstruct_graph = true;

  EPETRA_TEST_ERR( four_quads(Comm, preconstruct_graph, verbose), ierr);

  EPETRA_TEST_ERR( rectangular(Comm, verbose), ierr);

  EPETRA_TEST_ERR( Young1(Comm, verbose), ierr);

#ifdef EPETRA_MPI
  MPI_Finalize();
#endif

  return ierr;
}
Exemple #10
0
int main(int argc, char *argv[])
{
  int total_err=0;

  // Initialize MPI

  MPI_Init(&argc,&argv);
  int rank; // My process ID

  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  Epetra_MpiComm Comm( MPI_COMM_WORLD );

  bool verbose = false;

  // Check if we should print results to standard out
  if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true;

  int verbose_int = verbose ? 1 : 0;
  Comm.Broadcast(&verbose_int, 1, 0);
  verbose = verbose_int==1 ? true : false;

  Comm.SetTracebackMode(0); // This should shut down any error traceback reporting
  int MyPID = Comm.MyPID();
  int NumProc = Comm.NumProc();

  if(verbose && MyPID==0)
    cout << Epetra_Version() << std::endl << std::endl;

  if (verbose) cout << "Processor "<<MyPID<<" of "<< NumProc
		    << " is alive."<<endl;

  // Redefine verbose to only print on PE 0
  if(verbose && rank!=0) verbose = false;

  // Matrix & Map pointers
  Epetra_CrsMatrix *A, *B, *C;
  Epetra_Map* Map1;
  Epetra_Import* Import1;
  Epetra_Export* Export1;
  double diff_tol=1e-12;

#define ENABLE_TEST_1
#define ENABLE_TEST_2
#define ENABLE_TEST_3
#define ENABLE_TEST_4
#define ENABLE_TEST_5
#define ENABLE_TEST_6

  /////////////////////////////////////////////////////////
  // Test #1: Tridiagonal Matrix; Migrate to Proc 0
  /////////////////////////////////////////////////////////
#ifdef ENABLE_TEST_1
  {
    double diff;
    build_test_matrix(Comm,1,A);
    int num_global = A->RowMap().NumGlobalElements();

    // New map with all on Proc1
    if(MyPID==0) Map1=new Epetra_Map(num_global,num_global,0,Comm);
    else         Map1=new Epetra_Map(num_global,0,0,Comm);

    // Execute fused import constructor
    Import1 = new Epetra_Import(*Map1,A->RowMap());
    B=new Epetra_CrsMatrix(*A,*Import1,0,&A->RangeMap());

    diff=test_with_matvec(*A,*B);
    if(diff > diff_tol){
      if(MyPID==0) cout<<"FusedImport: Test #1 FAILED with norm diff = "<<diff<<"."<<endl;
      total_err--;
    }

    // Execute fused export constructor
    delete B;
    Export1 = new Epetra_Export(A->RowMap(),*Map1);
    B=new Epetra_CrsMatrix(*A,*Export1,0,&A->RangeMap());

    diff=test_with_matvec(*A,*B);
    if(diff > diff_tol){
      if(MyPID==0) cout<<"FusedExport: Test #1 FAILED with norm diff = "<<diff<<"."<<endl;
      total_err--;
    }

    delete A; delete B; delete Map1; delete Import1; delete Export1;
  }
#endif


  /////////////////////////////////////////////////////////
  // Test #2: Tridiagonal Matrix; Locally Reversed Map
  /////////////////////////////////////////////////////////
#ifdef ENABLE_TEST_2
  {
    double diff;
    build_test_matrix(Comm,1,A);
    int num_local = A->RowMap().NumMyElements();

    std::vector<int> MyGIDS(num_local);
    for(int i=0; i<num_local; i++)
      MyGIDS[i] = A->RowMap().GID(num_local-i-1);

    // New map with all on Proc1
    Map1=new Epetra_Map(-1,num_local,&MyGIDS[0],0,Comm);

    // Execute fused import constructor
    Import1 = new Epetra_Import(*Map1,A->RowMap());
    B=new Epetra_CrsMatrix(*A,*Import1,0,&A->RangeMap());

    diff=test_with_matvec(*A,*B);
    if(diff > diff_tol){
      if(MyPID==0) cout<<"FusedImport: Test #2 FAILED with norm diff = "<<diff<<"."<<endl;
      total_err--;
    }

    // Execute fused export constructor
    delete B;
    Export1 = new Epetra_Export(A->RowMap(),*Map1);
    B=new Epetra_CrsMatrix(*A,*Export1,0,&A->RangeMap());

    diff=test_with_matvec(*A,*B);
    if(diff > diff_tol){
      if(MyPID==0) cout<<"FusedExport: Test #2 FAILED with norm diff = "<<diff<<"."<<endl;
      total_err--;
    }

    delete A; delete B; delete Map1; delete Import1; delete Export1;
  }
#endif

  /////////////////////////////////////////////////////////
  // Test #3: Tridiagonal Matrix; Globally Reversed Map
  /////////////////////////////////////////////////////////
#ifdef ENABLE_TEST_3
  {
    double diff;
    build_test_matrix(Comm,1,A);
    int num_local  = A->RowMap().NumMyElements();
    int num_global = A->RowMap().NumGlobalElements();
    int num_scansum = 0;

    Comm.ScanSum(&num_local,&num_scansum,1);

    // New Map
    std::vector<int> MyGIDS(num_local);
    for(int i=0; i<num_local; i++)
      MyGIDS[i] = num_global - num_scansum + num_local - i - 1;
    Map1=new Epetra_Map(-1,num_local,&MyGIDS[0],0,Comm);


    // Execute fused import constructor
    Import1 = new Epetra_Import(*Map1,A->RowMap());
    B=new Epetra_CrsMatrix(*A,*Import1,0,&A->RangeMap());

    diff=test_with_matvec(*A,*B);
    if(diff > diff_tol){
      if(MyPID==0) cout<<"FusedImport: Test #3 FAILED with norm diff = "<<diff<<"."<<endl;
      total_err--;
    }

    // Execute fused export constructor
    delete B;
    Export1 = new Epetra_Export(A->RowMap(),*Map1);
    B=new Epetra_CrsMatrix(*A,*Export1,0,&A->RangeMap());

    diff=test_with_matvec(*A,*B);
    if(diff > diff_tol){
      if(MyPID==0) cout<<"FusedExport: Test #3 FAILED with norm diff = "<<diff<<"."<<endl;
      total_err--;
    }

    delete A; delete B; delete Map1; delete Import1; delete Export1;
  }
#endif


  /////////////////////////////////////////////////////////
  // Test #4: Tridiagonal Matrix; MMM style halo import
  /////////////////////////////////////////////////////////
#ifdef ENABLE_TEST_4
  {
    double diff;
    build_test_matrix(Comm,1,A);

    // Assume we always own the diagonal
    int num_local = A->NumMyCols()-A->NumMyRows();
    std::vector<int> MyGIDS(num_local);

    for(int i=0, idx=0; i<A->NumMyCols(); i++)
      if(A->LRID(A->GCID(i)) == -1){
	MyGIDS[idx] = A->GCID(i);
	idx++;
      }

    // New map
    const int * MyGIDS_ptr = MyGIDS.size() ? &MyGIDS[0] : 0;
    Map1=new Epetra_Map(-1,num_local,MyGIDS_ptr,0,Comm);


    // Execute fused import constructor
    Import1 = new Epetra_Import(*Map1,A->RowMap());
    B=new Epetra_CrsMatrix(*A,*Import1,0,&A->RangeMap());

    // Build unfused matrix to compare
    C=new Epetra_CrsMatrix(Copy,*Map1,0);
    build_matrix_unfused(*A,*Import1,C);

    diff=test_with_matvec(*B,*C);
    if(diff > diff_tol){
      if(MyPID==0) cout<<"FusedImport: Test #4 FAILED with norm diff = "<<diff<<"."<<endl;
      total_err--;
    }

    // Execute fused export constructor
    delete B;
    Export1 = new Epetra_Export(A->RowMap(),*Map1);
    B=new Epetra_CrsMatrix(*A,*Export1,0,&A->RangeMap());

    diff=test_with_matvec(*B,*C);
    if(diff > diff_tol){
      if(MyPID==0) cout<<"FusedExport: Test #4 FAILED with norm diff = "<<diff<<"."<<endl;
      total_err--;
    }

    delete A; delete B; delete C; delete Map1; delete Import1; delete Export1;
  }
#endif


  /////////////////////////////////////////////////////////
  // Test 5: Tridiagonal Matrix; Migrate to Proc 0, Replace Maps
  /////////////////////////////////////////////////////////
#ifdef ENABLE_TEST_5
  {
    double diff;
    build_test_matrix(Comm,1,A);

    // New map with all on Procs 0 and 2
    build_test_map(A->RowMap(),Map1);

    // Execute fused import constructor
    Import1 = new Epetra_Import(*Map1,A->RowMap());
    B=new Epetra_CrsMatrix(*A,*Import1,Map1,Map1);

    diff=test_with_matvec(*A,*B);
    if(diff > diff_tol){
      if(MyPID==0) cout<<"FusedImport: Test #5 FAILED with norm diff = "<<diff<<"."<<endl;
      total_err--;
    }

    // Execute fused export constructor
    delete B;
    Export1 = new Epetra_Export(A->RowMap(),*Map1);
    B=new Epetra_CrsMatrix(*A,*Export1,Map1,Map1);

    diff=test_with_matvec(*A,*B);
    if(diff > diff_tol){
      if(MyPID==0) cout<<"FusedExport: Test #5 FAILED with norm diff = "<<diff<<"."<<endl;
      total_err--;
    }

    delete A; delete B; delete Map1; delete Import1; delete Export1;
  }
#endif


  /////////////////////////////////////////////////////////
  // Test 6: Tridiagonal Matrix; Migrate to Proc 0, Replace Comm
  /////////////////////////////////////////////////////////
#ifdef ENABLE_TEST_6
  {
    double diff;
    build_test_matrix(Comm,1,A);

    // New map with all on Procs 0 and 2
    build_test_map(A->RowMap(),Map1);

    // Execute fused import constructor
    Import1 = new Epetra_Import(*Map1,A->RowMap());
    B=new Epetra_CrsMatrix(*A,*Import1,Map1,Map1,true);

    diff=test_with_matvec_reduced_maps(*A,*B,*Map1);
    if(diff > diff_tol){
      if(MyPID==0) cout<<"FusedImport: Test #6 FAILED with norm diff = "<<diff<<"."<<endl;
      total_err--;
    }

    // Execute fused export constructor
    delete B;
    Export1 = new Epetra_Export(A->RowMap(),*Map1);
    B=new Epetra_CrsMatrix(*A,*Export1,Map1,Map1,true);

    diff=test_with_matvec_reduced_maps(*A,*B,*Map1);
    if(diff > diff_tol){
      if(MyPID==0) cout<<"FusedExport: Test #6 FAILED with norm diff = "<<diff<<"."<<endl;
      total_err--;
    }

    delete A; delete B; delete Map1; delete Import1; delete Export1;
  }
#endif


  // Final output for OK
  if(MyPID==0 && total_err==0)
    cout<<"FusedImportExport: All tests PASSED."<<endl;

  // Cleanup
  MPI_Finalize();

  return total_err ;
}
Exemple #11
0
int main(int argc, char *argv[]) {

  int ierr = 0;

#ifdef EPETRA_MPI

  // Initialize MPI

  MPI_Init(&argc,&argv);

  Epetra_MpiComm Comm(MPI_COMM_WORLD);

#else

  Epetra_SerialComm Comm;

#endif

  bool verbose = false;

  // Check if we should print results to standard out
  if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true;

  int verbose_int = verbose ? 1 : 0;
  Comm.Broadcast(&verbose_int, 1, 0);
  verbose = verbose_int==1 ? true : false;

  int MyPID = Comm.MyPID();
  int NumProc = Comm.NumProc();

  if (verbose && MyPID==0)
    cout << Epetra_Version() << endl << endl;

  if (verbose) cout << Comm <<endl;

  int NumVectors = 1;
  int NumMyElements = 4;
  int NumGlobalElements = NumMyElements*NumProc;
  int IndexBase = 0;

  Epetra_Map Map(NumGlobalElements, NumMyElements, IndexBase, Comm);

  EPETRA_TEST_ERR( quad1(Map, verbose), ierr);

  EPETRA_TEST_ERR( quad2(Map, verbose), ierr);

  EPETRA_TEST_ERR( MultiVectorTests(Map, NumVectors, verbose), ierr);

  bool preconstruct_graph = false;

  EPETRA_TEST_ERR( four_quads(Comm, preconstruct_graph, verbose), ierr);

  preconstruct_graph = true;

  EPETRA_TEST_ERR( four_quads(Comm, preconstruct_graph, verbose), ierr);

#ifdef EPETRA_MPI
  MPI_Finalize();
#endif

  return ierr;
}
Exemple #12
0
int main(int argc, char *argv[])
{
  int ierr = 0, forierr = 0;
  bool debug = false;

#ifdef EPETRA_MPI

  // Initialize MPI

  MPI_Init(&argc,&argv);
  int rank; // My process ID

  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  Epetra_MpiComm Comm( MPI_COMM_WORLD );

#else

  int rank = 0;
  Epetra_SerialComm Comm;

#endif

  bool verbose = false;

  // Check if we should print results to standard out
  if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true;

  int verbose_int = verbose ? 1 : 0;
  Comm.Broadcast(&verbose_int, 1, 0);
  verbose = verbose_int==1 ? true : false;


  //  char tmp;
  //  if (rank==0) cout << "Press any key to continue..."<< std::endl;
  //  if (rank==0) cin >> tmp;
  //  Comm.Barrier();

  Comm.SetTracebackMode(0); // This should shut down any error traceback reporting
  int MyPID = Comm.MyPID();
  int NumProc = Comm.NumProc();

  if(verbose && MyPID==0)
    cout << Epetra_Version() << std::endl << std::endl;

  if (verbose) cout << "Processor "<<MyPID<<" of "<< NumProc
		    << " is alive."<<endl;

  bool verbose1 = verbose;

  // Redefine verbose to only print on PE 0
  if(verbose && rank!=0) 
		verbose = false;

  int NumMyEquations = 10000;
  int NumGlobalEquations = (NumMyEquations * NumProc) + EPETRA_MIN(NumProc,3);
  if(MyPID < 3) 
    NumMyEquations++;

  // Construct a Map that puts approximately the same Number of equations on each processor

  Epetra_Map Map(NumGlobalEquations, NumMyEquations, 0, Comm);
  
  // Get update list and number of local equations from newly created Map
  int* MyGlobalElements = new int[Map.NumMyElements()];
  Map.MyGlobalElements(MyGlobalElements);

  // Create an integer vector NumNz that is used to build the Petra Matrix.
  // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation on this processor

  int* NumNz = new int[NumMyEquations];

  // We are building a tridiagonal matrix where each row has (-1 2 -1)
  // So we need 2 off-diagonal terms (except for the first and last equation)

  for (int i = 0; i < NumMyEquations; i++)
    if((MyGlobalElements[i] == 0) || (MyGlobalElements[i] == NumGlobalEquations - 1))
      NumNz[i] = 1;
    else
      NumNz[i] = 2;

  // Create a Epetra_Matrix

  Epetra_CrsMatrix A(Copy, Map, NumNz);
  EPETRA_TEST_ERR(A.IndicesAreGlobal(),ierr);
  EPETRA_TEST_ERR(A.IndicesAreLocal(),ierr);
  
  // Add  rows one-at-a-time
  // Need some vectors to help
  // Off diagonal Values will always be -1


  double* Values = new double[2];
  Values[0] = -1.0; 
	Values[1] = -1.0;
  int* Indices = new int[2];
  double two = 2.0;
  int NumEntries;

  forierr = 0;
  for (int i = 0; i < NumMyEquations; i++) {
    if(MyGlobalElements[i] == 0) {
			Indices[0] = 1;
			NumEntries = 1;
		}
    else if (MyGlobalElements[i] == NumGlobalEquations-1) {
			Indices[0] = NumGlobalEquations-2;
			NumEntries = 1;
		}
    else {
			Indices[0] = MyGlobalElements[i]-1;
			Indices[1] = MyGlobalElements[i]+1;
			NumEntries = 2;
		}
		forierr += !(A.InsertGlobalValues(MyGlobalElements[i], NumEntries, Values, Indices)==0);
		forierr += !(A.InsertGlobalValues(MyGlobalElements[i], 1, &two, MyGlobalElements+i)>0); // Put in the diagonal entry
  }
  EPETRA_TEST_ERR(forierr,ierr);

  int * indexOffsetTmp;
  int * indicesTmp;
  double * valuesTmp;
  // Finish up
  EPETRA_TEST_ERR(!(A.IndicesAreGlobal()),ierr);
  EPETRA_TEST_ERR(!(A.ExtractCrsDataPointers(indexOffsetTmp, indicesTmp, valuesTmp)==-1),ierr);  // Should fail
  EPETRA_TEST_ERR(!(A.FillComplete(false)==0),ierr);
  EPETRA_TEST_ERR(!(A.ExtractCrsDataPointers(indexOffsetTmp, indicesTmp, valuesTmp)==-1),ierr);  // Should fail
  EPETRA_TEST_ERR(!(A.IndicesAreLocal()),ierr);
  EPETRA_TEST_ERR(A.StorageOptimized(),ierr);
  A.OptimizeStorage();
  EPETRA_TEST_ERR(!(A.StorageOptimized()),ierr);
  EPETRA_TEST_ERR(!(A.ExtractCrsDataPointers(indexOffsetTmp, indicesTmp, valuesTmp)==0),ierr);  // Should succeed
  const Epetra_CrsGraph & GofA = A.Graph();
  EPETRA_TEST_ERR((indicesTmp!=GofA[0] || valuesTmp!=A[0]),ierr); // Extra check to see if operator[] is consistent
  EPETRA_TEST_ERR(A.UpperTriangular(),ierr);
  EPETRA_TEST_ERR(A.LowerTriangular(),ierr);
	
  int NumMyNonzeros = 3 * NumMyEquations;
  if(A.LRID(0) >= 0) 
		NumMyNonzeros--; // If I own first global row, then there is one less nonzero
  if(A.LRID(NumGlobalEquations-1) >= 0) 
		NumMyNonzeros--; // If I own last global row, then there is one less nonzero
  EPETRA_TEST_ERR(check(A, NumMyEquations, NumGlobalEquations, NumMyNonzeros, 3*NumGlobalEquations-2, 
	       MyGlobalElements, verbose),ierr);
  forierr = 0;
  for (int i = 0; i < NumMyEquations; i++) 
		forierr += !(A.NumGlobalEntries(MyGlobalElements[i])==NumNz[i]+1);
  EPETRA_TEST_ERR(forierr,ierr);
  forierr = 0;
  for (int i = 0; i < NumMyEquations; i++) 
		forierr += !(A.NumMyEntries(i)==NumNz[i]+1);
  EPETRA_TEST_ERR(forierr,ierr);

  if (verbose) cout << "\n\nNumEntries function check OK" << std::endl<< std::endl;

  EPETRA_TEST_ERR(check_graph_sharing(Comm),ierr);

  // Create vectors for Power method

  Epetra_Vector q(Map);
  Epetra_Vector z(Map);
  Epetra_Vector resid(Map);

  // variable needed for iteration
  double lambda = 0.0;
  // int niters = 10000;
  int niters = 200;
  double tolerance = 1.0e-1;

  /////////////////////////////////////////////////////////////////////////////////////////////////
	
  // Iterate

  Epetra_Flops flopcounter;
  A.SetFlopCounter(flopcounter);
  q.SetFlopCounter(A);
  z.SetFlopCounter(A);
  resid.SetFlopCounter(A);
	

  Epetra_Time timer(Comm);
  EPETRA_TEST_ERR(power_method(false, A, q, z, resid, &lambda, niters, tolerance, verbose),ierr);
  double elapsed_time = timer.ElapsedTime();
  double total_flops = A.Flops() + q.Flops() + z.Flops() + resid.Flops();
  double MFLOPs = total_flops/elapsed_time/1000000.0;

  if (verbose) cout << "\n\nTotal MFLOPs for first solve = " << MFLOPs << std::endl<< std::endl;

  /////////////////////////////////////////////////////////////////////////////////////////////////
	
  // Solve transpose problem

  if (verbose) cout << "\n\nUsing transpose of matrix and solving again (should give same result).\n\n"
		    << std::endl;
  // Iterate
  lambda = 0.0;
  flopcounter.ResetFlops();
  timer.ResetStartTime();
  EPETRA_TEST_ERR(power_method(true, A, q, z, resid, &lambda, niters, tolerance, verbose),ierr);
  elapsed_time = timer.ElapsedTime();
  total_flops = A.Flops() + q.Flops() + z.Flops() + resid.Flops();
  MFLOPs = total_flops/elapsed_time/1000000.0;

  if (verbose) cout << "\n\nTotal MFLOPs for transpose solve = " << MFLOPs << std::endl<< endl;

  /////////////////////////////////////////////////////////////////////////////////////////////////

  // Increase diagonal dominance

  if (verbose) cout << "\n\nIncreasing the magnitude of first diagonal term and solving again\n\n"
		    << endl;

  
  if (A.MyGlobalRow(0)) {
    int numvals = A.NumGlobalEntries(0);
    double * Rowvals = new double [numvals];
    int    * Rowinds = new int    [numvals];
    A.ExtractGlobalRowCopy(0, numvals, numvals, Rowvals, Rowinds); // Get A[0,0]

    for (int i=0; i<numvals; i++) if (Rowinds[i] == 0) Rowvals[i] *= 10.0;
    
    A.ReplaceGlobalValues(0, numvals, Rowvals, Rowinds);
    delete [] Rowvals;
    delete [] Rowinds;
  }
  // Iterate (again)
  lambda = 0.0;
  flopcounter.ResetFlops();
  timer.ResetStartTime();
  EPETRA_TEST_ERR(power_method(false, A, q, z, resid, &lambda, niters, tolerance, verbose),ierr);
  elapsed_time = timer.ElapsedTime();
  total_flops = A.Flops() + q.Flops() + z.Flops() + resid.Flops();
  MFLOPs = total_flops/elapsed_time/1000000.0;

  if (verbose) cout << "\n\nTotal MFLOPs for second solve = " << MFLOPs << endl<< endl;

  /////////////////////////////////////////////////////////////////////////////////////////////////

  // Solve transpose problem

  if (verbose) cout << "\n\nUsing transpose of matrix and solving again (should give same result).\n\n"
		    << endl;

  // Iterate (again)
  lambda = 0.0;
  flopcounter.ResetFlops();
  timer.ResetStartTime();
  EPETRA_TEST_ERR(power_method(true, A, q, z, resid, &lambda, niters, tolerance, verbose),ierr);
  elapsed_time = timer.ElapsedTime();
  total_flops = A.Flops() + q.Flops() + z.Flops() + resid.Flops();
  MFLOPs = total_flops/elapsed_time/1000000.0;


  if (verbose) cout << "\n\nTotal MFLOPs for tranpose of second solve = " << MFLOPs << endl<< endl;

  if (verbose) cout << "\n\n*****Testing constant entry constructor" << endl<< endl;

  Epetra_CrsMatrix AA(Copy, Map, 5);
  
  if (debug) Comm.Barrier();

  double dble_one = 1.0;
  for (int i=0; i< NumMyEquations; i++) AA.InsertGlobalValues(MyGlobalElements[i], 1, &dble_one, MyGlobalElements+i);

  // Note:  All processors will call the following Insert routines, but only the processor
  //        that owns it will actually do anything

  int One = 1;
  if (AA.MyGlobalRow(0)) {
    EPETRA_TEST_ERR(!(AA.InsertGlobalValues(0, 0, &dble_one, &One)==0),ierr);
  }
  else EPETRA_TEST_ERR(!(AA.InsertGlobalValues(0, 1, &dble_one, &One)==-1),ierr);
  EPETRA_TEST_ERR(!(AA.FillComplete(false)==0),ierr);
  EPETRA_TEST_ERR(AA.StorageOptimized(),ierr);
  EPETRA_TEST_ERR(!(AA.UpperTriangular()),ierr);
  EPETRA_TEST_ERR(!(AA.LowerTriangular()),ierr);
  
  if (debug) Comm.Barrier();
  EPETRA_TEST_ERR(check(AA, NumMyEquations, NumGlobalEquations, NumMyEquations, NumGlobalEquations, 
	       MyGlobalElements, verbose),ierr);

  if (debug) Comm.Barrier();

  forierr = 0;
  for (int i=0; i<NumMyEquations; i++) forierr += !(AA.NumGlobalEntries(MyGlobalElements[i])==1);
  EPETRA_TEST_ERR(forierr,ierr);

  if (verbose) cout << "\n\nNumEntries function check OK" << endl<< endl;

  if (debug) Comm.Barrier();

  if (verbose) cout << "\n\n*****Testing copy constructor" << endl<< endl;

  Epetra_CrsMatrix B(AA);
  EPETRA_TEST_ERR(check(B, NumMyEquations, NumGlobalEquations, NumMyEquations, NumGlobalEquations, 
	       MyGlobalElements, verbose),ierr);

  forierr = 0;
  for (int i=0; i<NumMyEquations; i++) forierr += !(B.NumGlobalEntries(MyGlobalElements[i])==1);
  EPETRA_TEST_ERR(forierr,ierr);

  if (verbose) cout << "\n\nNumEntries function check OK" << endl<< endl;

  if (debug) Comm.Barrier();

  if (verbose) cout << "\n\n*****Testing local view constructor" << endl<< endl;

  Epetra_CrsMatrix BV(View, AA.RowMap(), AA.ColMap(), 0);

  forierr = 0;
  int* Inds;
  double* Vals;
  for (int i = 0; i < NumMyEquations; i++) {
    forierr += !(AA.ExtractMyRowView(i, NumEntries, Vals, Inds)==0);
    forierr += !(BV.InsertMyValues(i, NumEntries, Vals, Inds)==0);
  }
  BV.FillComplete(false);
  EPETRA_TEST_ERR(check(BV, NumMyEquations, NumGlobalEquations, NumMyEquations, NumGlobalEquations, 
												MyGlobalElements, verbose),ierr);

  forierr = 0;
  for (int i=0; i<NumMyEquations; i++) forierr += !(BV.NumGlobalEntries(MyGlobalElements[i])==1);
  EPETRA_TEST_ERR(forierr,ierr);

  if (verbose) cout << "\n\nNumEntries function check OK" << endl<< endl;

  if (debug) Comm.Barrier();
  if (verbose) cout << "\n\n*****Testing post construction modifications" << endl<< endl;

  EPETRA_TEST_ERR(!(B.InsertGlobalValues(0, 1, &dble_one, &One)==-2),ierr);


  // Release all objects
  delete [] NumNz;
  delete [] Values;
  delete [] Indices;
  delete [] MyGlobalElements;
			

  if (verbose1) {
    // Test ostream << operator (if verbose1)
    // Construct a Map that puts 2 equations on each PE
    
    int NumMyElements1 = 2;
    int NumMyEquations1 = NumMyElements1;
    int NumGlobalEquations1 = NumMyEquations1*NumProc;

    Epetra_Map Map1(-1, NumMyElements1, 0, Comm);
    
    // Get update list and number of local equations from newly created Map
    int * MyGlobalElements1 = new int[Map1.NumMyElements()];
    Map1.MyGlobalElements(MyGlobalElements1);
    
    // Create an integer vector NumNz that is used to build the Petra Matrix.
    // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation on this processor
    
    int * NumNz1 = new int[NumMyEquations1];
    
    // We are building a tridiagonal matrix where each row has (-1 2 -1)
    // So we need 2 off-diagonal terms (except for the first and last equation)
    
    for (int i=0; i<NumMyEquations1; i++)
      if (MyGlobalElements1[i]==0 || MyGlobalElements1[i] == NumGlobalEquations1-1)
	NumNz1[i] = 1;
      else
	NumNz1[i] = 2;
    
    // Create a Epetra_Matrix
    
    Epetra_CrsMatrix A1(Copy, Map1, NumNz1);
    
    // Add  rows one-at-a-time
    // Need some vectors to help
    // Off diagonal Values will always be -1
    
    
    double *Values1 = new double[2];
    Values1[0] = -1.0; Values1[1] = -1.0;
    int *Indices1 = new int[2];
    double two1 = 2.0;
    int NumEntries1;

    forierr = 0;
    for (int i=0; i<NumMyEquations1; i++)
      {
	if (MyGlobalElements1[i]==0)
	  {
	    Indices1[0] = 1;
	    NumEntries1 = 1;
	  }
	else if (MyGlobalElements1[i] == NumGlobalEquations1-1)
	  {
	    Indices1[0] = NumGlobalEquations1-2;
	    NumEntries1 = 1;
	  }
	else
	  {
	    Indices1[0] = MyGlobalElements1[i]-1;
	    Indices1[1] = MyGlobalElements1[i]+1;
	    NumEntries1 = 2;
	  }
	forierr += !(A1.InsertGlobalValues(MyGlobalElements1[i], NumEntries1, Values1, Indices1)==0);
	forierr += !(A1.InsertGlobalValues(MyGlobalElements1[i], 1, &two1, MyGlobalElements1+i)>0); // Put in the diagonal entry
      }
    EPETRA_TEST_ERR(forierr,ierr);
    delete [] Indices1;
    delete [] Values1;
    
    // Finish up
    EPETRA_TEST_ERR(!(A1.FillComplete(false)==0),ierr);
    
    // Test diagonal extraction function

    Epetra_Vector checkDiag(Map1);
    EPETRA_TEST_ERR(!(A1.ExtractDiagonalCopy(checkDiag)==0),ierr);

    forierr = 0;
    for (int i=0; i<NumMyEquations1; i++) forierr += !(checkDiag[i]==two1);
    EPETRA_TEST_ERR(forierr,ierr);

    // Test diagonal replacement method

    forierr = 0;
    for (int i=0; i<NumMyEquations1; i++) checkDiag[i]=two1*two1;
    EPETRA_TEST_ERR(forierr,ierr);

    EPETRA_TEST_ERR(!(A1.ReplaceDiagonalValues(checkDiag)==0),ierr);

    Epetra_Vector checkDiag1(Map1);
    EPETRA_TEST_ERR(!(A1.ExtractDiagonalCopy(checkDiag1)==0),ierr);

    forierr = 0;
    for (int i=0; i<NumMyEquations1; i++) forierr += !(checkDiag[i]==checkDiag1[i]);
    EPETRA_TEST_ERR(forierr,ierr);

    if (verbose) cout << "\n\nDiagonal extraction and replacement OK.\n\n" << endl;

    double orignorm = A1.NormOne();
    EPETRA_TEST_ERR(!(A1.Scale(4.0)==0),ierr);
    EPETRA_TEST_ERR(!(A1.NormOne()!=orignorm),ierr);
    
    if (verbose) cout << "\n\nMatrix scale OK.\n\n" << endl;

    if (verbose) cout << "\n\nPrint out tridiagonal matrix, each part on each processor.\n\n" << endl;
    cout << A1 << endl;
   

  // Release all objects
  delete [] NumNz1;
  delete [] MyGlobalElements1;

  }

  if (verbose) cout << "\n\n*****Testing LeftScale and RightScale" << endl << endl;

  int NumMyElements2 = 7;
  int NumMyRows2 = 1;//This value should not be changed without editing the
		// code below.
  Epetra_Map RowMap(-1,NumMyRows2,0,Comm);
  Epetra_Map ColMap(NumMyElements2,NumMyElements2,0,Comm);
  // The DomainMap needs to be different from the ColMap for the test to 
  // be meaningful.
  Epetra_Map DomainMap(NumMyElements2,0,Comm);
  int NumMyRangeElements2 = 0;
  // We need to distribute the elements differently for the range map also.
  if (MyPID % 2 == 0)
    NumMyRangeElements2 = NumMyRows2*2; //put elements on even number procs 
  if (NumProc % 2 == 1 && MyPID == NumProc-1)
    NumMyRangeElements2 = NumMyRows2; //If number of procs is odd, put
			// the last NumMyElements2 elements on the last proc
  Epetra_Map RangeMap(-1,NumMyRangeElements2,0,Comm);
  Epetra_CrsMatrix A2(Copy,RowMap,ColMap,NumMyElements2);
  double * Values2 = new double[NumMyElements2];
  int * Indices2 = new int[NumMyElements2]; 

  for (int i=0; i<NumMyElements2; i++) {
    Values2[i] = i+MyPID;
    Indices2[i]=i;
  }

  A2.InsertMyValues(0,NumMyElements2,Values2,Indices2);
  A2.FillComplete(DomainMap,RangeMap,false);
  Epetra_CrsMatrix A2copy(A2);

  double * RowLeftScaleValues = new double[NumMyRows2];
  double * ColRightScaleValues = new double[NumMyElements2];
  int RowLoopLength = RowMap.MaxMyGID()-RowMap.MinMyGID()+1;
  for (int i=0; i<RowLoopLength; i++)
    RowLeftScaleValues[i] = (i + RowMap.MinMyGID() ) % 2 + 1;
  // For the column map, all procs own all elements
  for (int  i=0; i<NumMyElements2;i++)
    ColRightScaleValues[i] = i % 2 + 1;

  int RangeLoopLength = RangeMap.MaxMyGID()-RangeMap.MinMyGID()+1;
  double * RangeLeftScaleValues = new double[RangeLoopLength];
  int DomainLoopLength = DomainMap.MaxMyGID()-DomainMap.MinMyGID()+1;
   double * DomainRightScaleValues = new double[DomainLoopLength];
  for (int i=0; i<RangeLoopLength; i++)
    RangeLeftScaleValues[i] = 1.0/((i + RangeMap.MinMyGID() ) % 2 + 1);
  for (int  i=0; i<DomainLoopLength;i++)
    DomainRightScaleValues[i] = 1.0/((i + DomainMap.MinMyGID() ) % 2 + 1);
                                                                                
  Epetra_Vector xRow(View,RowMap,RowLeftScaleValues);
  Epetra_Vector xCol(View,ColMap,ColRightScaleValues);
  Epetra_Vector xRange(View,RangeMap,RangeLeftScaleValues);
  Epetra_Vector xDomain(View,DomainMap,DomainRightScaleValues);

  double A2infNorm = A2.NormInf();
  double A2oneNorm = A2.NormOne();

  if (verbose1) cout << A2;
  EPETRA_TEST_ERR(A2.LeftScale(xRow),ierr);
  double A2infNorm1 = A2.NormInf();
  double A2oneNorm1 = A2.NormOne();
  bool ScalingBroke = false;
  if (A2infNorm1>2*A2infNorm||A2infNorm1<A2infNorm) {
    EPETRA_TEST_ERR(-31,ierr);
    ScalingBroke = true;
  }
  if (A2oneNorm1>2*A2oneNorm||A2oneNorm1<A2oneNorm) {

    EPETRA_TEST_ERR(-32,ierr);
    ScalingBroke = true;
  }
  if (verbose1) cout << A2;
  EPETRA_TEST_ERR(A2.RightScale(xCol),ierr);
  double A2infNorm2 = A2.NormInf();
  double A2oneNorm2 = A2.NormOne();
  if (A2infNorm2>=2*A2infNorm1||A2infNorm2<=A2infNorm1) {
    EPETRA_TEST_ERR(-33,ierr);
    ScalingBroke = true;
  }
  if (A2oneNorm2>2*A2oneNorm1||A2oneNorm2<=A2oneNorm1) {
    EPETRA_TEST_ERR(-34,ierr);
    ScalingBroke = true;
  }
  if (verbose1) cout << A2;
  EPETRA_TEST_ERR(A2.RightScale(xDomain),ierr);
  double A2infNorm3 = A2.NormInf();
  double A2oneNorm3 = A2.NormOne();
  // The last two scaling ops cancel each other out
  if (A2infNorm3!=A2infNorm1) {
    EPETRA_TEST_ERR(-35,ierr)
    ScalingBroke = true;
  }
  if (A2oneNorm3!=A2oneNorm1) {
    EPETRA_TEST_ERR(-36,ierr)
    ScalingBroke = true;
  }
  if (verbose1) cout << A2;
  EPETRA_TEST_ERR(A2.LeftScale(xRange),ierr);
  double A2infNorm4 = A2.NormInf();
  double A2oneNorm4 = A2.NormOne();
  // The 4 scaling ops all cancel out
  if (A2infNorm4!=A2infNorm) {
    EPETRA_TEST_ERR(-37,ierr)
    ScalingBroke = true;
  }
  if (A2oneNorm4!=A2oneNorm) {
    EPETRA_TEST_ERR(-38,ierr)
    ScalingBroke = true;
  }

  //
  //  Now try changing the values underneath and make sure that 
  //  telling one process about the change causes NormInf() and 
  //  NormOne() to recompute the norm on all processes.
  //
  
  double *values; 
  int num_my_rows = A2.NumMyRows() ; 
  int num_entries;

  for ( int  i=0 ; i< num_my_rows; i++ ) {
    EPETRA_TEST_ERR( A2.ExtractMyRowView( i, num_entries, values ), ierr );
    for ( int j = 0 ; j <num_entries; j++ ) {
      values[j] *= 2.0; 
    }
  }


  if ( MyPID == 0 )
    A2.SumIntoGlobalValues( 0, 0, 0, 0 ) ; 

  double A2infNorm5 = A2.NormInf();
  double A2oneNorm5 = A2.NormOne();

  if (A2infNorm5!=2.0 * A2infNorm4) {
    EPETRA_TEST_ERR(-39,ierr)
    ScalingBroke = true;
  }
  if (A2oneNorm5!= 2.0 * A2oneNorm4) {
    EPETRA_TEST_ERR(-40,ierr)
    ScalingBroke = true;
  }

  //
  //  Restore the values underneath
  //
  for ( int  i=0 ; i< num_my_rows; i++ ) {
    EPETRA_TEST_ERR( A2.ExtractMyRowView( i, num_entries, values ), ierr );
    for ( int j = 0 ; j <num_entries; j++ ) {
      values[j] /= 2.0; 
    }
  }

  if (verbose1) cout << A2;

  if (ScalingBroke) {
    if (verbose) cout << endl << "LeftScale and RightScale tests FAILED" << endl << endl;
  }
  else {
    if (verbose) cout << endl << "LeftScale and RightScale tests PASSED" << endl << endl;
  }

  Comm.Barrier();

  if (verbose) cout << "\n\n*****Testing InvRowMaxs and InvColMaxs" << endl << endl;

  if (verbose1) cout << A2 << endl;
  EPETRA_TEST_ERR(A2.InvRowMaxs(xRow),ierr);
  EPETRA_TEST_ERR(A2.InvRowMaxs(xRange),ierr);
  if (verbose1) cout << xRow << endl << xRange << endl;

  if (verbose) cout << "\n\n*****Testing InvRowSums and InvColSums" << endl << endl;
  bool InvSumsBroke = false;
// Works!
  EPETRA_TEST_ERR(A2.InvRowSums(xRow),ierr);
  if (verbose1) cout << xRow;
  EPETRA_TEST_ERR(A2.LeftScale(xRow),ierr);
  float A2infNormFloat = A2.NormInf();
  if (verbose1) cout << A2 << endl;
  if (fabs(1.0-A2infNormFloat) > 1.e-5) {
    EPETRA_TEST_ERR(-41,ierr);
    InvSumsBroke = true;
  }

  // Works
  int expectedcode = 1;
  if (Comm.NumProc()>1) expectedcode = 0;
  EPETRA_TEST_ERR(!(A2.InvColSums(xDomain)==expectedcode),ierr); // This matrix has a single row, the first column has a zero, so a warning is issued.
  if (verbose1) cout << xDomain << endl;
  EPETRA_TEST_ERR(A2.RightScale(xDomain),ierr);
  float A2oneNormFloat2 = A2.NormOne();
  if (verbose1) cout << A2;
  if (fabs(1.0-A2oneNormFloat2)>1.e-5) {
    EPETRA_TEST_ERR(-42,ierr)
    InvSumsBroke = true;
  }

// Works!
  EPETRA_TEST_ERR(A2.InvRowSums(xRange),ierr);

  if (verbose1) cout << xRange;
  EPETRA_TEST_ERR(A2.LeftScale(xRange),ierr);
  float A2infNormFloat2 = A2.NormInf(); // We use a float so that rounding error
	// will not prevent the sum from being 1.0.
  if (verbose1) cout << A2;
  if (fabs(1.0-A2infNormFloat2)>1.e-5) {
    cout << "InfNorm should be = 1, but InfNorm = " << A2infNormFloat2 << endl;
    EPETRA_TEST_ERR(-43,ierr);
    InvSumsBroke = true;
  }

  // Doesn't work - may not need this test because column ownership is not unique
  /*  EPETRA_TEST_ERR(A2.InvColSums(xCol),ierr);
cout << xCol;
  EPETRA_TEST_ERR(A2.RightScale(xCol),ierr);
  float A2oneNormFloat = A2.NormOne();
cout << A2;
  if (fabs(1.0-A2oneNormFloat)>1.e-5) {
    EPETRA_TEST_ERR(-44,ierr);
    InvSumsBroke = true;
  }
  */
  delete [] ColRightScaleValues;
  delete [] DomainRightScaleValues;
  if (verbose) cout << "Begin partial sum testing." << endl;
  // Test with a matrix that has partial sums for a subset of the rows 
  // on multiple processors. (Except for the serial case, of course.)
  int NumMyRows3 = 2; // Changing this requires further changes below
  int * myGlobalElements = new int[NumMyRows3];
  for (int i=0; i<NumMyRows3; i++) myGlobalElements[i] = MyPID+i;
  Epetra_Map RowMap3(NumProc*2, NumMyRows3, myGlobalElements, 0, Comm);
  int NumMyElements3 = 5;
  Epetra_CrsMatrix A3(Copy, RowMap3, NumMyElements3);
  double * Values3 = new double[NumMyElements3];
  int * Indices3 = new int[NumMyElements3];
  for (int i=0; i < NumMyElements3; i++) {
    Values3[i] = (int) (MyPID + (i+1));
    Indices3[i]=i;
  }
  for (int i=0; i<NumMyRows3; i++) {
    A3.InsertGlobalValues(myGlobalElements[i],NumMyElements3,Values3,Indices3);
  }
  Epetra_Map RangeMap3(NumProc+1, 0, Comm);
  Epetra_Map DomainMap3(NumMyElements3, 0, Comm);
  EPETRA_TEST_ERR(A3.FillComplete(DomainMap3, RangeMap3,false),ierr);
  if (verbose1) cout << A3;
  Epetra_Vector xRange3(RangeMap3,false);
  Epetra_Vector xDomain3(DomainMap3,false);

  EPETRA_TEST_ERR(A3.InvRowSums(xRange3),ierr);

  if (verbose1) cout << xRange3;
  EPETRA_TEST_ERR(A3.LeftScale(xRange3),ierr);
  float A3infNormFloat = A3.NormInf();
  if (verbose1) cout << A3;
  if (1.0!=A3infNormFloat) {
    cout << "InfNorm should be = 1, but InfNorm = " << A3infNormFloat <<endl;
    EPETRA_TEST_ERR(-61,ierr);
    InvSumsBroke = true;
  }
  // we want to take the transpose of our matrix and fill in different values.
  int NumMyColumns3 = NumMyRows3;
  Epetra_Map ColMap3cm(RowMap3); 
  Epetra_Map RowMap3cm(A3.ColMap());

  Epetra_CrsMatrix A3cm(Copy,RowMap3cm,ColMap3cm,NumProc+1);
  double *Values3cm = new double[NumMyColumns3];
  int * Indices3cm = new int[NumMyColumns3];
  for (int i=0; i<NumMyColumns3; i++) {
    Values3cm[i] = MyPID + i + 1;
    Indices3cm[i]= i + MyPID;
  }
  for (int ii=0; ii<NumMyElements3; ii++) {
    A3cm.InsertGlobalValues(ii, NumMyColumns3, Values3cm, Indices3cm);
  }

  // The DomainMap and the RangeMap from the last test will work fine for 
  // the RangeMap and DomainMap, respectively, but I will make copies to
  // avaoid confusion when passing what looks like a DomainMap where we
  // need a RangeMap and vice vera.
  Epetra_Map RangeMap3cm(DomainMap3);
  Epetra_Map DomainMap3cm(RangeMap3);
  EPETRA_TEST_ERR(A3cm.FillComplete(DomainMap3cm,RangeMap3cm),ierr);
  if (verbose1) cout << A3cm << endl;

  // Again, we can copy objects from the last example.
  //Epetra_Vector xRange3cm(xDomain3); //Don't use at this time
  Epetra_Vector xDomain3cm(DomainMap3cm,false);

  EPETRA_TEST_ERR(A3cm.InvColSums(xDomain3cm),ierr);

  if (verbose1) cout << xDomain3cm << endl;

  EPETRA_TEST_ERR(A3cm.RightScale(xDomain3cm),ierr);
  float A3cmOneNormFloat  = A3cm.NormOne();
  if (verbose1) cout << A3cm << endl;
  if (1.0!=A3cmOneNormFloat) {
    cout << "OneNorm should be = 1, but OneNorm = " << A3cmOneNormFloat << endl;
    EPETRA_TEST_ERR(-62,ierr);
    InvSumsBroke = true;
  }
  
  if (verbose) cout << "End partial sum testing" << endl;
  if (verbose) cout << "Begin replicated testing" << endl;

  // We will now view the shared row as a repliated row, rather than one 
  // that has partial sums of its entries on mulitple processors.
  // We will reuse much of the data used for the partial sum tesitng.
  Epetra_Vector xRow3(RowMap3,false); 
  Epetra_CrsMatrix A4(Copy, RowMap3, NumMyElements3);
  for (int ii=0; ii < NumMyElements3; ii++) {
    Values3[ii] = (int)((ii*.6)+1.0);
  }
  for (int ii=0; ii<NumMyRows3; ii++) {
    A4.InsertGlobalValues(myGlobalElements[ii],NumMyElements3,Values3,Indices3);
  }
  EPETRA_TEST_ERR(A4.FillComplete(DomainMap3, RangeMap3,false),ierr);
  if (verbose1) cout << A4 << endl;
  // The next two lines should be expanded into a verifiable test.
  EPETRA_TEST_ERR(A4.InvRowMaxs(xRow3),ierr);
  EPETRA_TEST_ERR(A4.InvRowMaxs(xRange3),ierr);
  if (verbose1) cout << xRow3 << xRange3;

  EPETRA_TEST_ERR(A4.InvRowSums(xRow3),ierr);                      
  if (verbose1) cout << xRow3;
  EPETRA_TEST_ERR(A4.LeftScale(xRow3),ierr);
  float A4infNormFloat = A4.NormInf();
  if (verbose1) cout << A4;
  if (2.0!=A4infNormFloat && NumProc != 1) {
    if (verbose1) cout << "InfNorm should be = 2 (because one column is replicated on two processors and NormOne() does not handle replication), but InfNorm = " << A4infNormFloat <<endl;
    EPETRA_TEST_ERR(-63,ierr);
    InvSumsBroke = true;
  }
  else if (1.0!=A4infNormFloat && NumProc == 1) {
    if (verbose1) cout << "InfNorm should be = 1, but InfNorm = " << A4infNormFloat <<endl;
    EPETRA_TEST_ERR(-63,ierr);
    InvSumsBroke = true;
  }
  
  Epetra_Vector xCol3cm(ColMap3cm,false);
  Epetra_CrsMatrix A4cm(Copy, RowMap3cm, ColMap3cm, NumProc+1);
  //Use values from A3cm
  for (int ii=0; ii<NumMyElements3; ii++) {
    A4cm.InsertGlobalValues(ii,NumMyColumns3,Values3cm,Indices3cm);
  }
  EPETRA_TEST_ERR(A4cm.FillComplete(DomainMap3cm, RangeMap3cm,false),ierr);
  if (verbose1) cout << A4cm << endl;
  // The next two lines should be expanded into a verifiable test.
  EPETRA_TEST_ERR(A4cm.InvColMaxs(xCol3cm),ierr);
  EPETRA_TEST_ERR(A4cm.InvColMaxs(xDomain3cm),ierr);
  if (verbose1) cout << xCol3cm << xDomain3cm;

  EPETRA_TEST_ERR(A4cm.InvColSums(xCol3cm),ierr);
 
  if (verbose1) cout << xCol3cm << endl;
  EPETRA_TEST_ERR(A4cm.RightScale(xCol3cm),ierr);
  float A4cmOneNormFloat = A4cm.NormOne();
  if (verbose1) cout << A4cm << endl;
  if (2.0!=A4cmOneNormFloat && NumProc != 1) {
    if (verbose1) cout << "OneNorm should be = 2 (because one column is replicated on two processors and NormOne() does not handle replication), but OneNorm = " << A4cmOneNormFloat << endl;
    EPETRA_TEST_ERR(-64,ierr);
    InvSumsBroke = true;
  }
  else if (1.0!=A4cmOneNormFloat && NumProc == 1) {
    if (verbose1) cout << "OneNorm should be = 1, but OneNorm = " << A4infNormFloat <<endl;
    EPETRA_TEST_ERR(-64,ierr);
    InvSumsBroke = true;
  }

  if (verbose) cout << "End replicated testing" << endl;

  if (InvSumsBroke) {
    if (verbose) cout << endl << "InvRowSums tests FAILED" << endl << endl;
  }
  else
    if (verbose) cout << endl << "InvRowSums tests PASSED" << endl << endl;

  A3cm.PutScalar(2.0);
  int nnz_A3cm = A3cm.Graph().NumGlobalNonzeros();
  double check_frobnorm = sqrt(nnz_A3cm*4.0);
  double frobnorm = A3cm.NormFrobenius();

  bool frobnorm_test_failed = false;
  if (fabs(check_frobnorm-frobnorm) > 5.e-5) {
    frobnorm_test_failed = true;
  }

  if (frobnorm_test_failed) {
    if (verbose) std::cout << "Frobenius-norm test FAILED."<<std::endl;
    EPETRA_TEST_ERR(-65, ierr);
  }

  delete [] Values2;
  delete [] Indices2;
  delete [] myGlobalElements;
  delete [] Values3;
  delete [] Indices3;
  delete [] Values3cm;
  delete [] Indices3cm;
  delete [] RangeLeftScaleValues;
  delete [] RowLeftScaleValues;
#ifdef EPETRA_MPI
  MPI_Finalize() ;
#endif

/* end main
*/
return ierr ;
}
Exemple #13
0
int main(int argc, char *argv[])
{

  std::cout << Epetra_Version() << std::endl << std::endl;

#ifdef HAVE_MPI
  MPI_Init(&argc,&argv);
  Epetra_MpiComm Comm (MPI_COMM_WORLD);
#else
  Epetra_SerialComm Comm;
#endif


  Teuchos::RCP<Teuchos::FancyOStream> fos = getFancyOStream(Teuchos::rcpFromRef(std::cout));

  // Construct a Map with NumElements and index base of 0
  Teuchos::RCP<Epetra_Map> rgMap = Teuchos::rcp(new Epetra_Map(63, 0, Comm));
  Teuchos::RCP<Epetra_Map> doMap = Teuchos::rcp(new Epetra_Map(20, 0, Comm));

  Epetra_CrsMatrix* Pin = NULL;
  EpetraExt::MatrixMarketFileToCrsMatrix("Test.mat",
      *rgMap, *rgMap, *doMap,
      Pin, false,
      true);
  Teuchos::RCP<Epetra_CrsMatrix> P = Teuchos::rcp(Pin);

  Epetra_CrsMatrix* A = NULL;
  A = TridiagMatrix(rgMap.get(), 1.0, -2.0, 1.0);
  Teuchos::RCP<Epetra_CrsMatrix> rcpA = Teuchos::rcp(A);

  ////////////////////////////////////////////
  // plain Epetra
  ////////////////////////////////////////////

  // Create x and b vectors
  Teuchos::RCP<Epetra_Vector> x = Teuchos::rcp(new Epetra_Vector(*doMap));
  Teuchos::RCP<Epetra_Vector> x2 = Teuchos::rcp(new Epetra_Vector(*rgMap));
  Teuchos::RCP<Epetra_Vector> b = Teuchos::rcp(new Epetra_Vector(*rgMap));
  Teuchos::RCP<Epetra_Vector> b2 = Teuchos::rcp(new Epetra_Vector(*rgMap));

  x->PutScalar(1.0);
  x2->PutScalar(1.0);
  double normx = 0.0;
  x->Norm1(&normx);
  if (Comm.MyPID() == 0) std::cout << "||x|| = " << normx << std::endl;
  x2->Norm1(&normx);
  if (Comm.MyPID() == 0) std::cout << "||x2|| = " << normx << std::endl;

  /*P->Apply(*x,*b);
  normx = 0.0;
  b->Norm1(&normx);*/
  //if (Comm.MyPID() == 0) std::cout << "||Px||_1 = " << normx << std::endl;

  /*Epetra_RowMatrixTransposer et(&*P);
        Epetra_CrsMatrix* PT;
        int rv = et.CreateTranspose(true,PT);
        if (rv != 0) {
          std::ostringstream buf;
          buf << rv;
          std::string msg = "Utils::Transpose: Epetra::RowMatrixTransposer returned value of " + buf.str();
          std::cout << msg << std::endl;
        }

  Teuchos::RCP<Epetra_CrsMatrix> rcpPT(PT);

  rcpPT->Apply(*x2,*b2);
  normx = 0.0;
  b2->Norm1(&normx);*/
  //if (Comm.MyPID() == 0) std::cout << "||P^T x||_1 = " << normx << std::endl;

  // matrix-matrix multiply
  Teuchos::RCP<Epetra_CrsMatrix> AP = Teuchos::rcp(new Epetra_CrsMatrix(Copy,rcpA->RangeMap(),1));
  EpetraExt::MatrixMatrix::Multiply(*rcpA,false,*P,false,*AP, *fos);
  //  AP->FillComplete(P->DomainMap(),rcpA->RangeMap());
  //std::cout << *AP << std::endl;
  AP->Apply(*x,*b2);
  normx = 0.0;
  b2->Norm1(&normx);
  if (Comm.MyPID() == 0) std::cout << "Epetra: ||AP x||_1 = " << normx << std::endl;

  // build A^T explicitely
  Epetra_RowMatrixTransposer etA(&*rcpA);
        Epetra_CrsMatrix* AT;
        int rv3 = etA.CreateTranspose(true,AT);
        if (rv3 != 0) {
          std::ostringstream buf;
          buf << rv3;
          std::string msg = "Utils::Transpose: Epetra::RowMatrixTransposer returned value of " + buf.str();
          std::cout << msg << std::endl;
        }
  Teuchos::RCP<Epetra_CrsMatrix> rcpAT(AT);

  // calculate A^T Px
  Teuchos::RCP<Epetra_CrsMatrix> APexpl = Teuchos::rcp(new Epetra_CrsMatrix(Copy,rcpA->DomainMap(),20));
  EpetraExt::MatrixMatrix::Multiply(*rcpAT,false,*P,false,*APexpl, *fos);
  //  APexpl->FillComplete(P->DomainMap(),rcpA->DomainMap()); // check me
  APexpl->Apply(*x,*b2);
  normx = 0.0;
  b2->Norm1(&normx);
  if (Comm.MyPID() == 0) std::cout << "Epetra: ||A^T_expl P x||_1 = " << normx << std::endl;

  // calculate A^T Px
  Teuchos::RCP<Epetra_CrsMatrix> APimpl = Teuchos::rcp(new Epetra_CrsMatrix(Copy,rcpA->RangeMap(),20));
  EpetraExt::MatrixMatrix::Multiply(*rcpA,true,*P,false,*APimpl, *fos);
  //  APimpl->FillComplete(P->DomainMap(),APimpl->RangeMap()); // check me
  APimpl->Apply(*x,*b2);
  normx = 0.0;
  b2->Norm1(&normx);
  if (Comm.MyPID() == 0) std::cout << "Epetra: ||A^T_impl P x||_1 = " << normx << std::endl;


  ///////////////////////////////////////
  // Xpetra
  ///////////////////////////////////////


   // wrap original matrix to Matrix
   Teuchos::RCP<Xpetra::EpetraMap> xrgMap = Teuchos::rcp(new Xpetra::EpetraMap(rgMap));
   Teuchos::RCP<Xpetra::EpetraMap> xdoMap = Teuchos::rcp(new Xpetra::EpetraMap(doMap));

   Teuchos::RCP<Xpetra::EpetraCrsMatrix> Pop = Teuchos::rcp(new Xpetra::EpetraCrsMatrix(P) );
   Teuchos::RCP<Xpetra::CrsMatrix<double> > crsP = Teuchos::rcp_implicit_cast<Xpetra::CrsMatrix<double> >(Pop);
   Teuchos::RCP<Xpetra::CrsMatrixWrap<double> > crsPOp = Teuchos::rcp( new Xpetra::CrsMatrixWrap<double>(crsP) );
   crsPOp->fillComplete(xdoMap,xrgMap);

   Teuchos::RCP<Xpetra::EpetraCrsMatrix> Aop = Teuchos::rcp(new Xpetra::EpetraCrsMatrix(rcpA) );
   Teuchos::RCP<Xpetra::CrsMatrix<double> > crsA = Teuchos::rcp_implicit_cast<Xpetra::CrsMatrix<double> >(Aop);
   Teuchos::RCP<Xpetra::CrsMatrixWrap<double> > crsAOp = Teuchos::rcp( new Xpetra::CrsMatrixWrap<double>(crsA) );
   crsAOp->fillComplete(xrgMap,xrgMap);

   // wrap vectors
   Teuchos::RCP<Xpetra::EpetraVector> xx = Teuchos::rcp(new Xpetra::EpetraVector(x));
   Teuchos::RCP<Xpetra::EpetraVector> xx2 = Teuchos::rcp(new Xpetra::EpetraVector(x2));
   Teuchos::RCP<Xpetra::EpetraVector> bb1 = Teuchos::rcp(new Xpetra::EpetraVector(b));
   Teuchos::RCP<Xpetra::EpetraVector> bb2 = Teuchos::rcp(new Xpetra::EpetraVector(b2));

   bb1->putScalar(0.0);
   bb2->putScalar(0.0);

   //crsPOp->apply(*xx,*bb1);

   // if (Comm.MyPID() == 0) std::cout << "||Pop x||_1 = " << bb1->norm1() << std::endl;

   //Teuchos::RCP<Xpetra::Matrix<double> > crsPOpT = MueLu::Utils2<double>::Transpose(crsPOp,false);

   //crsPOpT->apply(*xx2,*bb2);
   //if (Comm.MyPID() == 0) std::cout << "||Pop^T x||_1 = " << bb2->norm1() << std::endl;

   // calculate APx
   Teuchos::RCP<Xpetra::Matrix<double> > crsAP = MueLu::Utils<double>::Multiply(*crsAOp,false,*crsPOp,false, *fos);
   //crsAP->describe(*fos,Teuchos::VERB_EXTREME);
   bb1->putScalar(0.0);
   crsAP->apply(*xx,*bb1);
   normx = bb1->norm1();
   if (Comm.MyPID() == 0) std::cout << "Xpetra: ||A Pop x||_1 = " << normx << std::endl;

   // calculate A^T P x explicitely
   Teuchos::RCP<Xpetra::Matrix<double> > crsAOpT = MueLu::Utils2<double>::Transpose(*crsAOp,  false);
   Teuchos::RCP<Xpetra::Matrix<double> > AtPexpl = MueLu::Utils<double> ::Multiply (*crsAOpT, false, *crsPOp, false, *fos);
   bb1->putScalar(0.0);
   AtPexpl->apply(*xx,*bb1);
   normx = bb1->norm1();
   if (Comm.MyPID() == 0)
       std::cout << "Xpetra: ||A^T_expl Pop x||_1 = " << normx << std::endl;

   // calculate A^T P x
   Teuchos::RCP<Xpetra::Matrix<double> > AtPimpl = MueLu::Utils<double>::Multiply(*crsAOp,true,*crsPOp,false, *fos);
   bb1->putScalar(0.0);
   AtPimpl->apply(*xx,*bb1);
   normx = bb1->norm1();
   if (Comm.MyPID() == 0)
       std::cout << "Xpetra: ||A^T_impl Pop x||_1 = " << normx << std::endl;


#ifdef HAVE_MPI
  MPI_Finalize();
#endif

  return 0;
}
Exemple #14
0
int main(int argc, char *argv[])
{
  int ierr = 0, i, j, forierr = 0;

#ifdef EPETRA_MPI
  // Initialize MPI
  MPI_Init(&argc,&argv);
  Epetra_MpiComm Comm( MPI_COMM_WORLD );
#else
  Epetra_SerialComm Comm;
#endif

  bool verbose = false;

  // Check if we should print results to standard out
  if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true;




  //char tmp;
  //if (Comm.MyPID()==0) cout << "Press any key to continue..."<< endl;
  //if (Comm.MyPID()==0) cin >> tmp;
  //Comm.Barrier();

  Comm.SetTracebackMode(0); // This should shut down any error traceback reporting
  int MyPID = Comm.MyPID();
  int NumProc = Comm.NumProc();

  if (verbose && MyPID==0)
    cout << Epetra_Version() << endl << endl;

  if (verbose) cout << "Processor "<<MyPID<<" of "<< NumProc
              << " is alive."<<endl;

  // Redefine verbose to only print on PE 0
  if (verbose && Comm.MyPID()!=0) verbose = false;

  int NumMyEquations = 20;
  long long NumGlobalEquations = NumMyEquations*NumProc+EPETRA_MIN(NumProc,3);
  if (MyPID < 3) NumMyEquations++;
  // Construct a Source Map that puts approximately the same Number of equations on each processor in
  // uniform global ordering

  Epetra_Map SourceMap(NumGlobalEquations, NumMyEquations, 0LL, Comm);

  // Get update list and number of local equations from newly created Map
  int NumMyElements = SourceMap.NumMyElements();
  long long * SourceMyGlobalElements = new long long[NumMyElements];
  SourceMap.MyGlobalElements(SourceMyGlobalElements);

  // Construct a Target Map that will contain:
  //  some unchanged elements (relative to the soure map),
  //  some permuted elements
  //  some off-processor elements
  Epetra_Vector RandVec(SourceMap);
  RandVec.Random(); // This creates a vector of random numbers between negative one and one.

  long long *TargetMyGlobalElements = new long long[NumMyElements];

  long long MinGID = SourceMap.MinMyGID64();
  for (i=0; i< NumMyEquations/2; i++) TargetMyGlobalElements[i] = i + MinGID; // Half will be the same...
  for (i=NumMyEquations/2; i<NumMyEquations; i++) {
    int index = abs((int)(((double) (NumGlobalEquations-1) ) * RandVec[i]));
    TargetMyGlobalElements[i] = EPETRA_MIN(NumGlobalEquations-1,(long long) EPETRA_MAX(0,index));
  }

  int NumSameIDs = 0;
  int NumPermutedIDs = 0;
  int NumRemoteIDs = 0;
  bool StillContiguous = true;
  for (i=0; i < NumMyEquations; i++) {
    if (SourceMyGlobalElements[i]==TargetMyGlobalElements[i] && StillContiguous)
      NumSameIDs++;
    else if (SourceMap.MyGID(TargetMyGlobalElements[i])) {
      StillContiguous = false;
      NumPermutedIDs++;
    }
    else {
      StillContiguous = false;
      NumRemoteIDs++;
    }
  }
  EPETRA_TEST_ERR(!(NumMyEquations==NumSameIDs+NumPermutedIDs+NumRemoteIDs),ierr);

  Epetra_Map TargetMap((long long) -1, NumMyElements, TargetMyGlobalElements, 0LL, Comm);

  // Create a multivector whose elements are GlobalID * (column number +1)

  int NumVectors = 3;
  Epetra_MultiVector SourceMultiVector(SourceMap, NumVectors);
  for (j=0; j < NumVectors; j++)
    for (i=0; i < NumMyElements; i++)
      SourceMultiVector[j][i] = (double) SourceMyGlobalElements[i]*(j+1);

  // Create a target multivector that we will fill using an Import

  Epetra_MultiVector TargetMultiVector(TargetMap, NumVectors);

  Epetra_Import Importer(TargetMap, SourceMap);

  EPETRA_TEST_ERR(!(TargetMultiVector.Import(SourceMultiVector, Importer, Insert)==0),ierr);

  // Test Target against expected values
  forierr = 0;
  for (j=0; j < NumVectors; j++)
    for (i=0; i < NumMyElements; i++) {
      if (TargetMultiVector[j][i]!= (double) TargetMyGlobalElements[i]*(j+1))
	cout << "TargetMultiVector["<<i<<"]["<<j<<"] = " << TargetMultiVector[j][i]
	     <<  "  TargetMyGlobalElements[i]*(j+1) = " <<  TargetMyGlobalElements[i]*(j+1) << endl;
      forierr += !(TargetMultiVector[j][i]== (double) TargetMyGlobalElements[i]*(j+1));
    }
  EPETRA_TEST_ERR(forierr,ierr);

  if (verbose) cout << "MultiVector Import using Importer Check OK" << endl << endl;


  //////////////////////////////////////////////////////////////////////////////

  // Now use Importer to do an export

  Epetra_Vector TargetVector(SourceMap);
  Epetra_Vector ExpectedTarget(SourceMap);
  Epetra_Vector SourceVector(TargetMap);

  NumSameIDs = Importer.NumSameIDs();
  int NumPermuteIDs = Importer.NumPermuteIDs();
  int NumExportIDs = Importer.NumExportIDs();
  int *PermuteFromLIDs = Importer.PermuteFromLIDs();
  int *ExportLIDs = Importer.ExportLIDs();
  int *ExportPIDs = Importer.ExportPIDs();

  for (i=0; i < NumSameIDs; i++) ExpectedTarget[i] = (double) (MyPID+1);
  for (i=0; i < NumPermuteIDs; i++) ExpectedTarget[PermuteFromLIDs[i]] =
				      (double) (MyPID+1);
  for (i=0; i < NumExportIDs; i++) ExpectedTarget[ExportLIDs[i]] +=
				     (double) (ExportPIDs[i]+1);

  for (i=0; i < NumMyElements; i++) SourceVector[i] =  (double) (MyPID+1);

  EPETRA_TEST_ERR(!(TargetVector.Export(SourceVector, Importer, Add)==0),ierr);

  forierr = 0;
  for (i=0; i < NumMyElements; i++) {
    if (TargetVector[i]!= ExpectedTarget[i])
      cout <<  "     TargetVector["<<i<<"] = " << TargetVector[i]
	   <<  "   ExpectedTarget["<<i<<"] = " <<  ExpectedTarget[i] << " on PE " << MyPID << endl;
    forierr += !(TargetVector[i]== ExpectedTarget[i]);
  }
  EPETRA_TEST_ERR(forierr,ierr);

  if (verbose) cout << "Vector Export using Importer Check OK" << endl << endl;

  //////////////////////////////////////////////////////////////////////////////
  // Now use Importer to create a reverse exporter
  TargetVector.PutScalar(0.0);
  Epetra_Export ReversedImport(Importer);

  EPETRA_TEST_ERR(!(TargetVector.Export(SourceVector, ReversedImport, Add)==0),ierr);

  forierr = 0;
  for (i=0; i < NumMyElements; i++) {
    if (TargetVector[i]!= ExpectedTarget[i])
      cout <<  "     TargetVector["<<i<<"] = " << TargetVector[i]
	   <<  "   ExpectedTarget["<<i<<"] = " <<  ExpectedTarget[i] << " on PE " << MyPID << endl;
    forierr += !(TargetVector[i]== ExpectedTarget[i]);
  }
  EPETRA_TEST_ERR(forierr,ierr);

  if (verbose) cout << "Vector Export using Reversed Importer Check OK" << endl << endl;

  //////////////////////////////////////////////////////////////////////////////
  // Now use Exporter to create a reverse importer
  TargetVector.PutScalar(0.0);
  Epetra_Import ReversedExport(ReversedImport);

  EPETRA_TEST_ERR(!(TargetVector.Export(SourceVector, ReversedExport, Add)==0),ierr);

  forierr = 0;
  for (i=0; i < NumMyElements; i++) {
    if (TargetVector[i]!= ExpectedTarget[i])
      cout <<  "     TargetVector["<<i<<"] = " << TargetVector[i]
	   <<  "   ExpectedTarget["<<i<<"] = " <<  ExpectedTarget[i] << " on PE " << MyPID << endl;
    forierr += !(TargetVector[i]== ExpectedTarget[i]);
  }
  EPETRA_TEST_ERR(forierr,ierr);

  if (verbose) cout << "Vector Export using Reversed Exporter Check OK" << endl << endl;


  //////////////////////////////////////////////////////////////////////////////////////////
  //  Build a tridiagonal system two ways:
  //  1) From "standard" matrix view where equations are uniquely owned.
  //  2) From 1D PDE view where nodes (equations) between processors are shared and partial contributions are done
  //     in parallel, then merged together at the end of the construction process.
  //
  //////////////////////////////////////////////////////////////////////////////////////////



  // Construct a Standard Map that puts approximately the same number of equations on each processor in
  // uniform global ordering

  Epetra_Map StandardMap(NumGlobalEquations, NumMyEquations, 0LL, Comm);

  // Get update list and number of local equations from newly created Map
  NumMyElements = StandardMap.NumMyElements();
  long long * StandardMyGlobalElements = new long long[NumMyElements];
  StandardMap.MyGlobalElements(StandardMyGlobalElements);


  // Create a standard Epetra_CrsGraph

  Epetra_CrsGraph StandardGraph(Copy, StandardMap, 3);
  EPETRA_TEST_ERR(StandardGraph.IndicesAreGlobal(),ierr);
  EPETRA_TEST_ERR(StandardGraph.IndicesAreLocal(),ierr);

  // Add  rows one-at-a-time
  // Need some vectors to help
  // Off diagonal Values will always be -1


  long long *Indices = new long long[2];
  int NumEntries;

  forierr = 0;
  for (i=0; i<NumMyEquations; i++)
    {
    if (StandardMyGlobalElements[i]==0)
      {
	Indices[0] = 1;
	NumEntries = 1;
      }
    else if (StandardMyGlobalElements[i] == NumGlobalEquations-1)
      {
	Indices[0] = NumGlobalEquations-2;
	NumEntries = 1;
      }
    else
      {
	Indices[0] = StandardMyGlobalElements[i]-1;
	Indices[1] = StandardMyGlobalElements[i]+1;
	NumEntries = 2;
      }
    forierr += !(StandardGraph.InsertGlobalIndices(StandardMyGlobalElements[i], NumEntries, Indices)==0);
    forierr += !(StandardGraph.InsertGlobalIndices(StandardMyGlobalElements[i], 1, StandardMyGlobalElements+i)==0); // Put in the diagonal entry
    }
  EPETRA_TEST_ERR(forierr,ierr);

  // Finish up
  EPETRA_TEST_ERR(!(StandardGraph.IndicesAreGlobal()),ierr);
  EPETRA_TEST_ERR(!(StandardGraph.FillComplete()==0),ierr);
  EPETRA_TEST_ERR(!(StandardGraph.IndicesAreLocal()),ierr);
  EPETRA_TEST_ERR(StandardGraph.StorageOptimized(),ierr);
  StandardGraph.OptimizeStorage();
  EPETRA_TEST_ERR(!(StandardGraph.StorageOptimized()),ierr);
  EPETRA_TEST_ERR(StandardGraph.UpperTriangular(),ierr);
  EPETRA_TEST_ERR(StandardGraph.LowerTriangular(),ierr);

  // Create Epetra_CrsMatrix using the just-built graph

  Epetra_CrsMatrix StandardMatrix(Copy, StandardGraph);
  EPETRA_TEST_ERR(StandardMatrix.IndicesAreGlobal(),ierr);
  EPETRA_TEST_ERR(!(StandardMatrix.IndicesAreLocal()),ierr);

  // Add  rows one-at-a-time
  // Need some vectors to help
  // Off diagonal Values will always be -1


  double *Values = new double[2];
  Values[0] = -1.0; Values[1] = -1.0;
  double two = 2.0;

  forierr = 0;
  for (i=0; i<NumMyEquations; i++)
    {
    if (StandardMyGlobalElements[i]==0)
      {
	Indices[0] = 1;
	NumEntries = 1;
      }
    else if (StandardMyGlobalElements[i] == NumGlobalEquations-1)
      {
	Indices[0] = NumGlobalEquations-2;
	NumEntries = 1;
      }
    else
      {
	Indices[0] = StandardMyGlobalElements[i]-1;
	Indices[1] = StandardMyGlobalElements[i]+1;
	NumEntries = 2;
      }
    forierr += !(StandardMatrix.ReplaceGlobalValues(StandardMyGlobalElements[i], NumEntries, Values, Indices)==0);
    // Put in the diagonal entry
    forierr += !(StandardMatrix.ReplaceGlobalValues(StandardMyGlobalElements[i], 1, &two, StandardMyGlobalElements+i)==0);
    }
  EPETRA_TEST_ERR(forierr,ierr);

  // Finish up
  EPETRA_TEST_ERR(!(StandardMatrix.IndicesAreLocal()),ierr);
  EPETRA_TEST_ERR(!(StandardMatrix.FillComplete()==0),ierr);
  EPETRA_TEST_ERR(!(StandardMatrix.IndicesAreLocal()),ierr);
  //  EPETRA_TEST_ERR((StandardMatrix.StorageOptimized()),ierr);
  EPETRA_TEST_ERR((StandardMatrix.OptimizeStorage()),ierr);
  EPETRA_TEST_ERR(!(StandardMatrix.StorageOptimized()),ierr);
  EPETRA_TEST_ERR(StandardMatrix.UpperTriangular(),ierr);
  EPETRA_TEST_ERR(StandardMatrix.LowerTriangular(),ierr);

  // Construct an Overlapped Map of StandardMap that include the endpoints from two neighboring processors.

  int OverlapNumMyElements;
  long long OverlapMinMyGID;

  OverlapNumMyElements = NumMyElements + 1;
  if (MyPID==0) OverlapNumMyElements--;

  if (MyPID==0) OverlapMinMyGID = StandardMap.MinMyGID64();
  else OverlapMinMyGID = StandardMap.MinMyGID64()-1;

  long long * OverlapMyGlobalElements = new long long[OverlapNumMyElements];

  for (i=0; i< OverlapNumMyElements; i++) OverlapMyGlobalElements[i] = OverlapMinMyGID + i;

  Epetra_Map OverlapMap((long long) -1, OverlapNumMyElements, OverlapMyGlobalElements, 0LL, Comm);

  // Create the Overlap Epetra_Matrix

  Epetra_CrsMatrix OverlapMatrix(Copy, OverlapMap, 4);
  EPETRA_TEST_ERR(OverlapMatrix.IndicesAreGlobal(),ierr);
  EPETRA_TEST_ERR(OverlapMatrix.IndicesAreLocal(),ierr);

  // Add  matrix element one cell at a time.
  // Each cell does an incoming and outgoing flux calculation


  double pos_one = 1.0;
  double neg_one = -1.0;

  forierr = 0;
  for (i=0; i<OverlapNumMyElements; i++)
    {
      long long node_left = OverlapMyGlobalElements[i]-1;
      long long node_center = node_left + 1;
      long long node_right = node_left + 2;
      if (i>0) {
	if (node_left>-1)
	  forierr += !(OverlapMatrix.InsertGlobalValues(node_center, 1, &neg_one, &node_left)==0);
	forierr += !(OverlapMatrix.InsertGlobalValues(node_center, 1, &pos_one, &node_center)==0);
      }
      if (i<OverlapNumMyElements-1) {
	forierr += !(OverlapMatrix.InsertGlobalValues(node_center, 1, &pos_one, &node_center)==0);
	if (node_right<NumGlobalEquations)
	  forierr += !(OverlapMatrix.InsertGlobalValues(node_center, 1, &neg_one, &node_right)==0);
      }
    }
  EPETRA_TEST_ERR(forierr,ierr);

  // Handle endpoints
  if (MyPID==0) {
    long long node_center = 0;
    EPETRA_TEST_ERR(!(OverlapMatrix.InsertGlobalValues(node_center, 1, &pos_one, &node_center)==0),ierr);
  }
  if (MyPID==NumProc-1) {
    long long node_center = OverlapMyGlobalElements[OverlapNumMyElements-1];
    EPETRA_TEST_ERR(!(OverlapMatrix.InsertGlobalValues(node_center, 1, &pos_one, &node_center)==0),ierr);
  }

  EPETRA_TEST_ERR(!(OverlapMatrix.FillComplete()==0),ierr);

  // Make a gathered matrix from OverlapMatrix.  It should be identical to StandardMatrix

  Epetra_CrsMatrix GatheredMatrix(Copy, StandardGraph);
  Epetra_Export Exporter(OverlapMap, StandardMap);
  EPETRA_TEST_ERR(!(GatheredMatrix.Export(OverlapMatrix, Exporter, Add)==0),ierr);
  EPETRA_TEST_ERR(!(GatheredMatrix.FillComplete()==0),ierr);

  // Check if entries of StandardMatrix and GatheredMatrix are identical

  int StandardNumEntries, GatheredNumEntries;
  int * StandardIndices, * GatheredIndices;
  double * StandardValues, * GatheredValues;

  int StandardNumMyNonzeros = StandardMatrix.NumMyNonzeros();
  int GatheredNumMyNonzeros = GatheredMatrix.NumMyNonzeros();
  EPETRA_TEST_ERR(!(StandardNumMyNonzeros==GatheredNumMyNonzeros),ierr);

  int StandardNumMyRows = StandardMatrix.NumMyRows();
  int GatheredNumMyRows = GatheredMatrix.NumMyRows();
  EPETRA_TEST_ERR(!(StandardNumMyRows==GatheredNumMyRows),ierr);

  forierr = 0;
  for (i=0; i< StandardNumMyRows; i++)
    {
      forierr += !(StandardMatrix.ExtractMyRowView(i, StandardNumEntries, StandardValues, StandardIndices)==0);
      forierr += !(GatheredMatrix.ExtractMyRowView(i, GatheredNumEntries, GatheredValues, GatheredIndices)==0);
      forierr += !(StandardNumEntries==GatheredNumEntries);
      for (j=0; j < StandardNumEntries; j++) {
	//if (StandardIndices[j]!=GatheredIndices[j])
	// cout << "MyPID = " << MyPID << " i = " << i << "   StandardIndices[" << j << "] = " << StandardIndices[j]
	//      << "   GatheredIndices[" << j << "] = " << GatheredIndices[j] << endl;
	//if (StandardValues[j]!=GatheredValues[j])
	//cout << "MyPID = " << MyPID << " i = " << i << "    StandardValues[" << j << "] = " <<  StandardValues[j]
	//     << "    GatheredValues[" << j << "] = " <<  GatheredValues[j] << endl;
	forierr += !(StandardIndices[j]==GatheredIndices[j]);
	forierr += !(StandardValues[j]==GatheredValues[j]);
      }
    }
  EPETRA_TEST_ERR(forierr,ierr);

  if (verbose) cout << "Matrix Export Check OK" << endl << endl;

  //Do Again with use of Epetra_OffsetIndex object for speed
  Epetra_OffsetIndex OffsetIndex( OverlapMatrix.Graph(), GatheredMatrix.Graph(), Exporter );
  EPETRA_TEST_ERR(!(GatheredMatrix.Export(OverlapMatrix, Exporter, Add)==0),ierr);

  if (verbose) cout << "Optimized Matrix Export Check OK" << endl << endl;

  bool passed;
  Epetra_LongLongVector v1(StandardMap); v1.PutValue(2);
  Epetra_LongLongVector v2(StandardMap); v2.PutValue(3);

  Epetra_Export identExporter(StandardMap,StandardMap); // Identity exporter
  EPETRA_TEST_ERR(!(v2.Export(v1, identExporter, Insert)==0),ierr);
  passed = (v2.MinValue()==2);
  EPETRA_TEST_ERR(!passed,ierr);

  v1.PutValue(1);
  Epetra_Import identImporter(StandardMap,StandardMap); // Identity importer
  EPETRA_TEST_ERR(!(v2.Import(v1, identExporter, Insert)==0),ierr);
  passed = passed && (v2.MaxValue()==1);
  EPETRA_TEST_ERR(!passed,ierr);

  if (verbose) {
    if (passed) cout << "Identity Import/Export Check OK" << endl << endl;
    else cout << "Identity Import/Export Check Failed" << endl << endl;
  }

  int NumSubMapElements = StandardMap.NumMyElements()/2;
  int SubStart = Comm.MyPID();
  NumSubMapElements = EPETRA_MIN(NumSubMapElements,StandardMap.NumMyElements()-SubStart);
  Epetra_Map SubMap((long long) -1, NumSubMapElements, StandardMyGlobalElements+SubStart, 0LL, Comm);

  Epetra_LongLongVector v3(View, SubMap, SubMap.MyGlobalElements64()); // Fill v3 with GID values for variety
  Epetra_Export subExporter(SubMap, StandardMap); // Export to a subset of indices of standard map
  EPETRA_TEST_ERR(!(v2.Export(v3,subExporter,Insert)==0),ierr);

  forierr = 0;
  for (i=0; i<SubMap.NumMyElements(); i++) {
    int i1 = StandardMap.LID(SubMap.GID64(i));
    forierr += !(v3[i]==v2[i1]);
  }
  EPETRA_TEST_ERR(forierr,ierr);

  Epetra_Import subImporter(StandardMap, SubMap); // Import to a subset of indices of standard map
  EPETRA_TEST_ERR(!(v1.Import(v3,subImporter,Insert)==0),ierr);

  for (i=0; i<SubMap.NumMyElements(); i++) {
    int i1 = StandardMap.LID(SubMap.GID64(i));
    forierr += !(v3[i]==v1[i1]);
  }
  EPETRA_TEST_ERR(forierr,ierr);

  if (verbose) {
    if (forierr==0) cout << "SubMap Import/Export Check OK" << endl << endl;
    else cout << "SubMap Import/Export Check Failed" << endl << endl;
  }

#ifdef DOESNT_WORK_IN_PARALLEL
  forierr = special_submap_import_test(Comm);
  EPETRA_TEST_ERR(forierr, ierr);

  if (verbose) {
    if (forierr==0) cout << "Special SubMap Import Check OK" << endl << endl;
    else cout << "Special SubMap Import Check Failed" << endl << endl;
  }
#endif

  forierr =  alternate_import_constructor_test(Comm);
  EPETRA_TEST_ERR(forierr, ierr);

  if (verbose) {
    if (forierr==0) cout << "Alternative Import Constructor Check OK" << endl << endl;
    else cout << "Alternative Import Constructor Check Failed" << endl << endl;
  }

  // Release all objects

  delete [] SourceMyGlobalElements;
  delete [] TargetMyGlobalElements;
  delete [] OverlapMyGlobalElements;
  delete [] StandardMyGlobalElements;

  delete [] Values;
  delete [] Indices;

#ifdef EPETRA_MPI
  MPI_Finalize() ;
#endif

/* end main
*/
return ierr ;
}
Exemple #15
0
int main(int argc, char *argv[]) {

  int ierr=0, returnierr=0;

#ifdef EPETRA_MPI
  MPI_Init(&argc,&argv);
  Epetra_MpiComm Comm(MPI_COMM_WORLD);
#else
  Epetra_SerialComm Comm;
#endif

  bool verbose = false;

  // Check if we should print results to standard out
  if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true;


  if (!verbose) {
    Comm.SetTracebackMode(0); // This should shut down any error traceback reporting
  }
  int MyPID = Comm.MyPID();
  int NumProc = Comm.NumProc();

  if (verbose && MyPID==0)
    cout << Epetra_Version() << endl << endl;

  if (verbose) cout << Comm << endl;

  bool verbose1 = verbose;
  if (verbose) verbose = (MyPID==0);

  int NumMyElements = 10000;
  int NumMyElements1 = NumMyElements; // Used for local map
  long long NumGlobalElements = NumMyElements*NumProc+EPETRA_MIN(NumProc,3);
  if (MyPID < 3) NumMyElements++;
  int IndexBase = 0;
  bool DistributedGlobal = (NumGlobalElements>NumMyElements);
  
  Epetra_Map* Map;

  // Test exceptions

  if (verbose)
    cout << "*******************************************************************************************" << endl
	 << "        Testing Exceptions (Expect error messages if EPETRA_NO_ERROR_REPORTS is not defined" << endl
	 << "*******************************************************************************************" << endl
	 << endl << endl;

  try {
    if (verbose) cout << "Checking Epetra_Map(-2, IndexBase, Comm)" << endl;
    Map = new Epetra_Map((long long)-2, IndexBase, Comm);
  }
  catch (int Error) {
    if (Error!=-1) {
      if (Error!=0) {
	EPETRA_TEST_ERR(Error,returnierr);
	if (verbose) cout << "Error code should be -1" << endl;
      }
      else {
	cout << "Error code = " << Error << "Should be -1" << endl;
	returnierr+=1;
      }
    }
    else if (verbose) cout << "Checked OK\n\n" << endl;
  }

  try {
    if (verbose) cout << "Checking Epetra_Map(2, 3, IndexBase, Comm)" << endl;
    Map = new Epetra_Map((long long)2, 3, IndexBase, Comm);
  }
  catch (int Error) {
    if (Error!=-4) {
      if (Error!=0) {
	EPETRA_TEST_ERR(Error,returnierr);
	if (verbose) cout << "Error code should be -4" << endl;
      }
      else {
	cout << "Error code = " << Error << "Should be -4" << endl;
	returnierr+=1;
      }
    }
    else if (verbose) cout << "Checked OK\n\n" << endl;
  }

  if (verbose) cerr << flush;
  if (verbose) cout << flush;
  Comm.Barrier();
  if (verbose)
    cout << endl << endl
      << "*******************************************************************************************" << endl
      << "        Testing valid constructor now......................................................" << endl
      << "*******************************************************************************************" << endl
      << endl << endl;

  // Test Epetra-defined uniform linear distribution constructor
  Map = new Epetra_Map(NumGlobalElements, IndexBase, Comm);
  if (verbose) cout << "Checking Epetra_Map(NumGlobalElements, IndexBase, Comm)" << endl;
  ierr = checkmap(*Map, NumGlobalElements, NumMyElements, 0, 
		  IndexBase, Comm, DistributedGlobal);

  EPETRA_TEST_ERR(ierr,returnierr);
  if (verbose && ierr==0) cout << "Checked OK\n\n" <<endl;

  delete Map;

  // Test User-defined linear distribution constructor
  Map = new Epetra_Map(NumGlobalElements, NumMyElements, IndexBase, Comm);

  if (verbose) cout << "Checking Epetra_Map(NumGlobalElements, NumMyElements, IndexBase, Comm)" << endl;
  ierr = checkmap(*Map, NumGlobalElements, NumMyElements, 0, 
		  IndexBase, Comm, DistributedGlobal);

  EPETRA_TEST_ERR(ierr,returnierr);
  if (verbose && ierr==0) cout << "Checked OK\n\n" <<endl;
  delete Map;

  // Test User-defined arbitrary distribution constructor
  // Generate Global Element List.  Do in reverse for fun!

  long long * MyGlobalElements = new long long[NumMyElements];
  int MaxMyGID = (Comm.MyPID()+1)*NumMyElements-1+IndexBase;
  if (Comm.MyPID()>2) MaxMyGID+=3;
  for (int i = 0; i<NumMyElements; i++) MyGlobalElements[i] = MaxMyGID-i;

  Map = new Epetra_Map(NumGlobalElements, NumMyElements, MyGlobalElements, 
											 IndexBase, Comm);
  if (verbose) cout << "Checking Epetra_Map(NumGlobalElements, NumMyElements, MyGlobalElements,  IndexBase, Comm)" << endl;
  ierr = checkmap(*Map, NumGlobalElements, NumMyElements, MyGlobalElements, 
									IndexBase, Comm, DistributedGlobal);

  EPETRA_TEST_ERR(ierr,returnierr);
  if (verbose && ierr==0) cout << "Checked OK\n\n" <<endl;
  // Test Copy constructor
  Epetra_Map* Map1 = new Epetra_Map(*Map);

  // Test SameAs() method
  bool same = Map1->SameAs(*Map);
  EPETRA_TEST_ERR(!(same==true),ierr);// should return true since Map1 is a copy of Map

  Epetra_BlockMap* Map2 = new Epetra_Map(NumGlobalElements, NumMyElements, MyGlobalElements,  IndexBase, Comm);
  same = Map2->SameAs(*Map);
  EPETRA_TEST_ERR(!(same==true),ierr); // Map and Map2 were created with the same sets of parameters
  delete Map2;

  // now test SameAs() on a map that is different

  Map2 =  new Epetra_Map(NumGlobalElements, NumMyElements, MyGlobalElements, IndexBase-1, Comm);
  same = Map2->SameAs(*Map);
  EPETRA_TEST_ERR(!(same==false),ierr); // IndexBases are different
  delete Map2;

  // Back to testing copy constructor
  if (verbose) cout << "Checking Epetra_Map(*Map)" << endl;
  ierr = checkmap(*Map1, NumGlobalElements, NumMyElements, MyGlobalElements, 
		  IndexBase, Comm, DistributedGlobal);

  EPETRA_TEST_ERR(ierr,returnierr);
  if (verbose && ierr==0) cout << "Checked OK\n\n" <<endl;
  Epetra_Map* SmallMap = 0;
  if (verbose1) {
    // Build a small map for test cout.  Use 10 elements from current map
    long long* MyEls = Map->MyGlobalElements64();
    int IndBase = Map->IndexBase();
    int MyLen = EPETRA_MIN(10+Comm.MyPID(),Map->NumMyElements());
    SmallMap = new Epetra_Map((long long)-1, MyLen, MyEls, IndBase, Comm);
  }

  delete [] MyGlobalElements;
  delete Map;
  delete Map1;

	// Test reference-counting in Epetra_Map
	if (verbose) cout << "Checking Epetra_Map reference counting" << endl;
	ierr = checkMapDataClass(Comm, verbose);
	EPETRA_TEST_ERR(ierr,returnierr);
  if (verbose && ierr==0) cout << "Checked OK\n\n" <<endl;

  // Test LocalMap constructor
  Epetra_LocalMap* LocalMap = new Epetra_LocalMap((long long)NumMyElements1, IndexBase, Comm);
  if (verbose) cout << "Checking Epetra_LocalMap(NumMyElements1, IndexBase, Comm)" << endl;
  ierr = checkmap(*LocalMap, NumMyElements1, NumMyElements1, 0, IndexBase, Comm, false);

  EPETRA_TEST_ERR(ierr,returnierr);
  if (verbose && ierr==0) cout << "Checked OK\n\n" <<endl;
  // Test Copy constructor
  Epetra_LocalMap* LocalMap1 = new Epetra_LocalMap(*LocalMap);
  if (verbose) cout << "Checking Epetra_LocalMap(*LocalMap)" << endl;
  ierr = checkmap(*LocalMap1, NumMyElements1, NumMyElements1, 0, IndexBase, Comm, false);

  EPETRA_TEST_ERR(ierr,returnierr);
  if (verbose && ierr==0) cout << "Checked OK\n\n" <<endl;
  delete LocalMap1;
  delete LocalMap;

	// Test reference-counting in Epetra_LocalMap
	if (verbose) cout << "Checking Epetra_LocalMap reference counting" << endl;
	ierr = checkLocalMapDataClass(Comm, verbose);
	EPETRA_TEST_ERR(ierr,returnierr);
  if (verbose && ierr==0) cout << "Checked OK\n\n" <<endl;

	// Test output
  if (verbose1) {
    if (verbose) cout << "Test ostream << operator" << endl << flush;
    cout << *SmallMap;
    delete SmallMap;
  }

#ifdef EPETRA_MPI
  MPI_Finalize();
#endif

  return returnierr;
}
Exemple #16
0
int main(int argc, char *argv[])
{
  int ierr = 0, i, j, k;

#ifdef EPETRA_MPI
  MPI_Init(&argc,&argv);
  Epetra_MpiComm Comm( MPI_COMM_WORLD );
#else
  Epetra_SerialComm Comm;
#endif

  bool verbose = false;

  // Check if we should print results to standard out
  if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true;

  if(verbose && Comm.MyPID()==0)
    std::cout << Epetra_Version() << std::endl << std::endl;

  int rank = Comm.MyPID();
  //  char tmp;
  //  if (rank==0) std::cout << "Press any key to continue..."<< std::endl;
  //  if (rank==0) cin >> tmp;
  //  Comm.Barrier();

  Comm.SetTracebackMode(0); // This should shut down any error traceback reporting
  if (verbose) std::cout << Comm << std::endl;

  //  bool verbose1 = verbose;

  // Redefine verbose to only print on PE 0
  if (verbose && rank!=0) verbose = false;

  int N = 20;
  int NRHS = 4;
  double * A = new double[N*N];
  double * A1 = new double[N*N];
  double * X = new double[(N+1)*NRHS];
  double * X1 = new double[(N+1)*NRHS];
  int LDX = N+1;
  int LDX1 = N+1;
  double * B = new double[N*NRHS];
  double * B1 = new double[N*NRHS];
  int LDB = N;
  int LDB1 = N;

  int LDA = N;
  int LDA1 = LDA;
  double OneNorm1;
  bool Upper = false;

  Epetra_SerialSpdDenseSolver solver;
  Epetra_SerialSymDenseMatrix * Matrix;
  for (int kk=0; kk<2; kk++) {
    for (i=1; i<=N; i++) {
      GenerateHilbert(A, LDA, i);
      OneNorm1 = 0.0;
      for (j=1; j<=i; j++) OneNorm1 += 1.0/((double) j); // 1-Norm = 1 + 1/2 + ...+1/n

      if (kk==0) {
	Matrix = new Epetra_SerialSymDenseMatrix(View, A, LDA, i);
	LDA1 = LDA;
      }
      else {
	Matrix = new Epetra_SerialSymDenseMatrix(Copy, A, LDA, i);
	LDA1 = i;
      }
      GenerateHilbert(A1, LDA1, i);
	
      if (kk==1) {
	solver.FactorWithEquilibration(true);
	Matrix->SetUpper();
	Upper = true;
	solver.SolveToRefinedSolution(false);
      }

      for (k=0; k<NRHS; k++)
	for (j=0; j<i; j++) {
	  B[j+k*LDB] = 1.0/((double) (k+3)*(j+3));
	  B1[j+k*LDB1] = B[j+k*LDB1];
	}
      Epetra_SerialDenseMatrix Epetra_B(View, B, LDB, i, NRHS);
      Epetra_SerialDenseMatrix Epetra_X(View, X, LDX, i, NRHS);
      solver.SetMatrix(*Matrix);
      solver.SetVectors(Epetra_X, Epetra_B);

      ierr = check(solver, A1, LDA1,  i, NRHS, OneNorm1, B1, LDB1,  X1, LDX1, Upper, verbose);
      assert (ierr>-1);
      delete Matrix;
      if (ierr!=0) {
	if (verbose) std::cout << "Factorization failed due to bad conditioning.  This is normal if SCOND is small."
			  << std::endl;
	break;
      }
    }
  }

  delete [] A;
  delete [] A1;
  delete [] X;
  delete [] X1;
  delete [] B;
  delete [] B1;

  /////////////////////////////////////////////////////////////////////
  // Now test norms and scaling functions
  /////////////////////////////////////////////////////////////////////

  Epetra_SerialSymDenseMatrix D;
  double ScalarA = 2.0;

  int DM = 10;
  int DN = 10;
  D.Shape(DM);
  for (j=0; j<DN; j++)
    for (i=0; i<DM; i++) D[j][i] = (double) (1+i+j*DM) ;

  //std::cout << D << std::endl;

  double NormInfD_ref = (double)(DM*(DN*(DN+1))/2);
  double NormOneD_ref = NormInfD_ref;

  double NormInfD = D.NormInf();
  double NormOneD = D.NormOne();

  if (verbose) {
    std::cout << " *** Before scaling *** " << std::endl
	 << " Computed one-norm of test matrix = " << NormOneD << std::endl
	 << " Expected one-norm                = " << NormOneD_ref << std::endl
	 << " Computed inf-norm of test matrix = " << NormInfD << std::endl
	 << " Expected inf-norm                = " << NormInfD_ref << std::endl;
  }
  D.Scale(ScalarA); // Scale entire D matrix by this value

  //std::cout << D << std::endl;

  NormInfD = D.NormInf();
  NormOneD = D.NormOne();
  if (verbose) {
    std::cout << " *** After scaling *** " << std::endl
	 << " Computed one-norm of test matrix = " << NormOneD << std::endl
	 << " Expected one-norm                = " << NormOneD_ref*ScalarA << std::endl
	 << " Computed inf-norm of test matrix = " << NormInfD << std::endl
	 << " Expected inf-norm                = " << NormInfD_ref*ScalarA << std::endl;
  }



  /////////////////////////////////////////////////////////////////////
  // Now test for larger system, both correctness and performance.
  /////////////////////////////////////////////////////////////////////


  N = 2000;
  NRHS = 5;
  LDA = N;
  LDB = N;
  LDX = N;

  if (verbose) std::cout << "\n\nComputing factor of an " << N << " x " << N << " SPD matrix...Please wait.\n\n" << std::endl;

  // Define A and X

  A = new double[LDA*N];
  X = new double[LDB*NRHS];

  for (j=0; j<N; j++) {
    for (k=0; k<NRHS; k++) X[j+k*LDX] = 1.0/((double) (j+5+k));
    for (i=0; i<N; i++) {
      if (i==j) A[i+j*LDA] = 100.0 + i;
      else A[i+j*LDA] = -1.0/((double) (i+10)*(j+10));
    }
  }

  // Define Epetra_SerialDenseMatrix object

  Epetra_SerialSymDenseMatrix BigMatrix(Copy, A, LDA, N);
  Epetra_SerialSymDenseMatrix OrigBigMatrix(View, A, LDA, N);

  Epetra_SerialSpdDenseSolver BigSolver;
  BigSolver.FactorWithEquilibration(true);
  BigSolver.SetMatrix(BigMatrix);

  // Time factorization

  Epetra_Flops counter;
  BigSolver.SetFlopCounter(counter);
  Epetra_Time Timer(Comm);
  double tstart = Timer.ElapsedTime();
  ierr = BigSolver.Factor();
  if (ierr!=0 && verbose) std::cout << "Error in factorization = "<<ierr<< std::endl;
  assert(ierr==0);
  double time = Timer.ElapsedTime() - tstart;

  double FLOPS = counter.Flops();
  double MFLOPS = FLOPS/time/1000000.0;
  if (verbose) std::cout << "MFLOPS for Factorization = " << MFLOPS << std::endl;

  // Define Left hand side and right hand side
  Epetra_SerialDenseMatrix LHS(View, X, LDX, N, NRHS);
  Epetra_SerialDenseMatrix RHS;
  RHS.Shape(N,NRHS); // Allocate RHS

  // Compute RHS from A and X

  Epetra_Flops RHS_counter;
  RHS.SetFlopCounter(RHS_counter);
  tstart = Timer.ElapsedTime();
  RHS.Multiply('L', 1.0, OrigBigMatrix, LHS, 0.0); // Symmetric Matrix-multiply
  time = Timer.ElapsedTime() - tstart;

  Epetra_SerialDenseMatrix OrigRHS = RHS;

  FLOPS = RHS_counter.Flops();
  MFLOPS = FLOPS/time/1000000.0;
  if (verbose) std::cout << "MFLOPS to build RHS (NRHS = " << NRHS <<") = " << MFLOPS << std::endl;

  // Set LHS and RHS and solve
  BigSolver.SetVectors(LHS, RHS);

  tstart = Timer.ElapsedTime();
  ierr = BigSolver.Solve();
  if (ierr==1 && verbose) std::cout << "LAPACK guidelines suggest this matrix might benefit from equilibration." << std::endl;
  else if (ierr!=0 && verbose) std::cout << "Error in solve = "<<ierr<< std::endl;
  assert(ierr>=0);
  time = Timer.ElapsedTime() - tstart;

  FLOPS = BigSolver.Flops();
  MFLOPS = FLOPS/time/1000000.0;
  if (verbose) std::cout << "MFLOPS for Solve (NRHS = " << NRHS <<") = " << MFLOPS << std::endl;

  double * resid = new double[NRHS];
  bool OK = Residual(N, NRHS, A, LDA, BigSolver.X(), BigSolver.LDX(),
		     OrigRHS.A(), OrigRHS.LDA(), resid);

  if (verbose) {
    if (!OK) std::cout << "************* Residual do not meet tolerance *************" << std::endl;
    for (i=0; i<NRHS; i++)
      std::cout << "Residual[" << i <<"] = "<< resid[i] << std::endl;
    std::cout  << std::endl;
  }

  // Solve again using the Epetra_SerialDenseVector class for LHS and RHS

  Epetra_SerialDenseVector X2;
  Epetra_SerialDenseVector B2;
  X2.Size(BigMatrix.N());
  B2.Size(BigMatrix.M());
  int length = BigMatrix.N();
  {for (int kk=0; kk<length; kk++) X2[kk] = ((double ) kk)/ ((double) length);} // Define entries of X2

  RHS_counter.ResetFlops();
  B2.SetFlopCounter(RHS_counter);
  tstart = Timer.ElapsedTime();
  B2.Multiply('N', 'N', 1.0, OrigBigMatrix, X2, 0.0); // Define B2 = A*X2
  time = Timer.ElapsedTime() - tstart;

  Epetra_SerialDenseVector OrigB2 = B2;

  FLOPS = RHS_counter.Flops();
  MFLOPS = FLOPS/time/1000000.0;
  if (verbose) std::cout << "MFLOPS to build single RHS = " << MFLOPS << std::endl;

  // Set LHS and RHS and solve
  BigSolver.SetVectors(X2, B2);

  tstart = Timer.ElapsedTime();
  ierr = BigSolver.Solve();
  time = Timer.ElapsedTime() - tstart;
  if (ierr==1 && verbose) std::cout << "LAPACK guidelines suggest this matrix might benefit from equilibration." << std::endl;
  else if (ierr!=0 && verbose) std::cout << "Error in solve = "<<ierr<< std::endl;
  assert(ierr>=0);

  FLOPS = counter.Flops();
  MFLOPS = FLOPS/time/1000000.0;
  if (verbose) std::cout << "MFLOPS to solve single RHS = " << MFLOPS << std::endl;

  OK = Residual(N, 1, A, LDA, BigSolver.X(), BigSolver.LDX(), OrigB2.A(),
		OrigB2.LDA(), resid);

  if (verbose) {
    if (!OK) std::cout << "************* Residual do not meet tolerance *************" << std::endl;
      std::cout << "Residual = "<< resid[0] << std::endl;
  }
  delete [] resid;
  delete [] A;
  delete [] X;

  ///////////////////////////////////////////////////
  // Now test default constructor and index operators
  ///////////////////////////////////////////////////

  N = 5;
  Epetra_SerialSymDenseMatrix C; // Implicit call to default constructor, should not need to call destructor
  C.Shape(5); // Make it 5 by 5
  double * C1 = new double[N*N];
  GenerateHilbert(C1, N, N); // Generate Hilber matrix

  C1[1+2*N] = 1000.0;  // Make matrix nonsymmetric

  // Fill values of C with Hilbert values
  for (i=0; i<N; i++)
    for (j=0; j<N; j++)
      C(i,j) = C1[i+j*N];

  // Test if values are correctly written and read
  for (i=0; i<N; i++)
    for (j=0; j<N; j++) {
      assert(C(i,j) == C1[i+j*N]);
      assert(C(i,j) == C[j][i]);
    }

  if (verbose)
    std::cout << "Default constructor and index operator check OK.  Values of Hilbert matrix = "
	 << std::endl << C << std::endl
	 << "Values should be 1/(i+j+1), except value (1,2) should be 1000" << std::endl;

  delete [] C1;


#ifdef EPETRA_MPI
  MPI_Finalize() ;
#endif

/* end main
*/
return ierr ;
}
int main(int argc, char *argv[])
{
  int ierr = 0, i, forierr = 0;
#ifdef HAVE_MPI

  CT_Epetra_MpiComm_ID_Flex_t Comm;

  // Initialize MPI

  MPI_Init(&argc,&argv);
  int rank; // My process ID

  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  Comm.Epetra_MpiComm = Epetra_MpiComm_Create( MPI_COMM_WORLD );

#else

  int rank = 0;
  CT_Epetra_SerialComm_ID_Flex_t Comm;
  Comm.Epetra_SerialComm = Epetra_SerialComm_Create();

#endif

  bool verbose = false;

  // Check if we should print results to standard out
  if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true;

  int verbose_int = verbose ? 1 : 0;
  Epetra_Comm_Broadcast_Int(Comm.Epetra_Comm, &verbose_int, 1, 0);
  verbose = verbose_int==1 ? true : false;


  //  char tmp;
  //  if (rank==0) cout << "Press any key to continue..."<< endl;
  //  if (rank==0) cin >> tmp;
  //  Epetra_Comm_Barrier(Comm.Epetra_Comm);

//  Epetra_Comm_SetTracebackMode(Comm.Epetra_Comm, 0); // This should shut down any error traceback reporting
  int MyPID = Epetra_Comm_MyPID(Comm.Epetra_Comm);
  int NumProc = Epetra_Comm_NumProc(Comm.Epetra_Comm);

  if(verbose && MyPID==0)
    cout << Epetra_Version() << endl << endl;

  if (verbose) cout << "Processor "<<MyPID<<" of "<< NumProc
		    << " is alive."<<endl;

  // Redefine verbose to only print on PE 0
  if(verbose && rank!=0) 
		verbose = false;

  int NumMyEquations = 10000;
  int NumGlobalEquations = (NumMyEquations * NumProc) + EPETRA_MIN(NumProc,3);
  if(MyPID < 3) 
    NumMyEquations++;

  // Construct a Map that puts approximately the same Number of equations on each processor

  CT_Epetra_Map_ID_Flex_t Map;
  Map.Epetra_Map = Epetra_Map_Create_Linear(NumGlobalEquations, NumMyEquations, 0, Comm.Epetra_Comm);
  
  // Get update list and number of local equations from newly created Map
  vector<int> MyGlobalElements(Epetra_BlockMap_NumMyElements(Map.Epetra_BlockMap));
  Epetra_BlockMap_MyGlobalElements_Fill(Map.Epetra_BlockMap, &MyGlobalElements[0]);

  // Create an integer vector NumNz that is used to build the Petra Matrix.
  // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation on this processor

  vector<int> NumNz(NumMyEquations);

  // We are building a tridiagonal matrix where each row has (-1 2 -1)
  // So we need 2 off-diagonal terms (except for the first and last equation)

  for(i = 0; i < NumMyEquations; i++)
    if((MyGlobalElements[i] == 0) || (MyGlobalElements[i] == NumGlobalEquations - 1))
      NumNz[i] = 1;
    else
      NumNz[i] = 2;

  // Create a Epetra_Matrix

  CT_Epetra_CrsMatrix_ID_Flex_t A;
  A.Epetra_CrsMatrix = Epetra_CrsMatrix_Create_VarPerRow(
      CT_Epetra_DataAccess_E_Copy, Map.Epetra_Map, &NumNz[0], FALSE);
  EPETRA_TEST_ERR(Epetra_CrsMatrix_IndicesAreGlobal(A.Epetra_CrsMatrix),ierr);
  EPETRA_TEST_ERR(Epetra_CrsMatrix_IndicesAreLocal(A.Epetra_CrsMatrix),ierr);
  
  // Add  rows one-at-a-time
  // Need some vectors to help
  // Off diagonal Values will always be -1


  vector<double> Values(2);
  Values[0] = -1.0; 
	Values[1] = -1.0;
	vector<int> Indices(2);
  double two = 2.0;
  int NumEntries;

  forierr = 0;
  for(i = 0; i < NumMyEquations; i++) {
    if(MyGlobalElements[i] == 0) {
			Indices[0] = 1;
			NumEntries = 1;
		}
    else if (MyGlobalElements[i] == NumGlobalEquations-1) {
			Indices[0] = NumGlobalEquations-2;
			NumEntries = 1;
		}
    else {
			Indices[0] = MyGlobalElements[i]-1;
			Indices[1] = MyGlobalElements[i]+1;
			NumEntries = 2;
		}
		forierr += !(Epetra_CrsMatrix_InsertGlobalValues(A.Epetra_CrsMatrix,
                             MyGlobalElements[i], NumEntries, &Values[0], &Indices[0])==0);
		forierr += !(Epetra_CrsMatrix_InsertGlobalValues(A.Epetra_CrsMatrix,
                             MyGlobalElements[i], 1, &two, &MyGlobalElements[i])>0); // Put in the diagonal entry
  }
  EPETRA_TEST_ERR(forierr,ierr);

  // Finish up
  Epetra_CrsMatrix_FillComplete(A.Epetra_CrsMatrix, TRUE);
  Epetra_CrsMatrix_OptimizeStorage(A.Epetra_CrsMatrix);

  CT_Epetra_JadMatrix_ID_Flex_t JadA, JadA1, JadA2;
  JadA.Epetra_JadMatrix = Epetra_JadMatrix_Create(A.Epetra_RowMatrix);
  JadA1.Epetra_JadMatrix = Epetra_JadMatrix_Create(A.Epetra_RowMatrix);
  JadA2.Epetra_JadMatrix = Epetra_JadMatrix_Create(A.Epetra_RowMatrix);

  // Create vectors for Power method

  CT_Epetra_Vector_ID_Flex_t q, z, resid;
  q.Epetra_Vector = Epetra_Vector_Create(Map.Epetra_BlockMap, TRUE);
  z.Epetra_Vector = Epetra_Vector_Create(Map.Epetra_BlockMap, TRUE);
  Epetra_MultiVector_Random(z.Epetra_MultiVector);
  resid.Epetra_Vector = Epetra_Vector_Create(Map.Epetra_BlockMap, TRUE);

  CT_Epetra_Flops_ID_t flopcounter = Epetra_Flops_Create();
  Epetra_CompObject_SetFlopCounter(A.Epetra_CompObject, flopcounter);

  Epetra_CompObject_SetFlopCounter_Matching(q.Epetra_CompObject, A.Epetra_CompObject);
  Epetra_CompObject_SetFlopCounter_Matching(z.Epetra_CompObject, A.Epetra_CompObject);
  Epetra_CompObject_SetFlopCounter_Matching(resid.Epetra_CompObject, A.Epetra_CompObject);

  Epetra_CompObject_SetFlopCounter_Matching(JadA.Epetra_CompObject, A.Epetra_CompObject);
  Epetra_CompObject_SetFlopCounter_Matching(JadA1.Epetra_CompObject, A.Epetra_CompObject);
  Epetra_CompObject_SetFlopCounter_Matching(JadA2.Epetra_CompObject, A.Epetra_CompObject);
  

  if (verbose) cout << "=======================================" << endl
		    << "Testing Jad using CrsMatrix as input..." << endl
		    << "=======================================" << endl;

  Epetra_CompObject_ResetFlops(A.Epetra_CompObject);
  powerMethodTests(A.Epetra_RowMatrix, JadA.Epetra_RowMatrix, Map, q, z, resid, verbose);

  // Increase diagonal dominance

  if (verbose) cout << "\n\nIncreasing the magnitude of first diagonal term and solving again\n\n"
		    << endl;

  
  if (Epetra_CrsMatrix_MyGlobalRow(A.Epetra_CrsMatrix, 0)) {
    int numvals = Epetra_CrsMatrix_NumGlobalEntries(A.Epetra_CrsMatrix, 0);
    vector<double> Rowvals(numvals);
    vector<int> Rowinds(numvals);
    Epetra_CrsMatrix_ExtractGlobalRowCopy_WithIndices(A.Epetra_CrsMatrix, 0,
        numvals, &numvals, &Rowvals[0], &Rowinds[0]); // Get A[0,0]

    for (i=0; i<numvals; i++) if (Rowinds[i] == 0) Rowvals[i] *= 10.0;
    
    Epetra_CrsMatrix_ReplaceGlobalValues(A.Epetra_CrsMatrix, 0, numvals, &Rowvals[0], &Rowinds[0]);
  }
  Epetra_JadMatrix_UpdateValues(JadA.Epetra_JadMatrix, A.Epetra_RowMatrix, FALSE);
  Epetra_CompObject_ResetFlops(A.Epetra_CompObject);
  powerMethodTests(A.Epetra_RowMatrix, JadA.Epetra_RowMatrix, Map, q, z, resid, verbose);

  if (verbose) cout << "================================================================" << endl
		          << "Testing Jad using Jad matrix as input matrix for construction..." << endl
		          << "================================================================" << endl;
  Epetra_CompObject_ResetFlops(JadA1.Epetra_CompObject);
  powerMethodTests(JadA1.Epetra_RowMatrix, JadA2.Epetra_RowMatrix, Map, q, z, resid, verbose);

#ifdef HAVE_MPI
  MPI_Finalize() ;
#endif

return ierr ;
}
Exemple #18
0
int main(int argc, char *argv[])
{
  int ierr = 0;

#ifdef EPETRA_MPI

  // Initialize MPI

  MPI_Init(&argc,&argv);
  int rank; // My process ID

  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  Epetra_MpiComm Comm( MPI_COMM_WORLD );

#else

  int rank = 0;
  Epetra_SerialComm Comm;

#endif

  bool verbose = false;

  // Check if we should print results to standard out
  if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true;

  int verbose_int = verbose ? 1 : 0;
  Comm.Broadcast(&verbose_int, 1, 0);
  verbose = verbose_int==1 ? true : false;


  //  char tmp;
  //  if (rank==0) cout << "Press any key to continue..."<< std::endl;
  //  if (rank==0) cin >> tmp;
  //  Comm.Barrier();

  Comm.SetTracebackMode(0); // This should shut down any error traceback reporting
  int MyPID = Comm.MyPID();
  int NumProc = Comm.NumProc();

  if(verbose && MyPID==0)
    cout << Epetra_Version() << std::endl << std::endl;

  if (verbose) cout << "Processor "<<MyPID<<" of "<< NumProc
                    << " is alive."<<endl;

  //bool verbose1 = verbose; // unused

  // Redefine verbose to only print on PE 0
  if(verbose && rank!=0) verbose = false;

  int NumMyEquations = 1;
  long long NumGlobalEquations = NumProc;

  // Get update list and number of local equations from newly created Map
  long long* MyGlobalElementsLL = new long long[NumMyEquations];

  MyGlobalElementsLL[0] = 2000000000+MyPID;

  // Construct a Map that puts approximately the same Number of equations on each processor

  Epetra_Map MapLL(NumGlobalEquations, NumMyEquations, MyGlobalElementsLL, 0, Comm);

  EPETRA_TEST_ERR(MapLL.GlobalIndicesInt(),ierr);
  EPETRA_TEST_ERR(!(MapLL.GlobalIndicesLongLong()),ierr);

  // Create an integer vector NumNz that is used to build the Petra Matrix.
  // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation on this processor

  int* NumNzLL = new int[NumMyEquations];
  NumNzLL[0] = 0;

  // Create int types meant to add to long long matrix for test of failure
  int* MyIntGlobalElementsLL = new int[NumMyEquations];
  MyIntGlobalElementsLL[0] = 20000+MyPID;

  // Create a long long Epetra_Matrix
  Epetra_CrsMatrix A_LL(Copy, MapLL, NumNzLL);
  EPETRA_TEST_ERR(A_LL.IndicesAreGlobal(),ierr);
  EPETRA_TEST_ERR(A_LL.IndicesAreLocal(),ierr);

  // Insert values
  double one = 1.0;
#ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
  // Try to add ints which should fail and be caught as an int
  try {
    A_LL.InsertGlobalValues(MyIntGlobalElementsLL[0], 1, &one, MyIntGlobalElementsLL+0);
  } catch(int i) {
    EPETRA_TEST_ERR(!(i==-1),ierr);
  }
#endif

  // Add long longs which should succeed
  EPETRA_TEST_ERR(!(A_LL.InsertGlobalValues(MyGlobalElementsLL[0], 1, &one, MyGlobalElementsLL+0)==0),ierr);
  EPETRA_TEST_ERR(!(A_LL.IndicesAreGlobal()),ierr);
  EPETRA_TEST_ERR(!(A_LL.FillComplete(false)==0),ierr);
  EPETRA_TEST_ERR(!(A_LL.IndicesAreLocal()),ierr);


  // Get update list and number of local equations from newly created Map
  int* MyGlobalElementsInt = new int[NumMyEquations];

  MyGlobalElementsInt[0] = 2000+MyPID;

  // Create an integer vector NumNz that is used to build the Petra Matrix.
  // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation on this processor

  int* NumNzInt = new int[NumMyEquations];
  NumNzInt[0] = 0;

  // Create int types meant to add to long long matrix for test of failure
  long long* MyLLGlobalElementsInt = new long long[NumMyEquations];
  MyLLGlobalElementsInt[0] = 2000000000+MyPID;

#ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
  // Construct a Map that puts approximately the same Number of equations on each processor

  Epetra_Map MapInt(NumGlobalEquations, NumMyEquations, MyGlobalElementsInt, 0LL, Comm);

  EPETRA_TEST_ERR(!(MapInt.GlobalIndicesInt()),ierr);
  EPETRA_TEST_ERR(MapInt.GlobalIndicesLongLong(),ierr);

  // Create a int Epetra_Matrix
  Epetra_CrsMatrix A_Int(Copy, MapInt, NumNzInt);
  EPETRA_TEST_ERR(A_Int.IndicesAreGlobal(),ierr);
  EPETRA_TEST_ERR(A_Int.IndicesAreLocal(),ierr);

  // Insert values
  try {
    A_Int.InsertGlobalValues(MyLLGlobalElementsInt[0], 1, &one, MyLLGlobalElementsInt+0);
  } catch(int i) {
    EPETRA_TEST_ERR(!(i==-1),ierr);
  }
  // Add long longs which should succeed
  EPETRA_TEST_ERR(!(A_Int.InsertGlobalValues(MyGlobalElementsInt[0], 1, &one, MyGlobalElementsInt+0)==0),ierr);
  EPETRA_TEST_ERR(!(A_Int.IndicesAreGlobal()),ierr);
  EPETRA_TEST_ERR(!(A_Int.FillComplete(false)==0),ierr);
  EPETRA_TEST_ERR(!(A_Int.IndicesAreLocal()),ierr);
#endif

  delete [] MyGlobalElementsLL;
  delete [] NumNzLL;
  delete [] MyIntGlobalElementsLL;
  delete [] MyGlobalElementsInt;
  delete [] NumNzInt;
  delete [] MyLLGlobalElementsInt;

#ifdef EPETRA_MPI
  MPI_Finalize() ;
#endif

/* end main
*/
return ierr ;
}
Exemple #19
0
int main(int argc, char *argv[])
{
  int ierr = 0, i, forierr = 0;
#ifdef EPETRA_MPI

  // Initialize MPI

  MPI_Init(&argc,&argv);
  int rank; // My process ID

  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  Epetra_MpiComm Comm( MPI_COMM_WORLD );

#else

  int rank = 0;
  Epetra_SerialComm Comm;

#endif

  bool verbose = false;

  // Check if we should print results to standard out
  if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true;

  int verbose_int = verbose ? 1 : 0;
  Comm.Broadcast(&verbose_int, 1, 0);
  verbose = verbose_int==1 ? true : false;


  //  char tmp;
  //  if (rank==0) cout << "Press any key to continue..."<< endl;
  //  if (rank==0) cin >> tmp;
  //  Comm.Barrier();

  Comm.SetTracebackMode(0); // This should shut down any error traceback reporting
  int MyPID = Comm.MyPID();
  int NumProc = Comm.NumProc();

  if(verbose && MyPID==0)
    cout << Epetra_Version() << endl << endl;

  if (verbose) cout << "Processor "<<MyPID<<" of "<< NumProc
		    << " is alive."<<endl;

  // Redefine verbose to only print on PE 0
  if(verbose && rank!=0)
		verbose = false;

  int NumMyEquations = 10000;
  long long NumGlobalEquations = (NumMyEquations * NumProc) + EPETRA_MIN(NumProc,3);
  if(MyPID < 3)
    NumMyEquations++;

  // Construct a Map that puts approximately the same Number of equations on each processor

  Epetra_Map Map(NumGlobalEquations, NumMyEquations, 0LL, Comm);

  // Get update list and number of local equations from newly created Map
  vector<long long> MyGlobalElements(Map.NumMyElements());
  Map.MyGlobalElements(&MyGlobalElements[0]);

  // Create an integer vector NumNz that is used to build the Petra Matrix.
  // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation on this processor

  vector<int> NumNz(NumMyEquations);

  // We are building a tridiagonal matrix where each row has (-1 2 -1)
  // So we need 2 off-diagonal terms (except for the first and last equation)

  for(i = 0; i < NumMyEquations; i++)
    if((MyGlobalElements[i] == 0) || (MyGlobalElements[i] == NumGlobalEquations - 1))
      NumNz[i] = 1;
    else
      NumNz[i] = 2;

  // Create a Epetra_Matrix

  Epetra_CrsMatrix A(Copy, Map, &NumNz[0]);
  EPETRA_TEST_ERR(A.IndicesAreGlobal(),ierr);
  EPETRA_TEST_ERR(A.IndicesAreLocal(),ierr);

  // Add  rows one-at-a-time
  // Need some vectors to help
  // Off diagonal Values will always be -1


  vector<double> Values(2);
  Values[0] = -1.0;
	Values[1] = -1.0;
	vector<long long> Indices(2);
  double two = 2.0;
  int NumEntries;

  forierr = 0;
  for(i = 0; i < NumMyEquations; i++) {
    if(MyGlobalElements[i] == 0) {
			Indices[0] = 1;
			NumEntries = 1;
		}
    else if (MyGlobalElements[i] == NumGlobalEquations-1) {
			Indices[0] = NumGlobalEquations-2;
			NumEntries = 1;
		}
    else {
			Indices[0] = MyGlobalElements[i]-1;
			Indices[1] = MyGlobalElements[i]+1;
			NumEntries = 2;
		}
		forierr += !(A.InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0])==0);
		forierr += !(A.InsertGlobalValues(MyGlobalElements[i], 1, &two, &MyGlobalElements[i])>0); // Put in the diagonal entry
  }
  EPETRA_TEST_ERR(forierr,ierr);

  // Finish up
  A.FillComplete();
  A.OptimizeStorage();

  Epetra_JadMatrix JadA(A);
  Epetra_JadMatrix JadA1(A);
  Epetra_JadMatrix JadA2(A);

  // Create vectors for Power method

  Epetra_Vector q(Map);
  Epetra_Vector z(Map); z.Random();
  Epetra_Vector resid(Map);

  Epetra_Flops flopcounter;
  A.SetFlopCounter(flopcounter);
  q.SetFlopCounter(A);
  z.SetFlopCounter(A);
  resid.SetFlopCounter(A);
  JadA.SetFlopCounter(A);
  JadA1.SetFlopCounter(A);
  JadA2.SetFlopCounter(A);


  if (verbose) cout << "=======================================" << endl
		    << "Testing Jad using CrsMatrix as input..." << endl
		    << "=======================================" << endl;

  A.ResetFlops();
  powerMethodTests(A, JadA, Map, q, z, resid, verbose);

  // Increase diagonal dominance

  if (verbose) cout << "\n\nIncreasing the magnitude of first diagonal term and solving again\n\n"
		    << endl;


  if (A.MyGlobalRow(0)) {
    int numvals = A.NumGlobalEntries(0);
    vector<double> Rowvals(numvals);
    vector<long long> Rowinds(numvals);
    A.ExtractGlobalRowCopy(0, numvals, numvals, &Rowvals[0], &Rowinds[0]); // Get A[0,0]

    for (i=0; i<numvals; i++) if (Rowinds[i] == 0) Rowvals[i] *= 10.0;

    A.ReplaceGlobalValues(0, numvals, &Rowvals[0], &Rowinds[0]);
  }
  JadA.UpdateValues(A);
  A.ResetFlops();
  powerMethodTests(A, JadA, Map, q, z, resid, verbose);

  if (verbose) cout << "================================================================" << endl
		          << "Testing Jad using Jad matrix as input matrix for construction..." << endl
		          << "================================================================" << endl;
  JadA1.ResetFlops();
  powerMethodTests(JadA1, JadA2, Map, q, z, resid, verbose);

#ifdef EPETRA_MPI
  MPI_Finalize() ;
#endif

return ierr ;
}
Exemple #20
0
int main(int argc, char *argv[])
{
  int ierr = 0;
  double elapsed_time;
  double total_flops;
  double MFLOPs;


#ifdef EPETRA_MPI

  // Initialize MPI
  MPI_Init(&argc,&argv);
  Epetra_MpiComm comm( MPI_COMM_WORLD );
#else
  Epetra_SerialComm comm;
#endif

  bool verbose = false;
  bool summary = false;

  // Check if we should print verbose results to standard out
  if (argc>6) if (argv[6][0]=='-' && argv[6][1]=='v') verbose = true;

  // Check if we should print verbose results to standard out
  if (argc>6) if (argv[6][0]=='-' && argv[6][1]=='s') summary = true;

  if(argc < 6) {
    cerr << "Usage: " << argv[0]
         << " NumNodesX NumNodesY NumProcX NumProcY NumPoints [-v|-s]" << endl
         << "where:" << endl
         << "NumNodesX         - Number of mesh nodes in X direction per processor" << endl
         << "NumNodesY         - Number of mesh nodes in Y direction per processor" << endl
         << "NumProcX          - Number of processors to use in X direction" << endl
         << "NumProcY          - Number of processors to use in Y direction" << endl
         << "NumPoints         - Number of points to use in stencil (5, 9 or 25 only)" << endl
         << "-v|-s             - (Optional) Run in verbose mode if -v present or summary mode if -s present" << endl
         << " NOTES: NumProcX*NumProcY must equal the number of processors used to run the problem." << endl << endl
	 << " Serial example:" << endl
         << argv[0] << " 16 12 1 1 25 -v" << endl
	 << " Run this program in verbose mode on 1 processor using a 16 X 12 grid with a 25 point stencil."<< endl <<endl
	 << " MPI example:" << endl
         << "mpirun -np 32 " << argv[0] << " 10 12 4 8 9 -v" << endl
	 << " Run this program in verbose mode on 32 processors putting a 10 X 12 subgrid on each processor using 4 processors "<< endl
	 << " in the X direction and 8 in the Y direction.  Total grid size is 40 points in X and 96 in Y with a 9 point stencil."<< endl
         << endl;
    return(1);

  }
    //char tmp;
    //if (comm.MyPID()==0) cout << "Press any key to continue..."<< endl;
    //if (comm.MyPID()==0) cin >> tmp;
    //comm.Barrier();

  comm.SetTracebackMode(0); // This should shut down any error traceback reporting
  if (verbose && comm.MyPID()==0)
    cout << Epetra_Version() << endl << endl;
  if (summary && comm.MyPID()==0) {
    if (comm.NumProc()==1)
      cout << Epetra_Version() << endl << endl;
    else
      cout << endl << endl; // Print two blank line to keep output columns lined up
  }

  if (verbose) cout << comm <<endl;


  // Redefine verbose to only print on PE 0

  if (verbose && comm.MyPID()!=0) verbose = false;
  if (summary && comm.MyPID()!=0) summary = false;

  int numNodesX = atoi(argv[1]);
  int numNodesY = atoi(argv[2]);
  int numProcsX = atoi(argv[3]);
  int numProcsY = atoi(argv[4]);
  int numPoints = atoi(argv[5]);

  if (verbose || (summary && comm.NumProc()==1)) {
    cout << " Number of local nodes in X direction  = " << numNodesX << endl
	 << " Number of local nodes in Y direction  = " << numNodesY << endl
	 << " Number of global nodes in X direction = " << numNodesX*numProcsX << endl
	 << " Number of global nodes in Y direction = " << numNodesY*numProcsY << endl
	 << " Number of local nonzero entries       = " << numNodesX*numNodesY*numPoints << endl
	 << " Number of global nonzero entries      = " << numNodesX*numNodesY*numPoints*numProcsX*numProcsY << endl
	 << " Number of Processors in X direction   = " << numProcsX << endl
	 << " Number of Processors in Y direction   = " << numProcsY << endl
	 << " Number of Points in stencil           = " << numPoints << endl << endl;
  }
  // Print blank line to keep output columns lined up
  if (summary && comm.NumProc()>1)
    cout << endl << endl << endl << endl << endl << endl << endl << endl<< endl << endl;

  if (numProcsX*numProcsY!=comm.NumProc()) {
    cerr << "Number of processors = " << comm.NumProc() << endl
	 << " is not the product of " << numProcsX << " and " << numProcsY << endl << endl;
    return(1);
  }

  if (numPoints!=5 && numPoints!=9 && numPoints!=25) {
    cerr << "Number of points specified = " << numPoints << endl
	 << " is not 5, 9, 25" << endl << endl;
    return(1);
  }

  if (numNodesX*numNodesY<=0) {
    cerr << "Product of number of nodes is <= zero" << endl << endl;
    return(1);
  }

  Epetra_IntSerialDenseVector Xoff, XLoff, XUoff;
  Epetra_IntSerialDenseVector Yoff, YLoff, YUoff;
  if (numPoints==5) {

     // Generate a 5-point 2D Finite Difference matrix
    Xoff.Size(5);
    Yoff.Size(5);
    Xoff[0] = -1; Xoff[1] = 1; Xoff[2] = 0; Xoff[3] = 0;  Xoff[4] = 0;
    Yoff[0] = 0;  Yoff[1] = 0; Yoff[2] = 0; Yoff[3] = -1; Yoff[4] = 1;

     // Generate a 2-point 2D Lower triangular Finite Difference matrix
    XLoff.Size(2);
    YLoff.Size(2);
    XLoff[0] = -1; XLoff[1] =  0;
    YLoff[0] =  0; YLoff[1] = -1;

     // Generate a 3-point 2D upper triangular Finite Difference matrix
    XUoff.Size(3);
    YUoff.Size(3);
    XUoff[0] =  0; XUoff[1] =  1; XUoff[2] = 0;
    YUoff[0] =  0; YUoff[1] =  0; YUoff[2] = 1;
  }
  else if (numPoints==9) {
    // Generate a 9-point 2D Finite Difference matrix
    Xoff.Size(9);
    Yoff.Size(9);
    Xoff[0] = -1;  Xoff[1] =  0; Xoff[2] =  1;
    Yoff[0] = -1;  Yoff[1] = -1; Yoff[2] = -1;
    Xoff[3] = -1;  Xoff[4] =  0; Xoff[5] =  1;
    Yoff[3] =  0;  Yoff[4] =  0; Yoff[5] =  0;
    Xoff[6] = -1;  Xoff[7] =  0; Xoff[8] =  1;
    Yoff[6] =  1;  Yoff[7] =  1; Yoff[8] =  1;

    // Generate a 5-point lower triangular 2D Finite Difference matrix
    XLoff.Size(5);
    YLoff.Size(5);
    XLoff[0] = -1;  XLoff[1] =  0; Xoff[2] =  1;
    YLoff[0] = -1;  YLoff[1] = -1; Yoff[2] = -1;
    XLoff[3] = -1;  XLoff[4] =  0;
    YLoff[3] =  0;  YLoff[4] =  0;

    // Generate a 4-point upper triangular 2D Finite Difference matrix
    XUoff.Size(4);
    YUoff.Size(4);
    XUoff[0] =  1;
    YUoff[0] =  0;
    XUoff[1] = -1;  XUoff[2] =  0; XUoff[3] =  1;
    YUoff[1] =  1;  YUoff[2] =  1; YUoff[3] =  1;

  }
  else {
    // Generate a 25-point 2D Finite Difference matrix
    Xoff.Size(25);
    Yoff.Size(25);
    int xi = 0, yi = 0;
    int xo = -2, yo = -2;
    Xoff[xi++] = xo++;  Xoff[xi++] = xo++; Xoff[xi++] = xo++; Xoff[xi++] = xo++; Xoff[xi++] = xo++;
    Yoff[yi++] = yo  ;  Yoff[yi++] = yo  ; Yoff[yi++] = yo  ; Yoff[yi++] = yo  ; Yoff[yi++] = yo  ;
    xo = -2, yo++;
    Xoff[xi++] = xo++;  Xoff[xi++] = xo++; Xoff[xi++] = xo++; Xoff[xi++] = xo++; Xoff[xi++] = xo++;
    Yoff[yi++] = yo  ;  Yoff[yi++] = yo  ; Yoff[yi++] = yo  ; Yoff[yi++] = yo  ; Yoff[yi++] = yo  ;
    xo = -2, yo++;
    Xoff[xi++] = xo++;  Xoff[xi++] = xo++; Xoff[xi++] = xo++; Xoff[xi++] = xo++; Xoff[xi++] = xo++;
    Yoff[yi++] = yo  ;  Yoff[yi++] = yo  ; Yoff[yi++] = yo  ; Yoff[yi++] = yo  ; Yoff[yi++] = yo  ;
    xo = -2, yo++;
    Xoff[xi++] = xo++;  Xoff[xi++] = xo++; Xoff[xi++] = xo++; Xoff[xi++] = xo++; Xoff[xi++] = xo++;
    Yoff[yi++] = yo  ;  Yoff[yi++] = yo  ; Yoff[yi++] = yo  ; Yoff[yi++] = yo  ; Yoff[yi++] = yo  ;
    xo = -2, yo++;
    Xoff[xi++] = xo++;  Xoff[xi++] = xo++; Xoff[xi++] = xo++; Xoff[xi++] = xo++; Xoff[xi++] = xo++;
    Yoff[yi++] = yo  ;  Yoff[yi++] = yo  ; Yoff[yi++] = yo  ; Yoff[yi++] = yo  ; Yoff[yi++] = yo  ;

    // Generate a 13-point lower triangular 2D Finite Difference matrix
    XLoff.Size(13);
    YLoff.Size(13);
    xi = 0, yi = 0;
    xo = -2, yo = -2;
    XLoff[xi++] = xo++;  XLoff[xi++] = xo++; XLoff[xi++] = xo++; XLoff[xi++] = xo++; XLoff[xi++] = xo++;
    YLoff[yi++] = yo  ;  YLoff[yi++] = yo  ; YLoff[yi++] = yo  ; YLoff[yi++] = yo  ; YLoff[yi++] = yo  ;
    xo = -2, yo++;
    XLoff[xi++] = xo++;  XLoff[xi++] = xo++; XLoff[xi++] = xo++; XLoff[xi++] = xo++; XLoff[xi++] = xo++;
    YLoff[yi++] = yo  ;  YLoff[yi++] = yo  ; YLoff[yi++] = yo  ; YLoff[yi++] = yo  ; YLoff[yi++] = yo  ;
    xo = -2, yo++;
    XLoff[xi++] = xo++;  XLoff[xi++] = xo++; XLoff[xi++] = xo++;
    YLoff[yi++] = yo  ;  YLoff[yi++] = yo  ; YLoff[yi++] = yo  ;

    // Generate a 13-point upper triangular 2D Finite Difference matrix
    XUoff.Size(13);
    YUoff.Size(13);
    xi = 0, yi = 0;
    xo = 0, yo = 0;
    XUoff[xi++] = xo++;  XUoff[xi++] = xo++; XUoff[xi++] = xo++;
    YUoff[yi++] = yo  ;  YUoff[yi++] = yo  ; YUoff[yi++] = yo  ;
    xo = -2, yo++;
    XUoff[xi++] = xo++;  XUoff[xi++] = xo++; XUoff[xi++] = xo++; XUoff[xi++] = xo++; XUoff[xi++] = xo++;
    YUoff[yi++] = yo  ;  YUoff[yi++] = yo  ; YUoff[yi++] = yo  ; YUoff[yi++] = yo  ; YUoff[yi++] = yo  ;
    xo = -2, yo++;
    XUoff[xi++] = xo++;  XUoff[xi++] = xo++; XUoff[xi++] = xo++; XUoff[xi++] = xo++; XUoff[xi++] = xo++;
    YUoff[yi++] = yo  ;  YUoff[yi++] = yo  ; YUoff[yi++] = yo  ; YUoff[yi++] = yo  ; YUoff[yi++] = yo  ;

  }

  Epetra_Map * map;
  Epetra_Map * mapL;
  Epetra_Map * mapU;
  Epetra_CrsMatrix * A;
  Epetra_CrsMatrix * L;
  Epetra_CrsMatrix * U;
  Epetra_MultiVector * b;
  Epetra_MultiVector * bt;
  Epetra_MultiVector * xexact;
  Epetra_MultiVector * bL;
  Epetra_MultiVector * btL;
  Epetra_MultiVector * xexactL;
  Epetra_MultiVector * bU;
  Epetra_MultiVector * btU;
  Epetra_MultiVector * xexactU;
  Epetra_SerialDenseVector resvec(0);

  //Timings
  Epetra_Flops flopcounter;
  Epetra_Time timer(comm);

#ifdef EPETRA_VERY_SHORT_PERFTEST
  int jstop = 1;
#elif EPETRA_SHORT_PERFTEST
  int jstop = 1;
#else
  int jstop = 2;
#endif
  for (int j=0; j<jstop; j++) {
    for (int k=1; k<17; k++) {
#ifdef EPETRA_VERY_SHORT_PERFTEST
      if (k<3 || (k%4==0 && k<9)) {
#elif EPETRA_SHORT_PERFTEST
      if (k<6 || k%4==0) {
#else
      if (k<7 || k%2==0) {
#endif
      int nrhs=k;
      if (verbose) cout << "\n*************** Results for " << nrhs << " RHS with ";

      bool StaticProfile = (j!=0);
      if (verbose) {
        if (StaticProfile) cout << " static profile\n";
        else cout << " dynamic profile\n";
      }
      GenerateCrsProblem(numNodesX, numNodesY, numProcsX, numProcsY, numPoints,
			 Xoff.Values(), Yoff.Values(), nrhs, comm, verbose, summary,
			 map, A, b, bt, xexact, StaticProfile, false);


#ifdef EPETRA_HAVE_JADMATRIX

      timer.ResetStartTime();
      Epetra_JadMatrix JA(*A);
      elapsed_time = timer.ElapsedTime();
      if (verbose) cout << "Time to create Jagged diagonal matrix = " << elapsed_time << endl;

      //cout << "A = " << *A << endl;
      //cout << "JA = " << JA << endl;

      runJadMatrixTests(&JA, b, bt, xexact, StaticProfile, verbose, summary);

#endif
      runMatrixTests(A, b, bt, xexact, StaticProfile, verbose, summary);

      delete A;
      delete b;
      delete bt;
      delete xexact;

      GenerateCrsProblem(numNodesX, numNodesY, numProcsX, numProcsY, XLoff.Length(),
			 XLoff.Values(), YLoff.Values(), nrhs, comm, verbose, summary,
			 mapL, L, bL, btL, xexactL, StaticProfile, true);


      GenerateCrsProblem(numNodesX, numNodesY, numProcsX, numProcsY, XUoff.Length(),
			 XUoff.Values(), YUoff.Values(), nrhs, comm, verbose, summary,
			 mapU, U, bU, btU, xexactU, StaticProfile, true);


      runLUMatrixTests(L, bL, btL, xexactL, U, bU, btU, xexactU, StaticProfile, verbose, summary);

      delete L;
      delete bL;
      delete btL;
      delete xexactL;
      delete mapL;

      delete U;
      delete bU;
      delete btU;
      delete xexactU;
      delete mapU;

      Epetra_MultiVector q(*map, nrhs);
      Epetra_MultiVector z(q);
      Epetra_MultiVector r(q);

      delete map;
      q.SetFlopCounter(flopcounter);
      z.SetFlopCounter(q);
      r.SetFlopCounter(q);

      resvec.Resize(nrhs);


      flopcounter.ResetFlops();
      timer.ResetStartTime();

      //10 norms
      for( int i = 0; i < 10; ++i )
	q.Norm2( resvec.Values() );

      elapsed_time = timer.ElapsedTime();
      total_flops = q.Flops();
      MFLOPs = total_flops/elapsed_time/1000000.0;
      if (verbose) cout << "\nTotal MFLOPs for 10 Norm2's= " << MFLOPs << endl;

      if (summary) {
	if (comm.NumProc()==1) cout << "Norm2" << '\t';
	cout << MFLOPs << endl;
      }

      flopcounter.ResetFlops();
      timer.ResetStartTime();

      //10 dot's
      for( int i = 0; i < 10; ++i )
	q.Dot(z, resvec.Values());

      elapsed_time = timer.ElapsedTime();
      total_flops = q.Flops();
      MFLOPs = total_flops/elapsed_time/1000000.0;
      if (verbose) cout << "Total MFLOPs for 10 Dot's  = " << MFLOPs << endl;

      if (summary) {
	if (comm.NumProc()==1) cout << "DotProd" << '\t';
	cout << MFLOPs << endl;
      }

      flopcounter.ResetFlops();
      timer.ResetStartTime();

      //10 dot's
      for( int i = 0; i < 10; ++i )
	q.Update(1.0, z, 1.0, r, 0.0);

      elapsed_time = timer.ElapsedTime();
      total_flops = q.Flops();
      MFLOPs = total_flops/elapsed_time/1000000.0;
      if (verbose) cout << "Total MFLOPs for 10 Updates= " << MFLOPs << endl;

      if (summary) {
	if (comm.NumProc()==1) cout << "Update" << '\t';
	cout << MFLOPs << endl;
      }
    }
    }
  }
#ifdef EPETRA_MPI
  MPI_Finalize() ;
#endif

return ierr ;
}

// Constructs a 2D PDE finite difference matrix using the list of x and y offsets.
//
// nx      (In) - number of grid points in x direction
// ny      (In) - number of grid points in y direction
//   The total number of equations will be nx*ny ordered such that the x direction changes
//   most rapidly:
//      First equation is at point (0,0)
//      Second at                  (1,0)
//       ...
//      nx equation at             (nx-1,0)
//      nx+1st equation at         (0,1)

// numPoints (In) - number of points in finite difference stencil
// xoff    (In) - stencil offsets in x direction (of length numPoints)
// yoff    (In) - stencil offsets in y direction (of length numPoints)
//   A standard 5-point finite difference stencil would be described as:
//     numPoints = 5
//     xoff = [-1, 1, 0,  0, 0]
//     yoff = [ 0, 0, 0, -1, 1]

// nrhs - Number of rhs to generate. (First interface produces vectors, so nrhs is not needed

// comm    (In) - an Epetra_Comm object describing the parallel machine (numProcs and my proc ID)
// map    (Out) - Epetra_Map describing distribution of matrix and vectors/multivectors
// A      (Out) - Epetra_CrsMatrix constructed for nx by ny grid using prescribed stencil
//                Off-diagonal values are random between 0 and 1.  If diagonal is part of stencil,
//                diagonal will be slightly diag dominant.
// b      (Out) - Generated RHS.  Values satisfy b = A*xexact
// bt     (Out) - Generated RHS.  Values satisfy b = A'*xexact
// xexact (Out) - Generated exact solution to Ax = b and b' = A'xexact

// Note: Caller of this function is responsible for deleting all output objects.

void GenerateCrsProblem(int numNodesX, int numNodesY, int numProcsX, int numProcsY, int numPoints,
			int * xoff, int * yoff,
			const Epetra_Comm  &comm, bool verbose, bool summary,
			Epetra_Map *& map,
			Epetra_CrsMatrix *& A,
			Epetra_Vector *& b,
			Epetra_Vector *& bt,
			Epetra_Vector *&xexact, bool StaticProfile, bool MakeLocalOnly) {

  Epetra_MultiVector * b1, * bt1, * xexact1;
	
  GenerateCrsProblem(numNodesX, numNodesY, numProcsX, numProcsY, numPoints,
		     xoff, yoff, 1, comm, verbose, summary,
		     map, A, b1, bt1, xexact1, StaticProfile, MakeLocalOnly);

  b = dynamic_cast<Epetra_Vector *>(b1);
  bt = dynamic_cast<Epetra_Vector *>(bt1);
  xexact = dynamic_cast<Epetra_Vector *>(xexact1);

  return;
}

void GenerateCrsProblem(int numNodesX, int numNodesY, int numProcsX, int numProcsY, int numPoints,
			int * xoff, int * yoff, int nrhs,
			const Epetra_Comm  &comm, bool verbose, bool summary,
			Epetra_Map *& map,
			Epetra_CrsMatrix *& A,
			Epetra_MultiVector *& b,
			Epetra_MultiVector *& bt,
			Epetra_MultiVector *&xexact, bool StaticProfile, bool MakeLocalOnly) {

  Epetra_Time timer(comm);
  // Determine my global IDs
  long long * myGlobalElements;
  GenerateMyGlobalElements(numNodesX, numNodesY, numProcsX, numProcsY, comm.MyPID(), myGlobalElements);

  int numMyEquations = numNodesX*numNodesY;

  map = new Epetra_Map((long long)-1, numMyEquations, myGlobalElements, 0, comm); // Create map with 2D block partitioning.
  delete [] myGlobalElements;

  long long numGlobalEquations = map->NumGlobalElements64();

  int profile = 0; if (StaticProfile) profile = numPoints;

#ifdef EPETRA_HAVE_STATICPROFILE

  if (MakeLocalOnly)
    A = new Epetra_CrsMatrix(Copy, *map, *map, profile, StaticProfile); // Construct matrix with rowmap=colmap
  else
    A = new Epetra_CrsMatrix(Copy, *map, profile, StaticProfile); // Construct matrix

#else

  if (MakeLocalOnly)
    A = new Epetra_CrsMatrix(Copy, *map, *map, profile); // Construct matrix with rowmap=colmap
  else
    A = new Epetra_CrsMatrix(Copy, *map, profile); // Construct matrix

#endif

  long long * indices = new long long[numPoints];
  double * values = new double[numPoints];

  double dnumPoints = (double) numPoints;
  int nx = numNodesX*numProcsX;

  for (int i=0; i<numMyEquations; i++) {

    long long rowID = map->GID64(i);
    int numIndices = 0;

    for (int j=0; j<numPoints; j++) {
      long long colID = rowID + xoff[j] + nx*yoff[j]; // Compute column ID based on stencil offsets
      if (colID>-1 && colID<numGlobalEquations) {
	indices[numIndices] = colID;
	double value = - ((double) rand())/ ((double) RAND_MAX);
	if (colID==rowID)
	  values[numIndices++] = dnumPoints - value; // Make diagonal dominant
	else
	  values[numIndices++] = value;
      }
    }
    //cout << "Building row " << rowID << endl;
    A->InsertGlobalValues(rowID, numIndices, values, indices);
  }

  delete [] indices;
  delete [] values;
  double insertTime = timer.ElapsedTime();
  timer.ResetStartTime();
  A->FillComplete(false);
  double fillCompleteTime = timer.ElapsedTime();

  if (verbose)
    cout << "Time to insert matrix values = " << insertTime << endl
	 << "Time to complete fill        = " << fillCompleteTime << endl;
  if (summary) {
    if (comm.NumProc()==1) cout << "InsertTime" << '\t';
    cout << insertTime << endl;
    if (comm.NumProc()==1) cout << "FillCompleteTime" << '\t';
    cout << fillCompleteTime << endl;
  }

  if (nrhs<=1) {
    b = new Epetra_Vector(*map);
    bt = new Epetra_Vector(*map);
    xexact = new Epetra_Vector(*map);
  }
  else {
    b = new Epetra_MultiVector(*map, nrhs);
    bt = new Epetra_MultiVector(*map, nrhs);
    xexact = new Epetra_MultiVector(*map, nrhs);
  }

  xexact->Random(); // Fill xexact with random values

  A->Multiply(false, *xexact, *b);
  A->Multiply(true, *xexact, *bt);

  return;
}
Exemple #21
0
int main(int argc, char *argv[])
{
  int ierr = 0, i, j, k;
  bool debug = false;

#ifdef EPETRA_MPI
  MPI_Init(&argc,&argv);
  Epetra_MpiComm Comm( MPI_COMM_WORLD );
#else
  Epetra_SerialComm Comm;
#endif

  bool verbose = false;

  // Check if we should print results to standard out
  if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true;

  if (verbose && Comm.MyPID()==0)
    cout << Epetra_Version() << endl << endl;

  int rank = Comm.MyPID();
  //  char tmp;
  //  if (rank==0) cout << "Press any key to continue..."<< endl;
  //  if (rank==0) cin >> tmp;
  //  Comm.Barrier();

  Comm.SetTracebackMode(0); // This should shut down any error traceback reporting
  if (verbose) cout << Comm <<endl;

  //  bool verbose1 = verbose;

  // Redefine verbose to only print on PE 0
  if (verbose && rank!=0) verbose = false;
	
  int N = 20;
  int NRHS = 4;
  double * A = new double[N*N];
  double * A1 = new double[N*N];
  double * X = new double[(N+1)*NRHS];
  double * X1 = new double[(N+1)*NRHS];
  int LDX = N+1;
  int LDX1 = N+1;
  double * B = new double[N*NRHS];
  double * B1 = new double[N*NRHS];
  int LDB = N;
  int LDB1 = N;

  int LDA = N;
  int LDA1 = LDA;
  double OneNorm1;
  bool Transpose = false;

  Epetra_SerialDenseSolver solver;
  Epetra_SerialDenseMatrix * Matrix;
  for (int kk=0; kk<2; kk++) {
    for (i=1; i<=N; i++) {
      GenerateHilbert(A, LDA, i);
      OneNorm1 = 0.0;
      for (j=1; j<=i; j++) OneNorm1 += 1.0/((double) j); // 1-Norm = 1 + 1/2 + ...+1/n

      if (kk==0) {
	Matrix = new Epetra_SerialDenseMatrix(View, A, LDA, i, i);
	LDA1 = LDA;
      }
      else {
	Matrix = new Epetra_SerialDenseMatrix(Copy, A, LDA, i, i);
	LDA1 = i;
      }

      GenerateHilbert(A1, LDA1, i);
	
      if (kk==1) {
	solver.FactorWithEquilibration(true);
	solver.SolveWithTranspose(true);
	Transpose = true;
	solver.SolveToRefinedSolution(true);
      }

      for (k=0; k<NRHS; k++)
	for (j=0; j<i; j++) {
	  B[j+k*LDB] = 1.0/((double) (k+3)*(j+3));
	  B1[j+k*LDB1] = B[j+k*LDB1];
	}
      Epetra_SerialDenseMatrix Epetra_B(View, B, LDB, i, NRHS);
      Epetra_SerialDenseMatrix Epetra_X(View, X, LDX, i, NRHS);

      solver.SetMatrix(*Matrix);
      solver.SetVectors(Epetra_X, Epetra_B);

      ierr = check(solver, A1, LDA1,  i, NRHS, OneNorm1, B1, LDB1,  X1, LDX1, Transpose, verbose);
      assert (ierr>-1);
      delete Matrix;
      if (ierr!=0) {
	if (verbose) cout << "Factorization failed due to bad conditioning.  This is normal if RCOND is small."
			  << endl;
	break;
      }
    }
  }

  delete [] A;
  delete [] A1;
  delete [] X;
  delete [] X1;
  delete [] B;
  delete [] B1;

  /////////////////////////////////////////////////////////////////////
  // Now test norms and scaling functions
  /////////////////////////////////////////////////////////////////////

  Epetra_SerialDenseMatrix D;
  double ScalarA = 2.0;

  int DM = 10;
  int DN = 8;
  D.Shape(DM, DN);
  for (j=0; j<DN; j++)
    for (i=0; i<DM; i++) D[j][i] = (double) (1+i+j*DM) ;

  //cout << D << endl;

  double NormInfD_ref = (double)(DM*(DN*(DN+1))/2);
  double NormOneD_ref = (double)((DM*DN*(DM*DN+1))/2 - (DM*(DN-1)*(DM*(DN-1)+1))/2 );

  double NormInfD = D.NormInf();
  double NormOneD = D.NormOne();

  if (verbose) {
    cout << " *** Before scaling *** " << endl
	 << " Computed one-norm of test matrix = " << NormOneD << endl
	 << " Expected one-norm                = " << NormOneD_ref << endl
	 << " Computed inf-norm of test matrix = " << NormInfD << endl
	 << " Expected inf-norm                = " << NormInfD_ref << endl;
  }
  D.Scale(ScalarA); // Scale entire D matrix by this value
  NormInfD = D.NormInf();
  NormOneD = D.NormOne();
  if (verbose) {
    cout << " *** After scaling *** " << endl
	 << " Computed one-norm of test matrix = " << NormOneD << endl
	 << " Expected one-norm                = " << NormOneD_ref*ScalarA << endl
	 << " Computed inf-norm of test matrix = " << NormInfD << endl
	 << " Expected inf-norm                = " << NormInfD_ref*ScalarA << endl;
  }


  /////////////////////////////////////////////////////////////////////
  // Now test that A.Multiply(false, x, y) produces the same result
  // as y.Multiply('N','N', 1.0, A, x, 0.0).
  /////////////////////////////////////////////////////////////////////

  N = 10;
  int M = 10;
  LDA = N;
  Epetra_SerialDenseMatrix smallA(N, M, false);
  Epetra_SerialDenseMatrix x(N, 1, false);
  Epetra_SerialDenseMatrix y1(N, 1, false);
  Epetra_SerialDenseMatrix y2(N, 1, false);

  for(i=0; i<N; ++i) {
    for(j=0; j<M; ++j) {
      smallA(i,j) = 1.0*i+2.0*j+1.0;
    }
    x(i,0) = 1.0;
    y1(i,0) = 0.0;
    y2(i,0) = 0.0;
  }

  //quick check of operator==
  if (x == y1) {
    if (verbose) cout << "err in Epetra_SerialDenseMatrix::operator==, "
        << "erroneously returned true." << std::endl;
    return(-1);
  }

  //quick check of operator!=
  if (x != x) {
    if (verbose) cout << "err in Epetra_SerialDenseMatrix::operator==, "
        << "erroneously returned true." << std::endl;
    return(-1);
  }

  int err1 = smallA.Multiply(false, x, y1);
  int err2 = y2.Multiply('N','N', 1.0, smallA, x, 0.0);
  if (err1 != 0 || err2 != 0) {
    if (verbose) cout << "err in Epetra_SerialDenseMatrix::Multiply"<<endl;
    return(err1+err2);
  }

  for(i=0; i<N; ++i) {
    if (y1(i,0) != y2(i,0)) {
      if (verbose) cout << "different versions of Multiply don't match."<<endl;
      return(-99);
    }
  }

  /////////////////////////////////////////////////////////////////////
  // Now test for larger system, both correctness and performance.
  /////////////////////////////////////////////////////////////////////


  N = 2000;
  NRHS = 5;
  LDA = N;
  LDB = N;
  LDX = N;

  if (verbose) cout << "\n\nComputing factor of an " << N << " x " << N << " general matrix...Please wait.\n\n" << endl;

  // Define A and X

  A = new double[LDA*N];
  X = new double[LDB*NRHS];

  for (j=0; j<N; j++) {
    for (k=0; k<NRHS; k++) X[j+k*LDX] = 1.0/((double) (j+5+k));
    for (i=0; i<N; i++) {
      if (i==((j+2)%N)) A[i+j*LDA] = 100.0 + i;
      else A[i+j*LDA] = -11.0/((double) (i+5)*(j+2));
    }
  }

  // Define Epetra_SerialDenseMatrix object

  Epetra_SerialDenseMatrix BigMatrix(Copy, A, LDA, N, N);
  Epetra_SerialDenseMatrix OrigBigMatrix(View, A, LDA, N, N);

  Epetra_SerialDenseSolver BigSolver;
  BigSolver.FactorWithEquilibration(true);
  BigSolver.SetMatrix(BigMatrix);

  // Time factorization

  Epetra_Flops counter;
  BigSolver.SetFlopCounter(counter);
  Epetra_Time Timer(Comm);
  double tstart = Timer.ElapsedTime();
  ierr = BigSolver.Factor();
  if (ierr!=0 && verbose) cout << "Error in factorization = "<<ierr<< endl;
  assert(ierr==0);
  double time = Timer.ElapsedTime() - tstart;

  double FLOPS = counter.Flops();
  double MFLOPS = FLOPS/time/1000000.0;
  if (verbose) cout << "MFLOPS for Factorization = " << MFLOPS << endl;

  // Define Left hand side and right hand side
  Epetra_SerialDenseMatrix LHS(View, X, LDX, N, NRHS);
  Epetra_SerialDenseMatrix RHS;
  RHS.Shape(N,NRHS); // Allocate RHS

  // Compute RHS from A and X

  Epetra_Flops RHS_counter;
  RHS.SetFlopCounter(RHS_counter);
  tstart = Timer.ElapsedTime();
  RHS.Multiply('N', 'N', 1.0, OrigBigMatrix, LHS, 0.0);
  time = Timer.ElapsedTime() - tstart;

  Epetra_SerialDenseMatrix OrigRHS = RHS;

  FLOPS = RHS_counter.Flops();
  MFLOPS = FLOPS/time/1000000.0;
  if (verbose) cout << "MFLOPS to build RHS (NRHS = " << NRHS <<") = " << MFLOPS << endl;

  // Set LHS and RHS and solve
  BigSolver.SetVectors(LHS, RHS);

  tstart = Timer.ElapsedTime();
  ierr = BigSolver.Solve();
  if (ierr==1 && verbose) cout << "LAPACK guidelines suggest this matrix might benefit from equilibration." << endl;
  else if (ierr!=0 && verbose) cout << "Error in solve = "<<ierr<< endl;
  assert(ierr>=0);
  time = Timer.ElapsedTime() - tstart;

  FLOPS = BigSolver.Flops();
  MFLOPS = FLOPS/time/1000000.0;
  if (verbose) cout << "MFLOPS for Solve (NRHS = " << NRHS <<") = " << MFLOPS << endl;

  double * resid = new double[NRHS];
  bool OK = Residual(N, NRHS, A, LDA, BigSolver.Transpose(), BigSolver.X(), BigSolver.LDX(),
		     OrigRHS.A(), OrigRHS.LDA(), resid);

  if (verbose) {
    if (!OK) cout << "************* Residual do not meet tolerance *************" << endl;
    for (i=0; i<NRHS; i++)
      cout << "Residual[" << i <<"] = "<< resid[i] << endl;
    cout  << endl;
  }

  // Solve again using the Epetra_SerialDenseVector class for LHS and RHS

  Epetra_SerialDenseVector X2;
  Epetra_SerialDenseVector B2;
  X2.Size(BigMatrix.N());
  B2.Size(BigMatrix.M());
  int length = BigMatrix.N();
  {for (int kk=0; kk<length; kk++) X2[kk] = ((double ) kk)/ ((double) length);} // Define entries of X2

  RHS_counter.ResetFlops();
  B2.SetFlopCounter(RHS_counter);
  tstart = Timer.ElapsedTime();
  B2.Multiply('N', 'N', 1.0, OrigBigMatrix, X2, 0.0); // Define B2 = A*X2
  time = Timer.ElapsedTime() - tstart;

  Epetra_SerialDenseVector OrigB2 = B2;

  FLOPS = RHS_counter.Flops();
  MFLOPS = FLOPS/time/1000000.0;
  if (verbose) cout << "MFLOPS to build single RHS = " << MFLOPS << endl;

  // Set LHS and RHS and solve
  BigSolver.SetVectors(X2, B2);

  tstart = Timer.ElapsedTime();
  ierr = BigSolver.Solve();
  time = Timer.ElapsedTime() - tstart;
  if (ierr==1 && verbose) cout << "LAPACK guidelines suggest this matrix might benefit from equilibration." << endl;
  else if (ierr!=0 && verbose) cout << "Error in solve = "<<ierr<< endl;
  assert(ierr>=0);

  FLOPS = counter.Flops();
  MFLOPS = FLOPS/time/1000000.0;
  if (verbose) cout << "MFLOPS to solve single RHS = " << MFLOPS << endl;

  OK = Residual(N, 1, A, LDA, BigSolver.Transpose(), BigSolver.X(), BigSolver.LDX(), OrigB2.A(),
		OrigB2.LDA(), resid);

  if (verbose) {
    if (!OK) cout << "************* Residual do not meet tolerance *************" << endl;
      cout << "Residual = "<< resid[0] << endl;
  }
  delete [] resid;
  delete [] A;
  delete [] X;

  ///////////////////////////////////////////////////
  // Now test default constructor and index operators
  ///////////////////////////////////////////////////

  N = 5;
  Epetra_SerialDenseMatrix C; // Implicit call to default constructor, should not need to call destructor
  C.Shape(5,5); // Make it 5 by 5
  double * C1 = new double[N*N];
  GenerateHilbert(C1, N, N); // Generate Hilber matrix

  C1[1+2*N] = 1000.0;  // Make matrix nonsymmetric

  // Fill values of C with Hilbert values
  for (i=0; i<N; i++)
    for (j=0; j<N; j++)
      C(i,j) = C1[i+j*N];

  // Test if values are correctly written and read
  for (i=0; i<N; i++)
    for (j=0; j<N; j++) {
      assert(C(i,j) == C1[i+j*N]);
      assert(C(i,j) == C[j][i]);
    }

  if (verbose)
    cout << "Default constructor and index operator check OK.  Values of Hilbert matrix = "
	 << endl << C << endl
	 << "Values should be 1/(i+j+1), except value (1,2) should be 1000" << endl;

  delete [] C1;

  // now test sized/shaped constructor
  Epetra_SerialDenseMatrix shapedMatrix(10, 12);
  assert(shapedMatrix.M() == 10);
  assert(shapedMatrix.N() == 12);
  for(i = 0; i < 10; i++)
    for(j = 0; j < 12; j++)
      assert(shapedMatrix(i, j) == 0.0);
  Epetra_SerialDenseVector sizedVector(20);
  assert(sizedVector.Length() == 20);
  for(i = 0; i < 20; i++)
    assert(sizedVector(i) == 0.0);
  if (verbose)
    cout << "Shaped/sized constructors check OK." << endl;

  // test Copy/View mode in op= and cpy ctr
  int temperr = 0;
  temperr = matrixAssignment(verbose, debug);
  if(verbose && temperr == 0)
    cout << "Operator = checked OK." << endl;
  EPETRA_TEST_ERR(temperr, ierr);
  temperr = matrixCpyCtr(verbose, debug);
  if(verbose && temperr == 0)
    cout << "Copy ctr checked OK." << endl;
  EPETRA_TEST_ERR(temperr, ierr);

  // Test some vector methods

  Epetra_SerialDenseVector v1(3);
  v1[0] = 1.0;
  v1[1] = 3.0;
  v1[2] = 2.0;

  Epetra_SerialDenseVector v2(3);
  v2[0] = 2.0;
  v2[1] = 1.0;
  v2[2] = -2.0;

  temperr = 0;
  if (v1.Norm1()!=6.0) temperr++;
  if (fabs(sqrt(14.0)-v1.Norm2())>1.0e-6) temperr++;
  if (v1.NormInf()!=3.0) temperr++;
  if(verbose && temperr == 0)
    cout << "Vector Norms checked OK." << endl;
  temperr = 0;
  if (v1.Dot(v2)!=1.0) temperr++;
  if(verbose && temperr == 0)
    cout << "Vector Dot product checked OK." << endl;

#ifdef EPETRA_MPI
  MPI_Finalize() ;
#endif

/* end main
*/
return ierr ;
}
Exemple #22
0
int main(int argc, char *argv[])
{
  int ierr = 0, i, forierr = 0;
#ifdef EPETRA_MPI

  // Initialize MPI

  MPI_Init(&argc,&argv);
  int rank; // My process ID

  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  Epetra_MpiComm Comm( MPI_COMM_WORLD );

#else

  int rank = 0;
  Epetra_SerialComm Comm;

#endif

  bool verbose = false;

  // Check if we should print results to standard out
  if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true;

  int verbose_int = verbose ? 1 : 0;
  Comm.Broadcast(&verbose_int, 1, 0);
  verbose = verbose_int==1 ? true : false;


  //  char tmp;
  //  if (rank==0) cout << "Press any key to continue..."<< endl;
  //  if (rank==0) cin >> tmp;
  //  Comm.Barrier();

  Comm.SetTracebackMode(0); // This should shut down any error traceback reporting
  int MyPID = Comm.MyPID();
  int NumProc = Comm.NumProc();

  if(verbose && MyPID==0)
    cout << Epetra_Version() << endl << endl;

  if (verbose) cout << "Processor "<<MyPID<<" of "<< NumProc
		    << " is alive."<<endl;

  // Redefine verbose to only print on PE 0
  if(verbose && rank!=0) 
		verbose = false;

  int NumMyEquations = 10000;
  int NumGlobalEquations = (NumMyEquations * NumProc) + EPETRA_MIN(NumProc,3);
  if(MyPID < 3) 
    NumMyEquations++;

  // Construct a Map that puts approximately the same Number of equations on each processor

  Epetra_Map Map(NumGlobalEquations, NumMyEquations, 0, Comm);
  
  // Get update list and number of local equations from newly created Map
  vector<int> MyGlobalElements(Map.NumMyElements());
  Map.MyGlobalElements(&MyGlobalElements[0]);

  // Create an integer vector NumNz that is used to build the Petra Matrix.
  // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation on this processor

  vector<int> NumNz(NumMyEquations);

  // We are building a tridiagonal matrix where each row has (-1 2 -1)
  // So we need 2 off-diagonal terms (except for the first and last equation)

  for(i = 0; i < NumMyEquations; i++)
    if((MyGlobalElements[i] == 0) || (MyGlobalElements[i] == NumGlobalEquations - 1))
      NumNz[i] = 1;
    else
      NumNz[i] = 2;

  // Create a Epetra_Matrix

  Epetra_CrsMatrix A(Copy, Map, &NumNz[0]);
  EPETRA_TEST_ERR(A.IndicesAreGlobal(),ierr);
  EPETRA_TEST_ERR(A.IndicesAreLocal(),ierr);
  
  // Add  rows one-at-a-time
  // Need some vectors to help
  // Off diagonal Values will always be -1


  vector<double> Values(2);
  Values[0] = -1.0; 
	Values[1] = -1.0;
	vector<int> Indices(2);
  double two = 2.0;
  int NumEntries;

  forierr = 0;
  for(i = 0; i < NumMyEquations; i++) {
    if(MyGlobalElements[i] == 0) {
			Indices[0] = 1;
			NumEntries = 1;
		}
    else if (MyGlobalElements[i] == NumGlobalEquations-1) {
			Indices[0] = NumGlobalEquations-2;
			NumEntries = 1;
		}
    else {
			Indices[0] = MyGlobalElements[i]-1;
			Indices[1] = MyGlobalElements[i]+1;
			NumEntries = 2;
		}
		forierr += !(A.InsertGlobalValues(MyGlobalElements[i], NumEntries, &Values[0], &Indices[0])==0);
		forierr += !(A.InsertGlobalValues(MyGlobalElements[i], 1, &two, &MyGlobalElements[i])>0); // Put in the diagonal entry
  }
  EPETRA_TEST_ERR(forierr,ierr);

  // Finish up
  A.FillComplete();
  A.OptimizeStorage();

  HYPRE_IJMatrix Matrix;
  int ilower = Map.MinMyGID();
  int iupper = Map.MaxMyGID();

  //printf("Proc[%d], ilower = %d, iupper = %d.\n", MyPID, ilower, iupper);
  HYPRE_IJMatrixCreate(MPI_COMM_WORLD, ilower, iupper, ilower, iupper, &Matrix);
  HYPRE_IJMatrixSetObjectType(Matrix, HYPRE_PARCSR);
  HYPRE_IJMatrixInitialize(Matrix);
  
  for(i = 0; i < A.NumMyRows(); i++){
    int numElements;
    A.NumMyRowEntries(i, numElements);
    vector<int> my_indices; my_indices.resize(numElements);
    vector<double> my_values; my_values.resize(numElements);
    int numEntries;
    A.ExtractMyRowCopy(i, numElements, numEntries, &my_values[0], &my_indices[0]);
    for(int j = 0; j < numEntries; j++) {
      my_indices[j] = A.GCID(my_indices[j]);
    }
    int GlobalRow[1];
    GlobalRow[0] = A.GRID(i);
    HYPRE_IJMatrixSetValues(Matrix, 1, &numEntries, GlobalRow, &my_indices[0], &my_values[0]);
  } 
  HYPRE_IJMatrixAssemble(Matrix);

  EpetraExt_HypreIJMatrix JadA(Matrix);
 
  JadA.SetMaps(JadA.RowMatrixRowMap(), A.RowMatrixColMap());
  // Create vectors for Power method

  Epetra_Vector q(Map);
  Epetra_Vector z(Map); z.Random();
  Epetra_Vector resid(Map);

  Epetra_Flops flopcounter;
  A.SetFlopCounter(flopcounter);
  q.SetFlopCounter(A);
  z.SetFlopCounter(A);
  resid.SetFlopCounter(A);
  JadA.SetFlopCounter(A);

  if (verbose) cout << "=======================================" << endl
		    << "Testing Jad using CrsMatrix as input..." << endl
		    << "=======================================" << endl;

  A.ResetFlops();
  powerMethodTests(A, JadA, Map, q, z, resid, verbose);

#ifdef EPETRA_MPI
  MPI_Finalize() ;
#endif

return ierr ;
}