コード例 #1
0
// FIXME long long
Epetra_BlockMap
Epetra_Util::Create_OneToOne_BlockMap(const Epetra_BlockMap& usermap,
              bool high_rank_proc_owns_shared)
{
// FIXME long long

  //if usermap is already 1-to-1 then we'll just return a copy of it.
  if (usermap.IsOneToOne()) {
    Epetra_BlockMap newmap(usermap);
    return(newmap);
  }

  int myPID = usermap.Comm().MyPID();
  Epetra_Directory* directory = usermap.Comm().CreateDirectory(usermap);

  int numMyElems = usermap.NumMyElements();
  const int* myElems = usermap.MyGlobalElements();

  int* owner_procs = new int[numMyElems*2];
  int* sizes = owner_procs+numMyElems;

  directory->GetDirectoryEntries(usermap, numMyElems, myElems, owner_procs,
         0, sizes, high_rank_proc_owns_shared);

  //we'll fill a list of map-elements which belong on this processor

  int* myOwnedElems = new int[numMyElems*2];
  int* ownedSizes = myOwnedElems+numMyElems;
  int numMyOwnedElems = 0;

  for(int i=0; i<numMyElems; ++i) {
    int GID = myElems[i];
    int owner = owner_procs[i];

    if (myPID == owner) {
      ownedSizes[numMyOwnedElems] = sizes[i];
      myOwnedElems[numMyOwnedElems++] = GID;
    }
  }

  Epetra_BlockMap one_to_one_map(-1, numMyOwnedElems, myOwnedElems,
         sizes, usermap.IndexBase(), usermap.Comm());

  delete [] myOwnedElems;
  delete [] owner_procs;
  delete directory;

  return(one_to_one_map);
}
コード例 #2
0
Teuchos::Array<int>
Albany::NodeGIDsSolutionCullingStrategy::
selectedGIDs(const Epetra_BlockMap &sourceMap) const
{
  Teuchos::Array<int> result;
  {
    Teuchos::Array<int> mySelectedGIDs;

    // Subract 1 to convert exodus GIDs to our GIDs
    for (int i=0; i<nodeGIDs_.size(); i++)
      if (sourceMap.MyGID(nodeGIDs_[i] -1) ) mySelectedGIDs.push_back(nodeGIDs_[i] - 1);

    const Epetra_Comm &comm = sourceMap.Comm();

    {
      int selectedGIDCount;
      {
        int mySelectedGIDCount = mySelectedGIDs.size();
        comm.SumAll(&mySelectedGIDCount, &selectedGIDCount, 1);
      }
      result.resize(selectedGIDCount);
    }

    const int ierr = Epetra::GatherAllV(
        comm,
        mySelectedGIDs.getRawPtr(), mySelectedGIDs.size(),
        result.getRawPtr(), result.size());
    TEUCHOS_ASSERT(ierr == 0);
  }

  std::sort(result.begin(), result.end());

  return result;
}
コード例 #3
0
ファイル: MapEpetra.cpp プロジェクト: lifev/lifev
MapEpetra::MapEpetra ( const Epetra_BlockMap& blockMap, const Int offset, const Int maxId) :
    M_commPtr(blockMap.Comm().Clone())
{
    std::vector<Int> myGlobalElements;
    Int* sourceGlobalElements ( blockMap.MyGlobalElements() );
    Int const startIdOrig ( offset );
    Int const endIdOrig  ( startIdOrig + maxId );
    const Int maxMyElements = std::min ( maxId, blockMap.NumMyElements() );
    myGlobalElements.reserve ( maxMyElements );

    //Sort MyGlobalElements to avoid a bug in Trilinos (9?) when multiplying two matrices (A * B^T)
    std::sort ( myGlobalElements.begin(), myGlobalElements.end() );

    // We consider that the source Map may not be ordered
    for ( Int i (0); i < blockMap.NumMyElements(); ++i )
        if ( sourceGlobalElements[i] < endIdOrig && sourceGlobalElements[i] >= startIdOrig )
        {
            myGlobalElements.push_back ( sourceGlobalElements[i] - offset );
        }

    createMap ( -1,
                myGlobalElements.size(),
                &myGlobalElements.front(),
                *M_commPtr );
}
コード例 #4
0
  void EpetraCrsGraph::describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const {
    XPETRA_MONITOR("EpetraCrsGraph::describe");

    out << "EpetraCrsGraph::describe : Warning, verbosity level is ignored by this method." << std::endl;
    const Epetra_BlockMap rowmap = graph_->RowMap();
    if (rowmap.Comm().MyPID() == 0) out << "** EpetraCrsGraph **\n\nrowmap" << std::endl;
    rowmap.Print(out);
    graph_->Print(out);
  }
コード例 #5
0
ArrayRCP<zgno_t> roundRobinMap(const Epetra_BlockMap &emap)
{
  const Epetra_Comm &comm = emap.Comm();
  int proc = comm.MyPID();
  int nprocs = comm.NumProc();
  zgno_t basegid = emap.MinAllGID();
  zgno_t maxgid = emap.MaxAllGID();
  size_t nglobalrows = emap.NumGlobalElements();

  return roundRobinMapShared(proc, nprocs, basegid, maxgid, nglobalrows);
}
コード例 #6
0
//EpetraMap_To_TpetraMap: takes in Epetra_Map object, converts it to its equivalent Tpetra::Map object,
//and returns an RCP pointer to this Tpetra::Map
Teuchos::RCP<const Tpetra_Map> Petra::EpetraMap_To_TpetraMap(const Epetra_BlockMap& epetraMap_,
                                                      const Teuchos::RCP<const Teuchos::Comm<int> >& commT_)
{
  const std::size_t numElements = Teuchos::as<std::size_t>(epetraMap_.NumMyElements());
  const auto indexBase = Teuchos::as<GO>(epetraMap_.IndexBase());
  if (epetraMap_.DistributedGlobal() || epetraMap_.Comm().NumProc() == Teuchos::OrdinalTraits<int>::one()) {
    Teuchos::Array<Tpetra_GO> indices(numElements);
    int *epetra_indices = epetraMap_.MyGlobalElements();
    for(LO i=0; i < numElements; i++)
       indices[i] = epetra_indices[i];
    const Tpetra::global_size_t computeGlobalElements = Teuchos::OrdinalTraits<Tpetra::global_size_t>::invalid();
    return Teuchos::rcp(new Tpetra_Map(computeGlobalElements, indices, indexBase, commT_));
  } else {
    return Teuchos::rcp(new Tpetra_Map(numElements, indexBase, commT_, Tpetra::LocallyReplicated));
  }
}
コード例 #7
0
Teuchos::Array<int>
Albany::NodeSetSolutionCullingStrategy::
selectedGIDs(const Epetra_BlockMap &sourceMap) const
{
  Teuchos::Array<int> result;
  {
    Teuchos::Array<int> mySelectedGIDs;
    {
      const NodeSetList &nodeSets = disc_->getNodeSets();

      const NodeSetList::const_iterator it = nodeSets.find(nodeSetLabel_);
      if (it != nodeSets.end()) {
        typedef NodeSetList::mapped_type NodeSetEntryList;
        const NodeSetEntryList &sampleNodeEntries = it->second;

        for (NodeSetEntryList::const_iterator jt = sampleNodeEntries.begin(); jt != sampleNodeEntries.end(); ++jt) {
          typedef NodeSetEntryList::value_type NodeEntryList;
          const NodeEntryList &sampleEntries = *jt;
          for (NodeEntryList::const_iterator kt = sampleEntries.begin(); kt != sampleEntries.end(); ++kt) {
            mySelectedGIDs.push_back(sourceMap.GID(*kt));
          }
        }
      }
    }

    const Epetra_Comm &comm = sourceMap.Comm();

    {
      int selectedGIDCount;
      {
        int mySelectedGIDCount = mySelectedGIDs.size();
        comm.SumAll(&mySelectedGIDCount, &selectedGIDCount, 1);
      }
      result.resize(selectedGIDCount);
    }

    const int ierr = Epetra::GatherAllV(
        comm,
        mySelectedGIDs.getRawPtr(), mySelectedGIDs.size(),
        result.getRawPtr(), result.size());
    TEUCHOS_ASSERT(ierr == 0);
  }

  std::sort(result.begin(), result.end());

  return result;
}
コード例 #8
0
ファイル: BorderingHelpers.cpp プロジェクト: nschloe/nosh
// ============================================================================
std::shared_ptr<const Tpetra::Map<int,int>>
BorderingHelpers::
extendMapBy1(const Epetra_BlockMap & map)
{
  const Teuchos::Comm<int> & comm = map.Comm();
  // Create a new map that hosts one more entry.
  const int numGlobalElements = map.NumGlobalElements() + 1;
  const int numMyElements = map.NumMyElements();
  int * myGlobalElements = map.MyGlobalElements();
  // The following if-else construction just makes sure that
  // the Tpetra::Map<int,int> constructor is called with an extended
  // map on proc 0, and with the regular old stuff on all
  // other procs.
  std::shared_ptr<Tpetra::Map<int,int>> extendedMap;
  if (comm.MyPID() == 0) {
    // Copy over the global indices.
    std::vector<int> a(numMyElements+1);
    for (int k = 0; k < numMyElements; k++)
      a[k] = myGlobalElements[k];
    // Append one more.
    a[numMyElements] = map.NumGlobalElements();

    extendedMap = std::make_shared<Tpetra::Map<int,int>>(
        numGlobalElements,
        numMyElements+1,
        &a[0],
        map.IndexBase(),
        comm
        );
  } else {
    extendedMap = std::make_shared<Tpetra::Map<int,int>>(
        numGlobalElements,
        numMyElements,
        myGlobalElements,
        map.IndexBase(),
        comm
        );
  }

  return extendedMap;
}
コード例 #9
0
Teuchos::Array<int>
Albany::UniformSolutionCullingStrategy::
selectedGIDs(const Epetra_BlockMap &sourceMap) const
{
  Teuchos::Array<int> allGIDs(sourceMap.NumGlobalElements());
  {
    const int ierr = Epetra::GatherAllV(
        sourceMap.Comm(),
        sourceMap.MyGlobalElements(), sourceMap.NumMyElements(),
        allGIDs.getRawPtr(), allGIDs.size());
    TEUCHOS_ASSERT(ierr == 0);
  }
  std::sort(allGIDs.begin(), allGIDs.end());

  Teuchos::Array<int> result(numValues_);
  const int stride = 1 + (allGIDs.size() - 1) / numValues_;
  for (int i = 0; i < numValues_; ++i) {
    result[i] = allGIDs[i * stride];
  }
  return result;
}
コード例 #10
0
//=========================================================================
int Ifpack_CrsRiluk::BlockMap2PointMap(const Epetra_BlockMap & BlockMap, Teuchos::RefCountPtr<Epetra_Map>* PointMap) {
	// Generate an Epetra_Map that has the same number and distribution of points
	// as the input Epetra_BlockMap object.  The global IDs for the output PointMap
	// are computed by using the MaxElementSize of the BlockMap.  For variable block
	// sizes this will create gaps in the GID space, but that is OK for Epetra_Maps.

	int MaxElementSize = BlockMap.MaxElementSize();
	int PtNumMyElements = BlockMap.NumMyPoints();
	vector<int> PtMyGlobalElements;
	if (PtNumMyElements>0) PtMyGlobalElements.resize(PtNumMyElements);

	int NumMyElements = BlockMap.NumMyElements();

	int curID = 0;
	for (int i=0; i<NumMyElements; i++) {
		int StartID = BlockMap.GID(i)*MaxElementSize;
		int ElementSize = BlockMap.ElementSize(i);
		for (int j=0; j<ElementSize; j++) PtMyGlobalElements[curID++] = StartID+j;
	}
	assert(curID==PtNumMyElements); // Sanity test

	(*PointMap) = Teuchos::rcp( new Epetra_Map(-1, PtNumMyElements, &PtMyGlobalElements[0], BlockMap.IndexBase(), BlockMap.Comm()) );

	if (!BlockMap.PointSameAs(*(*PointMap))) {EPETRA_CHK_ERR(-1);} // Maps not compatible
  return(0);
}
コード例 #11
0
ファイル: Epetra_Export.cpp プロジェクト: haripandey/trilinos
//==============================================================================
// Epetra_Export constructor for a Epetra_BlockMap object
Epetra_Export::Epetra_Export( const Epetra_BlockMap &  SourceMap, const Epetra_BlockMap & TargetMap)
  : Epetra_Object("Epetra::Export"), 
    TargetMap_(TargetMap),
    SourceMap_(SourceMap),
    NumSameIDs_(0),
    NumPermuteIDs_(0),
    PermuteToLIDs_(0),
    PermuteFromLIDs_(0),
    NumRemoteIDs_(0),
    RemoteLIDs_(0),
    NumExportIDs_(0),
    ExportLIDs_(0),
    ExportPIDs_(0),
    NumSend_(0),
    NumRecv_(0),
    Distor_(0)
{

  int i;

  // Build three ID lists:
  // NumSameIDs - Number of IDs in TargetMap and SourceMap that are identical, up to the first
  //              nonidentical ID.
  // NumPermuteIDs - Number of IDs in SourceMap that must be indirectly loaded but are on this processor.
  // NumExportIDs - Number of IDs that are in SourceMap but not in TargetMap, and thus must be exported.

  int NumSourceIDs = SourceMap.NumMyElements();
  int NumTargetIDs = TargetMap.NumMyElements();

  int *TargetGIDs = 0;
  if (NumTargetIDs>0) {
    TargetGIDs = new int[NumTargetIDs];
    TargetMap.MyGlobalElements(TargetGIDs);
  }

  int * SourceGIDs = 0;
  if (NumSourceIDs>0) {
    SourceGIDs = new int[NumSourceIDs];
    SourceMap.MyGlobalElements(SourceGIDs);
  }

  int MinIDs = EPETRA_MIN(NumSourceIDs, NumTargetIDs);

  NumSameIDs_ = 0;
  for (i=0; i< MinIDs; i++) if (TargetGIDs[i]==SourceGIDs[i]) NumSameIDs_++; else break;

  // Find count of Source IDs that are truly remote and those that are local but permuted

  NumPermuteIDs_ = 0;
  NumExportIDs_ = 0;
  for (i=NumSameIDs_; i< NumSourceIDs; i++) 
    if (TargetMap.MyGID(SourceGIDs[i])) NumPermuteIDs_++; // Check if Source GID is a local Target GID
    else NumExportIDs_++; // If not, then it is remote

  // Define remote and permutation lists

  int * ExportGIDs = 0;
  if (NumExportIDs_>0) {
    ExportLIDs_ = new int[NumExportIDs_];
    ExportGIDs = new int[NumExportIDs_];
  }
  if (NumPermuteIDs_>0)  {
    PermuteToLIDs_ = new int[NumPermuteIDs_];
    PermuteFromLIDs_ = new int[NumPermuteIDs_];
  }

  NumPermuteIDs_ = 0;
  NumExportIDs_ = 0;
  for (i=NumSameIDs_; i< NumSourceIDs; i++) {
    if (TargetMap.MyGID(SourceGIDs[i])) {
      PermuteFromLIDs_[NumPermuteIDs_] = i;
      PermuteToLIDs_[NumPermuteIDs_++] = TargetMap.LID(SourceGIDs[i]);
    }
    else {
      //NumSend_ +=SourceMap.ElementSize(i); // Count total number of entries to send
      NumSend_ +=SourceMap.MaxElementSize(); // Count total number of entries to send (currently need max)
      ExportGIDs[NumExportIDs_] = SourceGIDs[i];
      ExportLIDs_[NumExportIDs_++] = i;
    }
  }
     
  if ( NumExportIDs_>0 && !SourceMap.DistributedGlobal()) 
    ReportError("Warning in Epetra_Export: Serial Export has remote IDs. (Exporting from Subset of Source Map)", 1);

  // Test for distributed cases
  int ierr = 0;

  if (SourceMap.DistributedGlobal()) {

    if (NumExportIDs_>0) ExportPIDs_ = new int[NumExportIDs_];
    ierr = TargetMap.RemoteIDList(NumExportIDs_, ExportGIDs, ExportPIDs_, 0); // Get remote PIDs
    if( ierr ) throw ReportError("Error in Epetra_BlockMap::RemoteIDList", ierr);

    //Get rid of IDs not in Target Map
    if(NumExportIDs_>0) {
      int cnt = 0;
      for( i = 0; i < NumExportIDs_; ++i )
	if( ExportPIDs_[i] == -1 ) ++cnt;
      if( cnt ) {
	int * NewExportGIDs = 0;
	int * NewExportPIDs = 0;
	int * NewExportLIDs = 0;
	int cnt1 = NumExportIDs_-cnt;
	if (cnt1) {
	  NewExportGIDs = new int[cnt1];
	  NewExportPIDs = new int[cnt1];
	  NewExportLIDs = new int[cnt1];
	}
	cnt = 0;
	for( i = 0; i < NumExportIDs_; ++i )
	  if( ExportPIDs_[i] != -1 ) {
	    NewExportGIDs[cnt] = ExportGIDs[i];
	    NewExportPIDs[cnt] = ExportPIDs_[i];
	    NewExportLIDs[cnt] = ExportLIDs_[i];
	    ++cnt;
          }
	assert(cnt==cnt1); // Sanity test
	NumExportIDs_ = cnt;
	delete [] ExportGIDs;
	delete [] ExportPIDs_;
	delete [] ExportLIDs_;
	ExportGIDs = NewExportGIDs;
	ExportPIDs_ = NewExportPIDs;
	ExportLIDs_ = NewExportLIDs;
	ReportError("Warning in Epetra_Export: Source IDs not found in Target Map (Do you want to export from subset of Source Map?)", 1 );
      }
    }
    
    //Make sure Export IDs are ordered by processor
    Epetra_Util util;
    int * tmpPtr[2];
    tmpPtr[0] = ExportLIDs_, tmpPtr[1] = ExportGIDs;
    util.Sort(true,NumExportIDs_,ExportPIDs_,0,0,2,tmpPtr);

    Distor_ = SourceMap.Comm().CreateDistributor();
    
    // Construct list of exports that calling processor needs to send as a result
    // of everyone asking for what it needs to receive.
    
    ierr = Distor_->CreateFromSends( NumExportIDs_, ExportPIDs_, true, NumRemoteIDs_);
    if (ierr!=0) throw ReportError("Error in Epetra_Distributor.CreateFromSends()", ierr);
    
    // Use comm plan with ExportGIDs to find out who is sending to us and
    // get proper ordering of GIDs for remote entries 
    // (that we will convert to LIDs when done).
    
    if (NumRemoteIDs_>0) RemoteLIDs_ = new int[NumRemoteIDs_]; // Allocate space for LIDs in target that are
    // going to get something from off-processor.
    char * cRemoteGIDs = 0; //Do will alloc memory for this object
    int LenCRemoteGIDs = 0;
    ierr = Distor_->Do(reinterpret_cast<char *> (ExportGIDs), 
		sizeof( int ),
		LenCRemoteGIDs,
		cRemoteGIDs);
    if (ierr) throw ReportError("Error in Epetra_Distributor.Do()", ierr);
    int * RemoteGIDs = reinterpret_cast<int*>(cRemoteGIDs);

    // Remote IDs come in as GIDs, convert to LIDs
    for (i=0; i< NumRemoteIDs_; i++) {
      RemoteLIDs_[i] = TargetMap.LID(RemoteGIDs[i]);
      //NumRecv_ += TargetMap.ElementSize(RemoteLIDs_[i]); // Count total number of entries to receive
      NumRecv_ += TargetMap.MaxElementSize(); // Count total number of entries to receive (currently need max)
    }

    if (NumExportIDs_>0) delete [] ExportGIDs;
    if (LenCRemoteGIDs>0) delete [] cRemoteGIDs;
  }
  if (NumTargetIDs>0) delete [] TargetGIDs;
  if (NumSourceIDs>0) delete [] SourceGIDs;
  
  return;
}
コード例 #12
0
int
LOCA::Epetra::AugmentedOp::blockMap2PointMap(const Epetra_BlockMap& BlockMap,
				    Epetra_Map*& PointMap) const
{
  // Generate an Epetra_Map that has the same number and distribution of points
  // as the input Epetra_BlockMap object.  The global IDs for the output PointMap
  // are computed by using the MaxElementSize of the BlockMap.  For variable block
  // sizes this will create gaps in the GID space, but that is OK for Epetra_Maps.

  int MaxElementSize = BlockMap.MaxElementSize();
  int PtNumMyElements = BlockMap.NumMyPoints();
  int * PtMyGlobalElements = 0;
  if (PtNumMyElements>0) PtMyGlobalElements = new int[PtNumMyElements];

  int NumMyElements = BlockMap.NumMyElements();

  int curID = 0;
  for (int i=0; i<NumMyElements; i++) {
    int StartID = BlockMap.GID(i)*MaxElementSize;
    int ElementSize = BlockMap.ElementSize(i);
    for (int j=0; j<ElementSize; j++) PtMyGlobalElements[curID++] = StartID+j;
  }
  assert(curID==PtNumMyElements); // Sanity test

  PointMap = new Epetra_Map(-1, PtNumMyElements, PtMyGlobalElements, BlockMap.IndexBase(), BlockMap.Comm());

  if (PtNumMyElements>0) delete [] PtMyGlobalElements;

  if (!BlockMap.PointSameAs(*PointMap)) {EPETRA_CHK_ERR(-1);} // Maps not compatible
  return(0);
}
コード例 #13
0
void Epetra_Import::Construct( const Epetra_BlockMap &  targetMap, const Epetra_BlockMap & sourceMap)
{
  int i;
  
  // Build three ID lists:
  // NumSameIDs - Number of IDs in TargetMap and SourceMap that are identical, up to the first
  //              nonidentical ID.
  // NumPermuteIDs - Number of IDs in SourceMap that must be indirectly loaded but are on this processor.
  // NumRemoteIDs - Number of IDs that are in SourceMap but not in TargetMap, and thus must be imported.
  
  int NumSourceIDs = sourceMap.NumMyElements();
  int NumTargetIDs = targetMap.NumMyElements();
  
  int_type *TargetGIDs = 0;
  if (NumTargetIDs>0) {
    TargetGIDs = new int_type[NumTargetIDs];
    targetMap.MyGlobalElements(TargetGIDs);
  }
  
  int_type * SourceGIDs = 0;
  if (NumSourceIDs>0) {
    SourceGIDs = new int_type[NumSourceIDs];
    sourceMap.MyGlobalElements(SourceGIDs);
  }
  
  int MinIDs = EPETRA_MIN(NumSourceIDs, NumTargetIDs);
  
  
  NumSameIDs_ = 0;
  for (i=0; i< MinIDs; i++) if (TargetGIDs[i]==SourceGIDs[i]) NumSameIDs_++; else break;
  
  
  // Find count of Target IDs that are truly remote and those that are local but permuted

  NumPermuteIDs_ = 0;
  NumRemoteIDs_ = 0;
  for (i=NumSameIDs_; i< NumTargetIDs; i++) 
    if (sourceMap.MyGID(TargetGIDs[i])) NumPermuteIDs_++; // Check if Target GID is a local Source GID
    else NumRemoteIDs_++; // If not, then it is remote
  
  
  
  // Define remote and permutation lists
  
  int_type * RemoteGIDs=0;
  RemoteLIDs_ = 0;
  if (NumRemoteIDs_>0) {
    RemoteLIDs_ = new int[NumRemoteIDs_];
    RemoteGIDs = new int_type[NumRemoteIDs_];
  }
  if (NumPermuteIDs_>0)  {
    PermuteToLIDs_ = new int[NumPermuteIDs_];
    PermuteFromLIDs_ = new int[NumPermuteIDs_];
  }
  
  NumPermuteIDs_ = 0;
  NumRemoteIDs_ = 0;
  for (i=NumSameIDs_; i< NumTargetIDs; i++) {
    if (sourceMap.MyGID(TargetGIDs[i])) {
      PermuteToLIDs_[NumPermuteIDs_] = i;
      PermuteFromLIDs_[NumPermuteIDs_++] = sourceMap.LID(TargetGIDs[i]);
    }
    else {
      //NumRecv_ +=TargetMap.ElementSize(i); // Count total number of entries to receive
      NumRecv_ +=targetMap.MaxElementSize(); // Count total number of entries to receive (currently need max)
      RemoteGIDs[NumRemoteIDs_] = TargetGIDs[i];
      RemoteLIDs_[NumRemoteIDs_++] = i;
    }
  }

  if( NumRemoteIDs_>0 && !sourceMap.DistributedGlobal() )
    ReportError("Warning in Epetra_Import: Serial Import has remote IDs. (Importing to Subset of Target Map)", 1);
  
  // Test for distributed cases
  
  int * RemotePIDs = 0;

  if (sourceMap.DistributedGlobal()) {
    
    if (NumRemoteIDs_>0)  RemotePIDs = new int[NumRemoteIDs_];
    int ierr = sourceMap.RemoteIDList(NumRemoteIDs_, RemoteGIDs, RemotePIDs, 0); // Get remote PIDs
    if (ierr) throw ReportError("Error in sourceMap.RemoteIDList call", ierr);

    //Get rid of IDs that don't exist in SourceMap
    if(NumRemoteIDs_>0) {
      int cnt = 0;
      for( i = 0; i < NumRemoteIDs_; ++i )
        if( RemotePIDs[i] == -1 ) ++cnt;
      if( cnt ) {
        if( NumRemoteIDs_-cnt ) {
          int_type * NewRemoteGIDs = new int_type[NumRemoteIDs_-cnt];
          int * NewRemotePIDs = new int[NumRemoteIDs_-cnt];
          int * NewRemoteLIDs = new int[NumRemoteIDs_-cnt];
          cnt = 0;
          for( i = 0; i < NumRemoteIDs_; ++i )
            if( RemotePIDs[i] != -1 ) {
              NewRemoteGIDs[cnt] = RemoteGIDs[i];
              NewRemotePIDs[cnt] = RemotePIDs[i];
              NewRemoteLIDs[cnt] = targetMap.LID(RemoteGIDs[i]);
              ++cnt;
            }
          NumRemoteIDs_ = cnt;
          delete [] RemoteGIDs;
          delete [] RemotePIDs;
          delete [] RemoteLIDs_;
          RemoteGIDs = NewRemoteGIDs;
          RemotePIDs = NewRemotePIDs;
          RemoteLIDs_ = NewRemoteLIDs;
          ReportError("Warning in Epetra_Import: Target IDs not found in Source Map (Do you want to import to subset of Target Map?)", 1);
        }
        else { //valid RemoteIDs empty
          NumRemoteIDs_ = 0;
          delete [] RemoteGIDs;
          RemoteGIDs = 0;
          delete [] RemotePIDs;
          RemotePIDs = 0;
        }
      }
    }

    //Sort Remote IDs by processor so DoReverses will work
    Epetra_Util util;

  if(targetMap.GlobalIndicesLongLong())
  {
      util.Sort(true,NumRemoteIDs_,RemotePIDs,0,0, 1,&RemoteLIDs_, 1,(long long**)&RemoteGIDs);
  }
  else if(targetMap.GlobalIndicesInt())
  {
    int* ptrs[2] = {RemoteLIDs_, (int*)RemoteGIDs};
    util.Sort(true,NumRemoteIDs_,RemotePIDs,0,0,2,&ptrs[0], 0, 0);
  }
  else
  {
    throw ReportError("Epetra_Import::Epetra_Import: GlobalIndices Internal Error", -1);
  }

    Distor_ = sourceMap.Comm().CreateDistributor();
    
    // Construct list of exports that calling processor needs to send as a result
    // of everyone asking for what it needs to receive.
    
    bool Deterministic = true;
  int_type* tmp_ExportLIDs; //Export IDs come in as GIDs
  ierr = Distor_->CreateFromRecvs( NumRemoteIDs_, RemoteGIDs, RemotePIDs,
             Deterministic, NumExportIDs_, tmp_ExportLIDs, ExportPIDs_ );
  if (ierr!=0) throw ReportError("Error in Epetra_Distributor.CreateFromRecvs()", ierr);

  // Export IDs come in as GIDs, convert to LIDs
  if(targetMap.GlobalIndicesLongLong())
  {
    ExportLIDs_ = new int[NumExportIDs_];

    for (i=0; i< NumExportIDs_; i++) {
      if (ExportPIDs_[i] < 0) throw ReportError("targetMap requested a GID that is not in the sourceMap.", -1);
      ExportLIDs_[i] = sourceMap.LID(tmp_ExportLIDs[i]);
      NumSend_ += sourceMap.MaxElementSize(); // Count total number of entries to send (currently need max)
    }

    delete[] tmp_ExportLIDs;
  }
  else if(targetMap.GlobalIndicesInt())
  {
    for (i=0; i< NumExportIDs_; i++) {
      if (ExportPIDs_[i] < 0) throw ReportError("targetMap requested a GID that is not in the sourceMap.", -1);
      tmp_ExportLIDs[i] = sourceMap.LID(tmp_ExportLIDs[i]);
      NumSend_ += sourceMap.MaxElementSize(); // Count total number of entries to send (currently need max)
    }

    ExportLIDs_ = reinterpret_cast<int *>(tmp_ExportLIDs); // Can't reach here if tmp_ExportLIDs is long long.
  }
  else
  {
    throw ReportError("Epetra_Import::Epetra_Import: GlobalIndices Internal Error", -1);
  }
  }

  if( NumRemoteIDs_>0 ) delete [] RemoteGIDs;
  if( NumRemoteIDs_>0 ) delete [] RemotePIDs;

  if (NumTargetIDs>0) delete [] TargetGIDs;
  if (NumSourceIDs>0) delete [] SourceGIDs;
  
  return;
}
コード例 #14
0
int BlockMapToMatrixMarketFile( const char *filename, const Epetra_BlockMap & map, 
				 const char * mapName,
				 const char *mapDescription, 
				 bool writeHeader) {
  int M = map.NumGlobalElements();
  int N = 1;
  if (map.MaxElementSize()>1) N = 2; // Non-trivial block map, store element sizes in second column

  FILE * handle = 0;

  if (map.Comm().MyPID()==0) { // Only PE 0 does this section

    handle = fopen(filename,"w");
    if (!handle) return(-1);
    MM_typecode matcode;
    mm_initialize_typecode(&matcode);
    mm_set_matrix(&matcode);
    mm_set_array(&matcode);
    mm_set_integer(&matcode);

    if (writeHeader==true) { // Only write header if requested (true by default)
    
      if (mm_write_banner(handle, matcode)) return(-1);
      
      if (mapName!=0) fprintf(handle, "%% \n%% %s\n", mapName);
      if (mapDescription!=0) fprintf(handle, "%% %s\n%% \n", mapDescription);

    }
  }
    
  if (writeHeader==true) { // Only write header if requested (true by default)

    // Make an Epetra_IntVector of length numProc such that all elements are on PE 0 and
    // the ith element is NumMyElements from the ith PE

    Epetra_Map map1(-1, 1, 0, map.Comm()); // map with one element on each processor
    int length = 0;
    if (map.Comm().MyPID()==0) length = map.Comm().NumProc();
    Epetra_Map map2(-1, length, 0, map.Comm());
    Epetra_Import lengthImporter(map2, map1);
    Epetra_IntVector v1(map1);
    Epetra_IntVector v2(map2);
    v1[0] = map.NumMyElements();
    if (v2.Import(v1, lengthImporter, Insert)) return(-1);
    if (map.Comm().MyPID()==0) { 
      fprintf(handle, "%s", "%Format Version:\n");
      //int version = 1; // We may change the format scheme at a later date.
      fprintf(handle, "%% %d \n", map.Comm().NumProc());
      fprintf(handle, "%s", "%NumProc: Number of processors:\n");
      fprintf(handle, "%% %d \n", map.Comm().NumProc());
      fprintf(handle, "%s", "%MaxElementSize: Maximum element size:\n");
      fprintf(handle, "%% %d \n", map.MaxElementSize());
      fprintf(handle, "%s", "%MinElementSize: Minimum element size:\n");
      fprintf(handle, "%% %d \n", map.MinElementSize());
      fprintf(handle, "%s", "%IndexBase: Index base of map:\n");
      fprintf(handle, "%% %d \n", map.IndexBase());
      fprintf(handle, "%s", "%NumGlobalElements: Total number of GIDs in map:\n");
      fprintf(handle, "%% %d \n", map.NumGlobalElements());
      fprintf(handle, "%s", "%NumMyElements: BlockMap lengths per processor:\n");
      for ( int i=0; i< v2.MyLength(); i++) fprintf(handle, "%% %d\n", v2[i]);
      
      if (mm_write_mtx_array_size(handle, M, N)) return(-1);
    }
  }
  if (BlockMapToHandle(handle, map)) return(-1); // Everybody calls this routine
  
  if (map.Comm().MyPID()==0) // Only PE 0 opened a file
    if (fclose(handle)) return(-1);
  return(0);
}
コード例 #15
0
int BlockMapToHandle(FILE * handle, const Epetra_BlockMap & map) {

  const Epetra_Comm & comm = map.Comm();
  int numProc = comm.NumProc();
  bool doSizes = !map.ConstantElementSize();

  if (numProc==1) {
    int * myElements = map.MyGlobalElements();
    int * elementSizeList = 0;
    if (doSizes) elementSizeList = map.ElementSizeList();
    return(writeBlockMap(handle, map.NumGlobalElements(), myElements, elementSizeList, doSizes));
  }

  int numRows = map.NumMyElements();
  
  Epetra_Map allGidsMap(-1, numRows, 0,comm);
  
  Epetra_IntVector allGids(allGidsMap);
  for (int i=0; i<numRows; i++) allGids[i] = map.GID(i);
  
  Epetra_IntVector allSizes(allGidsMap);
  for (int i=0; i<numRows; i++) allSizes[i] = map.ElementSize(i);
  
  // Now construct a Map on PE 0 by strip-mining the rows of the input matrix map.
  int numChunks = numProc;
  int stripSize = allGids.GlobalLength()/numChunks;
  int remainder = allGids.GlobalLength()%numChunks;
  int curStart = 0;
  int curStripSize = 0;
  Epetra_IntSerialDenseVector importGidList;
  Epetra_IntSerialDenseVector importSizeList;
  if (comm.MyPID()==0) {
    importGidList.Size(stripSize+1); // Set size of vector to max needed
    if (doSizes) importSizeList.Size(stripSize+1); // Set size of vector to max needed
  }
  for (int i=0; i<numChunks; i++) {
    if (comm.MyPID()==0) { // Only PE 0 does this part
      curStripSize = stripSize;
      if (i<remainder) curStripSize++; // handle leftovers
      for (int j=0; j<curStripSize; j++) importGidList[j] = j + curStart;
      curStart += curStripSize;
    }
    // The following import map will be non-trivial only on PE 0.
    Epetra_Map importGidMap(-1, curStripSize, importGidList.Values(), 0, comm);
    Epetra_Import gidImporter(importGidMap, allGidsMap);
    
    Epetra_IntVector importGids(importGidMap);
    if (importGids.Import(allGids, gidImporter, Insert)) return(-1); 
    Epetra_IntVector importSizes(importGidMap);
    if (doSizes) if (importSizes.Import(allSizes, gidImporter, Insert)) return(-1); 
    
    // importGids (and importSizes, if non-trivial block map)
    // now have a list of GIDs (and sizes, respectively) for the current strip of map.
    
    int * myElements = importGids.Values();
    int * elementSizeList = 0;
    if (doSizes) elementSizeList = importSizes.Values();
    // Finally we are ready to write this strip of the map to file
    writeBlockMap(handle, importGids.MyLength(), myElements, elementSizeList, doSizes);
  }
  return(0);
}
コード例 #16
0
int MatrixMarketFileToMultiVector( const char *filename, const Epetra_BlockMap & map, Epetra_MultiVector * & A) {

  const int lineLength = 1025;
  const int tokenLength = 35;
  char line[lineLength];
  char token1[tokenLength];
  char token2[tokenLength];
  char token3[tokenLength];
  char token4[tokenLength];
  char token5[tokenLength];
  int M, N;

  FILE * handle = 0;

  handle = fopen(filename,"r");  // Open file
  if (handle == 0)
    EPETRA_CHK_ERR(-1); // file not found

  // Check first line, which should be "%%MatrixMarket matrix coordinate real general" (without quotes)
  if(fgets(line, lineLength, handle)==0) return(-1);
  if(sscanf(line, "%s %s %s %s %s", token1, token2, token3, token4, token5 )==0) return(-1);
  if (strcmp(token1, "%%MatrixMarket") ||
      strcmp(token2, "matrix") ||
      strcmp(token3, "array") ||
      strcmp(token4, "real") ||
      strcmp(token5, "general")) return(-1);

  // Next, strip off header lines (which start with "%")
  do {
    if(fgets(line, lineLength, handle)==0) return(-1);
  } while (line[0] == '%');

  // Next get problem dimensions: M, N
  if(sscanf(line, "%d %d", &M, &N)==0) return(-1);

  // Compute the offset for each processor for when it should start storing values
  int numMyPoints = map.NumMyPoints();
  int offset;
  map.Comm().ScanSum(&numMyPoints, &offset, 1); // ScanSum will compute offsets for us
  offset -= numMyPoints; // readjust for my PE

  // Now construct vector/multivector
  if (N==1)
    A = new Epetra_Vector(map);
  else
    A = new Epetra_MultiVector(map, N);

  double ** Ap = A->Pointers();

  for (int j=0; j<N; j++) {
    double * v = Ap[j];

    // Now read in lines that we will discard
    for (int i=0; i<offset; i++)
      if(fgets(line, lineLength, handle)==0) return(-1);
    
    // Now read in each value and store to the local portion of the the  if the row is owned.
    double V;
    for (int i=0; i<numMyPoints; i++) {
      if(fgets(line, lineLength, handle)==0) return(-1);
      if(sscanf(line, "%lg\n", &V)==0) return(-1);
      v[i] = V;
    }
    // Now read in the rest of the lines to discard
    for (int i=0; i < M-numMyPoints-offset; i++) {
      if(fgets(line, lineLength, handle)==0) return(-1);
    }
  }

  if (fclose(handle)) return(-1);
  
  return(0);
}
コード例 #17
0
int CopyMultiVector(double** matlabApr, const Epetra_MultiVector& A) {

  Epetra_BlockMap bmap = A.Map();
  const Epetra_Comm & comm = bmap.Comm();
  int numProc = comm.NumProc();

  if (numProc==1)
    DoCopyMultiVector(matlabApr, A);
  else {

    // In the case of more than one column in the multivector, and writing to MatrixMarket
    // format, we call this function recursively, passing each vector of the multivector
    // individually so that we can get all of it written to file before going on to the next 
    // multivector
    if (A.NumVectors() > 1) {
      for (int i=0; i < A.NumVectors(); i++)
	if (CopyMultiVector(matlabApr, *(A(i)))) return(-1);
      return(0);
    }

    Epetra_Map map(-1, bmap.NumMyPoints(), 0, comm);
    // Create a veiw of this multivector using a map (instead of block map)
    Epetra_MultiVector A1(View, map, A.Pointers(), A.NumVectors());
    int numRows = map.NumMyElements();
    
    Epetra_Map allGidsMap(-1, numRows, 0,comm);
    
    Epetra_IntVector allGids(allGidsMap);
    for (int i=0; i<numRows; i++) allGids[i] = map.GID(i);
    
    // Now construct a MultiVector on PE 0 by strip-mining the rows of the input matrix A.
    int numChunks = numProc;
    int stripSize = allGids.GlobalLength()/numChunks;
    int remainder = allGids.GlobalLength()%numChunks;
    int curStart = 0;
    int curStripSize = 0;
    Epetra_IntSerialDenseVector importGidList;
    int numImportGids = 0;
    if (comm.MyPID()==0) 
      importGidList.Size(stripSize+1); // Set size of vector to max needed
    for (int i=0; i<numChunks; i++) {
      if (comm.MyPID()==0) { // Only PE 0 does this part
	curStripSize = stripSize;
	if (i<remainder) curStripSize++; // handle leftovers
	for (int j=0; j<curStripSize; j++) importGidList[j] = j + curStart;
	curStart += curStripSize;
      }
      // The following import map will be non-trivial only on PE 0.
      Epetra_Map importGidMap(-1, curStripSize, importGidList.Values(), 0, comm);
      Epetra_Import gidImporter(importGidMap, allGidsMap);
      Epetra_IntVector importGids(importGidMap);
      if (importGids.Import(allGids, gidImporter, Insert)) return(-1); 

      // importGids now has a list of GIDs for the current strip of matrix rows.
      // Use these values to build another importer that will get rows of the matrix.

      // The following import map will be non-trivial only on PE 0.
      Epetra_Map importMap(-1, importGids.MyLength(), importGids.Values(), 0, comm);
      Epetra_Import importer(importMap, map);
      Epetra_MultiVector importA(importMap, A1.NumVectors());
      if (importA.Import(A1, importer, Insert)) return(-1); 

      // Finally we are ready to write this strip of the matrix to ostream
      if (DoCopyMultiVector(matlabApr, importA)) return(-1);
    }
  }
  return(0);
}
コード例 #18
0
int MultiVectorTests(const Epetra_BlockMap & Map, int NumVectors, bool verbose)
{
  (void)NumVectors;
  const Epetra_Comm & Comm = Map.Comm();
  int ierr = 0;
  
  /* get number of processors and the name of this processor */
  
  // int NumProc = Comm.getNumProc();
  int MyPID   = Comm.MyPID();
  
  // Construct FEVector
  
  if (verbose&&MyPID==0) cout << "constructing Epetra_FEVector" << endl;

  Epetra_FEVector A(Map, 1);
 
  //For an extreme test, we'll have each processor sum-in a 1.0 for All
  //global ids.

  int minGID = Map.MinAllGID();
  int numGlobalIDs = Map.NumGlobalElements();

  //For now we're going to have just one point associated with
  //each GID (element).

  int* ptIndices = new int[numGlobalIDs];
  double* ptCoefs = new double[numGlobalIDs];

  Epetra_IntSerialDenseVector epetra_indices(View, ptIndices, numGlobalIDs);
  Epetra_SerialDenseVector epetra_coefs(View, ptCoefs, numGlobalIDs);

  {for(int i=0; i<numGlobalIDs; ++i) {
    ptIndices[i] = minGID+i;
    ptCoefs[i] = 1.0;
  }}

  if (verbose&&MyPID==0) {
    cout << "calling A.SumIntoGlobalValues with " << numGlobalIDs << " values"<<endl;
  }
  EPETRA_TEST_ERR( A.SumIntoGlobalValues(numGlobalIDs, ptIndices, ptCoefs), ierr);

  if (verbose&&MyPID==0) {
    cout << "calling A.SumIntoGlobalValues with " << numGlobalIDs << " values"<<endl;
  }
  EPETRA_TEST_ERR( A.SumIntoGlobalValues(epetra_indices, epetra_coefs), ierr);

  if (verbose&&MyPID==0) {
    cout << "calling A.GlobalAssemble()" << endl;
  }

  EPETRA_TEST_ERR( A.GlobalAssemble(), ierr );

  if (verbose&&MyPID==0) {
  cout << "after globalAssemble"<<endl;
  }
  if (verbose) {
  A.Print(cout);
  }

  //now do a quick test of the copy constructor
  Epetra_FEVector B(A);

  double nrm2a, nrm2b;
  A.Norm2(&nrm2a);
  B.Norm2(&nrm2b);

  if (nrm2a != nrm2b) {
    cerr << "copy-constructor test failed, norm of copy doesn't equal"
         << " norm of original."<<endl;
    return(-1);
  }

  delete [] ptIndices;
  delete [] ptCoefs;

  return(ierr);
}
コード例 #19
0
void Epetra_Import::Construct_Expert( const Epetra_BlockMap &  targetMap, const Epetra_BlockMap & sourceMap, int NumRemotePIDs, const int * UserRemotePIDs,
				      const int & UserNumExportIDs, const int * UserExportLIDs,  const int * UserExportPIDs)
{
  int i,ierr;
  // Build three ID lists:
  // NumSameIDs - Number of IDs in TargetMap and SourceMap that are identical, up to the first
  //              nonidentical ID.
  // NumPermuteIDs - Number of IDs in SourceMap that must be indirectly loaded but are on this processor.
  // NumRemoteIDs - Number of IDs that are in SourceMap but not in TargetMap, and thus must be imported.
  
  int NumSourceIDs = sourceMap.NumMyElements();
  int NumTargetIDs = targetMap.NumMyElements();
  
  int_type *TargetGIDs = 0;
  if (NumTargetIDs>0) {
    TargetGIDs = new int_type[NumTargetIDs];
    targetMap.MyGlobalElements(TargetGIDs);
  }
  
  int_type * SourceGIDs = 0;
  if (NumSourceIDs>0) {
    SourceGIDs = new int_type[NumSourceIDs];
    sourceMap.MyGlobalElements(SourceGIDs);
  }
  
  int MinIDs = EPETRA_MIN(NumSourceIDs, NumTargetIDs);
    
  NumSameIDs_ = 0;
  for (i=0; i< MinIDs; i++) if (TargetGIDs[i]==SourceGIDs[i]) NumSameIDs_++; else break;
  
  // Find count of Target IDs that are truly remote and those that are local but permuted
  NumPermuteIDs_ = 0;
  NumRemoteIDs_ = 0;
  for (i=NumSameIDs_; i< NumTargetIDs; i++) 
    if (sourceMap.MyGID(TargetGIDs[i])) NumPermuteIDs_++; // Check if Target GID is a local Source GID
    else NumRemoteIDs_++; // If not, then it is remote
     
  // Define remote and permutation lists  
  int_type * RemoteGIDs=0;
  RemoteLIDs_ = 0;
  if (NumRemoteIDs_>0) {
    RemoteLIDs_ = new int[NumRemoteIDs_];
    RemoteGIDs = new int_type[NumRemoteIDs_];
  }
  if (NumPermuteIDs_>0)  {
    PermuteToLIDs_ = new int[NumPermuteIDs_];
    PermuteFromLIDs_ = new int[NumPermuteIDs_];
  }
  
  NumPermuteIDs_ = 0;
  NumRemoteIDs_ = 0;
  for (i=NumSameIDs_; i< NumTargetIDs; i++) {
    if (sourceMap.MyGID(TargetGIDs[i])) {
      PermuteToLIDs_[NumPermuteIDs_] = i;
      PermuteFromLIDs_[NumPermuteIDs_++] = sourceMap.LID(TargetGIDs[i]);
    }
    else {
      //NumRecv_ +=TargetMap.ElementSize(i); // Count total number of entries to receive
      NumRecv_ +=targetMap.MaxElementSize(); // Count total number of entries to receive (currently need max)
      RemoteGIDs[NumRemoteIDs_] = TargetGIDs[i];
      RemoteLIDs_[NumRemoteIDs_++] = i;
    }
  }

  if( NumRemoteIDs_>0 && !sourceMap.DistributedGlobal() )
    ReportError("Warning in Epetra_Import: Serial Import has remote IDs. (Importing to Subset of Target Map)", 1);
  
  // Test for distributed cases
  int * RemotePIDs = 0;
  
  if (sourceMap.DistributedGlobal()) {
    if (NumRemoteIDs_>0)  RemotePIDs = new int[NumRemoteIDs_];
  
#ifdef EPETRA_ENABLE_DEBUG
    int myeq = (NumRemotePIDs==NumRemoteIDs_);
    int globaleq=0;
    sourceMap.Comm().MinAll(&myeq,&globaleq,1);
    if(globaleq!=1) { 
      printf("[%d] UserRemotePIDs count wrong %d != %d\n",sourceMap.Comm().MyPID(),NumRemotePIDs,NumRemoteIDs_);
      fflush(stdout);
      sourceMap.Comm().Barrier();
      sourceMap.Comm().Barrier();
      sourceMap.Comm().Barrier();
      throw ReportError("Epetra_Import: UserRemotePIDs count wrong");
    }
#endif

    if(NumRemotePIDs==NumRemoteIDs_){
      // Since I need to sort these, I'll copy them
      for(i=0; i<NumRemoteIDs_; i++)  RemotePIDs[i] = UserRemotePIDs[i];
    }

    //Get rid of IDs that don't exist in SourceMap
    if(NumRemoteIDs_>0) {
      int cnt = 0;
      for( i = 0; i < NumRemoteIDs_; ++i )
        if( RemotePIDs[i] == -1 ) ++cnt;
      if( cnt ) {
        if( NumRemoteIDs_-cnt ) {
          int_type * NewRemoteGIDs = new int_type[NumRemoteIDs_-cnt];
          int * NewRemotePIDs = new int[NumRemoteIDs_-cnt];
          int * NewRemoteLIDs = new int[NumRemoteIDs_-cnt];
          cnt = 0;
          for( i = 0; i < NumRemoteIDs_; ++i )
            if( RemotePIDs[i] != -1 ) {
              NewRemoteGIDs[cnt] = RemoteGIDs[i];
              NewRemotePIDs[cnt] = RemotePIDs[i];
              NewRemoteLIDs[cnt] = targetMap.LID(RemoteGIDs[i]);
              ++cnt;
            }
          NumRemoteIDs_ = cnt;
          delete [] RemoteGIDs;
          delete [] RemotePIDs;
          delete [] RemoteLIDs_;
          RemoteGIDs = NewRemoteGIDs;
          RemotePIDs = NewRemotePIDs;
          RemoteLIDs_ = NewRemoteLIDs;
          ReportError("Warning in Epetra_Import: Target IDs not found in Source Map (Do you want to import to subset of Target Map?)", 1);
        }
        else { //valid RemoteIDs empty
          NumRemoteIDs_ = 0;
          delete [] RemoteGIDs;
          RemoteGIDs = 0;
          delete [] RemotePIDs;
          RemotePIDs = 0;
        }
      }
    }

    //Sort Remote IDs by processor so DoReverses will work
    Epetra_Util util;
    
    if(targetMap.GlobalIndicesLongLong())
      {
	util.Sort(true,NumRemoteIDs_,RemotePIDs,0,0, 1,&RemoteLIDs_, 1,(long long**)&RemoteGIDs);
      }
    else if(targetMap.GlobalIndicesInt())
      {
	int* ptrs[2] = {RemoteLIDs_, (int*)RemoteGIDs};
	util.Sort(true,NumRemoteIDs_,RemotePIDs,0,0,2,&ptrs[0], 0, 0);
      }
    else
      {
	throw ReportError("Epetra_Import::Epetra_Import: GlobalIndices Internal Error", -1);
      }
    
    // Build distributor & Export lists
    Distor_ = sourceMap.Comm().CreateDistributor();    
    
    NumExportIDs_=UserNumExportIDs;
    ExportLIDs_ = new int[NumExportIDs_];
    ExportPIDs_ = new int[NumExportIDs_];
    for(i=0; i<NumExportIDs_; i++)  {
      ExportPIDs_[i] = UserExportPIDs[i];
      ExportLIDs_[i] = UserExportLIDs[i];
    }

#ifdef HAVE_MPI
    Epetra_MpiDistributor* MpiDistor = dynamic_cast< Epetra_MpiDistributor*>(Distor_);
    bool Deterministic = true;
    if(MpiDistor)
      ierr=MpiDistor->CreateFromSendsAndRecvs(NumExportIDs_,ExportPIDs_,					      
					      NumRemoteIDs_, RemoteGIDs, RemotePIDs,Deterministic);
    else ierr=-10;
#else
    ierr=-20;
#endif
    
    if (ierr!=0) throw ReportError("Error in Epetra_Distributor.CreateFromRecvs()", ierr);   
  }  

  if( NumRemoteIDs_>0 ) delete [] RemoteGIDs;
  if( NumRemoteIDs_>0 ) delete [] RemotePIDs;
  
  if (NumTargetIDs>0) delete [] TargetGIDs;
  if (NumSourceIDs>0) delete [] SourceGIDs;


#ifdef EPETRA_ENABLE_DEBUG
// Sanity check to make sure we got the import right
  Epetra_IntVector Source(sourceMap);
  Epetra_IntVector Target(targetMap);

  for(i=0; i<Source.MyLength(); i++)
    Source[i] = (int) (Source.Map().GID(i) % INT_MAX);
  Target.PutValue(-1);
 
  Target.Import(Source,*this,Insert);
  
  bool test_passed=true;
  for(i=0; i<Target.MyLength(); i++){
    if(Target[i] != Target.Map().GID(i) % INT_MAX) test_passed=false;
  }

  if(!test_passed) {  
    printf("[%d] PROCESSOR has a mismatch... prepearing to crash or hang!\n",sourceMap.Comm().MyPID());
    fflush(stdout);
    sourceMap.Comm().Barrier();
    sourceMap.Comm().Barrier();
    sourceMap.Comm().Barrier();
    throw ReportError("Epetra_Import: ERROR. User provided IDs do not match what an import generates.");
  }
#endif
  
  return;
}
コード例 #20
0
ファイル: checkmap.cpp プロジェクト: cakeisalie/oomphlib_003
int checkmap(Epetra_BlockMap & Map, int NumGlobalElements, int NumMyElements, 
	     int *MyGlobalElements, int ElementSize, int * ElementSizeList,
	     int NumGlobalPoints, int NumMyPoints,
	     int IndexBase, Epetra_Comm& Comm,
	     bool DistributedGlobal,
	     bool IsOneToOne)
{

  int i, ierr=0, forierr=0;// forierr is used in for loops, then is tested
  // after for loop completes to see if it is non zero - potentially prevents
  // thousands of error messages

  if (ElementSizeList==0)
    {
      EPETRA_TEST_ERR(!Map.ConstantElementSize(),ierr);
    }
  else
    EPETRA_TEST_ERR(Map.ConstantElementSize(),ierr);
  
  EPETRA_TEST_ERR(DistributedGlobal!=Map.DistributedGlobal(),ierr);

  EPETRA_TEST_ERR(IsOneToOne!=Map.IsOneToOne(),ierr);

  int *MyElementSizeList;

  if (ElementSizeList==0)
    {
      EPETRA_TEST_ERR(Map.ElementSize()!=ElementSize,ierr);
      
      MyElementSizeList = new int[NumMyElements];
      
      EPETRA_TEST_ERR(Map.ElementSizeList(MyElementSizeList)!=0,ierr);
      forierr = 0;
      for (i=0; i<NumMyElements; i++) 
        forierr += MyElementSizeList[i]!=ElementSize;
      EPETRA_TEST_ERR(forierr,ierr);

      EPETRA_TEST_ERR(Map.MaxMyElementSize() != ElementSize,ierr);
      EPETRA_TEST_ERR(Map.MinMyElementSize() != ElementSize,ierr);
    }
  else
    {
      MyElementSizeList = new int[NumMyElements];
      EPETRA_TEST_ERR(Map.ElementSizeList(MyElementSizeList)!=0,ierr);
      int MaxSize = MyElementSizeList[0];
      int MinSize = MyElementSizeList[0];
      forierr=0;
      for (i=0; i<NumMyElements; i++) {
        forierr += MyElementSizeList[i]!=ElementSizeList[i];
	if (MyElementSizeList[i] > MaxSize)
	  MaxSize = MyElementSizeList[i];
	if (MyElementSizeList[i] < MinSize)
	  MinSize = MyElementSizeList[i];

	// Test ElementSize(int LID) method	

	forierr += Map.ElementSize(Map.LID(MyGlobalElements[i])) != ElementSizeList[i];
      }
      EPETRA_TEST_ERR(forierr,ierr);
   
      EPETRA_TEST_ERR(MaxSize !=Map.MaxMyElementSize(),ierr);
      EPETRA_TEST_ERR(MinSize !=Map.MinMyElementSize(),ierr);
    }

  const Epetra_Comm & Comm1 = Map.Comm();

  EPETRA_TEST_ERR(Comm1.NumProc()!=Comm.NumProc(),ierr);

  EPETRA_TEST_ERR(Comm1.MyPID()!=Comm.MyPID(),ierr);

  EPETRA_TEST_ERR(Map.IndexBase()!=IndexBase,ierr);

  EPETRA_TEST_ERR(!Map.LinearMap() && MyGlobalElements==0,ierr);

  EPETRA_TEST_ERR(Map.LinearMap() && MyGlobalElements!=0,ierr);

  EPETRA_TEST_ERR(Map.MaxAllGID()!=NumGlobalElements-1+IndexBase,ierr);

  EPETRA_TEST_ERR(Map.MaxElementSize()!=ElementSize,ierr);

  int MaxLID = Map.MaxLID();
  EPETRA_TEST_ERR(MaxLID!=NumMyElements-1,ierr);

  int MaxMyGID = (Comm.MyPID()+1)*NumMyElements-1+IndexBase;
  if (Comm.MyPID()>2) MaxMyGID+=3;
  if (!DistributedGlobal) MaxMyGID = NumMyElements-1+IndexBase;
  EPETRA_TEST_ERR(Map.MaxMyGID()!=MaxMyGID,ierr);

  EPETRA_TEST_ERR(Map.MinAllGID()!=IndexBase,ierr);

  if (ElementSizeList==0)
    {
      EPETRA_TEST_ERR(Map.MinElementSize()!=ElementSize,ierr);
    }
  else EPETRA_TEST_ERR(Map.MinElementSize()!=2,ierr);

  int MinLID = Map.MinLID();
  EPETRA_TEST_ERR(MinLID!=0,ierr);

  int MinMyGID = Comm.MyPID()*NumMyElements+IndexBase;
  if (Comm.MyPID()>2) MinMyGID+=3;
  if (!DistributedGlobal) MinMyGID = IndexBase; // Not really needed
  EPETRA_TEST_ERR(Map.MinMyGID()!=MinMyGID,ierr);

  int * MyGlobalElements1 = new int[NumMyElements];
  EPETRA_TEST_ERR(Map.MyGlobalElements(MyGlobalElements1)!=0,ierr);
  
  forierr = 0;
  if (MyGlobalElements==0) {
    for (i=0; i<NumMyElements; i++) 
      forierr += MyGlobalElements1[i]!=MinMyGID+i;
    EPETRA_TEST_ERR(forierr,ierr);
  }
  else {
    for (i=0; i<NumMyElements; i++)
      forierr += MyGlobalElements[i]!=MyGlobalElements1[i];
    EPETRA_TEST_ERR(forierr,ierr);
  }
  EPETRA_TEST_ERR(Map.NumGlobalElements()!=NumGlobalElements,ierr);
  
  EPETRA_TEST_ERR(Map.NumGlobalPoints()!=NumGlobalPoints,ierr);
  
  EPETRA_TEST_ERR(Map.NumMyElements()!=NumMyElements,ierr);  

  EPETRA_TEST_ERR(Map.NumMyPoints()!=NumMyPoints,ierr);

  int MaxMyGID2 = Map.GID(Map.LID(MaxMyGID));
  EPETRA_TEST_ERR(MaxMyGID2 != MaxMyGID,ierr);
  int MaxLID2 = Map.LID(Map.GID(MaxLID));
  EPETRA_TEST_ERR(MaxLID2 != MaxLID,ierr);

  EPETRA_TEST_ERR(Map.GID(MaxLID+1) != IndexBase-1,ierr);// MaxLID+1 doesn't exist
  EPETRA_TEST_ERR(Map.LID(MaxMyGID+1) != -1,ierr);// MaxMyGID+1 doesn't exist or is on a different processor

  EPETRA_TEST_ERR(!Map.MyGID(MaxMyGID),ierr);
  EPETRA_TEST_ERR(Map.MyGID(MaxMyGID+1),ierr);

  EPETRA_TEST_ERR(!Map.MyLID(MaxLID),ierr);
  EPETRA_TEST_ERR(Map.MyLID(MaxLID+1),ierr);

  EPETRA_TEST_ERR(!Map.MyGID(Map.GID(MaxLID)),ierr);
  EPETRA_TEST_ERR(Map.MyGID(Map.GID(MaxLID+1)),ierr);

  EPETRA_TEST_ERR(!Map.MyLID(Map.LID(MaxMyGID)),ierr);
  EPETRA_TEST_ERR(Map.MyLID(Map.LID(MaxMyGID+1)),ierr);

  // Test the FirstPointInElementList methods, begin by testing that they produce identical results
  int * FirstPointInElementList = new int[NumMyElements+1];
  Map.FirstPointInElementList(FirstPointInElementList);
  int * FirstPointInElementList1 = Map.FirstPointInElementList();
  forierr = 0;
  for (i=0; i<=NumMyElements; i++)
    forierr += FirstPointInElementList[i]!=FirstPointInElementList1[i];
  EPETRA_TEST_ERR(forierr,ierr);
  // Now make sure values are correct
  forierr = 0;
  if (Map.ConstantElementSize()) {
    for (i=0; i<=NumMyElements; i++)
      forierr += FirstPointInElementList1[i]!=(i*ElementSize);// NOTE:FirstPointInElement[NumMyElements] is not the first point of an element
    EPETRA_TEST_ERR(forierr,ierr);
  }
  else {
    int FirstPoint = 0;
    for (i=0; i<NumMyElements; i++) {
      forierr += FirstPointInElementList1[i]!=FirstPoint;
      FirstPoint += ElementSizeList[i];
    }
    EPETRA_TEST_ERR(forierr,ierr);
    EPETRA_TEST_ERR(FirstPointInElementList[NumMyElements] != NumMyPoints,ierr);// The last entry in the array = the total number of Points on the proc
  }
  delete [] FirstPointInElementList;

  // Declare some variables for the FindLocalElementID test
  int ElementID, Offset;
  // Test the PointToElementList methods, begin by testing that they produce identical results
  int * PointToElementList = new int[NumMyPoints];
  Map.PointToElementList(PointToElementList);
  int * PointToElementList1 = Map.PointToElementList();
  forierr = 0;
  for (i=0; i<NumMyPoints; i++)
    forierr += PointToElementList1[i] != PointToElementList[i];
  EPETRA_TEST_ERR(forierr,ierr);
  //Now make sure values are correct
  forierr=0;
  if (Map.ConstantElementSize()) {
    for (i=0; i<NumMyElements; i++)
      for (int j=0; j<ElementSize; j++) {
	forierr += PointToElementList[i*ElementSize+j] != i;
	// Test FindLocalElementID method
	Map.FindLocalElementID(i*ElementSize+j,ElementID,Offset);
	forierr += ElementID != i || Offset != j;
      }
    EPETRA_TEST_ERR(forierr,ierr);
  }
  else {
    int MyPointTot = 0; // Keep track of total number of points in all previously completely checked elements
    for (i=0; i<NumMyElements; i++) {
      for (int j=0; j<ElementSizeList[i]; j++) {
	forierr += PointToElementList[MyPointTot+j] != i;
	// Test FindLocalElementID method
	Map.FindLocalElementID(MyPointTot+j,ElementID,Offset);
	forierr += ElementID != i || Offset != j;
      }
      MyPointTot += ElementSizeList[i];
    }
    EPETRA_TEST_ERR(forierr,ierr);
  }
  delete [] PointToElementList;

  // Check RemoteIDList function that includes a parameter for size
  // Get some GIDs off of each processor to test
  int TotalNumEle, NumElePerProc, NumProc = Comm.NumProc();
  int MinNumEleOnProc;
  int NumMyEle = Map.NumMyElements();
  Comm.MinAll(&NumMyEle,&MinNumEleOnProc,1);
  if (MinNumEleOnProc > 5) NumElePerProc = 6;
  else NumElePerProc = MinNumEleOnProc;
  if (NumElePerProc > 0) {
    TotalNumEle = NumElePerProc*NumProc;
    int * MyGIDlist = new int[NumElePerProc];
    int * GIDlist = new int[TotalNumEle];
    int * PIDlist = new int[TotalNumEle];
    int * LIDlist = new int[TotalNumEle];
    int * SizeList = new int[TotalNumEle];
    for (i=0; i<NumElePerProc; i++)
	  MyGIDlist[i] = MyGlobalElements1[i];
    Comm.GatherAll(MyGIDlist,GIDlist,NumElePerProc);// Get a few values from each proc
    Map.RemoteIDList(TotalNumEle, GIDlist, PIDlist, LIDlist, SizeList);
    int MyPID= Comm.MyPID();
    forierr = 0;
    for (i=0; i<TotalNumEle; i++) {
      if (Map.MyGID(GIDlist[i])) {
	forierr += PIDlist[i] != MyPID;
	forierr += !Map.MyLID(Map.LID(GIDlist[i])) || Map.LID(GIDlist[i]) != LIDlist[i] || Map.GID(LIDlist[i]) != GIDlist[i];
	forierr += SizeList[i] != Map.ElementSize(LIDlist[i]);
      }
      else {
	forierr += PIDlist[i] == MyPID; // If MyGID comes back false, the PID listed should be that of another proc
      }
    }
    EPETRA_TEST_ERR(forierr,ierr);

    delete [] MyGIDlist;
    delete [] GIDlist;
    delete [] PIDlist;
    delete [] LIDlist;
    delete [] SizeList;
  }

  delete [] MyGlobalElements1;
  delete [] MyElementSizeList;

  // Check RemoteIDList function (assumes all maps are linear, even if not stored that way)

  if (Map.LinearMap()) {

    int * GIDList = new int[3];
    int * PIDList = new int[3];
    int * LIDList = new int[3];
    int MyPID = Map.Comm().MyPID();
  
    int NumIDs = 0;
    //GIDList[NumIDs++] = Map.MaxAllGID()+1; // Should return -1 for both PID and LID
    if (Map.MinMyGID()-1>=Map.MinAllGID()) GIDList[NumIDs++] = Map.MinMyGID()-1;
    if (Map.MaxMyGID()+1<=Map.MaxAllGID()) GIDList[NumIDs++] = Map.MaxMyGID()+1;

    Map.RemoteIDList(NumIDs, GIDList, PIDList, LIDList);

    NumIDs = 0;

    //EPETRA_TEST_ERR(!(PIDList[NumIDs]==-1),ierr);
    //EPETRA_TEST_ERR(!(LIDList[NumIDs++]==-1),ierr);

    if (Map.MinMyGID()-1>=Map.MinAllGID()) EPETRA_TEST_ERR(!(PIDList[NumIDs++]==MyPID-1),ierr);
    if (Map.MaxMyGID()+1<=Map.MaxAllGID()) EPETRA_TEST_ERR(!(PIDList[NumIDs]==MyPID+1),ierr);
    if (Map.MaxMyGID()+1<=Map.MaxAllGID()) EPETRA_TEST_ERR(!(LIDList[NumIDs++]==0),ierr);

    delete [] GIDList;
    delete [] PIDList;
    delete [] LIDList;


  }
  return (ierr);
}
コード例 #21
0
static int compute_hypergraph_metrics(const Epetra_BlockMap &rowmap, 
            const Epetra_BlockMap &colmap,
            int numGlobalColumns,
            Isorropia::Epetra::CostDescriber &costs,
            double &myGoalWeight,
            double &balance, double &cutn, double &cutl)  // output
{
  const Epetra_Comm &comm  = rowmap.Comm();
#ifdef HAVE_MPI
  const Epetra_MpiComm* mpiComm =
    dynamic_cast<const Epetra_MpiComm*>(&comm);

  MPI_Comm mcomm = mpiComm->Comm();
#endif
  int nProcs = comm.NumProc();
  int myProc = comm.MyPID();
  double min, avg;
  std::map<int, float> vertexWeights;
  std::map<int, std::map<int, float > > graphEdgeWeights;
  std::map<int, float> hyperEdgeWeights;

  costs.getCosts(vertexWeights,  // vertex global ID -> weight
           graphEdgeWeights,    //  vertex global ID -> map from neighbor global ID to edge weight
           hyperEdgeWeights);   // hyperedge global ID -> weight

  Epetra_Vector vwgt(rowmap);
  int numVWgts = vertexWeights.size();

  if (numVWgts > 0){
    double *wvals = new double [numVWgts];
    int *gids = new int [numVWgts];

    std::map<int, float>::iterator vnext = vertexWeights.begin();
    int i=0;
    while (vnext != vertexWeights.end()){
      wvals[i] =  vnext->second;
      gids[i] = vnext->first;
      vnext++;
      i++;
    }

    vwgt.ReplaceGlobalValues(i, wvals, gids);

    delete [] wvals;
    delete [] gids;
  }
  else{
    vwgt.PutScalar(1.0);   // default to unit weights
  }

  compute_balance(vwgt, myGoalWeight, min, balance, avg);

  if (balance < 0){
    return 1;
  }

  /* Compute cutl and cutn. 
   */

  int totalHEWeights = 0; 

  int numHEWeights = hyperEdgeWeights.size();

  comm.SumAll(&numHEWeights, &totalHEWeights, 1);
 
  if ((totalHEWeights > 0) && (totalHEWeights <  numGlobalColumns)){
    if (myProc == 0)
      std::cerr << "Must supply either no h.e. weights or else supply at least one for each column" << std::endl;
      return -1;
  }

  std::map<int, float>::iterator heWgtIter;

  // Create a set containing all the columns in my rows.  We assume all
  // the rows are in the same partition.

  int numMyCols = colmap.NumMyElements();

  std::set<int> colGIDS;
  std::set<int>::iterator gidIter;

  for (int j=0; j<numMyCols; j++){
    colGIDS.insert(colmap.GID(j));
  }
  
  /* Divide columns among processes, then each process computes its
   * assigned columns' cutl and cutn.
   *  TODO - numGlobalColumns can be less than nprocs

   * Fix this when a process is assigned no columns. TODO
   */
  int ncols = numGlobalColumns / nProcs;
  int leftover = numGlobalColumns - (nProcs * ncols);
  std::vector<int> colCount(nProcs, 0);
  for (int i=0; i<nProcs; i++){
    colCount[i] = ncols;
    if (i < leftover) colCount[i]++;
  }
  int *colTotals = NULL;
  double *colWeights = NULL;
  if (colCount[myProc] > 0){
    colTotals = new int [colCount[myProc]];
    if (totalHEWeights > 0){
      colWeights = new double [colCount[myProc]];
    } 
  }
  int *colLocal= new int [ncols + 1];
  double *localWeights = NULL;
  if (totalHEWeights > 0){
    localWeights = new double [ncols + 1];
  }

  int base = colmap.IndexBase();
  int colStart = base;

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

    // All processes send info to the process reponsible
    // for the next group of columns

    int ncols = colCount[i];
    int colEnd = colStart + ncols;
    for (int j=colStart,k=0; j < colEnd; j++,k++){
      gidIter = colGIDS.find(j);
      if (gidIter != colGIDS.end()){
        colLocal[k] = 1;     // column j has rows in my partition
      }
      else{
        colLocal[k] = 0;
      }
      if (totalHEWeights > 0){
        std::map<int, float>::iterator heWgtIter = hyperEdgeWeights.find(j);
        if (heWgtIter != hyperEdgeWeights.end()){
          // I have the edge weight for column j
          localWeights[k] = heWgtIter->second;
        }
        else{
          localWeights[k] = 0.0;
        }
      }
      
    }
#ifdef HAVE_MPI
    int rc = MPI_Reduce(colLocal, colTotals, ncols, MPI_INT, MPI_SUM, i, mcomm);
    if (totalHEWeights > 0){
      rc = MPI_Reduce(localWeights, colWeights, ncols, MPI_DOUBLE, MPI_SUM, i, mcomm);
    }
    // TODO handle possible MPI error
#else
    memcpy(colTotals, colLocal, ncols * sizeof(int));
    if (totalHEWeights > 0){
      memcpy(colWeights, localWeights, ncols * sizeof(double));
    }
#endif
    colStart = colEnd;
  }

  delete [] colLocal;
  if (localWeights) delete [] localWeights;

  double localCutN=0;
  double localCutL=0;
  double ewgt = 1.0;

  for (int j=0; j<colCount[myProc]; j++){
    if (totalHEWeights > 0){
      ewgt = colWeights[j];
    }
    if (colTotals[j] > 1){
      localCutL += (colTotals[j] - 1) * ewgt; // # of cuts in columns/edges
      localCutN += ewgt;                      // # of cut columns/edges
    }
  }
  if (colTotals) delete [] colTotals;
  if (colWeights) delete [] colWeights;

  comm.SumAll(&localCutN, &cutn, 1);
  comm.SumAll(&localCutL, &cutl, 1);

  return 0;
}
コード例 #22
0
static int compute_graph_metrics(const Epetra_BlockMap &rowmap, const Epetra_BlockMap &colmap,
            std::vector<std::vector<int> > &rows, 
            Isorropia::Epetra::CostDescriber &costs, double &myGoalWeight,
            double &balance, int &numCuts, double &cutWgt, double &cutn, double &cutl)
{
  const Epetra_Comm &comm  = rowmap.Comm();
  int myProc = comm.MyPID();
  int myCols = colmap.NumMyElements();
  double min, avg;
  std::map<int, float> vertexWeights;
  std::map<int, std::map<int, float > > graphEdgeWeights;
  std::map<int, float> hyperEdgeWeights;

  costs.getCosts(vertexWeights,  // vertex global ID -> weight
           graphEdgeWeights,    //  vertex global ID -> map from neighbor global ID to edge weight
           hyperEdgeWeights);   // hyperedge global ID -> weight

  // Compute the balance

  Epetra_Vector vwgt(rowmap);
  int numVWgts = vertexWeights.size();

  if (numVWgts > 0){
    double *wvals = new double [numVWgts];
    int *gids = new int [numVWgts];

    std::map<int, float>::iterator vnext = vertexWeights.begin();
    int i=0;
    while (vnext != vertexWeights.end()){
      wvals[i] =  vnext->second;
      gids[i] = vnext->first;
      vnext++;
      i++;
    }

    vwgt.ReplaceGlobalValues(i, wvals, gids);

    delete [] wvals;
    delete [] gids;
  }
  else{
    vwgt.PutScalar(1.0);   // default to unit weights
  }

  compute_balance(vwgt, myGoalWeight, min, balance, avg);

  if (balance < 0){
    return 1;
  }

  // Compute the measures based on cut edges

  int *procID = new int [myCols];
  int *GID = new int [myCols];
  int *tmp = new int [myCols];

  for (int i=0; i < myCols; i++){
    GID[i] = colmap.GID(i);
  }

  rowmap.RemoteIDList(myCols, GID, procID, tmp);  // matrix is square

  delete [] tmp;

  int haveEdgeWeights = graphEdgeWeights.size();

  int localNumCuts = 0;
  double localCutWgt = 0.0;
  double localCutn = 0.0;
  double localCutl = 0.0;

  for (int i=0; i < rowmap.NumMyElements(); i++){
    int vtxGID = rowmap.GID(i);

    int numEdges = rows[i].size();

    if (numEdges > 0){

      std::map<int, std::map<int, float> >::iterator wnext;
      if (haveEdgeWeights){
        wnext = graphEdgeWeights.find(vtxGID);
        if (wnext == graphEdgeWeights.end()){
          std::cerr << "Graph edge weights are missing for vertex " << vtxGID;
          std::cerr << std::endl;
          return -1;
        }
      }

      double heWeight = 0.0;
      std::set<int> nbors;

      for (int j=0; j < numEdges; j++){

        int colGID = GID[rows[i][j]];

        int nborProc = procID[rows[i][j]];

        if (colGID == vtxGID) continue;  // skip self edges

        float wgt = 1.0;
        if (haveEdgeWeights){
          std::map<int, float>::iterator curr = (wnext->second).find(colGID);
          if (curr == (wnext->second).end()){
            std::cerr << "Graph edge weights do not match matrix";
            std::cerr << std::endl;
            return -1;
          }
          wgt = curr->second;
        }

        if (nborProc != myProc){
          localNumCuts++;            // number of graph edges that are cut 
          nbors.insert(nborProc);     // count number of neighboring processes
          localCutWgt += wgt;        // sum of weights of cut edges
        }
        heWeight += wgt;             // implied hyperedge weight, sum all edges
      }
      int numNbors = nbors.size();

      if (numNbors > 0){
        // implied hyperedge is vertex and neighbors, if cut, add in its he weight
        localCutn += heWeight;   

        // sum of (number of partitions - 1) weighted by the 
        // implied hyperedge weight
        localCutl += (numNbors * heWeight);
      }
    }
  } // next vertex in my partition

  delete [] GID;
  delete [] procID;

  double lval[4], gval[4];

  lval[0] = (double)localNumCuts;
  lval[1] = localCutWgt;
  lval[2] = localCutn;
  lval[3] = localCutl;

  comm.SumAll(lval, gval, 4);

  numCuts = (int)gval[0];
  cutWgt = gval[1];
  cutn   = gval[2];
  cutl   = gval[3];

  return 0;
}
コード例 #23
0
ファイル: Epetra_Export.cpp プロジェクト: EllieGong/trilinos
void Epetra_Export::Construct( const Epetra_BlockMap &  sourceMap, const Epetra_BlockMap & targetMap)
{

  int i;

  // Build three ID lists:
  // NumSameIDs - Number of IDs in TargetMap and SourceMap that are identical, up to the first
  //              nonidentical ID.
  // NumPermuteIDs - Number of IDs in SourceMap that must be indirectly loaded but are on this processor.
  // NumExportIDs - Number of IDs that are in SourceMap but not in TargetMap, and thus must be exported.

  int NumSourceIDs = sourceMap.NumMyElements();
  int NumTargetIDs = targetMap.NumMyElements();

  int_type *TargetGIDs = 0;
  if (NumTargetIDs>0) {
    TargetGIDs = new int_type[NumTargetIDs];
    targetMap.MyGlobalElements(TargetGIDs);
  }

  int_type * SourceGIDs = 0;
  if (NumSourceIDs>0) {
    SourceGIDs = new int_type[NumSourceIDs];
    sourceMap.MyGlobalElements(SourceGIDs);
  }

  int MinIDs = EPETRA_MIN(NumSourceIDs, NumTargetIDs);

  NumSameIDs_ = 0;
  for (i=0; i< MinIDs; i++) if (TargetGIDs[i]==SourceGIDs[i]) NumSameIDs_++; else break;

  // Find count of Source IDs that are truly remote and those that are local but permuted

  NumPermuteIDs_ = 0;
  NumExportIDs_ = 0;
  for (i=NumSameIDs_; i< NumSourceIDs; i++)
    if (targetMap.MyGID(SourceGIDs[i])) NumPermuteIDs_++; // Check if Source GID is a local Target GID
    else NumExportIDs_++; // If not, then it is remote

  // Define remote and permutation lists

  int_type * ExportGIDs = 0;
  if (NumExportIDs_>0) {
    ExportLIDs_ = new int[NumExportIDs_];
    ExportGIDs = new int_type[NumExportIDs_];
  }
  if (NumPermuteIDs_>0)  {
    PermuteToLIDs_ = new int[NumPermuteIDs_];
    PermuteFromLIDs_ = new int[NumPermuteIDs_];
  }

  NumPermuteIDs_ = 0;
  NumExportIDs_ = 0;
  for (i=NumSameIDs_; i< NumSourceIDs; i++) {
    if (targetMap.MyGID(SourceGIDs[i])) {
      PermuteFromLIDs_[NumPermuteIDs_] = i;
      PermuteToLIDs_[NumPermuteIDs_++] = targetMap.LID(SourceGIDs[i]);
    }
    else {
      //NumSend_ +=sourceMap.ElementSize(i); // Count total number of entries to send
      NumSend_ +=sourceMap.MaxElementSize(); // Count total number of entries to send (currently need max)
      ExportGIDs[NumExportIDs_] = SourceGIDs[i];
      ExportLIDs_[NumExportIDs_++] = i;
    }
  }

  if ( NumExportIDs_>0 && !sourceMap.DistributedGlobal())
    ReportError("Warning in Epetra_Export: Serial Export has remote IDs. (Exporting from Subset of Source Map)", 1);

  // Test for distributed cases
  int ierr = 0;

  if (sourceMap.DistributedGlobal()) {

    if (NumExportIDs_>0) ExportPIDs_ = new int[NumExportIDs_];
    ierr = targetMap.RemoteIDList(NumExportIDs_, ExportGIDs, ExportPIDs_, 0); // Get remote PIDs
    if( ierr ) throw ReportError("Error in Epetra_BlockMap::RemoteIDList", ierr);

    //Get rid of IDs not in Target Map
    if(NumExportIDs_>0) {
      int cnt = 0;
      for( i = 0; i < NumExportIDs_; ++i )
  if( ExportPIDs_[i] == -1 ) ++cnt;
      if( cnt ) {
  int_type * NewExportGIDs = 0;
  int * NewExportPIDs = 0;
  int * NewExportLIDs = 0;
  int cnt1 = NumExportIDs_-cnt;
  if (cnt1) {
    NewExportGIDs = new int_type[cnt1];
    NewExportPIDs = new int[cnt1];
    NewExportLIDs = new int[cnt1];
  }
  cnt = 0;
  for( i = 0; i < NumExportIDs_; ++i )
    if( ExportPIDs_[i] != -1 ) {
      NewExportGIDs[cnt] = ExportGIDs[i];
      NewExportPIDs[cnt] = ExportPIDs_[i];
      NewExportLIDs[cnt] = ExportLIDs_[i];
      ++cnt;
          }
  assert(cnt==cnt1); // Sanity test
  NumExportIDs_ = cnt;
  delete [] ExportGIDs;
  delete [] ExportPIDs_;
  delete [] ExportLIDs_;
  ExportGIDs = NewExportGIDs;
  ExportPIDs_ = NewExportPIDs;
  ExportLIDs_ = NewExportLIDs;
  ReportError("Warning in Epetra_Export: Source IDs not found in Target Map (Do you want to export from subset of Source Map?)", 1 );
      }
    }

    //Make sure Export IDs are ordered by processor
    Epetra_Util util;

    if(targetMap.GlobalIndicesLongLong()) {
      // FIXME (mfh 11 Jul 2013) This breaks ANSI aliasing rules, if
      // int_type != long long.  On some compilers, it results in
      // warnings such as this: "dereferencing type-punned pointer
      // will break strict-aliasing rules".
      util.Sort(true,NumExportIDs_,ExportPIDs_,0,0,1,&ExportLIDs_, 1, (long long **)&ExportGIDs);
    }
    else if(targetMap.GlobalIndicesInt()) {
      int* ptrs[2] = {ExportLIDs_, (int*) ExportGIDs};
      util.Sort(true,NumExportIDs_,ExportPIDs_,0,0, 2,&ptrs[0], 0, 0);
    }
    else {
      throw ReportError("Epetra_Import::Epetra_Import: GlobalIndices Internal Error", -1);
    }

    Distor_ = sourceMap.Comm().CreateDistributor();

    // Construct list of exports that calling processor needs to send as a result
    // of everyone asking for what it needs to receive.

    ierr = Distor_->CreateFromSends( NumExportIDs_, ExportPIDs_, true, NumRemoteIDs_);
    if (ierr!=0) throw ReportError("Error in Epetra_Distributor.CreateFromSends()", ierr);

    // Use comm plan with ExportGIDs to find out who is sending to us and
    // get proper ordering of GIDs for remote entries
    // (that we will convert to LIDs when done).

    if (NumRemoteIDs_>0) RemoteLIDs_ = new int[NumRemoteIDs_]; // Allocate space for LIDs in target that are
    // going to get something from off-processor.
    char * cRemoteGIDs = 0; //Do will alloc memory for this object
    int LenCRemoteGIDs = 0;
    ierr = Distor_->Do(reinterpret_cast<char *> (ExportGIDs),
    sizeof( int_type ),
    LenCRemoteGIDs,
    cRemoteGIDs);
    if (ierr) throw ReportError("Error in Epetra_Distributor.Do()", ierr);
    int_type * RemoteGIDs = reinterpret_cast<int_type*>(cRemoteGIDs);

    // Remote IDs come in as GIDs, convert to LIDs
    for (i=0; i< NumRemoteIDs_; i++) {
      RemoteLIDs_[i] = targetMap.LID(RemoteGIDs[i]);
      //NumRecv_ += targetMap.ElementSize(RemoteLIDs_[i]); // Count total number of entries to receive
      NumRecv_ += targetMap.MaxElementSize(); // Count total number of entries to receive (currently need max)
    }

    if (LenCRemoteGIDs>0) delete [] cRemoteGIDs;
  }
  if (NumExportIDs_>0) delete [] ExportGIDs;
  if (NumTargetIDs>0) delete [] TargetGIDs;
  if (NumSourceIDs>0) delete [] SourceGIDs;

  return;
}
コード例 #24
0
  int MatrixTests(const Epetra_BlockMap & Map, const Epetra_LocalMap & LocalMap, int NumVectors,
		      bool verbose)
  {
    const Epetra_Comm & Comm = Map.Comm();
    int ierr = 0, i;
    int IndexBase = 0;
    double *residual = new double[NumVectors];

    /* get ID of this processor */


    // Test GEMM first.  7 cases:

    //                                       Num
    //     OPERATIONS                        case  Notes
    // 1) C(local) = A^X(local) * B^X(local)  4   (X=Trans or Not, No Comm needed)
    // 2) C(local) = A^T(distr) * B  (distr)  1   (2D dot product, replicate C)
    // 3) C(distr) = A  (distr) * B^X(local)  2   (2D vector update, no Comm needed)

    // ==================================================================
    // Case 1 through 4 (A, B, C all local) Strided and non-strided cases
    // ==================================================================

    // Construct MultiVectors

    {
    Epetra_MultiVector A(LocalMap, NumVectors);
    Epetra_MultiVector B(LocalMap, NumVectors);
    Epetra_LocalMap  Map2d(NumVectors, IndexBase, Comm);
    Epetra_MultiVector C(Map2d, NumVectors);
    Epetra_MultiVector C_GEMM(Map2d, NumVectors);

    double **App, **Bpp, **Cpp;

    Epetra_MultiVector *Ap, *Bp, *Cp;

    // For testing non-strided mode, create MultiVectors that are scattered throughout memory

    App = new double *[NumVectors];
    Bpp = new double *[NumVectors];
    Cpp = new double *[NumVectors];
    for (i=0; i<NumVectors; i++) App[i] = new double[A.MyLength()+i];
    for (i=0; i<NumVectors; i++) Bpp[i] = new double[B.MyLength()+i];
    for (i=0; i<NumVectors; i++) Cpp[i] = new double[C.MyLength()+i];

    Epetra_MultiVector A1(View, LocalMap, App, NumVectors);
    Epetra_MultiVector B1(View, LocalMap, Bpp, NumVectors);
    Epetra_MultiVector C1(View, Map2d, Cpp, NumVectors);

    for (int strided = 0; strided<2; strided++) {

    // Loop through all trans cases using a variety of values for alpha and beta
    for (i=0; i<4; i++)  {
	char transa = 'N'; if (i>1) transa = 'T';
	char transb = 'N'; if (i%2!=0) transb = 'T';
	double alpha = (double) i+1;
	double beta  = (double) (i/2);
	EPETRA_TEST_ERR(C.Random(),ierr);  // Fill C with random numbers
	int localierr = BuildMatrixTests(C,transa, transb, alpha, A, B, beta, C_GEMM );
	if (localierr!=-2) { // -2 means the shapes didn't match and we skip the tests
	  if (strided)
	    {
	      Ap = &A; Bp = &B; Cp = &C;
	    }
	  else
	    {
	      A.ExtractCopy(App); Ap = &A1;
	      B.ExtractCopy(Bpp); Bp = &B1;
	      C.ExtractCopy(Cpp); Cp = &C1;
	    }
	
	  localierr = Cp->Multiply(transa, transb, alpha, *Ap, *Bp, beta);
	  if (localierr!=-2) { // -2 means the shapes didn't match and we skip the tests
	    ierr += Cp->Update(-1.0, C_GEMM, 1.0);
	    ierr += Cp->Norm2(residual);
	
	    if (verbose)
	      {
		cout << "XXXXX Replicated Local MultiVector GEMM tests";
		if (strided)
		  cout << " (Strided Multivectors)" << endl;
		else
		  cout << " (Non-Strided Multivectors)" << endl;
		cout << "  alpha = " << alpha << ",  beta = " << beta <<", transa = "<<transa
		     <<", transb = " << transb;
	      }
	    if (BadResidual(verbose,residual, NumVectors)) return(-1);
	  }
	}
      }

      }
    for (i=0; i<NumVectors; i++)
      {
	delete [] App[i];
	delete [] Bpp[i];
	delete [] Cpp[i];
      }
    delete [] App;
    delete [] Bpp;
    delete [] Cpp;
    }

    // ====================================
    // Case 5  (A, B distributed C  local)
    // ====================================

    // Construct MultiVectors
  {
    Epetra_MultiVector A(Map, NumVectors);
    Epetra_MultiVector B(Map, NumVectors);
    Epetra_LocalMap Map2d(NumVectors, IndexBase, Comm);
    Epetra_MultiVector C(Map2d, NumVectors);
    Epetra_MultiVector C_GEMM(Map2d, NumVectors);

    char transa = 'T';
    char transb = 'N';
    double alpha = 2.0;
    double beta  = 1.0;
    EPETRA_TEST_ERR(C.Random(),ierr);  // Fill C with random numbers
    ierr += BuildMatrixTests(C, transa, transb, alpha, A, B, beta, C_GEMM );
    int localierr = C.Multiply(transa, transb, alpha, A, B, beta);
    if (localierr!=-2) { // -2 means the shapes didn't match
      ierr += C.Update(-1.0, C_GEMM, 1.0);
      ierr += C.Norm2(residual);

      if (verbose)
	{
	  cout << "XXXXX Generalized 2D dot product via GEMM call     " << endl;
	  cout << "  alpha = " << alpha << ",  beta = " << beta <<", transa = "<<transa
	       <<", transb = " << transb;
	}
      if (BadResidual(verbose,residual, NumVectors)) return(-1);
    }

  }
    // ====================================
    // Case 6-7  (A, C distributed, B local)
    // ====================================

    // Construct MultiVectors
  {
    Epetra_MultiVector A(Map, NumVectors);
    Epetra_LocalMap Map2d(NumVectors, IndexBase, Comm);
    Epetra_MultiVector B(Map2d, NumVectors);
    Epetra_MultiVector C(Map, NumVectors);
    Epetra_MultiVector C_GEMM(Map, NumVectors);

    for (i=0; i<2; i++)
      {
	char transa = 'N';
	char transb = 'N'; if (i>0) transb = 'T';
	double alpha = 2.0;
	double beta  = 1.1;
	EPETRA_TEST_ERR(C.Random(),ierr);  // Fill C with random numbers
	ierr += BuildMatrixTests(C,transa, transb, alpha, A, B, beta, C_GEMM );
	ierr += C.Multiply(transa, transb, alpha, A, B, beta);
	ierr += C.Update(-1.0, C_GEMM, 1.0);
	ierr += C.Norm2(residual);
	
	if (verbose)
	  {
	    cout << "XXXXX Generalized 2D vector update via GEMM call     " << endl;
	    cout << "  alpha = " << alpha << ",  beta = " << beta <<", transa = "<<transa
		 <<", transb = " << transb;
	  }
	if (BadResidual(verbose,residual, NumVectors)) return(-1);
      }


  }
    // ====================================
    // LocalMap Tests
    // ====================================

    // Construct MultiVectors
  {

        int localLength = 10;
        double *localMinValue = new double[localLength];
        double *localMaxValue = new double[localLength];
        double *localNorm1 = new double[localLength];
        double *localDot = new double[localLength];
        double *localNorm2 = new double[localLength];
        double *localMeanValue = new double[localLength];
        Epetra_LocalMap MapSmall(localLength, IndexBase, Comm);
        Epetra_MultiVector A(MapSmall, NumVectors);

        double doubleLocalLength = (double) localLength;
        for (int j=0; j< NumVectors; j++) {
          for (i=0; i< localLength-1; i++) A[j][i] = (double) (i+1);
          A[j][localLength-1] = (double) (localLength+j); // Only the last value differs across multivectors
          localMinValue[j] = A[j][0]; // Increasing values
          localMaxValue[j] = A[j][localLength-1];
          localNorm1[j] = (doubleLocalLength-1.0)*(doubleLocalLength)/2.0+A[j][localLength-1];
          localDot[j] = (doubleLocalLength-1.0)*(doubleLocalLength)*(2.0*(doubleLocalLength-1.0)+1.0)/6.0+A[j][localLength-1]*A[j][localLength-1];
          localNorm2[j] = std::sqrt(localDot[j]);
          localMeanValue[j] = localNorm1[j]/doubleLocalLength;
        }
	ierr += A.MinValue(residual);
        for (int j=0; j<NumVectors; j++) residual[j] = std::abs(residual[j] - localMinValue[j]);
	if (verbose) cout << "XXXXX MinValue" << endl;
	if (BadResidual(verbose,residual, NumVectors)) return(-1);

	ierr += A.MaxValue(residual);
        for (int j=0; j<NumVectors; j++) residual[j] = std::abs(residual[j] - localMaxValue[j]);
	if (verbose) cout << "XXXXX MaxValue" << endl;
	if (BadResidual(verbose,residual, NumVectors)) return(-1);

	ierr += A.Norm1(residual);
        for (int j=0; j<NumVectors; j++) residual[j] = std::abs(residual[j] - localNorm1[j]);
	if (verbose) cout << "XXXXX Norm1" << endl;
	if (BadResidual(verbose,residual, NumVectors)) return(-1);

	ierr += A.Dot(A,residual);
        for (int j=0; j<NumVectors; j++) residual[j] = std::abs(residual[j] - localDot[j]);
	if (verbose) cout << "XXXXX Dot" << endl;
	if (BadResidual(verbose,residual, NumVectors)) return(-1);

	ierr += A.Norm2(residual);
        for (int j=0; j<NumVectors; j++) residual[j] = std::abs(residual[j] - localNorm2[j]);
	if (verbose) cout << "XXXXX Norm2" << endl;
	if (BadResidual(verbose,residual, NumVectors)) return(-1);

	ierr += A.MeanValue(residual);
        for (int j=0; j<NumVectors; j++) residual[j] = std::abs(residual[j] - localMeanValue[j]);
	if (verbose) cout << "XXXXX MeanValue" << endl;
	if (BadResidual(verbose,residual, NumVectors)) return(-1);

        delete [] localMinValue;
        delete [] localMaxValue;
        delete [] localNorm1;
        delete [] localDot;
        delete [] localNorm2;
        delete [] localMeanValue;

  }

    delete [] residual;

    return(ierr);
  }
コード例 #25
-8
int MultiVectorTests(const Epetra_BlockMap & Map, int NumVectors, bool verbose)
{
  const Epetra_Comm & Comm = Map.Comm();
  int ierr = 0, i;
  double *residual = new double[NumVectors];

  Epetra_BLAS BLAS;
  /* get number of processors and the name of this processor */

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

  // Construct MultiVectors

  Epetra_MultiVector A(Map, NumVectors);
  Epetra_MultiVector sqrtA(Map, NumVectors);
  Epetra_MultiVector B(Map, NumVectors);
  Epetra_MultiVector C(Map, NumVectors);
  Epetra_MultiVector C_alphaA(Map, NumVectors);
  Epetra_MultiVector C_alphaAplusB(Map, NumVectors);
  Epetra_MultiVector C_plusB(Map, NumVectors);
  Epetra_MultiVector Weights(Map, NumVectors);

  // Construct double vectors
  double *dotvec_AB   = new double[NumVectors];
  double *norm1_A     = new double[NumVectors];
  double *norm2_sqrtA = new double[NumVectors];
  double *norminf_A = new double[NumVectors];
  double *normw_A = new double[NumVectors];
  double *minval_A = new double[NumVectors];
  double *maxval_A = new double[NumVectors];
  double *meanval_A = new double[NumVectors];

  // Generate data


  EPETRA_TEST_ERR(C.Random(),ierr); // Fill C with random numbers.
  double alpha = 2.0;
  BuildMultiVectorTests (C,alpha, A, sqrtA, B, C_alphaA, C_alphaAplusB,
			     C_plusB, dotvec_AB, norm1_A, norm2_sqrtA, norminf_A,
			     normw_A, Weights, minval_A, maxval_A, meanval_A);

  int err = 0;
  if (verbose) cout << "XXXXX Testing alpha * A     ";
  // Test alpha*A
  Epetra_MultiVector alphaA(A); // Copy of A
  EPETRA_TEST_ERR(alphaA.Scale(alpha),err);
  EPETRA_TEST_ERR(alphaA.Update(-1.0, C_alphaA, 1.0),err);
  EPETRA_TEST_ERR(alphaA.Norm2(residual),err);

  if (err) ierr += err;
  else {
    EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr);
  }

  err = 0;
  if (verbose) cout << "XXXXX Testing C = alpha * A + B      ";
  // Test alpha*A + B
  Epetra_MultiVector alphaAplusB(A); // Copy of A
  EPETRA_TEST_ERR(alphaAplusB.Update(1.0, B, alpha, A, 0.0),err);
  EPETRA_TEST_ERR(alphaAplusB.Update(-1.0, C_alphaAplusB, 1.0),err);
  EPETRA_TEST_ERR(alphaAplusB.Norm2(residual),err);

  if (err) ierr += err;
  else {
    EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr);
  }

  err = 0;
  if (verbose) cout << "XXXXX Testing C += B      ";
  // Test + B
  Epetra_MultiVector plusB(C); // Copy of C
  EPETRA_TEST_ERR(plusB.Update(1.0, B, 1.0),err);
  EPETRA_TEST_ERR(plusB.Update(-1.0, C_plusB, 1.0),err);
  EPETRA_TEST_ERR(plusB.Norm2(residual),err);

  if (err) ierr += err;
  else {
    EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr);
  }

  err = 0;
  if (verbose) cout << "XXXXX Testing A.dotProd(B)     ";
  // Test A.dotvec(B)
  double *dotvec = residual;
  EPETRA_TEST_ERR(A.Dot(B,dotvec),err);
  BLAS.AXPY(NumVectors,-1.0,dotvec_AB,dotvec);

  if (err) ierr += err;
  else {
    EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr);
  }

  err = 0;
  if (verbose) cout << "XXXXX Testing norm1_A      ";
  // Test A.norm1()
  double *norm1 = residual;
  EPETRA_TEST_ERR(A.Norm1(norm1),err);
  BLAS.AXPY(NumVectors,-1.0,norm1_A,norm1);

  if (err) ierr += err;
  else {
    EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr);
  }

  err = 0;
  if (verbose) cout << "XXXXX Testing norm2_sqrtA     ";
  // Test sqrtA.norm2()
  double *norm2 = residual;
  EPETRA_TEST_ERR(sqrtA.Norm2(norm2),err);
  BLAS.AXPY(NumVectors,-1.0,norm2_sqrtA,norm2);

  if (err) ierr += err;
  else {
    EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr);
  }

  err = 0;
  if (verbose) cout << "XXXXX Testing norminf_A     ";
  // Test A.norminf()
  double *norminf = residual;
  EPETRA_TEST_ERR(A.NormInf(norminf),err);
  BLAS.AXPY(NumVectors,-1.0,norminf_A,norminf);

  if (err) ierr += err;
  else {
    EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr);
  }

  err = 0;
  if (verbose) cout << "XXXXX Testing normw_A     ";
  // Test A.NormWeighted()
  double *normw = residual;
  EPETRA_TEST_ERR(A.NormWeighted(Weights, normw),err);
  BLAS.AXPY(NumVectors,-1.0,normw_A,normw);

  if (err) ierr += err;
  else {
    EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr);
  }

  err = 0;
  if (verbose) cout << "XXXXX Testing minval_A     ";
  // Test A.MinValue()
  double *minval = residual;
  EPETRA_TEST_ERR(A.MinValue(minval),err);
  BLAS.AXPY(NumVectors,-1.0,minval_A,minval);

  if (err) ierr += err;
  else {
    EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr);
  }

  err = 0;
  if (verbose) cout << "XXXXX Testing maxval_A     ";
  // Test A.MaxValue()
  double *maxval = residual;
  EPETRA_TEST_ERR(A.MaxValue(maxval),err);
  BLAS.AXPY(NumVectors,-1.0,maxval_A,maxval);

  if (err) ierr += err;
  else {
    EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr);
  }

  err = 0;
  if (verbose) cout << "XXXXX Testing meanval_A     ";
  // Test A.MeanValue()
  double *meanval = residual;
  EPETRA_TEST_ERR(A.MeanValue(meanval),err);
  BLAS.AXPY(NumVectors,-1.0,meanval_A,meanval);

  if (err) ierr += err;
  else {
    EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr);
  }

  err = 0;
  if (verbose) cout << "XXXXX Testing abs_A     ";
  // Test A.Abs()
  Epetra_MultiVector Abs_A = A;
  EPETRA_TEST_ERR(Abs_A.Abs(A),err);
  EPETRA_TEST_ERR(Abs_A.Update(1.0, A, -1.0),err); // Abs_A = A - Abs_A (should be zero since A > 0)
  EPETRA_TEST_ERR(Abs_A.Norm2(residual),err);

  if (err) ierr += err;
  else {
    EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr);
  }

  err = 0;
  if (verbose) cout << "XXXXX Testing random_A (Test1) ";
  // Test A.Random()
  Epetra_MultiVector Rand1_A(A);
  Epetra_MultiVector Rand2_A(A);
  EPETRA_TEST_ERR(Rand1_A.Random(),err);
  EPETRA_TEST_ERR(Rand2_A.Random(),err);
  // Rand2_A = Rand1_A - Rand2_A (should be nonzero since Random() should give different vectors > 0)
  EPETRA_TEST_ERR(Rand2_A.Update(1.0, Rand1_A, -1.0),err);
  EPETRA_TEST_ERR(Rand2_A.Norm2(residual),err);

  if (err) ierr += err;
  else {
    EPETRA_TEST_ERR(BadResidual1(verbose,residual, NumVectors),ierr);
  }

  err = 0;
  if (verbose) cout << "XXXXX Testing random_A (Test2) ";

  // Next test that each column of the multivector is different from all other columns by testing the first value
  // of each vector against the first value of every other vector.
  int randvalsdiffer = 1; // Assume they all differ
  for (i=0; i< NumVectors; i++)
    for (int j=i+1; j<NumVectors; j++)
      if (Rand1_A[i][0]==Rand1_A[j][0]) randvalsdiffer = 0; // make false if equal
  int allrandvals = 0;
  Comm.MinAll(&randvalsdiffer, &allrandvals, 1); // get min of all values across all processors

  EPETRA_TEST_ERR(1-allrandvals, err); // If allrandvals is anything but 1, this will cause an error
  int locerr = err;
  Comm.MinAll(&locerr, &err, 1);

  if (verbose) {
    if (err==0) {
      cout << "\t Checked OK" << endl;
    } else {
      cout << "\t Checked Failed" << endl;
    }
  }
  err = 0;
  if (verbose) cout << "XXXXX Testing random_A (Test3) ";

  // Next test that the first element on each processor of the first column of Rand1_A is different from all others
  // First we will gather them all to PE 0


  Epetra_Map RandstartsMap(-1, 1, 0, Comm); // This Map has a single element on each PE
  int itmp = 0;
  int nproc = Comm.NumProc();
  if (MyPID==0) itmp = nproc;
  Epetra_Map AllrandstartsMap(nproc, itmp, 0, Comm); // Map has NumProc elements on PE 0, none elsewhere
  Epetra_MultiVector Randstarts(RandstartsMap, NumVectors);
  Epetra_MultiVector Allrandstarts(AllrandstartsMap, NumVectors);
  for (i=0; i< NumVectors; i++) Randstarts[i][0] = Rand1_A[i][0]; // Load first value of local multivector

  Epetra_Import Randimporter(AllrandstartsMap,RandstartsMap);
  EPETRA_TEST_ERR(Allrandstarts.Import(Randstarts,Randimporter,Insert),err);
  // cout << "Randstarts = " << Randstarts << endl << "Allrandstarts = " << Allrandstarts << endl;
  // Allrandstarts now contains the first values for each local section of Rand1_A.
  // Next test that this is true.
  randvalsdiffer = 1; // Assume they all differ
  if (MyPID==0) {
    for (i=0; i< NumVectors; i++)
      for (int irand=0; irand<nproc; irand++)
	for (int jrand=irand+1; jrand<nproc; jrand++)
	  if (Allrandstarts[i][irand]==Allrandstarts[i][jrand]) randvalsdiffer = 0; // make false if equal
  }
  allrandvals = 0;
  Comm.MinAll(&randvalsdiffer, &allrandvals, 1); // get min of all values across all processors

  EPETRA_TEST_ERR(1-allrandvals, err); // If allrandvals is anything but 1, this will cause an error
  locerr = err;
  Comm.MinAll(&locerr, &err, 1);
  if (verbose) {
    if (err==0) {
      cout << "\t Checked OK" << endl;
    } else {
      cout << "\t Checked Failed" << endl;
    }
  }

  // Delete everything

  delete [] dotvec_AB;
  delete [] norm1_A;
  delete [] norm2_sqrtA;
  delete [] norminf_A;
  delete [] normw_A;
  delete [] minval_A;
  delete [] maxval_A;
  delete [] meanval_A;
  delete [] residual;

  //*******************************************************************
  // Post-construction modification tests
  //*******************************************************************

  if (verbose) cout <<  "\n\nXXXXX Testing Post-construction modification of a multivector"
		    <<endl<<endl;

  err = 0;

  Epetra_MultiVector X(Map, NumVectors);
  X.Random();

  // Pick middle range values for GID, LID and Vector Index
  int testGID = Map.NumGlobalElements()/2;
  int testVecIndex = NumVectors/2;

  int GIDSize = 1;
  int LIDOfGID = 0;
  int FirstEntryOfGID = 0;

  if (Map.MyGID(testGID)) {
    LIDOfGID = Map.LID(testGID);
    GIDSize = Map.ElementSize(LIDOfGID);
    FirstEntryOfGID = Map.FirstPointInElement(LIDOfGID);
  }

  // ========================================================================
  // Test int ReplaceGlobalValue (int GlobalRow, int VectorIndex, double ScalarValue)
  // ========================================================================

  double newGIDValue = 4.0;
  locerr = X.ReplaceGlobalValue(testGID, testVecIndex, newGIDValue);

  if (Map.MyGID(testGID)) {
    if (X[testVecIndex][FirstEntryOfGID]!=newGIDValue) err++;
    if (verbose) cout << "X["<<testVecIndex<<"]["<<FirstEntryOfGID<<"] = "
		      <<  X[testVecIndex][FirstEntryOfGID]
		      << " should = " << newGIDValue << endl;
  }
  else
    if (locerr!=1) err++; // Test for GID out of range error (=1)

  // ========================================================================
  // Test int ReplaceGlobalValue (int GlobalRow, intBlockRowOffset, int VectorIndex, double ScalarValue)
  // ========================================================================
  newGIDValue = 8.0;
  locerr = X.ReplaceGlobalValue(testGID, GIDSize-1, testVecIndex, newGIDValue);

  if (Map.MyGID(testGID)) {
    if (X[testVecIndex][FirstEntryOfGID+GIDSize-1]!=newGIDValue) err++;
    if (verbose) cout << "X["<<testVecIndex<<"]["<<FirstEntryOfGID+GIDSize-1<<"] = "
		      <<  X[testVecIndex][FirstEntryOfGID+GIDSize-1]
		      << " should = " << newGIDValue << endl;
  }
  else
    if (locerr!=1) err++; // Test for GID out of range error (=1)

  // ========================================================================
  // Test int SumIntoGlobalValue (int GlobalRow, int VectorIndex, double ScalarValue)
  // ========================================================================

  newGIDValue = 1.0;
  locerr = X.ReplaceGlobalValue(testGID, testVecIndex, newGIDValue);
  locerr = X.SumIntoGlobalValue(testGID, testVecIndex, newGIDValue);
  if (Map.MyGID(testGID)) {
    if (X[testVecIndex][FirstEntryOfGID]!=(newGIDValue+newGIDValue)) err++;
    if (verbose) cout << "X["<<testVecIndex<<"]["<<FirstEntryOfGID<<"] = "
		      <<  X[testVecIndex][FirstEntryOfGID]
		      << " should = " << newGIDValue << endl;
  }
  else
    if (locerr!=1) err++; // Test for GID out of range error (=1)

  // ========================================================================
  // Test int SumIntoGlobalValue (int GlobalRow, intBlockRowOffset, int VectorIndex, double ScalarValue)
  // ========================================================================

  newGIDValue = 1.0;
  locerr = X.ReplaceGlobalValue(testGID, GIDSize-1, testVecIndex, newGIDValue);
  locerr = X.SumIntoGlobalValue(testGID, GIDSize-1, testVecIndex, newGIDValue);

  if (Map.MyGID(testGID)) {
    if (X[testVecIndex][FirstEntryOfGID+GIDSize-1]!=(newGIDValue+newGIDValue)) err++;
    if (verbose) cout << "X["<<testVecIndex<<"]["<<FirstEntryOfGID+GIDSize-1<<"] = "
		      <<  X[testVecIndex][FirstEntryOfGID+GIDSize-1]
		      << " should = " << newGIDValue << endl;
  }
  else
    if (locerr!=1) err++; // Test for GID out of range error (=1)

  // ========================================================================
  // Test Local "My" versions of same routine (less complicated)
  // ========================================================================

  // Pick middle range values for LID
  int testLID = Map.NumMyElements()/2;

  int LIDSize = Map.ElementSize(testLID);
  int FirstEntryOfLID = Map.FirstPointInElement(testLID);


  double newLIDValue = 4.0;
  locerr = X.ReplaceMyValue(testLID, testVecIndex, newLIDValue);

  if (X[testVecIndex][FirstEntryOfLID]!=newLIDValue) err++;
  if (verbose) cout << "X["<<testVecIndex<<"]["<<FirstEntryOfLID<<"] = "
		    <<  X[testVecIndex][FirstEntryOfLID]
		    << " should = " << newLIDValue << endl;

  newLIDValue = 8.0;
  locerr = X.ReplaceMyValue(testLID, LIDSize-1, testVecIndex, newLIDValue);
  if (X[testVecIndex][FirstEntryOfLID+LIDSize-1]!=newLIDValue) err++;
  if (verbose) cout << "X["<<testVecIndex<<"]["<<FirstEntryOfLID+LIDSize-1<<"] = "
		    <<  X[testVecIndex][FirstEntryOfLID+LIDSize-1]
		    << " should = " << newLIDValue << endl;
  newLIDValue = 1.0;
  locerr = X.ReplaceMyValue(testLID, testVecIndex, newLIDValue);
  locerr = X.SumIntoMyValue(testLID, testVecIndex, newLIDValue);
  if (X[testVecIndex][FirstEntryOfLID]!=(newLIDValue+newLIDValue)) err++;
  if (verbose) cout << "X["<<testVecIndex<<"]["<<FirstEntryOfLID<<"] = "
		    <<  X[testVecIndex][FirstEntryOfLID]
		    << " should = " << newLIDValue << endl;
  newLIDValue = 2.0;
  locerr = X.ReplaceMyValue(testLID, LIDSize-1, testVecIndex, newLIDValue);
  locerr = X.SumIntoMyValue(testLID, LIDSize-1, testVecIndex, newLIDValue);
  if (verbose) cout << "X["<<testVecIndex<<"]["<<FirstEntryOfLID+LIDSize-1<<"] = "
		    <<  X[testVecIndex][FirstEntryOfLID+LIDSize-1]
		    << " should = " << newLIDValue << endl;
  if (X[testVecIndex][FirstEntryOfLID+LIDSize-1]!=(newLIDValue+newLIDValue)) err++;

  ierr += err;

  // ========================================================================
  // Test Post-construction modification of an Epetra_Vector using a vector
  // our multivector X
  // ========================================================================

  if (verbose) cout <<  "\n\nXXXXX Testing Post-construction modification of a vector"
		    << endl << endl;

  Epetra_Vector * x = X(testVecIndex);

  int NumEntries = 2;
  double * VecValues = new double[NumEntries];
  int * VecGIDs = new int[NumEntries];
  VecGIDs[0] = testGID;
  VecGIDs[1] = testGID+1; // Some pathological chance that these GIDs are not valid

  // ========================================================================
  // Test int ReplaceGlobalValues (int NumEntries, double *Values, int *Indices)
  // ========================================================================

  VecValues[0] = 2.0; VecValues[1] = 4.0;
  locerr = x->ReplaceGlobalValues(NumEntries, VecValues, VecGIDs);

  for (i=0; i<NumEntries; i++) {
    testGID = VecGIDs[i];
    if (Map.MyGID(testGID)) {
      LIDOfGID = Map.LID(testGID);
      GIDSize = EPETRA_MIN(GIDSize,Map.ElementSize(LIDOfGID)); // Need this value below
      FirstEntryOfGID = Map.FirstPointInElement(LIDOfGID);
      if ((*x)[FirstEntryOfGID]!=VecValues[i]) err++;
      if (verbose) cout << "x["<<FirstEntryOfGID<<"] = "
			<< (*x)[FirstEntryOfGID]
			<< " should = " << VecValues[i] << endl;
    }
    else
      if (locerr!=1) err++; // Test for GID out of range error (=1)
  }


  // ========================================================================
  // Test int ReplaceGlobalValues (int NumEntries, int BlockOffset, double *Values, int *Indices)
  // ========================================================================

  VecValues[0] = 4.0; VecValues[1] = 8.0;
  locerr = x->ReplaceGlobalValues(NumEntries, GIDSize-1, VecValues, VecGIDs);

  for (i=0; i<NumEntries; i++) {
    testGID = VecGIDs[i];
    if (Map.MyGID(testGID)) {
      LIDOfGID = Map.LID(testGID);
      FirstEntryOfGID = Map.FirstPointInElement(LIDOfGID);
      if ((*x)[FirstEntryOfGID+GIDSize-1]!=VecValues[i]) err++;
      if (verbose) cout << "x["<<FirstEntryOfGID+GIDSize-1<<"] = "
			<< (*x)[FirstEntryOfGID+GIDSize-1]
			<< " should = " << VecValues[i] << endl;
    }
    else
      if (locerr!=1) err++; // Test for GID out of range error (=1)
  }

  // ========================================================================
  // Test int SumIntoGlobalValues (int NumEntries, double *Values, int *Indices)
  // ========================================================================

  VecValues[0] = 1.0; VecValues[1] = 2.0;
  locerr = x->ReplaceGlobalValues(NumEntries, VecValues, VecGIDs);
  locerr = x->SumIntoGlobalValues(NumEntries, VecValues, VecGIDs);

  for (i=0; i<NumEntries; i++) {
    testGID = VecGIDs[i];
    if (Map.MyGID(testGID)) {
      LIDOfGID = Map.LID(testGID);
      FirstEntryOfGID = Map.FirstPointInElement(LIDOfGID);
      if ((*x)[FirstEntryOfGID]!=(VecValues[i]+VecValues[i])) err++;
      if (verbose) cout << "x["<<FirstEntryOfGID<<"] = "
			<< (*x)[FirstEntryOfGID]
			<< " should = " << (VecValues[i]+VecValues[i]) << endl;
    }
    else
      if (locerr!=1) err++; // Test for GID out of range error (=1)
  }
  // ========================================================================
  // Test int ReplaceGlobalValues (int NumEntries, int BlockOffset, double *Values, int *Indices)
  // ========================================================================

  VecValues[0] = 1.0; VecValues[1] = 2.0;
  locerr = x->ReplaceGlobalValues(NumEntries, GIDSize-1, VecValues, VecGIDs);
  locerr = x->SumIntoGlobalValues(NumEntries, GIDSize-1, VecValues, VecGIDs);

  for (i=0; i<NumEntries; i++) {
    testGID = VecGIDs[i];
    if (Map.MyGID(testGID)) {
      LIDOfGID = Map.LID(testGID);
      FirstEntryOfGID = Map.FirstPointInElement(LIDOfGID);
      if ((*x)[FirstEntryOfGID+GIDSize-1]!=(VecValues[i]+VecValues[i])) err++;
      if (verbose) cout << "x["<<FirstEntryOfGID+GIDSize-1<<"] = "
			<< (*x)[FirstEntryOfGID+GIDSize-1]
			<< " should = " << (VecValues[i]+VecValues[i]) << endl;
    }
    else
      if (locerr!=1) err++; // Test for GID out of range error (=1)
  }

  // ========================================================================
  // Test Local "My" versions of same routine (less complicated)
  // ========================================================================
  int * VecLIDs = new int[NumEntries];
  VecLIDs[0] = testLID;
  VecLIDs[1] = testLID+1; // Some pathological chance that these LIDs are not valid

  VecValues[0] = 2.0; VecValues[1] = 4.0;
  locerr = x->ReplaceMyValues(NumEntries, VecValues, VecLIDs);

  for (i=0; i<NumEntries; i++) {
    testLID = VecLIDs[i];
    LIDSize = EPETRA_MIN(LIDSize,Map.ElementSize(testLID)); // Need this value below
    FirstEntryOfLID = Map.FirstPointInElement(testLID);
    if ((*x)[FirstEntryOfLID]!=VecValues[i]) err++;
    if (verbose) cout << "x["<<FirstEntryOfLID<<"] = "
		      << (*x)[FirstEntryOfLID]
		      << " should = " << VecValues[i] << endl;
  }

  VecValues[0] = 4.0; VecValues[1] = 8.0;
  locerr = x->ReplaceMyValues(NumEntries, LIDSize-1, VecValues, VecLIDs);

  for (i=0; i<NumEntries; i++) {
    testLID = VecLIDs[i];
    LIDSize = EPETRA_MIN(LIDSize,Map.ElementSize(testLID)); // Need this value below
    FirstEntryOfLID = Map.FirstPointInElement(testLID);
    if ((*x)[FirstEntryOfLID+LIDSize-1]!=VecValues[i]) err++;
    if (verbose) cout << "x["<<FirstEntryOfLID+LIDSize-1<<"] = "
		      << (*x)[FirstEntryOfLID+LIDSize-1]
		      << " should = " << VecValues[i] << endl;
  }

  VecValues[0] = 1.0; VecValues[1] = 1.0;
  locerr = x->ReplaceMyValues(NumEntries, VecValues, VecLIDs);
  locerr = x->SumIntoMyValues(NumEntries, VecValues, VecLIDs);

  for (i=0; i<NumEntries; i++) {
    testLID = VecLIDs[i];
    LIDSize = EPETRA_MIN(LIDSize,Map.ElementSize(testLID)); // Need this value below
    FirstEntryOfLID = Map.FirstPointInElement(testLID);
    if ((*x)[FirstEntryOfLID]!=(VecValues[i]+VecValues[i])) err++;
    if (verbose) cout << "x["<<FirstEntryOfLID<<"] = "
		      << (*x)[FirstEntryOfLID]
		      << " should = " << (VecValues[i]+VecValues[i]) << endl;
  }

  VecValues[0] = 2.0; VecValues[1] = 4.0;
  locerr = x->ReplaceMyValues(NumEntries, LIDSize-1, VecValues, VecLIDs);
  locerr = x->SumIntoMyValues(NumEntries, LIDSize-1, VecValues, VecLIDs);

  for (i=0; i<NumEntries; i++) {
    testLID = VecLIDs[i];
    LIDSize = EPETRA_MIN(LIDSize,Map.ElementSize(testLID)); // Need this value below
    FirstEntryOfLID = Map.FirstPointInElement(testLID);
    if ((*x)[FirstEntryOfLID+LIDSize-1]!=(VecValues[i]+VecValues[i])) err++;
    if (verbose) cout << "x["<<FirstEntryOfLID+LIDSize-1<<"] = "
		      << (*x)[FirstEntryOfLID+LIDSize-1]
		      << " should = " << (VecValues[i]+VecValues[i]) << endl;
  }

    delete [] VecValues;
    delete [] VecGIDs;
    delete [] VecLIDs;

  return(ierr);
}