void createBasicVector( std::vector<const scalar_t *> &entries, std::vector<int> &entryStride, std::vector<const scalar_t *> &weights, std::vector<int> &weightStrides) { typedef StridedData<lno_t,scalar_t> input_t; if (numIds_){ int stride = 1; entries_ = arcp(new input_t[numEntriesPerID_], 0, numEntriesPerID_, true); for (int v=0; v < numEntriesPerID_; v++) { if (entryStride.size()) stride = entryStride[v]; ArrayRCP<const scalar_t> eltV(entries[v], 0, stride*numIds_, false); entries_[v] = input_t(eltV, stride); } } if (numWeights_) { int stride = 1; weights_ = arcp(new input_t [numWeights_], 0, numWeights_, true); for (int w=0; w < numWeights_; w++){ if (weightStrides.size()) stride = weightStrides[w]; ArrayRCP<const scalar_t> wgtV(weights[w], 0, stride*numIds_, false); weights_[w] = input_t(wgtV, stride); } } }
void PartitioningProblem<Adapter>::initializeProblem() { HELLO; this->env_->debug(DETAILED_STATUS, "PartitioningProblem::initializeProblem"); if (getenv("DEBUGME")){ #ifndef _WIN32 std::cout << getpid() << std::endl; sleep(15); #else std::cout << _getpid() << std::endl; Sleep(15000); #endif } #ifdef HAVE_ZOLTAN2_OVIS ovis_enabled(this->comm_->getRank()); #endif // Create a copy of the user's communicator. problemComm_ = this->comm_->duplicate(); problemCommConst_ = rcp_const_cast<const Comm<int> > (problemComm_); machine_ = RCP <Zoltan2::MachineRepresentation<typename Adapter::scalar_t> >(new Zoltan2::MachineRepresentation<typename Adapter::scalar_t>(problemComm_)); // Number of criteria is number of user supplied weights if non-zero. // Otherwise it is 1 and uniform weight is implied. numberOfWeights_ = this->inputAdapter_->getNumWeightsPerID(); numberOfCriteria_ = (numberOfWeights_ > 1) ? numberOfWeights_ : 1; inputType_ = this->inputAdapter_->adapterType(); // The Caller can specify part sizes in setPartSizes(). If he/she // does not, the part size arrays are empty. ArrayRCP<part_t> *noIds = new ArrayRCP<part_t> [numberOfCriteria_]; ArrayRCP<scalar_t> *noSizes = new ArrayRCP<scalar_t> [numberOfCriteria_]; partIds_ = arcp(noIds, 0, numberOfCriteria_, true); partSizes_ = arcp(noSizes, 0, numberOfCriteria_, true); if (this->env_->getDebugLevel() >= DETAILED_STATUS){ std::ostringstream msg; msg << problemComm_->getSize() << " procs," << numberOfWeights_ << " user-defined weights\n"; this->env_->debug(DETAILED_STATUS, msg.str()); } this->env_->memory("After initializeProblem"); }
void GidLookupHelper<T, lno_t>::getIndices( ArrayRCP<lno_t> &indices) const { lno_t numIds = size(); lno_t *idx = new lno_t [numIds]; ArrayRCP<lno_t> indexList = arcp(idx, 0, numIds, true); if (numIds == gidList_.size()){ for (lno_t i=0; i < gidList_.size(); i++){ *idx++ = i; } } else{ const T *ids = gidList_.getRawPtr(); set<T> allGids; for (lno_t i=0; i < gidList_.size(); i++){ typename set<T>::iterator rec = allGids.find(ids[i]); if (rec == allGids.end()){ allGids.insert(ids[i]); *idx++ = i; } } } indices = indexList; }
IdentifierModel<Adapter>::IdentifierModel( const RCP<const Adapter> &ia, const RCP<const Environment> &env, const RCP<const Comm<int> > &comm, modelFlag_t &modelFlags): numGlobalIdentifiers_(), env_(env), comm_(comm), gids_(), nUserWeights_(0), weights_() { // Get the local and global problem size size_t nLocalIds = ia->getLocalNumIDs(); gno_t lsum = nLocalIds; reduceAll<int, gno_t>(*comm_, Teuchos::REDUCE_SUM, 1, &lsum, &numGlobalIdentifiers_); // Get the number of weights // Use max number of weights over all processes as nUserWeights_ int tmp = ia->getNumWeightsPerID(); Teuchos::reduceAll<int, int>(*comm, Teuchos::REDUCE_MAX, 1, &tmp, &nUserWeights_); // Prepare to store views from input adapter // TODO: Do we have to store these views, or can we get them on an // TODO: as-needed basis? Array<const scalar_t *> wgts(nUserWeights_, (const scalar_t *)NULL); Array<int> wgtStrides(nUserWeights_, 0); if (nUserWeights_ > 0){ input_t *w = new input_t [nUserWeights_]; weights_ = arcp<input_t>(w, 0, nUserWeights_); } const gno_t *gids=NULL; // Get the input adapter's views try{ ia->getIDsView(gids); for (int idx=0; idx < nUserWeights_; idx++) ia->getWeightsView(wgts[idx], wgtStrides[idx], idx); } Z2_FORWARD_EXCEPTIONS; if (nLocalIds){ gids_ = arcp(gids, 0, nLocalIds, false); if (nUserWeights_ > 0){ for (int idx=0; idx < nUserWeights_; idx++){ ArrayRCP<const scalar_t> wgtArray(wgts[idx], 0, nLocalIds*wgtStrides[idx], false); weights_[idx] = input_t(wgtArray, wgtStrides[idx]); } } } env_->memory("After construction of identifier model"); }
void PartitioningProblem<Adapter>::setPartSizesForCriteria( int criteria, int len, part_t *partIds, scalar_t *partSizes, bool makeCopy) { this->env_->localInputAssertion(__FILE__, __LINE__, "invalid length", len>= 0, BASIC_ASSERTION); this->env_->localInputAssertion(__FILE__, __LINE__, "invalid criteria", criteria >= 0 && criteria < numberOfCriteria_, BASIC_ASSERTION); if (len == 0){ partIds_[criteria] = ArrayRCP<part_t>(); partSizes_[criteria] = ArrayRCP<scalar_t>(); return; } this->env_->localInputAssertion(__FILE__, __LINE__, "invalid arrays", partIds && partSizes, BASIC_ASSERTION); // The global validity of the partIds and partSizes arrays is performed // by the PartitioningSolution, which computes global part distribution and // part sizes. part_t *z2_partIds = NULL; scalar_t *z2_partSizes = NULL; bool own_memory = false; if (makeCopy){ z2_partIds = new part_t [len]; z2_partSizes = new scalar_t [len]; this->env_->localMemoryAssertion(__FILE__, __LINE__, len, z2_partSizes); memcpy(z2_partIds, partIds, len * sizeof(part_t)); memcpy(z2_partSizes, partSizes, len * sizeof(scalar_t)); own_memory=true; } else{ z2_partIds = partIds; z2_partSizes = partSizes; } partIds_[criteria] = arcp(z2_partIds, 0, len, own_memory); partSizes_[criteria] = arcp(z2_partSizes, 0, len, own_memory); }
/*! \brief Get the parts belonging to this rank * \param numParts on return, set to the number of parts assigned to rank. * \param parts on return, pointer (view) to the parts assigned to rank */ void getMyPartsView(part_t &numParts, part_t *&parts) { bool useAlg = true; // Check first whether this algorithm answers getMyPartsView. if (mapping_algorithm != Teuchos::null) { try { mapping_algorithm->getMyPartsView(numParts, parts); } catch (NotImplemented &e) { // It is OK if the algorithm did not implement this method; // we'll get the information from the solution below. useAlg = false; } Z2_FORWARD_EXCEPTIONS; } if (!useAlg) { // Algorithm did not implement this method. // Did the algorithm register a result with the solution? if ((partsForRank==Teuchos::null) && (rankForPart==Teuchos::null)) { numParts = 0; parts = NULL; throw std::runtime_error("No mapping solution available."); } if (partsForRank == Teuchos::null) { // Need to create the array since we haven't created it before. Teuchos::Array<part_t> tmp; part_t cnt = 0; for (typename rankmap_t::iterator it = rankForPart->begin(); it != rankForPart->end(); it++) { if (it->second == myRank) { tmp.push_back(it->first); cnt++; } } if (cnt) partsForRank = arcp(&tmp[0], 0, cnt, true); } numParts = partsForRank.size(); if (numParts) parts = partsForRank.getRawPtr(); else parts = NULL; } }
BasicIdentifierAdapter<User>::BasicIdentifierAdapter( lno_t numIds, const gno_t *idPtr, std::vector<const scalar_t *> &weights, std::vector<int> &weightStrides): numIds_(numIds), idList_(idPtr), weights_() { typedef StridedData<lno_t,scalar_t> input_t; size_t numWeights = weights.size(); if (numWeights > 0){ weights_ = arcp(new input_t [numWeights], 0, numWeights, true); if (numIds > 0){ for (size_t i=0; i < numWeights; i++){ int stride = weightStrides.size() ? weightStrides[i] : 1; ArrayRCP<const scalar_t> wgtV(weights[i], 0, stride*numIds, false); weights_[i] = input_t(wgtV, stride); } } } }
ArrayRCP<std::string> GetFileList(const std::string & dirPath, const std::string & filter) { RCP<std::vector<std::string> > files = rcp(new std::vector<std::string>()); DIR *dir; struct dirent *dirEntry; dir = opendir(dirPath.c_str()); TEUCHOS_TEST_FOR_EXCEPTION(dir == NULL, MueLu::Exceptions::RuntimeError, "GetFileList(\"" + dirPath + "\") : " + strerror(errno)); while ((dirEntry = readdir(dir)) != NULL) { std::string dirEntryS(dirEntry->d_name); if (dirEntryS.rfind(filter) != string::npos) files->push_back(std::string(dirEntryS)); } closedir(dir); return arcp(files); }
IdentifierModel<IdentifierInput<User> >::IdentifierModel( const IdentifierInput<User> *ia, const RCP<const Environment> &env, const RCP<const Comm<int> > &comm, modelFlag_t &modelFlags): gnosAreGids_(false), numGlobalIdentifiers_(), env_(env), comm_(comm), gids_(), userWeightDim_(0), weights_(), gnos_(), gnosConst_() { userWeightDim_ = ia->getNumberOfWeights(); size_t nLocalIds = ia->getLocalNumberOfIdentifiers(); Model<IdentifierInput<User> >::maxCount(*comm, userWeightDim_); Array<const scalar_t *> wgts(userWeightDim_, (const scalar_t *)NULL); Array<int> wgtStrides(userWeightDim_, 0); Array<lno_t> weightArrayLengths(userWeightDim_, 0); if (userWeightDim_ > 0){ input_t *w = new input_t [userWeightDim_]; weights_ = arcp<input_t>(w, 0, userWeightDim_); } const gid_t *gids=NULL; try{ ia->getIdentifierList(gids); for (int dim=0; dim < userWeightDim_; dim++) ia->getIdentifierWeights(dim, wgts[dim], wgtStrides[dim]); } Z2_FORWARD_EXCEPTIONS; if (nLocalIds){ gids_ = arcp(gids, 0, nLocalIds, false); if (userWeightDim_ > 0){ for (int i=0; i < userWeightDim_; i++){ if (wgts[i] != NULL){ ArrayRCP<const scalar_t> wgtArray( wgts[i], 0, nLocalIds*wgtStrides[i], false); weights_[i] = input_t(wgtArray, wgtStrides[i]); weightArrayLengths[i] = nLocalIds; } } } } this->setWeightArrayLengths(weightArrayLengths, *comm_); RCP<const idmap_t> idMap; try{ if (modelFlags.test(IDS_MUST_BE_GLOBALLY_CONSECUTIVE)) idMap = rcp(new idmap_t(env_, comm_, gids_, true)); else idMap = rcp(new idmap_t(env_, comm_, gids_, false)); } Z2_FORWARD_EXCEPTIONS; gnosAreGids_ = idMap->gnosAreGids(); this->setIdentifierMap(idMap); gno_t lsum = nLocalIds; reduceAll<int, gno_t>(*comm_, Teuchos::REDUCE_SUM, 1, &lsum, &numGlobalIdentifiers_); if (!gnosAreGids_ && nLocalIds>0){ gno_t *tmpGno = new gno_t [nLocalIds]; env_->localMemoryAssertion(__FILE__, __LINE__, nLocalIds, tmpGno); gnos_ = arcp(tmpGno, 0, nLocalIds); try{ ArrayRCP<gid_t> gidsNonConst = arcp_const_cast<gid_t>(gids_); idMap->gidTranslate( gidsNonConst(0,nLocalIds), gnos_(0,nLocalIds), TRANSLATE_APP_TO_LIB); } Z2_FORWARD_EXCEPTIONS; }
size_t computeLocalEdgeList( const RCP<const Environment> &env, const RCP<const Comm<int> > &comm, size_t numLocalEdges, // local edges size_t numLocalGraphEdges, // edges in "local" graph RCP<const IdentifierMap<User> > &idMap, ArrayRCP<const typename InputTraits<User>::zgid_t> &allEdgeIds, // in ArrayRCP<const typename InputTraits<User>::gno_t> &allEdgeGnos, // in ArrayRCP<int> &allProcs, // in ArrayRCP<const typename InputTraits<User>::lno_t> &allOffs, // in ArrayRCP<StridedData<typename InputTraits<User>::lno_t, typename InputTraits<User>::scalar_t> > &allWeights,// in ArrayRCP<const typename InputTraits<User>::lno_t> &edgeLocalIds, // ArrayRCP<const typename InputTraits<User>::lno_t> &offsets, // out ArrayRCP<StridedData<typename InputTraits<User>::lno_t, typename InputTraits<User>::scalar_t> > &eWeights) // out { typedef typename InputTraits<User>::zgid_t zgid_t; typedef typename InputTraits<User>::gno_t gno_t; typedef typename InputTraits<User>::scalar_t scalar_t; typedef typename InputTraits<User>::lno_t lno_t; typedef StridedData<lno_t, scalar_t> input_t; int rank = comm->getRank(); bool gnosAreGids = idMap->gnosAreGids(); edgeLocalIds = ArrayRCP<const lno_t>(Teuchos::null); eWeights = ArrayRCP<input_t>(Teuchos::null); offsets = ArrayRCP<const lno_t>(Teuchos::null); if (numLocalGraphEdges == 0) { // Set the offsets array and return size_t allOffsSize = allOffs.size(); lno_t *offs = new lno_t [allOffsSize]; env->localMemoryAssertion(__FILE__, __LINE__, allOffsSize, offs); for (size_t i = 0; i < allOffsSize; i++) offs[i] = 0; offsets = arcp(offs, 0, allOffsSize, true); return 0; } if (numLocalGraphEdges == numLocalEdges){ // Entire graph is local. lno_t *lnos = new lno_t [numLocalGraphEdges]; env->localMemoryAssertion(__FILE__, __LINE__, numLocalGraphEdges, lnos); if (comm->getSize() == 1) { // With one rank, Can use gnos as local index. if (gnosAreGids) for (size_t i=0; i < numLocalEdges; i++) lnos[i] = allEdgeIds[i]; else for (size_t i=0; i < numLocalEdges; i++) lnos[i] = allEdgeGnos[i]; } else { ArrayRCP<gno_t> gnoArray; if (gnosAreGids){ ArrayRCP<const gno_t> gnosConst = arcp_reinterpret_cast<const gno_t>(allEdgeIds); gnoArray = arcp_const_cast<gno_t>(gnosConst); } else { gnoArray = arcp_const_cast<gno_t>(allEdgeGnos); } // Need to translate to gnos to local indexing ArrayView<lno_t> lnoView(lnos, numLocalGraphEdges); try { idMap->lnoTranslate(lnoView, gnoArray.view(0,numLocalGraphEdges), TRANSLATE_LIB_TO_APP); } Z2_FORWARD_EXCEPTIONS; } edgeLocalIds = arcp(lnos, 0, numLocalGraphEdges, true); offsets = allOffs; eWeights = allWeights; }
size_t removeUndesiredEdges( const RCP<const Environment> &env, int myRank, bool removeSelfEdges, bool removeOffProcessEdges, bool removeOffGroupEdges, ArrayView<const typename InputTraits<User>::zgid_t> &gids, ArrayView<const typename InputTraits<User>::zgid_t> &gidNbors, ArrayView<const int> &procIds, ArrayView<StridedData<typename InputTraits<User>::lno_t, typename InputTraits<User>::scalar_t> > &edgeWeights, ArrayView<const typename InputTraits<User>::lno_t> &offsets, ArrayRCP<const typename InputTraits<User>::zgid_t> &newGidNbors, // out typename InputTraits<User>::scalar_t **&newWeights, // out ArrayRCP<const typename InputTraits<User>::lno_t> &newOffsets) // out { typedef typename InputTraits<User>::zgid_t zgid_t; typedef typename InputTraits<User>::scalar_t scalar_t; typedef typename InputTraits<User>::lno_t lno_t; size_t numKeep = 0; size_t numVtx = offsets.size() - 1; size_t numNbors = gidNbors.size(); env->localInputAssertion(__FILE__, __LINE__, "need more input", (!removeSelfEdges || gids.size() >= static_cast<typename ArrayView<const zgid_t>::size_type>(numVtx)) && (!removeOffProcessEdges || procIds.size() >= static_cast<typename ArrayView<const int>::size_type>(numNbors)) && (!removeOffGroupEdges || procIds.size() >= static_cast<typename ArrayView<const int>::size_type>(numNbors)), BASIC_ASSERTION); // initialize edge weight array newWeights = NULL; int eDim = edgeWeights.size(); // count desired edges lno_t *offs = new lno_t [numVtx + 1]; env->localMemoryAssertion(__FILE__, __LINE__, numVtx+1, offs); for (size_t i = 0; i < numVtx+1; i++) offs[i] = 0; ArrayRCP<const lno_t> offArray = arcp(offs, 0, numVtx+1, true); const lno_t *allOffs = offsets.getRawPtr(); const zgid_t *allIds = gidNbors.getRawPtr(); const zgid_t *vtx = NULL; const int *proc = NULL; if (gids.size() > 0) vtx = gids.getRawPtr(); if (procIds.size() > 0) proc = procIds.getRawPtr(); offs[0] = 0; for (size_t i=0; i < numVtx; i++){ offs[i+1] = 0; zgid_t vid = vtx ? vtx[i] : zgid_t(0); for (lno_t j=allOffs[i]; j < allOffs[i+1]; j++){ int owner = proc ? proc[j] : 0; bool keep = (!removeSelfEdges || vid != allIds[j]) && (!removeOffProcessEdges || owner == myRank) && (!removeOffGroupEdges || owner >= 0); if (keep) offs[i+1]++; } } // from counters to offsets for (size_t i=1; i < numVtx; i++) offs[i+1] += offs[i]; numKeep = offs[numVtx]; // do we need a new neighbor list? if (numNbors == numKeep){ newGidNbors = Teuchos::arcpFromArrayView(gidNbors); newOffsets = Teuchos::arcpFromArrayView(offsets); return numNbors; } else if (numKeep == 0){ newGidNbors = ArrayRCP<const zgid_t>(Teuchos::null); newOffsets = offArray; return 0; } // Build the subset neighbor lists (id, weight, and offset). zgid_t *newGids = new zgid_t [numKeep]; env->localMemoryAssertion(__FILE__, __LINE__, numKeep, newGids); newGidNbors = arcp(newGids, 0, numKeep, true); newOffsets = offArray; if (eDim > 0){ newWeights = new scalar_t * [eDim]; env->localMemoryAssertion(__FILE__, __LINE__, eDim, newWeights); if (numKeep) { for (int w=0; w < eDim; w++){ newWeights[w] = new scalar_t [numKeep]; env->localMemoryAssertion(__FILE__, __LINE__, numKeep, newWeights[w]); } } else { for (int w=0; w < eDim; w++) newWeights[w] = NULL; } } size_t next = 0; for (size_t i=0; i < numVtx && next < numKeep; i++){ zgid_t vid = vtx ? vtx[i] : zgid_t(0); for (lno_t j=allOffs[i]; j < allOffs[i+1]; j++){ int owner = proc ? proc[j] : 0; bool keep = (!removeSelfEdges || vid != allIds[j]) && (!removeOffProcessEdges || owner == myRank) && (!removeOffGroupEdges || owner >= 0); if (keep){ newGids[next] = allIds[j]; for (int w=0; w < eDim; w++){ newWeights[w][next] = edgeWeights[w][j]; } next++; if (next == numKeep) break; } // if (keep) } } return numKeep; }
void resetValues(){ scalar_t *tmp = new scalar_t [evalNumMetrics]; memset(tmp, 0, sizeof(scalar_t) * evalNumMetrics); values_ = arcp(tmp, 0, evalNumMetrics, true); }
void globalSumsByPart( const RCP<const Environment> &env, const RCP<const Comm<int> > &comm, const ArrayView<const pnum_t> &part, const ArrayView<StridedData<lno_t, scalar_t> > &vwgts, multiCriteriaNorm mcNorm, partId_t &numParts, partId_t &numNonemptyParts, ArrayRCP<MetricValues<scalar_t> > &metrics, ArrayRCP<scalar_t> &globalSums) { env->debug(DETAILED_STATUS, "Entering globalSumsByPart"); ////////////////////////////////////////////////////////// // Initialize return values numParts = numNonemptyParts = 0; int vwgtDim = vwgts.size(); int numMetrics = 1; // "object count" if (vwgts[0].size() > 0) numMetrics++; // "normed weight" or "weight 1" if (vwgtDim > 1) numMetrics += vwgtDim; // "weight n" typedef MetricValues<scalar_t> mv_t; mv_t *newMetrics = new mv_t [numMetrics]; env->localMemoryAssertion(__FILE__, __LINE__, numMetrics, newMetrics); ArrayRCP<mv_t> metricArray(newMetrics, 0, numMetrics, true); metrics = metricArray; ////////////////////////////////////////////////////////// // Figure out the global number of parts in use. // Verify vertex weight dim is the same everywhere. lno_t localNumObj = part.size(); partId_t localNum[2], globalNum[2]; localNum[0] = static_cast<partId_t>(vwgtDim); localNum[1] = 0; for (lno_t i=0; i < localNumObj; i++) if (part[i] > localNum[1]) localNum[1] = part[i]; try{ reduceAll<int, partId_t>(*comm, Teuchos::REDUCE_MAX, 2, localNum, globalNum); } Z2_THROW_OUTSIDE_ERROR(*env) env->globalBugAssertion(__FILE__, __LINE__, "inconsistent vertex dimension", globalNum[0] > 0 && globalNum[0] == localNum[0], DEBUG_MODE_ASSERTION, comm); partId_t nparts = globalNum[1] + 1; int globalSumSize = nparts * numMetrics; scalar_t * sumBuf = new scalar_t [globalSumSize]; env->localMemoryAssertion(__FILE__, __LINE__, globalSumSize, sumBuf); globalSums = arcp(sumBuf, 0, globalSumSize); ////////////////////////////////////////////////////////// // Calculate the local totals by part. scalar_t *localBuf = new scalar_t [globalSumSize]; env->localMemoryAssertion(__FILE__, __LINE__, globalSumSize, localBuf); memset(localBuf, 0, sizeof(scalar_t) * globalSumSize); scalar_t *obj = localBuf; // # of objects for (lno_t i=0; i < localNumObj; i++) obj[part[i]]++; if (numMetrics > 1){ scalar_t *wgt = localBuf + nparts; // single normed weight try{ normedPartWeights<scalar_t, pnum_t, lno_t>(env, nparts, part, vwgts, mcNorm, wgt); } Z2_FORWARD_EXCEPTIONS //KDDKDD TODO This code assumes the solution has the part ordered the //KDDKDD TODO same way as the user input. That assumption is not //KDDKDD TODO currently true, although we plan to make it true. //KDDKDD TODO As a results, currently the weight metrics may be wrong. //KDDKDD TODO See bug 5891. April 5, 2013 if (vwgtDim > 1){ wgt += nparts; // individual weights for (int vdim = 0; vdim < vwgtDim; vdim++){ if (vwgts[vdim].size()){ for (lno_t i=0; i < localNumObj; i++) wgt[part[i]] += vwgts[vdim][i]; } else{ // uniform weights for (int p=0; p < nparts; p++) wgt[p] = obj[p]; } wgt += nparts; } } }