#ifndef _TRISKELE_DEAL_THREADS_HPP #define _TRISKELE_DEAL_THREADS_HPP #include namespace triskele { template inline void dealThreadRange (const DimImg &maxId, const unsigned int &coreCount, const FunctId &functId/* functId (id) */); template inline void dealThreadThreadRange (const DimImg &maxId, const unsigned int &coreCount, const FunctThreadId &functThreadId/* functThreadId (threadId, id) */); template inline void dealThreadBound (const DimImg &maxId, const unsigned int &coreCount, const FunctMinMax &functMinMax/* functMinMax (minVal, maxVal) */); template inline std::vector getDealThreadBounds (const DimImg &maxId, const unsigned int &coreCount); template inline void dealThread (const DimImg &maxId, unsigned int coreCount, const FunctThreadMinMax &functThreadMinMax/* functThreadMinMax (threadId, minVal, maxVal) */); // ---------------------------------------- template inline void callOnSortedSets (const std::vector &sizes, const WeightFunct &getWeight/* getWeight (vectId, itemId) */, CmpFunct isWeightInf/* isWeightInf (w1, w2) */, const CallFunct &callIdId/* callIdId (vectId, itemId) */); // ======================================== template inline void dealThreadRange (const DimImg &maxId, const unsigned int &coreCount, const FunctId &functId/* functId (id) */) { dealThread (maxId, coreCount, [&functId] (const unsigned int &threadId, const DimImg &minVal, const DimImg &maxVal) { for (DimImg id = minVal; id < maxVal; ++id) functId (id); }); } // ---------------------------------------- template inline void dealThreadThreadRange (const DimImg &maxId, const unsigned int &coreCount, const FunctThreadId &functThreadId/* functThreadId (threadId, id) */) { dealThread (maxId, coreCount, [&functThreadId] (const unsigned int &threadId, const DimImg &minVal, const DimImg &maxVal) { for (DimImg id = minVal; id < maxVal; ++id) functThreadId (threadId, id); }); } // ---------------------------------------- template inline void dealThreadBound (const DimImg &maxId, const unsigned int &coreCount, const FunctMinMax &functMinMax/* functMinMax (minVal, maxVal) */) { dealThread (maxId, coreCount, [&functMinMax] (const unsigned int &threadId, const DimImg &minVal, const DimImg &maxVal) { functMinMax (minVal, maxVal); }); } // ---------------------------------------- template inline std::vector getDealThreadBounds (const DimImg &maxId, const unsigned int &coreCount) { if (!maxId || !coreCount) return std::vector (0); DimImg average = maxId/coreCount; std::vector maxIds (coreCount+1, average); for (unsigned int core = 0; core < coreCount; ++core) maxIds[core] = DimImg (core*average); maxIds[coreCount] = maxId; return maxIds; } // ---------------------------------------- template inline void dealThread (const DimImg &maxId, unsigned int coreCount, const FunctThreadMinMax &functThreadMinMax/* functThreadMinMax (threadId, minVal, maxVal) */) { //DEF_LOG ("dealThreadBound", "coreCount:" << coreCount << " maxId:" << maxId); if (!maxId || !coreCount) return; if (DimImg (coreCount) > maxId) coreCount = (unsigned int) maxId; if (coreCount == 1) { functThreadMinMax (0, 0, maxId); return; } std::vector maxIds = getDealThreadBounds (maxId, coreCount); boost::thread tasks [coreCount]; for (unsigned int idCopyValInThread = 0; idCopyValInThread < coreCount; ++idCopyValInThread) { tasks[idCopyValInThread] = boost::thread ([/*no ref!!!*/idCopyValInThread, &maxIds, &functThreadMinMax] () { functThreadMinMax (idCopyValInThread, maxIds[idCopyValInThread], maxIds[idCopyValInThread+1]); }); } for (unsigned int i = 0; i < coreCount; ++i) tasks[i].join (); } // ======================================== template void dealThreadFill_n (const DimImg &maxId, unsigned int coreCount, OutputIterator first, const T& val) { dealThreadBound (maxId, coreCount, [&first, &val] (const DimImg &minVal, const DimImg &maxVal) { fill_n (first+minVal, maxVal-minVal, val); }); } // ======================================== template inline void callOnSortedSets (const std::vector &sizes, const WeightFunct &getWeight/* getWeight (vectId, itemId) */, CmpFunct isWeightInf/* isWeightInf (w1, w2) */, const CallFunct &callIdId/* callIdId (vectId, itemId) */) { DimImg size = sizes.size (); DEF_LOG ("callOnSortedSets", "size:" << size); if (!size) return; std::vector vectIds (size, 0); std::vector vectCounts (sizes); // get min bool found = false; DimImg minVectIdx = 0; WeightT minWeight = 0; for (DimImg vectId = 0; vectId < size; ++vectId) { if (!vectCounts [vectId]) continue; WeightT tmpWeight = getWeight (vectId, 0); if (found && !isWeightInf (tmpWeight, minWeight)) continue; minVectIdx = vectId; minWeight = tmpWeight; found = true; } LOG ("found:" << found << " minVectIdx:" << minVectIdx << " minWeight:" << minWeight); // loop for ( ; found; ) { // get next min found = false; DimImg nextMinVectIdx = 0; WeightT nextMinWeight = 0; for (DimImg vectId = minVectIdx; ; ) { if (vectCounts [vectId]) { WeightT tmpWeight = getWeight (vectId, vectIds [vectId]); if (!isWeightInf (minWeight, tmpWeight)) { // minWeight == tmpWeight callIdId (vectId, vectIds [vectId]); ++vectIds [vectId]; --vectCounts [vectId]; continue; } if (!found || isWeightInf (tmpWeight, nextMinWeight)) { nextMinVectIdx = vectId; nextMinWeight = tmpWeight; found = true; } } vectId = (vectId+1)%size; if (vectId == minVectIdx) break; } minVectIdx = nextMinVectIdx; minWeight = nextMinWeight; } } } // triskele #endif // _TRISKELE_DEAL_THREADS_HPP