예제 #1
0
/** \brief Build an inverse library from a parameter list.
  * 
  * Build an inverse library from a parameter list. This will
  * contain all the labeled inverses specified.
  *
  * \param[in] pl Parameter list to build the library from
  *
  * \returns A pointer to the inverse library created.
  */
RCP<InverseLibrary> InverseLibrary::buildFromParameterList(const Teuchos::ParameterList & pl,bool useStratDefaults)
{
   // build from Stratimikos or allocate a new inverse library
   RCP<InverseLibrary> invLib;
   if(useStratDefaults)
      invLib = InverseLibrary::buildFromStratimikos();
   else
      invLib = rcp(new InverseLibrary());

   // to convert the void* like entry
   Teuchos::ParameterList * temp = 0;

   // loop over all entries in parameter list
   Teuchos::ParameterList::ConstIterator itr;
   for(itr=pl.begin();itr!=pl.end();++itr) {
      // get current entry
      std::string label             = itr->first;
      Teuchos::ParameterList & list = itr->second.getValue(temp);
      
      // add to library
      invLib->addInverse(label,list);
   }
   
   return invLib;
}
예제 #2
0
void printListDocumentation(
  const Teuchos::ParameterList &pl,
  std::ostream &os,
  std::string listNames)
{

  if (listNames.size() == 0)
    listNames = std::string("top");

  Array<std::string> subLists;
  ParameterList::ConstIterator next = pl.begin();

  while (next != pl.end()){
    const std::string &name = next->first;
    const ParameterEntry &entry = pl.getEntry(name);

    if (entry.isList()){
      subLists.append(name);
    }
    else{
      std::string doc = entry.docString();
      os << "List: "<< listNames << ", parameter: " << name << "\n";
      if (doc.size())
        os << doc << "\n";
    }

    ++next;
  }

  for (int i=0; i < subLists.size(); i++){
    std::string newListName = listNames + std::string("/") + subLists[i];
    const ParameterList &sublist = pl.sublist(subLists[i]);
    printListDocumentation(sublist, os, newListName);
  }
}
void buildResponseMap(const Teuchos::ParameterList & p,
                      std::map<std::string,std::pair<ResponseId,std::pair<std::list<std::string>,std::list<std::string> > > > & responses)
{
   static Teuchos::RCP<const Teuchos::ParameterList> validList;

   // build valid parameter list
   if(validList==Teuchos::null) {
      Teuchos::RCP<Teuchos::ParameterList> tmpList = Teuchos::rcp(new Teuchos::ParameterList);
      tmpList->set<std::string>("Type","");
      tmpList->set<std::string>("Field Name","");
      tmpList->set<std::string>("Element Blocks","empty","Element blocks for this response",Teuchos::rcp(new CommaSeperatedEntryValidator));
      tmpList->set<std::string>("Evaluation Types","empty","Evaluation types for this response",Teuchos::rcp(new CommaSeperatedEntryValidator));

      validList = tmpList;
   }
 
   CommaSeperatedEntryValidator validator;
   const std::string & sublistName = p.name();
   std::vector<std::string> tokens;

   responses.clear();

   // loop over entries of parameter list, must satisfy response formatting
   for(Teuchos::ParameterList::ConstIterator itr=p.begin(); itr!=p.end();++itr) {
 
      const std::string & paramName = itr->first;
      const Teuchos::ParameterEntry & pe = itr->second;

      // make sure this is a parameter list
      TEUCHOS_TEST_FOR_EXCEPTION(!pe.isList(),Teuchos::Exceptions::InvalidParameterValue,
                         "In list \""+sublistName+"\", the parameter \""+paramName+"\" is expected "
                         "to be a sublist. Response map cannot be built!");

      // extract parameter list and validate
      const Teuchos::ParameterList & respList = Teuchos::getValue<Teuchos::ParameterList>(pe); 
      respList.validateParameters(*validList);

      const std::string & respLabel = paramName;
      ResponseId & rid = responses[respLabel].first;
      std::list<std::string> & eBlocks = responses[respLabel].second.first; // element blocks
      std::list<std::string> & eTypes = responses[respLabel].second.second;  // evaluation types

      rid.type = respList.get<std::string>("Type");
      rid.name = respList.get<std::string>("Field Name");

      CommaSeperatedEntryValidator::split(respList.get<std::string>("Element Blocks"),",",tokens);
      eBlocks.assign(tokens.begin(),tokens.end()); // this should automatically wipe out old values
      
      CommaSeperatedEntryValidator::split(respList.get<std::string>("Evaluation Types"),",",tokens);
      eTypes.assign(tokens.begin(),tokens.end()); // this should automatically wipe out old values
   }
}
bool ML_Epetra::ValidateMLPParameters(const Teuchos::ParameterList &inList, int depth){
  using Teuchos::ParameterList;
  using Teuchos::Exceptions::InvalidParameterName;
  using Teuchos::Exceptions::InvalidParameterType;
  using Teuchos::Exceptions::InvalidParameterValue;
  using std::cout;
  using std::endl;
  using std::string;
  
  ParameterList List,*validList;
  bool rv=true;

  /* Build a copy of the list to be validated. */
  for (ParameterList::ConstIterator param = inList.begin(); param != inList.end(); ++param) {
    const std::string pname=inList.name(param);
    if (pname.find("user-defined function",0) == std::string::npos) {
      List.setEntry(pname,inList.entry(param));
    }
  }

  List.setName(inList.name());

  /* Get Defaults + Validate */
  try {
    validList = GetValidMLPParameters();
  }
  catch(...) {
    std::cout << "Error in GetValidMLPParameters.  Please report this bug to the ML "
      "developers." << std::endl;
#ifdef HAVE_MPI
    MPI_Finalize();
#endif
    exit(EXIT_FAILURE);
  }
  try {
    List.validateParameters (*validList, depth, Teuchos::VALIDATE_USED_ENABLED, 
			     Teuchos::VALIDATE_DEFAULTS_DISABLED);
  }
#ifdef HAVE_IFPACK_DYNAMIC_FACTORY
  catch(InvalidParameterName &excpt)  {/*rv=false; std::cout<<excpt.what()<<std::endl;*/}
#else
  catch(InvalidParameterName &excpt)  {rv=false; std::cout<<excpt.what()<<std::endl;}
#endif
  catch(InvalidParameterType &excpt)  {rv=false; std::cout<<excpt.what()<<std::endl;}
  catch(InvalidParameterValue &excpt) {rv=false; std::cout<<excpt.what()<<std::endl;}
  catch(...) {rv=false;}
  delete validList;
  return rv;
}
예제 #5
0
bool ML_Epetra::ValidateRefMaxwellParameters(const Teuchos::ParameterList &inList){
  using Teuchos::ParameterList;
  using Teuchos::Exceptions::InvalidParameterName;
  using Teuchos::Exceptions::InvalidParameterType;
  using Teuchos::Exceptions::InvalidParameterValue;
  using std::cout;
  using std::endl;
  using std::string;

  ParameterList List,*validList;
  bool rv=true;
  
  /* Build a list with level-specific stuff stripped */
  //TODO this should be fixed
  for (ParameterList::ConstIterator param = inList.begin(); param != inList.end(); ++param) {
    const string pname=inList.name(param);
    if (pname.find("(level",0) == string::npos) {
      List.setEntry(pname,inList.entry(param));
    }
  }

  List.setName(inList.name());

  /* Get Defaults + Validate */
  try{
    validList = GetValidRefMaxwellParameters();
  }
  catch(...) {
    cout << "Error in GetValidMLPParameters.  Please report this bug to the ML "
      "developers." << endl;
#ifdef HAVE_MPI
    MPI_Finalize();
#endif
    exit(EXIT_FAILURE);
  }
  try {
    List.validateParameters(*validList, 0, Teuchos::VALIDATE_USED_DISABLED,
			    Teuchos::VALIDATE_DEFAULTS_DISABLED);
  }
  catch(InvalidParameterName &excpt)  {rv=false; cout<<excpt.what();}
  catch(InvalidParameterType &excpt)  {rv=false; cout<<excpt.what();}
  catch(InvalidParameterValue &excpt) {rv=false; cout<<excpt.what();}
  catch(...) {rv=false;}
  delete validList;
  return rv;
}
예제 #6
0
template<typename T> void
QCAD::MaterialDatabase:: 
getAllMatchingParams_helper(const std::string& paramName, std::vector<T>& results, Teuchos::ParameterList& list)
{
  Teuchos::ParameterList::ConstIterator it;
  Teuchos::ParameterList* list_type = NULL;
  T* param_type = NULL;

  for(it = list.begin(); it != list.end(); it++) {
    if( it->second.isList() ) {
      Teuchos::ParameterList& subList = it->second.getValue(list_type);
      getAllMatchingParams_helper(paramName, results, subList);
      continue;
    }

    if( it->second.isType<T>() && it->first == paramName )
      results.push_back( it->second.getValue(param_type) );
  }
}
예제 #7
0
bool TouchContFileParameters( Teuchos::ParameterList & fileParams )
{
  // Either int or double type
  int dummyInt;
  double dummyDouble;

  // Looping the list
  Teuchos::map<string, Teuchos::ParameterEntry>::const_iterator i;
  for (i = fileParams.begin(); i !=fileParams.end(); ++i) {

    if (fileParams.isType<int>(fileParams.name(i)))
      dummyInt = fileParams.get<int>(fileParams.name(i));

    if (fileParams.isType<double>(fileParams.name(i)))
      dummyDouble = fileParams.get<double>(fileParams.name(i));
  }

  return true;
}
예제 #8
0
void PeridigmNS::HorizonManager::loadHorizonInformationFromBlockParameters(Teuchos::ParameterList& blockParams) {

  // Find the horizon value for each block and record the default horizon value (if any)
  for(Teuchos::ParameterList::ConstIterator it = blockParams.begin() ; it != blockParams.end() ; it++){
    Teuchos::ParameterList& params = blockParams.sublist(it->first);
    bool hasConstantHorizon = params.isType<double>("Horizon");
    bool hasVariableHorizon = params.isType<string>("Horizon");
    TEUCHOS_TEST_FOR_EXCEPT_MSG(hasConstantHorizon && hasVariableHorizon, "\n**** Error parsing horizon information!  Multiple horizon definitions found!\n");
    TEUCHOS_TEST_FOR_EXCEPT_MSG(!hasConstantHorizon && !hasVariableHorizon, "\n**** Error parsing horizon information!  No horizon definition found!\n");

    // Record the horizon as a string regardless of whether or not it is constant
    string horizonString;
    if(hasConstantHorizon){
      double constantHorizon = params.get<double>("Horizon");
      stringstream horizonStringStream;
      horizonStringStream.precision(16);
      horizonStringStream << constantHorizon;
      horizonString = horizonStringStream.str();
    }
    else{
      horizonString = params.get<string>("Horizon");
    }

    // Parse space-delimited list of block names
    string blockNamesString = params.get<string>("Block Names");
    istringstream iss(blockNamesString);
    vector<string> blockNames;
    copy(istream_iterator<string>(iss),
         istream_iterator<string>(),
         back_inserter<vector<string> >(blockNames));

    for(vector<string>::const_iterator it = blockNames.begin() ; it != blockNames.end() ; ++it){
      if( *it == "Default" || *it == "default" || *it == "DEFAULT" ){
        horizonIsConstant["default"] = hasConstantHorizon;
        horizonStrings["default"] = horizonString;
      }
      else{
        horizonIsConstant[*it] = hasConstantHorizon;
        horizonStrings[*it] = horizonString;
      }
    }
  }
}
/** \brief Update this object with the fields from a parameter list.
  *
  * Update the requested fields using a parameter list. This method is
  * expected to pair with the getRequestedParameters method (i.e. the fields
  * requested are going to be update using this method).
  *
  * \param[in] pl Parameter list containing the requested parameters.
  *
  * \returns If the method succeeded (found all its required parameters) this
  *          method returns true, otherwise it returns false.
  *
  * \note The default implementation returns true (it does nothing!).
  */
bool PreconditionerInverseFactory::updateRequestedParameters(const Teuchos::ParameterList & pl)
{
   Teuchos::RCP<BlockPreconditionerFactory> bpf = rcp_dynamic_cast<BlockPreconditionerFactory>(precFactory_);

   // update the parameters of a BPF is required
   if(bpf!=Teuchos::null)
      return bpf->updateRequestedParameters(pl);

   // for non block preconditioners see if there are user requested additional parameters
   if(extraParams_==Teuchos::null)
      return true;

   Teuchos::ParameterList::ConstIterator itr;
   RCP<Teuchos::ParameterList> srcPl = precFactory_->unsetParameterList();

   // find name of settings sublist
   std::string subName = "";
   for(itr=srcPl->begin();itr!=srcPl->end();++itr) {
      // search for std::string with "Settings" in name
      if(itr->first.find("Settings")!=std::string::npos) {
         subName = itr->first;
         continue;
      }
   }

   // update fails if no settings list was found
   if(subName=="") {
      precFactory_->setParameterList(srcPl);
      return false;
   }

   // add extra parameters to list
   Teuchos::ParameterList & settingsList = srcPl->sublist(subName);
   for(itr=pl.begin();itr!=pl.end();++itr) {
      if(extraParams_->isParameter(itr->first))
         settingsList.setEntry(itr->first,itr->second);
   }

   // set the parameter list
   precFactory_->setParameterList(srcPl);

   return true;
}
예제 #10
0
bool WriteHeaderToContFile( const string & fileName,
    const Teuchos::ParameterList & fileParams )
{
  // The file to open
  ofstream oFile(fileName.c_str());

  // Writing the header
  oFile << "#" << setw(6) << "ID";

  // Looping on the parameters
  Teuchos::map<string, Teuchos::ParameterEntry>::const_iterator i;
  for (i = fileParams.begin(); i !=fileParams.end(); ++i) 
    oFile << setw(15) << fileParams.name(i);
  oFile << std::endl;

  // Closing
  oFile.close();

  return true;
}
예제 #11
0
bool UpdateContFile( const string & fileName,
    const int & idStep,
    const Teuchos::ParameterList & fileParams )
{

  // The file to open
  ofstream oFile(fileName.c_str(), ios_base::app);

  // Writing the id
  oFile << scientific << setw(7)  << idStep;

  // Looping on the parameters
  Teuchos::map<string, Teuchos::ParameterEntry>::const_iterator i;
  for (i = fileParams.begin(); i !=fileParams.end(); ++i) 
    oFile << scientific << setw(15) << fileParams.entry(i);
  oFile << std::endl;

  // Closing
  oFile.close();

  return true;
}
예제 #12
0
void Operator<Node>::paramsToUpper(Teuchos::ParameterList &plist, int &changed, bool rmUnderscore)
{
  changed = 0;

  // get a list of all parameter names in the list

  std::vector<std::string> paramNames ;
  Teuchos::ParameterList::ConstIterator pIter;

  pIter = plist.begin();

  while (1){
    //////////////////////////////////////////////////////////////////////
    // Compiler considered this while statement an error
    // for ( pIter = plist.begin() ; pIter != plist.end() ; pIter++ ){
    // }
    //////////////////////////////////////////////////////////////////////
    if (pIter == plist.end()) break;
    const std::string & nm = plist.name(pIter);
    paramNames.push_back(nm);
    pIter++;
  }

  // Change parameter names and values to upper case

  for (unsigned int i=0; i < paramNames.size(); i++){

    std::string origName(paramNames[i]);
    int paramNameChanged = 0;
    stringToUpper(paramNames[i], paramNameChanged, rmUnderscore);

    if (plist.isSublist(origName)){
      Teuchos::ParameterList &sublist = plist.sublist(origName);

      int sublistChanged=0;
      paramsToUpper(sublist, sublistChanged, false);

      if (paramNameChanged){

        // this didn't work, so I need to remove the old sublist
        // and create a new one
        //
        //sublist.setName(paramNames[i]);

        Teuchos::ParameterList newlist(sublist);
        plist.remove(origName);
        plist.set(paramNames[i], newlist);
      }
    }
    else if (plist.isParameter(origName)){

      std::string paramVal(plist.get<std::string>(origName));

      int paramValChanged=0;
      stringToUpper(paramVal, paramValChanged);

      if (paramNameChanged || paramValChanged){
        if (paramNameChanged){
          plist.remove(origName);
        }
        plist.set(paramNames[i], paramVal);
        changed++;
      }
    }
  } // next parameter or sublist
}
    //! @name Constructor/Destructor
    //@{
    AMGXOperator(const Teuchos::RCP<Tpetra::CrsMatrix<SC,LO,GO,NO> > &inA, Teuchos::ParameterList &paramListIn) {
      RCP<const Teuchos::Comm<int> > comm = inA->getRowMap()->getComm();
      int numProcs = comm->getSize();
      int myRank   = comm->getRank();

      RCP<Teuchos::Time> amgxTimer = Teuchos::TimeMonitor::getNewTimer("MueLu: AMGX: initialize");
      amgxTimer->start();
      // Initialize
      AMGX_SAFE_CALL(AMGX_initialize());
      AMGX_SAFE_CALL(AMGX_initialize_plugins());

      /*system*/
      //AMGX_SAFE_CALL(AMGX_register_print_callback(&print_callback));
      AMGX_SAFE_CALL(AMGX_install_signal_handler());
      Teuchos::ParameterList configs = paramListIn.sublist("amgx:params", true);
      if (configs.isParameter("json file")) {
        AMGX_SAFE_CALL(AMGX_config_create_from_file(&Config_, (const char *) &configs.get<std::string>("json file")[0]));
      } else {
        std::ostringstream oss;
        oss << "";
        ParameterList::ConstIterator itr;
        for (itr = configs.begin(); itr != configs.end(); ++itr) {
          const std::string&    name  = configs.name(itr);
          const ParameterEntry& entry = configs.entry(itr);
          oss << name << "=" << filterValueToString(entry) << ", ";
        }
        oss << "\0";
        std::string configString = oss.str();
        if (configString == "") {
          //print msg that using defaults
          //GetOStream(Warnings0) << "Warning: No configuration parameters specified, using default AMGX configuration parameters. \n";
        }
        AMGX_SAFE_CALL(AMGX_config_create(&Config_, configString.c_str()));
      }

      // TODO: we probably need to add "exception_handling=1" to the parameter list
      // to switch on internal error handling (with no need for AMGX_SAFE_CALL)

#define NEW_COMM
#ifdef NEW_COMM
      // NOTE: MPI communicator used in AMGX_resources_create must exist in the scope of AMGX_matrix_comm_from_maps_one_ring
      // FIXME: fix for serial comm
      RCP<const Teuchos::MpiComm<int> > tmpic = Teuchos::rcp_dynamic_cast<const Teuchos::MpiComm<int> >(comm->duplicate());
      TEUCHOS_TEST_FOR_EXCEPTION(tmpic.is_null(), Exceptions::RuntimeError, "Communicator is not MpiComm");

      RCP<const Teuchos::OpaqueWrapper<MPI_Comm> > rawMpiComm = tmpic->getRawMpiComm();
      MPI_Comm mpiComm = *rawMpiComm;
#endif

      // Construct AMGX resources
      if (numProcs == 1) {
        AMGX_resources_create_simple(&Resources_, Config_);

      } else {
        int numGPUDevices;
        cudaGetDeviceCount(&numGPUDevices);
        int device[] = {(comm->getRank() % numGPUDevices)};

        AMGX_config_add_parameters(&Config_, "communicator=MPI");
#ifdef NEW_COMM
        AMGX_resources_create(&Resources_, Config_, &mpiComm, 1/* number of GPU devices utilized by this rank */, device);
#else
        AMGX_resources_create(&Resources_, Config_, MPI_COMM_WORLD, 1/* number of GPU devices utilized by this rank */, device);
#endif
      }

      AMGX_Mode mode = AMGX_mode_dDDI;
      AMGX_solver_create(&Solver_, Resources_, mode,  Config_);
      AMGX_matrix_create(&A_,      Resources_, mode);
      AMGX_vector_create(&X_,      Resources_, mode);
      AMGX_vector_create(&Y_,      Resources_, mode);

      amgxTimer->stop();
      amgxTimer->incrementNumCalls();

      std::vector<int> amgx2muelu;

      // Construct AMGX communication pattern
      if (numProcs > 1) {
        RCP<const Tpetra::Import<LO,GO> > importer = inA->getCrsGraph()->getImporter();

        TEUCHOS_TEST_FOR_EXCEPTION(importer.is_null(), MueLu::Exceptions::RuntimeError, "The matrix A has no Import object.");

        Tpetra::Distributor distributor = importer->getDistributor();

        Array<int> sendRanks = distributor.getImagesTo();
        Array<int> recvRanks = distributor.getImagesFrom();

        std::sort(sendRanks.begin(), sendRanks.end());
        std::sort(recvRanks.begin(), recvRanks.end());

        bool match = true;
        if (sendRanks.size() != recvRanks.size()) {
          match = false;
        } else {
          for (int i = 0; i < sendRanks.size(); i++) {
            if (recvRanks[i] != sendRanks[i])
              match = false;
              break;
          }
        }
        TEUCHOS_TEST_FOR_EXCEPTION(!match, MueLu::Exceptions::RuntimeError, "AMGX requires that the processors that we send to and receive from are the same. "
                                   "This is not the case: we send to {" << sendRanks << "} and receive from {" << recvRanks << "}");

        int        num_neighbors = sendRanks.size();  // does not include the calling process
        const int* neighbors     = &sendRanks[0];

        // Later on, we'll have to organize the send and recv data by PIDs,
        // i.e, a vector V of vectors, where V[i] is PID i's vector of data.
        // Hence we need to be able to quickly look up  an array index
        // associated with each PID.
        Tpetra::Details::HashTable<int,int> hashTable(3*num_neighbors);
        for (int i = 0; i < num_neighbors; i++)
          hashTable.add(neighbors[i], i);

        // Get some information out
        ArrayView<const int> exportLIDs = importer->getExportLIDs();
        ArrayView<const int> exportPIDs = importer->getExportPIDs();
        Array<int> importPIDs;
        Tpetra::Import_Util::getPids(*importer, importPIDs, true/* make local -1 */);

        // Construct the reordering for AMGX as in AMGX_matrix_upload_all documentation
        RCP<const Map> rowMap = inA->getRowMap();
        RCP<const Map> colMap = inA->getColMap();

        int N = rowMap->getNodeNumElements(), Nc = colMap->getNodeNumElements();
        muelu2amgx_.resize(Nc, -1);

        int numUniqExports = 0;
        for (int i = 0; i < exportLIDs.size(); i++)
          if (muelu2amgx_[exportLIDs[i]] == -1) {
            numUniqExports++;
            muelu2amgx_[exportLIDs[i]] = -2;
          }

        int localOffset = 0, exportOffset = N - numUniqExports;
        // Go through exported LIDs and put them at the end of LIDs
        for (int i = 0; i < exportLIDs.size(); i++)
          if (muelu2amgx_[exportLIDs[i]] < 0) // exportLIDs are not unique
            muelu2amgx_[exportLIDs[i]] = exportOffset++;
        // Go through all non-export LIDs, and put them at the beginning of LIDs
        for (int i = 0; i < N; i++)
          if (muelu2amgx_[i] == -1)
            muelu2amgx_[i] = localOffset++;
        // Go through the tail (imported LIDs), and order those by neighbors
        int importOffset = N;
        for (int k = 0; k < num_neighbors; k++)
          for (int i = 0; i < importPIDs.size(); i++)
            if (importPIDs[i] != -1 && hashTable.get(importPIDs[i]) == k)
              muelu2amgx_[i] = importOffset++;

        amgx2muelu.resize(muelu2amgx_.size());
        for (int i = 0; i < muelu2amgx_.size(); i++)
          amgx2muelu[muelu2amgx_[i]] = i;

        // Construct send arrays
        std::vector<std::vector<int> > sendDatas (num_neighbors);
        std::vector<int>               send_sizes(num_neighbors, 0);
        for (int i = 0; i < exportPIDs.size(); i++) {
          int index = hashTable.get(exportPIDs[i]);
          sendDatas [index].push_back(muelu2amgx_[exportLIDs[i]]);
          send_sizes[index]++;
        }
        // FIXME: sendDatas must be sorted (based on GIDs)

        std::vector<const int*> send_maps(num_neighbors);
        for (int i = 0; i < num_neighbors; i++)
          send_maps[i] = &(sendDatas[i][0]);

        // Debugging
        printMaps(comm, sendDatas, amgx2muelu, neighbors, *importer->getTargetMap(), "send_map_vector");

        // Construct recv arrays
        std::vector<std::vector<int> > recvDatas (num_neighbors);
        std::vector<int>               recv_sizes(num_neighbors, 0);
        for (int i = 0; i < importPIDs.size(); i++)
          if (importPIDs[i] != -1) {
            int index = hashTable.get(importPIDs[i]);
            recvDatas [index].push_back(muelu2amgx_[i]);
            recv_sizes[index]++;
        }
        // FIXME: recvDatas must be sorted (based on GIDs)

        std::vector<const int*> recv_maps(num_neighbors);
        for (int i = 0; i < num_neighbors; i++)
          recv_maps[i] = &(recvDatas[i][0]);

        // Debugging
        printMaps(comm, recvDatas, amgx2muelu, neighbors, *importer->getTargetMap(), "recv_map_vector");

        AMGX_SAFE_CALL(AMGX_matrix_comm_from_maps_one_ring(A_, 1, num_neighbors, neighbors, &send_sizes[0], &send_maps[0], &recv_sizes[0], &recv_maps[0]));

        AMGX_vector_bind(X_, A_);
        AMGX_vector_bind(Y_, A_);
      }

      RCP<Teuchos::Time> matrixTransformTimer = Teuchos::TimeMonitor::getNewTimer("MueLu: AMGX: transform matrix");
      matrixTransformTimer->start();

      ArrayRCP<const size_t> ia_s;
      ArrayRCP<const int>    ja;
      ArrayRCP<const double> a;
      inA->getAllValues(ia_s, ja, a);

      ArrayRCP<int> ia(ia_s.size());
      for (int i = 0; i < ia.size(); i++)
        ia[i] = Teuchos::as<int>(ia_s[i]);

      N_      = inA->getNodeNumRows();
      int nnz = inA->getNodeNumEntries();

      matrixTransformTimer->stop();
      matrixTransformTimer->incrementNumCalls();


      // Upload matrix
      // TODO Do we need to pin memory here through AMGX_pin_memory?
      RCP<Teuchos::Time> matrixTimer = Teuchos::TimeMonitor::getNewTimer("MueLu: AMGX: transfer matrix  CPU->GPU");
      matrixTimer->start();
      if (numProcs == 1) {
        AMGX_matrix_upload_all(A_, N_, nnz, 1, 1, &ia[0], &ja[0], &a[0], NULL);

      } else {
        // Transform the matrix
        std::vector<int>    ia_new(ia.size());
        std::vector<int>    ja_new(ja.size());
        std::vector<double> a_new (a.size());

        ia_new[0] = 0;
        for (int i = 0; i < N_; i++) {
          int oldRow = amgx2muelu[i];

          ia_new[i+1] = ia_new[i] + (ia[oldRow+1] - ia[oldRow]);

          for (int j = ia[oldRow]; j < ia[oldRow+1]; j++) {
            int offset = j - ia[oldRow];
            ja_new[ia_new[i] + offset] = muelu2amgx_[ja[j]];
            a_new [ia_new[i] + offset] = a[j];
          }
          // Do bubble sort on two arrays
          // NOTE: There are multiple possible optimizations here (even of bubble sort)
          bool swapped;
          do {
            swapped = false;

            for (int j = ia_new[i]; j < ia_new[i+1]-1; j++)
              if (ja_new[j] > ja_new[j+1]) {
                std::swap(ja_new[j], ja_new[j+1]);
                std::swap(a_new [j], a_new [j+1]);
                swapped = true;
              }
          } while (swapped == true);
        }

        AMGX_matrix_upload_all(A_, N_, nnz, 1, 1, &ia_new[0], &ja_new[0], &a_new[0], NULL);
      }
      matrixTimer->stop();
      matrixTimer->incrementNumCalls();

      domainMap_ = inA->getDomainMap();
      rangeMap_  = inA->getRangeMap();

      RCP<Teuchos::Time> realSetupTimer = Teuchos::TimeMonitor::getNewTimer("MueLu: AMGX: real setup");
      realSetupTimer->start();
      AMGX_solver_setup(Solver_, A_);
      realSetupTimer->stop();
      realSetupTimer->incrementNumCalls();

      vectorTimer1_ = Teuchos::TimeMonitor::getNewTimer("MueLu: AMGX: transfer vectors CPU->GPU");
      vectorTimer2_ = Teuchos::TimeMonitor::getNewTimer("MueLu: AMGX: transfer vector  GPU->CPU");
    }
예제 #14
0
  HybridPlatform::
  HybridPlatform (const Teuchos::RCP<const Teuchos::Comm<int> >& comm, 
		  Teuchos::ParameterList& pl)
    : comm_ (comm)
    , nodeCreated_ (false)
    , nodeType_ (SERIALNODE)
  {
    // ParameterList format:
    // 
    // Node designation sublists have a name beginning with one of the
    // following characters: % = [ and satisfying the following
    // format:

    //   %M=N    is satisfied if mod(myrank,M) == N
    //   =N      is satisfied if myrank == N
    //   [M,N]   is satisfied if myrank \in [M,N]
    // 
    // A node designation sublist must have a parameter entry of type
    // std::string named "NodeType". The value indicates the type of
    // the Node.  The activated node designation sublist will be
    // passed to the Node constructor.
    // 
    // For example:
    // "%2=0"  ->  
    //    NodeType     = "KokkosClassic::ThrustGPUNode"
    //    DeviceNumber = 0
    //    Verbose      = 1
    // "%2=1"  ->
    //    NodeType     = "KokkosClassic::TPINode"
    //    NumThreads   = 8
    // 
    // In this scenario, nodes that are equivalent to zero module 2,
    // that is, even nodes, will be selected to use ThrustGPUNode
    // objects and initialized with the parameter list containing
    //    NodeType   = "KokkosClassic::ThrustGPUNode"
    //    DeviceNumber = 0
    //    Verbose      = 1
    //
    // Nodes that are equivalent to one modulo 2, i.e., odd nodes,
    // will be selected to use TPINode objects and initialized with
    // the parameter list containing
    //    NodeType   = "KokkosClassic::TPINode"
    //    NumThreads = 8
    // 
    // If multiple node designation sublists match the process rank,
    // then the first encountered node designation will be used.  I
    // don't know if ParameterList respects any ordering, therefore,
    // multiple matching designations are to be avoided.

    const int myrank = comm_->getRank();
    std::string desigNode("");
    bool matchFound = false;
    for (Teuchos::ParameterList::ConstIterator it = pl.begin(); it != pl.end(); ++it) {
      if (it->second.isList()) {
        int parsedLen, M, N;
        const std::string &name = it->first;
        const Teuchos::ParameterList &sublist = Teuchos::getValue<Teuchos::ParameterList>(it->second);
        // select and assign instList_;
        parsedLen = 0;
        if (std::sscanf(name.c_str(),"%%%d=%d%n",&M,&N,&parsedLen) == 2 && (size_t)parsedLen == name.length()) {
          if ((myrank % M) == N) {
            matchFound = true;
          }
        }
        parsedLen = 0;
        if (std::sscanf(name.c_str(),"=%d%n",&N,&parsedLen) == 1 && (size_t)parsedLen == name.length()) {
          if (myrank == N) {
            matchFound = true;
          }
        }
        parsedLen = 0;
        if (std::sscanf(name.c_str(),"[%d,%d]%n",&M,&N,&parsedLen) == 2 && (size_t)parsedLen == name.length()) {
          if (M <= myrank && myrank <= N) {
            matchFound = true;
          }
        }
        if (name == "default") {
          matchFound = true;
        }
        if (matchFound) {
          try {
            desigNode = sublist.get<std::string>("NodeType");
          }
          catch (Teuchos::Exceptions::InvalidParameterName &e) {
            TEUCHOS_TEST_FOR_EXCEPTION_PURE_MSG(true, std::runtime_error, 
              std::endl << Teuchos::typeName(*this) << ": Invalid machine file." << std::endl 
              << "Missing parameter \"NodeType\" on Node " << myrank << " for Node designator " << "\"" << name << "\":" << std::endl 
              << sublist << std::endl);
          }
          if (desigNode == "KokkosClassic::SerialNode") {
            nodeType_ = SERIALNODE;
          }
#ifdef HAVE_KOKKOSCLASSIC_THREADPOOL
          else if (desigNode == "KokkosClassic::TPINode") {
            nodeType_ = TPINODE;
          }
#endif
#ifdef HAVE_KOKKOSCLASSIC_TBB
          else if (desigNode == "KokkosClassic::TBBNode") {
            nodeType_ = TBBNODE;
          }
#endif
#ifdef HAVE_KOKKOSCLASSIC_OPENMP
          else if (desigNode == "KokkosClassic::OpenMPNode") {
            nodeType_ = OMPNODE;
          }
#endif
#ifdef HAVE_KOKKOSCLASSIC_THRUST
          else if (desigNode == "KokkosClassic::ThrustGPUNode") {
            nodeType_ = THRUSTGPUNODE;
          }
#endif
          else {
            matchFound = false;
          }
          if (matchFound) {
            instList_ = sublist;
            break;
          }
        }
      }
    }
    if (!matchFound) {
      TEUCHOS_TEST_FOR_EXCEPTION_PURE_MSG(true, std::runtime_error, 
          Teuchos::typeName(*this) << ": No matching node type on rank " << myrank);
    }
  }