static int parseHour(char *def, char *minDef, SCHEDULE_ENTRY *e) { char *p = def, c; int i, a, b, m; if (*p == '*') { for (i = 0; i < 24; i++) if (parseMin(minDef, e, i * 60)) return 1; return 0; } // Comma for multiple fields? char *q = find(p, ','); if (*q) { do { c = *q; *q = '\0'; if (parseHour(p, minDef, e)) return 1; *q = c; p = q + 1; q = find(p, ','); } while (*q); } // Look for / if (!findMultiplier(p, &m, 24)) { if (findRange(p, &a, &b, 24)) { // Just a/m i.e. repeat a every m if (getNumber(p, &a, 24)) return 1; for (i = a; i < 24; i += m) if (parseMin(minDef, e, i * 60)) return 1; } else { // a-b/m, i.e. repeat a-b every m for (; a < 24; a += m, b += m) { for (i = a; i <= b && i < 24; i++) if (parseMin(minDef, e, i * 60)) return 1; } } return 0; } // Look for - if (!findRange(p, &a, &b, 24)) for (i = a; i < b; i++) if (parseMin(minDef, e, i * 60)) return 0; // Just a number if (getNumber(p, &a, 24)) return 1; return parseMin(minDef, e, a * 60); }
static int parseMin(char *def, SCHEDULE_ENTRY *e, int offset) { char *p = def, c; int i, a, b, m; if (*p == '*') { for (i = 0; i < 60; i++) scheduler_setBit(e, offset + i); return 0; } // Comma for multiple fields? char *q = find(p, ','); if (*q) { do { c = *q; *q = '\0'; if (parseMin(p, e, offset)) return i; *q = c; p = q + 1; q = find(p, ','); } while (*q); } // Look for / if (!findMultiplier(p, &m, 60)) { if (findRange(p, &a, &b, 60)) { // Just a/m i.e. repeat a every m if (getNumber(p, &a, 60)) return 1; for (i = a; i < 60; i += m) scheduler_setBit(e, offset + i); } else { // a-b/m, i.e. repeat a-b every m for (; a < 60; a += m, b += m) { for (i = a; i <= b && i < 60; i++) scheduler_setBit(e, offset + i); } } return 0; } // Look for - if (!findRange(p, &a, &b, 60)) { for (i = a; i < b; i++) scheduler_setBit(e, offset + i); return 0; } // Just a number if (getNumber(p, &a, 60)) return 1; scheduler_setBit(e, offset + a); return 0; }
void ThreePhaseDecoder::makePhase() { int n = width * height; float i1, i2, i3; for (int i = 0; i < n; i++) { i1 = (float) graySequence[0][i]; i2 = (float) graySequence[1][i]; i3 = (float) graySequence[2][i]; #ifdef USE_GAMMA i1 = Gamma(i1 / 255.0, gamma) * 255.0; i2 = Gamma(i2 / 255.0, gamma) * 255.0; i3 = Gamma(i3 / 255.0, gamma) * 255.0; #endif range[i] = findRange(i1, i2, i3); mask[i] = range[i] <= rangeThreshold; ready[i] = !mask[i]; reflectivity[i] = (byte) ((i1 + i2 + i3) / 3); if(ready[i]) phase[i] = atan2f(sqrtf(3) * (i1 - i3), 2.f * i2 - i1 - i3) / (float) TWO_PI; } #ifdef LINEARIZE_PHASE if(linearize) { buildLut(); applyLut(); } #endif }
vector<int> searchRange(int A[], int n, int target) { vector<int> res; if (n <= 0) return res; findRange(A, 0, n, n, target, res); return res; }
int K3b::AudioEditorWidget::findRange( int pos ) const { Range* r = findRange( QPoint( pos, 0 ) ); if( r ) return r->id; else return 0; }
/** * \note Range invalidation event may occur only if document gets relaoded * cuz we've made it w/ \c EmptyAllow option */ void DocumentInfo::rangeInvalid(KTextEditor::MovingRange* range) { kDebug(DEBUG_AREA) << "It seems document reloaded... cleanup ranges???"; // Erase internal data auto it = findRange(range); if (it != m_ranges.end()) { kDebug(DEBUG_AREA) << "MovingRange: invalid range deleted: " << range; it->range->setFeedback(0); m_ranges.erase(it); } }
void DocumentInfo::addRange(KTextEditor::MovingRange* const range, const IncludeStyle style) { assert("Sanity check" && !range->isEmpty() && range->onSingleLine()); assert("Sanity check" && findRange(range) == m_ranges.end()); // m_ranges.emplace_back( range , static_cast<KTextEditor::MovingRangeFeedback* const>(this) , style ); // Find a real file and update status updateStatus(m_ranges.back()); kDebug(DEBUG_AREA) << "MovingRange registered: " << range; }
void findRange(int A[], int first, int last, int n, int target, vector<int> &res) { if (first > last) { res.push_back(-1); res.push_back(-1); return; } int mid = (first + last) / 2; if (A[mid] == target) { int i = mid; while (i > 0 && A[i-1] == target) i--; res.push_back(i); i = mid; while (i < n-1 && A[i+1] == target) i++; res.push_back(i); return; } if (A[mid] < target) findRange(A, mid+1, last, n, target, res); else findRange(A, first, mid-1, n, target, res); }
void DocumentInfo::rangeEmpty(KTextEditor::MovingRange* range) { assert( "Range must be valid (possible empty, but valid)" && range->start().line() != -1 && range->end().line() != -1 && range->start().column() != -1 && range->end().column() != -1 ); // Remove possible mark on a line auto* iface = qobject_cast<KTextEditor::MarkInterface*>(range->document()); iface->clearMark(range->start().line()); // Erase internal data auto it = findRange(range); if (it != m_ranges.end()) { kDebug(DEBUG_AREA) << "MovingRange: empty range deleted: " << range; it->range->setFeedback(0); m_ranges.erase(it); } }
void CurveBranch::draw(const DrawContext& drawContext) { const int ANTIALIASING_STEP = 3; const bool PLAIN_DRAWING = qAbs(drawContext.thickness - 1.) < EPS; const QPair<qreal, qreal> range = findRange(drawContext.viewPort); const qreal t0 = range.first; const qreal t1 = range.second; CurveDrawer& drawer = drawContext.drawer; drawer.setAntiAliasing(drawContext.antiAliasing); QPointF absolutePoint(Curve::calcX(t0), Curve::calcY(t0)); QPointF prevPoint = drawer.toRelative(absolutePoint); drawer.fillCircle(prevPoint, drawContext.thickness); for (qreal t = t0, h; t < t1; t += h) { h = findStep(t, t1, 1 / drawContext.scale); absolutePoint = QPointF(Curve::calcX(t), Curve::calcY(t)); QPointF curPoint = drawer.toRelative(absolutePoint); QPoint drawerPoint = Utils::roundPoint(curPoint); if (PLAIN_DRAWING) { drawer.setPixel(drawerPoint); } else if (drawer.contains(drawerPoint) && (curPoint - prevPoint).manhattanLength() > ANTIALIASING_STEP) { drawer.drawLine(prevPoint, curPoint, drawContext.thickness / 2); drawer.fillCircle(curPoint, drawContext.thickness); prevPoint = curPoint; } } if (PLAIN_DRAWING == false) { QPointF lastPoint = drawer.toRelative(QPointF(Curve::calcX(t1), Curve::calcY(t1))); drawer.drawLine(prevPoint, lastPoint, drawContext.thickness / 2); drawer.fillCircle(lastPoint, drawContext.thickness); } }
/// ITERATOR BitmapTriplesSearchIterator::BitmapTriplesSearchIterator(BitmapTriples *trip, TripleID &pat) : triples(trip), pattern(pat), adjY(trip->arrayY, trip->bitmapY), adjZ(trip->arrayZ, trip->bitmapZ) { // Convert pattern to local order. swapComponentOrder(&pattern, SPO, triples->order); patX = pattern.getSubject(); patY = pattern.getPredicate(); patZ = pattern.getObject(); #if 0 cout << "Pattern: " << patX << " " << patY << " " << patZ << endl; cout << "AdjY: " << endl; adjY.dump(); cout << "AdjZ: " << endl; adjZ.dump(); #endif #if 0 for(uint mposZ=0; mposZ<adjZ.getSize(); mposZ++) { uint z = adjZ.get(mposZ); uint posY = adjZ.findListIndex(mposZ); uint y = adjY.get(posY); uint x = adjY.findListIndex(posY)+1; cout << "FWD2 posZ: " << mposZ << " posY: " << posY << "\t"; cout << "Triple: " << x << ", " << y << ", " << z << endl; } #endif findRange(); goToStart(); }
void GHash::rehash() { int range = findRange( m_capacity ); int newSize = s_prime_list[ range + m_grow_factor ]; HashElem ** newTable = (HashElem **)malloc( newSize * sizeof( HashElem* ) ); if ( newTable == NULL ) return; ::memset( newTable, 0, sizeof( HashElem* ) * newSize ); iterator iterNext = begin(); while( iterNext != end() ) { iterator iter = iterNext; iterNext = next( iter ); HashElem **pElem = newTable + getindex( iter->m_hkey, newSize ); iter->m_pNext = *pElem; *pElem = iter; } free( m_table ); m_table = newTable; m_capacity = newSize; m_tableEnd = m_table + newSize; }
bool vptr_safe(const void *vptr, const char *className) { Dl_info inf, inf1; RangeMap_t *rMap = NULL; WhiteList_t *wList = NULL; void *dlH; printf("Checking %p for %s\n", vptr, className); if (!dladdr(vptr, &inf)) { return false; } printf("Pointer lies in library %s loaded at %p", inf.dli_fname, inf.dli_fbase); if (inf.dli_sname) { printf(" in symbol %s at index %p\n", inf.dli_sname, ((intptr_t)vptr - (intptr_t)inf.dli_saddr)/8); } else { printf("\n"); } dlH = dlopen(inf.dli_fname, RTLD_NOLOAD | RTLD_LOCAL | RTLD_LAZY); /* printf("dlH = %p error=%s\n", dlH, dlerror()); */ assert(dlH && "dlH should be not null"); struct link_map *map; dlinfo(dlH, RTLD_DI_LINKMAP, &map); // printf("%s loaded at %p dynamic sec at %p\n", map->l_name, map->l_addr, map->l_ld); Elf64_Dyn *e = map->l_ld; while (e->d_tag != DT_NULL) { // printf("Tag: %d val: %p\n", e->d_tag, e->d_un.d_ptr); if (e->d_tag == 0x70000035) { rMap = (RangeMap_t*) (((intptr_t)inf.dli_fbase) + ((intptr_t)e->d_un.d_ptr)); } else if (e->d_tag == 0x70000036) { wList = (WhiteList_t*) (((intptr_t)inf.dli_fbase) + ((intptr_t)e->d_un.d_ptr)); } e++; } if (rMap) { RangeMapElement_t *range = findRange(rMap, className); if (range) { int64_t start = range->start; int64_t size = range->size; int64_t alignment = range->alignment; if (((int64_t)vptr) >= start && ((int64_t)vptr < (start + size * alignment)) && ((int64_t)vptr) % alignment == 0) { /* printf("%p is in the range %p-%p for %s\n", (void*)vptr, (void*)start, (void*)(start+size), className); fflush(stdout); */ return true; } else { /* printf("%p is not in the range %p-%p for %s\n", (void*)vptr, (void*)start, (void*)(start+size), className); fflush(stdout); */ goto fail_l; } } } else { /* printf("Module %s was not compiled by our tool :(\n", inf.dli_fname); */ return true; } fail_l: if (wList) { printf("wList->nelements=%d\n", wList->nelements); for (int64_t i = 0; i < wList->nelements; i++) { printf("Class %s\n", wList->elements[i].name); if (!strcmp(className, wList->elements[i].name)) { if (wList->elements[i].value == (intptr_t)vptr) { // printf("%s found\n", className); return true; } } } } printf("%s not found\n", className); return false; }
void DocumentInfo::caretExitedRange(KTextEditor::MovingRange* range, KTextEditor::View*) { auto it = findRange(range); if (it != end(m_ranges)) updateStatus(*it); }
void computeKmerFrequencyIncreasing(std::vector<T>& localvector, MPI_Comm comm = MPI_COMM_WORLD) { //Know my rank int rank; MPI_Comm_rank(comm, &rank); static layer_comparator<kmerLayer, T> kmerCmp; auto start = localvector.begin(); auto end = localvector.end(); //Sort by kmer, read id mxx::sort(start, end, [](const T& x, const T&y){ return (std::get<kmerLayer>(x) < std::get<kmerLayer>(y) || (std::get<kmerLayer>(x) == std::get<kmerLayer>(y) && std::get<readIdLayer>(x) < std::get<readIdLayer>(y))); }, comm, false); //Keep frequency for leftmost and rightmost kmers seperately //Tuples of KmerId and count using tupleType = std::tuple<uint64_t, uint64_t>; std::vector<tupleType> toSend(2); for(auto it = start; it!= end;) // iterate over all segments. { auto innerLoopBound = findRange(it, end, *it, kmerCmp); //Leftmost bucket, appends information for sending to other ranks if(innerLoopBound.first == start) { std::get<0>(toSend[0]) = std::get<kmerLayer>(*start); std::get<1>(toSend[0]) = (innerLoopBound.second - innerLoopBound.first); } //Rightmost bucket else if(innerLoopBound.second == end) { std::get<0>(toSend[1]) = std::get<kmerLayer>(*innerLoopBound.first); std::get<1>(toSend[1]) = innerLoopBound.second - innerLoopBound.first; for(auto it1 = innerLoopBound.first; it1 != innerLoopBound.second; it1++) std::get<tmpLayer>(*it1) = std::distance(innerLoopBound.first, it1) + 1; } else { //Mark frequency as 1,2...totalCount for(auto it1 = innerLoopBound.first; it1 != innerLoopBound.second; it1++) std::get<tmpLayer>(*it1) = std::distance(innerLoopBound.first, it1) + 1; } it = innerLoopBound.second; } auto allBoundaryKmers = mxx::allgather_vectors(toSend); static layer_comparator<0, tupleType> gatherCmp; //Left boundary case //Count size only on the left side of this rank auto leftBucketBoundaryRange = std::equal_range(allBoundaryKmers.begin(), allBoundaryKmers.begin() + 2*rank, toSend[0], gatherCmp); uint64_t leftBucketSize = 0; for(auto it = leftBucketBoundaryRange.first; it != leftBucketBoundaryRange.second; it++) { leftBucketSize += std::get<1>(*it); } { //Update leftmost bucket auto innerLoopBound = findRange(start, end, *start, kmerCmp); for(auto it = innerLoopBound.first; it != innerLoopBound.second; it ++) std::get<tmpLayer>(*it) = leftBucketSize + (std::distance(innerLoopBound.first, it) + 1); } }
void updateReadFilterFlags(std::vector<T>& localvector, std::vector<bool>& readFilterFlags, std::vector<ReadLenType>& readTrimLengths, uint32_t firstReadId, MPI_Comm comm = MPI_COMM_WORLD) { //Know my rank int rank; MPI_Comm_rank(comm, &rank); //Custom comparators for tuples inside localvector static layer_comparator<readIdLayer, T> readCmp; static layer_comparator<tmpLayer, T> freqCmp; auto start = localvector.begin(); auto end = localvector.end(); //Need to sort the data by readId,kmer-Sno mxx::sort(start, end, [](const T& x, const T&y){ return (std::get<readIdLayer>(x) < std::get<readIdLayer>(y) || (std::get<readIdLayer>(x) == std::get<readIdLayer>(y) && std::get<kmerSnoLayer>(x) < std::get<kmerSnoLayer>(y)));} , comm, false); //Since the partitioning size haven't been modified yet, the partitions shouldn't spawn //across processors //Track count of kmers removed uint64_t localElementsRemoved = 0; for(auto it = start; it!= end;) // iterate over all segments. { auto innerLoopBound = findRange(it, end, *it, readCmp); //To compute the median of this bucket if (filterbyMedian) std::nth_element(innerLoopBound.first, innerLoopBound.first + std::distance(innerLoopBound.first, innerLoopBound.second)/2, innerLoopBound.second, freqCmp); auto currentMedian = *(innerLoopBound.first + std::distance(innerLoopBound.first, innerLoopBound.second)/2); //Compute the max auto currentMax = std::max_element(innerLoopBound.first, innerLoopBound.second, freqCmp); //Read id auto readId = std::get<readIdLayer>(*innerLoopBound.first); //Either mark the tuples as removed or restore their tmpLayer if(filterbyMedian && std::get<tmpLayer>(currentMedian) > HIST_EQ_THRESHOLD) { readFilterFlags[readId - firstReadId] = false; localElementsRemoved += 1; readTrimLengths[readId - firstReadId] = 0; //Mark the flag inside tuple to delete later std::for_each(innerLoopBound.first, innerLoopBound.second, [](T &t){ std::get<tmpLayer>(t) = MAX_FREQ;}); } else if(filterbyMax && std::get<tmpLayer>(*currentMax) > KMER_FREQ_THRESHOLD) { readFilterFlags[readId - firstReadId] = false; localElementsRemoved += 1; //Find first element greater than KMER_FREQ_THRESHOLD auto firstHighFreq= std::find_if(innerLoopBound.first, innerLoopBound.second, [](T &t){return std::get<tmpLayer>(t) > KMER_FREQ_THRESHOLD;}); readTrimLengths[readId - firstReadId] = KMER_LEN_PRE + (firstHighFreq - innerLoopBound.first) - 1; } else { readFilterFlags[readId - firstReadId] = true; } it = innerLoopBound.second; } //Count the reads filtered auto totalReadsRemoved = mxx::reduce(localElementsRemoved); if(!rank) std::cerr << "[PREPROCESS: ] " << totalReadsRemoved << " reads removed/trimmed from dataset\n"; }
void computeKmerFrequencyAbsolute(std::vector<T>& localvector, MPI_Comm comm = MPI_COMM_WORLD) { //Know my rank int rank; MPI_Comm_rank(comm, &rank); static layer_comparator<kmerLayer, T> kmerCmp; auto start = localvector.begin(); auto end = localvector.end(); //Sort by kmer id mxx::sort(start, end, kmerCmp, comm, false); //Keep frequency for leftmost and rightmost kmers seperately //Tuples of KmerId and count using tupleType = std::tuple<uint64_t, uint64_t>; std::vector<tupleType> toSend(2); for(auto it = start; it!= end;) // iterate over all segments. { auto innerLoopBound = findRange(it, end, *it, kmerCmp); //Leftmost bucket, appends information for sending to other ranks if(innerLoopBound.first == start) { std::get<0>(toSend[0]) = std::get<kmerLayer>(*start); std::get<1>(toSend[0]) = (innerLoopBound.second - innerLoopBound.first); } //Rightmost bucket else if(innerLoopBound.second == end) { std::get<0>(toSend[1]) = std::get<kmerLayer>(*innerLoopBound.first); std::get<1>(toSend[1]) = innerLoopBound.second - innerLoopBound.first; uint64_t currentCount = innerLoopBound.second - innerLoopBound.first; std::for_each(innerLoopBound.first, innerLoopBound.second, [currentCount](T &t){ std::get<tmpLayer>(t) = currentCount;}); } else { uint64_t currentCount = innerLoopBound.second - innerLoopBound.first; std::for_each(innerLoopBound.first, innerLoopBound.second, [currentCount](T &t){ std::get<tmpLayer>(t) = currentCount;}); } it = innerLoopBound.second; } auto allBoundaryKmers = mxx::allgather_vectors(toSend); static layer_comparator<0, tupleType> gatherCmp; //Left boundary case //Count size only on the left side of this rank auto leftBucketBoundaryRange = std::equal_range(allBoundaryKmers.begin(), allBoundaryKmers.end(), toSend[0], gatherCmp); uint64_t leftBucketSize = 0; for(auto it = leftBucketBoundaryRange.first; it != leftBucketBoundaryRange.second; it++) { leftBucketSize += std::get<1>(*it); } { //Update leftmost bucket auto innerLoopBound = findRange(start, end, *start, kmerCmp); std::for_each(innerLoopBound.first, innerLoopBound.second, [leftBucketSize](T &t){ std::get<tmpLayer>(t) = leftBucketSize;}); } }
static size_t roundUp( size_t sz ) { return s_prime_list[findRange(sz)]; }
void ZLTextView::drawTextLine(const ZLTextLineInfo &info, int y, size_t from, size_t to) { const ZLTextParagraphCursor ¶graph = info.RealStart.paragraphCursor(); const ZLTextElementIterator fromIt = myTextElementMap.begin() + from; const ZLTextElementIterator toIt = myTextElementMap.begin() + to; if (!mySelectionModel.isEmpty() && (from != to)) { const std::vector<ZLTextSelectionModel::Range> &ranges = mySelectionModel.ranges(); if (!ranges.empty()) { RangeVector::const_iterator rt = ranges.end(); const int top = y + 1; int bottom = y + info.Height + info.Descent; if (strongFindRange(ranges, info.End) != ranges.end()) { bottom += info.VSpaceAfter; } int left = viewWidth() + lineStartMargin() - 1; int right = lineStartMargin(); const int baseRTL = myStyle.baseBidiLevel() % 2; for (ZLTextElementIterator it = fromIt; it < toIt; ++it) { const ZLTextElementArea &area = *it; RangeVector::const_iterator rt2 = findRange(ranges, area); if (rt2 == rt) { if (rt != ranges.end()) { const bool mainDir = area.BidiLevel % 2 == baseRTL; int r = area.XEnd; const ZLTextSelectionModel::BoundElement &bound = mainDir ? rt->second : rt->first; if (bound.ElementIndex == area.ElementIndex) { const ZLTextElement &element = paragraph[area.ElementIndex]; if (element.kind() == ZLTextElement::WORD_ELEMENT) { r = areaBound(paragraph, area, bound.CharIndex, mainDir); } } right = std::max(right, r); } } else { if (rt != ranges.end()) { drawSelectionRectangle(left, top, right, bottom); left = viewWidth() + lineStartMargin() - 1; right = lineStartMargin(); } rt = rt2; if (rt != ranges.end()) { if ((it == fromIt) && (info.StartBidiLevel % 2 == baseRTL) && strongContains(*rt, info.Start)) { left = lineStartMargin(); } const bool mainDir = area.BidiLevel % 2 == baseRTL; int l = area.XStart - 1; int r = area.XEnd; const ZLTextSelectionModel::BoundElement &rightBound = mainDir ? rt->second : rt->first; const ZLTextSelectionModel::BoundElement &leftBound = mainDir ? rt->first : rt->second; if (paragraph[area.ElementIndex].kind() == ZLTextElement::WORD_ELEMENT) { if (rightBound.ElementIndex == area.ElementIndex) { r = areaBound(paragraph, area, rightBound.CharIndex, mainDir); } if (leftBound.ElementIndex == area.ElementIndex) { l = areaBound(paragraph, area, leftBound.CharIndex, mainDir); } } left = std::min(left, l); right = std::max(right, r); } } } if (rt != ranges.end()) { if ((paragraph.index() < (size_t)rt->second.ParagraphIndex) && strongContains(*rt, info.End)) { right = viewWidth() + lineStartMargin() - 1; } drawSelectionRectangle(left, top, right, bottom); } } } y = std::min(y + info.Height, topMargin() + textAreaHeight()); int x = lineStartMargin(); if (!info.NodeInfo.isNull()) { drawTreeLines(*info.NodeInfo, x, y, info.Height, info.Descent + info.VSpaceAfter); } ZLTextElementIterator it = fromIt; const int endElementIndex = info.End.elementIndex(); for (; (it != toIt) && (it->ElementIndex != endElementIndex); ++it) { const ZLTextElement &element = paragraph[it->ElementIndex]; ZLTextElement::Kind kind = element.kind(); if ((kind == ZLTextElement::WORD_ELEMENT) || (kind == ZLTextElement::IMAGE_ELEMENT)) { myStyle.setTextStyle(it->Style, it->BidiLevel); const int wx = myStyle.baseIsRtl() ? context().width() - it->XEnd : it->XStart; const int wy = it->YEnd - myStyle.elementDescent(element) - myStyle.textStyle()->verticalShift(); if (kind == ZLTextElement::WORD_ELEMENT) { drawWord(wx, wy, (const ZLTextWord&)element, it->StartCharIndex, -1, false); } else { context().drawImage(wx, wy, *((const ZLTextImageElement&)element).image()); } } } if (it != toIt) { myStyle.setTextStyle(it->Style, it->BidiLevel); int start = 0; if (info.Start.equalElementIndex(info.End)) { start = info.Start.charIndex(); } int len = info.End.charIndex() - start; const ZLTextWord &word = (const ZLTextWord&)info.End.element(); context().setColor(myStyle.textStyle()->color()); const int x = myStyle.baseIsRtl() ? context().width() - it->XEnd : it->XStart; const int y = it->YEnd - myStyle.elementDescent(word) - myStyle.textStyle()->verticalShift(); drawWord(x, y, word, start, len, it->AddHyphenationSign); } }
void generatePartitionSizeHistogram(typename std::vector<T>& localVector, std::string filename, MPI_Comm comm = MPI_COMM_WORLD) { /* * Approach : * 1. Do a global sort by keyLayer (Partition id). * 2. Compute the information Partition_Id:Size for boundary partitions (Avoid duplication). * 3. Do an all_gather of boundary values plugged with ranks. * 4. All boundary partitions should be owned by minimum rank that shares it. * 5. Locally compute the largest partition size and do MPI_Allreduce * with MPI_MAX. * 6. Build the histogram locally. * 7. Finally do MPI_Reduce over whole histogram to root node. * 8. Write the output to file */ int p; int rank; MPI_Comm_size(comm, &p); MPI_Comm_rank(comm, &rank); static layer_comparator<keyLayer, T> pccomp; //Sort the vector by each tuple's keyLayer element mxx::sort(localVector.begin(), localVector.end(), pccomp, comm, false); //Iterate over tuples to compute boundary information bool iownLeftBucket, iownRightBucket, onlySingleLocalPartition; //Type of tuple to communicate : (Partition Id, rank, size) typedef std::tuple<uint32_t, int, uint64_t> tupletypeforbucketSize; std::vector<tupletypeforbucketSize> toSend; toSend.resize(2); //Find the left most bucket auto leftBucketRange = findRange(localVector.begin(), localVector.end(), *(localVector.begin()), pccomp); std::get<0>(toSend[0]) = std::get<keyLayer>(*localVector.begin()); std::get<1>(toSend[0]) = rank; std::get<2>(toSend[0]) = leftBucketRange.second - leftBucketRange.first; //Find the right most bucket auto rightBucketRange = findRange(localVector.rbegin(), localVector.rend(), *(localVector.rbegin()), pccomp); std::get<0>(toSend[1]) = std::get<keyLayer>(*localVector.rbegin()); std::get<1>(toSend[1]) = rank; std::get<2>(toSend[1]) = rightBucketRange.second - rightBucketRange.first; //If we have only single partition, make sure we are not creating duplicates if(std::get<0>(toSend[0]) == std::get<0>(toSend[1])) { //Make second send element's size zero std::get<2>(toSend[1]) = 0; onlySingleLocalPartition = true; } else onlySingleLocalPartition = false; //Gather all the boundary information auto allBoundaryPartitionSizes = mxx::allgather_vectors(toSend, comm); uint64_t leftBucketSize = 0; uint64_t rightBucketSize = 0; //Need to parse boundary information that matches the partitionIds we have static layer_comparator<0, tupletypeforbucketSize> pccomp2; auto leftBucketBoundaryRange = std::equal_range(allBoundaryPartitionSizes.begin(), allBoundaryPartitionSizes.end(), toSend[0], pccomp2); //Check if this processor owns this bucket if(std::get<1>(*(leftBucketBoundaryRange.first)) == rank) { iownLeftBucket = true; for(auto it = leftBucketBoundaryRange.first; it != leftBucketBoundaryRange.second; it++) { leftBucketSize += std::get<2>(*it); } } else iownLeftBucket = false; auto rightBucketBoundaryRange = std::equal_range(allBoundaryPartitionSizes.begin(), allBoundaryPartitionSizes.end(), toSend[1], pccomp2); //Check if this processor owns right partition if(std::get<1>(*rightBucketBoundaryRange.first) == rank && !onlySingleLocalPartition) { iownRightBucket = true; for(auto it = rightBucketBoundaryRange.first; it != rightBucketBoundaryRange.second; it++) { rightBucketSize += std::get<2>(*it); } } else iownRightBucket = false; //Map from partition size to count typedef std::map <uint64_t, uint32_t> MapType; MapType localHistMap; for(auto it = localVector.begin(); it!= localVector.end();) // iterate over all segments. { auto innerLoopBound = findRange(it, localVector.end(), *it, pccomp); //Left most bucket if (innerLoopBound.first == localVector.begin()) // first { if(iownLeftBucket) insertToHistogram(localHistMap, leftBucketSize); } //Right most bucket else if (innerLoopBound.second == localVector.end()) // first { if(iownRightBucket) insertToHistogram(localHistMap, rightBucketSize); } //Inner buckets else { insertToHistogram(localHistMap, innerLoopBound.second - innerLoopBound.first); } it = innerLoopBound.second; } //Convert map to vector using tupleTypeforHist = std::tuple<uint64_t, uint32_t>; std::vector<tupleTypeforHist> localHistVector; for(MapType::iterator it = localHistMap.begin(); it != localHistMap.end(); ++it ) { localHistVector.push_back(std::make_tuple(it->first, it->second)); } //Gather vector from all processors to root auto globalHistVector = mxx::gather_vectors(localHistVector, comm); static layer_comparator<0, tupleTypeforHist> partition_size_cmp; //Write to file if(rank == 0) { //Sort the vector to bring counts with same size adjacent (default comparator will work) std::sort(globalHistVector.begin(), globalHistVector.end()); std::ofstream ofs; ofs.open(filename, std::ios_base::out); //Iterate over the global vector for(auto it = globalHistVector.begin(); it != globalHistVector.end();) { //Range of counts belonging to same partition size auto innerLoopRange = findRange(it, globalHistVector.end(), *it, partition_size_cmp); auto p_size = std::get<0>(*it); uint32_t sum = 0; //Loop over the range for(auto it2 = innerLoopRange.first; it2 != innerLoopRange.second; it2++) sum += std::get<1>(*it2); ofs << p_size << " " << sum <<"\n"; it = innerLoopRange.second; } ofs.close(); } }