void tst_QThreadPool::expiryTimeout() { ExpiryTimeoutTask task; QThreadPool threadPool; threadPool.setMaxThreadCount(1); int expiryTimeout = threadPool.expiryTimeout(); threadPool.setExpiryTimeout(1000); QCOMPARE(threadPool.expiryTimeout(), 1000); // run the task threadPool.start(&task); QVERIFY(task.semaphore.tryAcquire(1, 10000)); QCOMPARE(task.runCount, 1); QVERIFY(!task.thread->wait(100)); // thread should expire QThread *firstThread = task.thread; QVERIFY(task.thread->wait(10000)); // run task again, thread should be restarted threadPool.start(&task); QVERIFY(task.semaphore.tryAcquire(1, 10000)); QCOMPARE(task.runCount, 2); QVERIFY(!task.thread->wait(100)); // thread should expire again QVERIFY(task.thread->wait(10000)); // thread pool should have reused the expired thread (instead of // starting a new one) QCOMPARE(firstThread, task.thread); threadPool.setExpiryTimeout(expiryTimeout); QCOMPARE(threadPool.expiryTimeout(), expiryTimeout); }
void MultithreadedRandomForest::trainMulticlass(boost::shared_ptr<DataFrame> data, unsigned int numTrees, unsigned int numFactors, unsigned int nodeSize, double retrain, bool balanced) { try { std::cerr << "DEBUG MTRF TRAINMULTI" << std::endl; data->validateData(); _trainInputs.data = data; _trainInputs.numFactors = numFactors; _trainInputs.nodeSize = nodeSize; _trainInputs.balanced = balanced; _factorLabels = data->getFactorLabels(); _forest.clear(); numFactors = std::min<size_t>(data->getActiveFactorCount(), numFactors); _numSplitFactors = numFactors; if(!data->empty()) { _forest.reserve(numTrees); //Initialize the thread pool QThreadPool pool; pool.setExpiryTimeout(-1); QList<boost::shared_ptr<RandomTree> > mapTrees; for(unsigned int i = 0; i < numTrees; i++) { mapTrees.append(boost::shared_ptr<RandomTree>(new RandomTree())); } QList<boost::shared_ptr<RandomTree> > forestList = QtConcurrent::blockingMapped(mapTrees, train); for(unsigned int i = 0; i < numTrees; i++) { _forest.push_back(forestList[i]); } if(retrain >= 0 && retrain < 1.0) { std::cout << "Retraining model on top " << (retrain * 100) << "% of factors" << std::endl; std::map<std::string, double> topFactors; std::map<std::string, double>::iterator mapItr; getFactorImportance(data, topFactors); std::vector<std::string> badFactors; unsigned int cutOffIdx = topFactors.size() - (unsigned int)((double)topFactors.size() * retrain); std::multimap<double, std::string> sortedFactors; std::multimap<double, std::string>::iterator mMapItr; //Create a map from lowest to highest of important mapped to factor type for(mapItr = topFactors.begin(); mapItr != topFactors.end(); ++mapItr) { sortedFactors.insert(std::pair<double, std::string>(mapItr->second, mapItr->first)); } unsigned int cutOffCtr = 0; for(mMapItr = sortedFactors.begin(); mMapItr != sortedFactors.end(); ++mMapItr) { if(cutOffCtr < cutOffIdx) { badFactors.push_back(mMapItr->second); cutOffCtr++; } else { break; } } for(unsigned int i = 0; i < badFactors.size(); i++) { data->deactivateFactor(badFactors[i]); } _forest.clear(); _forest.reserve(numTrees); _trainInputs.numFactors = (unsigned int)sqrt((double)(topFactors.size() - cutOffIdx)); _trainInputs.nodeSize = 1; QList<boost::shared_ptr<RandomTree> > mapRetrainingTrees; for(unsigned int i = 0; i < numTrees; i++) { mapRetrainingTrees.append(boost::shared_ptr<RandomTree>(new RandomTree())); } QList<boost::shared_ptr<RandomTree> > forestRetrainList = QtConcurrent::blockingMapped(mapRetrainingTrees, train); for(unsigned int i = 0; i < numTrees; i++) { _forest[i] = forestRetrainList[i]; } } _forestCreated = true; } else { throw Exception(__LINE__, "Unable to operate on empty dataset"); } } catch(const Exception & e) { throw Exception(typeid(this).name(), __FUNCTION__, __LINE__, e); } }