Пример #1
0
    //! Update matrix
    static void update(Epetra_CrsMatrix& mat, double a, 
		       const Epetra_CrsMatrix& x) {
      int num_col;
      for (int i=0; i<mat.NumMyRows(); i++) {
	mat.NumMyRowEntries(i, num_col);
	for (int j=0; j<num_col; j++)
	  mat[i][j] += a*x[i][j];
      }
    }
Пример #2
0
int TPackAndPrepareWithOwningPIDs(const Epetra_CrsMatrix & A, 
				 int NumExportIDs,
				 int * ExportLIDs,
				 int & LenExports,
				 char *& Exports,
				 int & SizeOfPacket,
				 int * Sizes,
				 bool & VarSizes,
				 std::vector<int>& pids)
{
  int i, j;

  VarSizes = true; //enable variable block size data comm

  int TotalSendLength = 0;
  int * IntSizes = 0; 
  if( NumExportIDs>0 ) IntSizes = new int[NumExportIDs];

  int SizeofIntType = sizeof(int_type);

  for(i = 0; i < NumExportIDs; ++i) {
    int NumEntries;
    A.NumMyRowEntries( ExportLIDs[i], NumEntries );
    // Will have NumEntries doubles, 2*NumEntries +2 ints pack them interleaved     Sizes[i] = NumEntries;
    // NTS: We add the owning PID as the SECOND int of the pair for each entry
    Sizes[i] = NumEntries;
    // NOTE: Mixing and matching Int Types would be more efficient, BUT what about variable alignment?
    IntSizes[i] = 1 + (((2*NumEntries+2)*SizeofIntType)/(int)sizeof(double));
    TotalSendLength += (Sizes[i]+IntSizes[i]);
  }    
  
  double * DoubleExports = 0; 
  SizeOfPacket = (int)sizeof(double);
       
  //setup buffer locally for memory management by this object
  if( TotalSendLength*SizeOfPacket > LenExports ) {
    if( LenExports > 0 ) delete [] Exports;
    LenExports = TotalSendLength*SizeOfPacket;
    DoubleExports = new double[TotalSendLength];
    for( int i = 0; i < TotalSendLength; ++i ) DoubleExports[i] = 0.0;
    Exports = (char *) DoubleExports;
  } 
  
  int NumEntries;
  double * values;
  double * valptr, * dintptr; 

  // Each segment of Exports will be filled by a packed row of information for each row as follows:
  // 1st int: GRID of row where GRID is the global row ID for the source matrix
  // next int:  NumEntries, Number of indices in row
  // next 2*NumEntries: The actual indices and owning [1] PID each for the row in (GID,PID) pairs with the GID first.

  // [1] Owning is defined in the sense of "Who owns the GID in the DomainMap," aka, who sends the GID in the importer

  const Epetra_Map & rowMap = A.RowMap();
  const Epetra_Map & colMap = A.ColMap();
  
  if( NumExportIDs > 0 ) {
    int_type * Indices;
    int_type FromRow; 
    int_type * intptr;                         
    
    int maxNumEntries = A.MaxNumEntries();
    std::vector<int> MyIndices(maxNumEntries);
    dintptr = (double *) Exports;
    valptr = dintptr + IntSizes[0];
    intptr = (int_type *) dintptr;
    for (i=0; i<NumExportIDs; i++) {
      FromRow   = (int_type) rowMap.GID64(ExportLIDs[i]);
      intptr[0] = FromRow;
      values    = valptr;
      Indices   = intptr + 2;
      EPETRA_CHK_ERR(A.ExtractMyRowCopy(ExportLIDs[i], maxNumEntries, NumEntries, values, &MyIndices[0]));
      for (j=0; j<NumEntries; j++) {
	Indices[2*j]   = (int_type) colMap.GID64(MyIndices[j]);   // convert to GIDs
	Indices[2*j+1] = pids[MyIndices[j]];                      // PID owning the entry.
      }
      intptr[1] = NumEntries; // Load second slot of segment
      if( i < (NumExportIDs-1) ) {
	dintptr += (IntSizes[i]+Sizes[i]);
	valptr = dintptr + IntSizes[i+1];
	intptr = (int_type *) dintptr;
      }	
    }    

    for(i = 0; i < NumExportIDs; ++i )
      Sizes[i] += IntSizes[i];
  }
  
  if( IntSizes ) delete [] IntSizes;
  
  return(0);
}