Exemplo n.º 1
0
//==============================================================================
int Ifpack_AMDReordering::Compute(const Ifpack_Graph& Graph)
{
  using std::cout;
  using std::endl;

  IsComputed_ = false;
  NumMyRows_ = Graph.NumMyRows();
  int NumNz = Graph.NumMyNonzeros();

  if (NumMyRows_ == 0)
    IFPACK_CHK_ERR(-1); // strange graph this one

  // Extract CRS format
  std::vector<int> ia(NumMyRows_+1,0);
  std::vector<int> ja(NumNz);
  int cnt;
  for( int i = 0; i < NumMyRows_; ++i )
  {
    int * tmpP = &ja[ia[i]];
    Graph.ExtractMyRowCopy( i, NumNz-ia[i], cnt, tmpP );
    ia[i+1] = ia[i] + cnt;
  }

  // Trim down to local only
  std::vector<int> iat(NumMyRows_+1);
  std::vector<int> jat(NumNz);
  int loc = 0;
  for( int i = 0; i < NumMyRows_; ++i )
  {
    iat[i] = loc;
    for( int j = ia[i]; j < ia[i+1]; ++j )
    {
      if( ja[j] < NumMyRows_ )
        jat[loc++] = ja[j];
      else
        break;
    }
  }
  iat[NumMyRows_] = loc;

  // Compute AMD permutation
  Reorder_.resize(NumMyRows_);
  std::vector<double> info(AMD_INFO);

  trilinos_amd_order( NumMyRows_, &iat[0], &jat[0], &Reorder_[0], NULL, &info[0] );

  if( info[AMD_STATUS] == AMD_INVALID )
    cout << "AMD ORDERING: Invalid!!!!" << endl;

  // Build inverse reorder (will be used by ExtractMyRowCopy()
  InvReorder_.resize(NumMyRows_);

  for (int i = 0 ; i < NumMyRows_ ; ++i)
    InvReorder_[i] = -1;

  for (int i = 0 ; i < NumMyRows_ ; ++i)
    InvReorder_[Reorder_[i]] = i;

  for (int i = 0 ; i < NumMyRows_ ; ++i) {
    if (InvReorder_[i] == -1)
      IFPACK_CHK_ERR(-1);
  }

  IsComputed_ = true;
  return(0);
}
//==============================================================================
int Ifpack_RCMReordering::Compute(const Ifpack_Graph& Graph)
{
  IsComputed_ = false;
  NumMyRows_ = Graph.NumMyRows();

  if ((RootNode_ < 0) || (RootNode_ >= NumMyRows_))
    RootNode_ = 0;

  Reorder_.resize(NumMyRows_);

  // the case where one processor holds no chunk of the graph happens...
  if (!NumMyRows_) {
    InvReorder_.resize(NumMyRows_);
    IsComputed_ = true;
    return(0);
  }

  for (int i = 0 ; i < NumMyRows_ ; ++i)
    Reorder_[i] = -1;

  std::vector<int> tmp;
  tmp.push_back(RootNode_);

  int count = NumMyRows_ - 1;
  int Length = Graph.MaxMyNumEntries();
  std::vector<int> Indices(Length);

  Reorder_[RootNode_] = count;
  count--;

  // stop when no nodes have been added in the previous level

  while (tmp.size()) {

    std::vector<int> tmp2;

    // for each node in the previous level, look for non-marked
    // neighbors.
    for (int i = 0 ; i < (int)tmp.size() ; ++i) {
      int NumEntries;
      IFPACK_CHK_ERR(Graph.ExtractMyRowCopy(tmp[i], Length,
                                             NumEntries, &Indices[0]));

      if (Length > 1)
        std::sort(Indices.begin(), Indices.begin() + Length);

      for (int j = 0 ; j < NumEntries ; ++j) {
        int col = Indices[j];
        if (col >= NumMyRows_)
          continue;

        if (Reorder_[col] == -1) {
          Reorder_[col] = count;
          count--;
          if (col != tmp[i]) {
            tmp2.push_back(col);
          }
        }
      }
    }

    // if no nodes have been found but we still have
    // rows to walk through, to localize the next -1
    // and restart.
    // FIXME: I can replace with STL
    if ((tmp2.size() == 0) && (count != -1)) {
      for (int i = 0 ; i < NumMyRows_ ; ++i)
        if (Reorder_[i] == -1) {
          tmp2.push_back(i);
          Reorder_[i] = count--;
          break;
        }
    }

    // prepare for the next level
    tmp = tmp2;
  }

  // check nothing went wrong
  for (int i = 0 ; i < NumMyRows_ ; ++i) {
    if (Reorder_[i] == -1)
      IFPACK_CHK_ERR(-1);
  }

  // build inverse reorder (will be used by ExtractMyRowCopy()
  InvReorder_.resize(NumMyRows_);

  for (int i = 0 ; i < NumMyRows_ ; ++i)
    InvReorder_[i] = -1;

  for (int i = 0 ; i < NumMyRows_ ; ++i)
    InvReorder_[Reorder_[i]] = i;

  for (int i = 0 ; i < NumMyRows_ ; ++i) {
    if (InvReorder_[i] == -1)
      IFPACK_CHK_ERR(-1);
  }

  IsComputed_ = true;
  return(0);
}