31 TuneParams(T repPart, T fixPart,
BackEnd be,
int gs,
int bs): repeatPart(repPart), fixedPart(fixPart)
33 backendParams.backend=be;
34 backendParams.maxThreads=bs;
35 backendParams.maxBlocks=gs;
38 TuneParams(T repPart, T fixPart,
BackEnd be,
int num_omp=1): repeatPart(repPart), fixedPart(fixPart)
40 backendParams.backend=be;
41 backendParams.numOmpThreads=num_omp;
44 T getPrediction(
int repetition=1)
46 return (repeatPart*repetition) + fixedPart;
49 T getPredictionPercentage(
int percent=100,
int repetition=1)
51 return (repeatPart*repetition) + (fixedPart* ((double)percent/100.0f));
56 return backendParams.backend;
60 return backendParams.maxBlocks;
64 return backendParams.maxThreads;
68 return backendParams.numOmpThreads;
73 backendParams.backend=be;
75 void maxBlocks(
int mb)
77 backendParams.maxBlocks=mb;
79 void maxThreads(
int mt)
81 backendParams.maxThreads=mt;
83 void numOmpThreads(
int numTrd)
85 backendParams.numOmpThreads=numTrd;
88 BackEndParams backendParams;
108 template <
typename Tx,
typename Ty>
113 TuneData(
const std::string& _dataSetName,
const std::string& _axisNameX,
const std::string& _axisNameY);
115 void addData(Tx x, TuneParams<Ty> params,
int repetition=1);
117 void writeDataToFile(
const std::string& filename =
"",
int repeatition=1, DataExportFormat format = GNUPLOT);
121 Ty getPrediction(Tx index,
int repeatition=1);
124 void loadPrediction(
const std::string& filename,
int repetition=1);
126 friend std::ostream& operator <<(std::ostream &os,
TuneData& tunedata)
128 os<<
"MapDataSet Size:"<<tunedata.predictionData.size()<<
"\n";
130 for(
typename std::map< Tx, TuneParams<Ty> >::iterator it = tunedata.predictionData.begin(); it != tunedata.predictionData.end(); ++it)
132 TuneParams<Ty> params= it->second;
134 if(bp.backend==CPU_BACKEND)
135 os<<
" " <<std::setw(tabLength) <<it->first <<std::setw(tabLength) << params.repeatPart << std::setw(tabLength) << params.fixedPart <<std::setw(20)<< tunedata.convertBackendToStr(bp.backend) <<
"\n";
136 else if(bp.backend==OMP_BACKEND)
137 os<<
" " <<std::setw(tabLength) <<it->first <<std::setw(tabLength) << params.repeatPart << std::setw(tabLength) << params.fixedPart <<std::setw(20)<< tunedata.convertBackendToStr(bp.backend) <<std::setw(20)<< bp.numOmpThreads<<
"\n";
139 os<<
" " <<std::setw(tabLength) <<it->first <<std::setw(tabLength) << params.repeatPart << std::setw(tabLength) << params.fixedPart <<std::setw(20)<< tunedata.convertBackendToStr(bp.backend) <<std::setw(20)<< bp.maxBlocks<< std::setw(10)<<bp.maxThreads <<
"\n";
144 void writeGnuPlotFileOMP(
const std::string& filename,
int threads=1);
148 void changeRepeatPart(std::pair<int, Ty> newRep[],
int size);
149 void changeRepeatPart_NoAvg(std::pair<int, Ty> newRep[],
int size);
151 std::pair<Ty,Ty> getPredictionPair(Tx size);
155 ExecPlan& buildExecPlanMultiEntries();
158 std::string dataSetName;
159 std::pair<std::string, std::string> axisNames;
163 #ifdef SKEPU_COMPOSE_PREDICTION
164 std::multimap< Tx, TuneParams<Ty> > predictionData;
166 std::map< Tx, TuneParams<Ty> > predictionData;
170 std::string convertBackendToStr(
BackEnd be);
171 BackEnd convertStrToBackend(std::string str);
172 void writeGnuPlotFile(
const std::string& filename,
int repeatition=1);
174 void savePrediction(
const std::string& filename);
186 template <
typename Tx,
typename Ty>
189 dataSetName = _dataSetName;
190 axisNames.first = _axisNameX;
191 axisNames.second = _axisNameY;
218 template <
typename Tx,
typename Ty>
221 #ifndef SKEPU_COMPOSE_PREDICTION
222 typename std::map< Tx, TuneParams<Ty> >::iterator it=predictionData.find(size);
223 if(it!=predictionData.end())
225 TuneParams<Ty> org_p= it->second;
226 if( org_p.getPrediction(repetition) > params.getPrediction(repetition))
228 predictionData.erase(it);
236 predictionData.insert(std::make_pair(size, params));
242 template <
typename Tx,
typename Ty>
245 std::string retval(
"CPU_BACKEND");
250 retval= std::string(
"CL_BACKEND");
253 retval= std::string(
"CLM_BACKEND");
256 retval= std::string(
"CU_BACKEND");
259 retval= std::string(
"CUM_BACKEND");
262 retval= std::string(
"OMP_BACKEND");
265 retval= std::string(
"CPU_BACKEND");
271 template <
typename Tx,
typename Ty>
272 BackEnd TuneData<Tx, Ty>::convertStrToBackend(std::string str)
274 std::transform(str.begin(), str.end(), str.begin(), ::toupper);
277 if(str==
"CL_BACKEND")
279 else if(str==
"CLM_BACKEND")
281 else if(str==
"CU_BACKEND")
283 else if(str==
"CUM_BACKEND")
285 else if(str==
"OMP_BACKEND")
287 else if(str==
"CPU_BACKEND")
294 template <
typename Tx,
typename Ty>
295 void TuneData<Tx, Ty>::changeRepeatPart(std::pair<int, Ty> newRep[],
int size)
298 double *ratios =
new double[size];
299 for(
int i=0; i<size; i++)
301 std::pair<Ty, Ty> p= getPredictionPair(newRep[i].first);
302 ratios[i]= (double)p.first/newRep[i].second;
303 std::cout<<
"First for loop: "<<p.first<<
" "<<newRep[i].second<<
" ratio:"<<ratios[i]<<
"\n";
306 for(
int i=0; i<size; i++)
308 avgRatio += ratios[i];
311 std::cout<<
"AvgRatio: "<<avgRatio<<
"\n";
314 typename std::map< Tx, TuneParams<Ty> >::iterator it;
315 for(it=predictionData.begin(); it!=predictionData.end(); it++)
317 std::cout<<
"Before: "<<it->second.repeatPart;
318 it->second.repeatPart = ((double)(it->second.repeatPart)/avgRatio);
319 std::cout<<
" After: "<<it->second.repeatPart<<
"\n";
328 template <
typename Tx,
typename Ty>
329 void TuneData<Tx, Ty>::changeRepeatPart_NoAvg(std::pair<int, Ty> newRep[],
int size)
333 std::map<std::pair<int, int>,
double> rangesRatio;
334 int lower=1, upper=1, prev_upper=-1;
335 for(
int i=0; i<size; i++)
338 lower = ((prev_upper == -1) ? ((newRep[i].first + newRep[(i-1)].first)/2) : (prev_upper+1) );
343 upper = (newRep[i].first + newRep[(i+1)].first)/2;
345 upper = newRep[i].first +1;
348 std::pair<Ty, Ty> p= getPredictionPair(newRep[i].first);
349 ratio= (double)p.first/newRep[i].second;
351 rangesRatio.insert(std::make_pair(std::make_pair(lower, upper), ratio));
353 std::cout<<
"First for loop: "<<p.first<<
" "<<newRep[i].second<<
" ratio:"<<ratio<<
" "<<newRep[i].first<<
" "<<lower<<
" --- "<<upper<<
"\n";
358 typename std::map< Tx, TuneParams<Ty> >::iterator it, prev_it, nxt_it;
360 for(it=predictionData.begin(); it!=predictionData.end(); it++)
362 std::map< std::pair<int, int>,
double >::iterator ratio_it;
363 for(ratio_it = rangesRatio.begin(); ratio_it != rangesRatio.end(); ++ratio_it)
365 if(it->first >= ratio_it->first.first && it->first <= ratio_it->first.second)
367 std::cout<<
"Before: "<<it->second.repeatPart;
368 it->second.repeatPart = ((double)(it->second.repeatPart)/ratio_it->second);
369 std::cout<<
" After: "<<it->second.repeatPart<<
"\n";
378 template <
typename Tx,
typename Ty>
379 ExecPlan& TuneData<Tx, Ty>::buildExecPlanMultiEntries()
381 if(predictionData.empty())
387 int optionsCount=predictionData.count(predictionData.begin()->first);
388 BackEndParams *prev_bp=
new BackEndParams[optionsCount];
391 int prev_upperLimit=-1;
392 int lowerLimit=1, upperLimit;
394 typedef typename std::map< Tx, TuneParams<Ty> >::iterator CIT;
395 std::pair<CIT,CIT> range;
397 typename std::map< Tx, TuneParams<Ty> >::iterator it;
398 for(it = predictionData.begin(); it != predictionData.end();)
402 bp= (it->second.backendParams);
407 if(prev_upperLimit!=-1)
410 if(prev_bp[0].backend == bp.backend)
412 if(prev_bp[0].backend == OMP_BACKEND && (prev_bp[0].numOmpThreads == bp.numOmpThreads))
416 else if(prev_bp[0].backend == CPU_BACKEND)
418 else if((prev_bp[0].backend != OMP_BACKEND && prev_bp[0].backend != CPU_BACKEND) && prev_bp[0].maxThreads == bp.maxThreads && prev_bp[0].maxBlocks == bp.maxBlocks)
440 newLimit= ((upperLimit+prev_upperLimit)/2);
446 range= predictionData.equal_range(size);
447 TuneParams<Ty> params;
449 for(CIT subit=range.first; subit!=range.second; subit++)
451 TuneParams<Ty> params= subit->second;
452 plan.add(lowerLimit, newLimit, prev_bp[ind]);
453 std::cout<<lowerLimit<<
" --- "<<newLimit<<
" "<<convertBackendToStr(prev_bp[ind].backend)<<
" "<<prev_bp[ind].numOmpThreads<<
" "<<prev_bp[ind].maxThreads<<
" "<<prev_bp[ind].maxBlocks<<
"\n";
457 lowerLimit= (newLimit+1);
462 range= predictionData.equal_range(size);
463 TuneParams<Ty> params;
465 for(CIT subit=range.first; subit!=range.second; subit++)
467 TuneParams<Ty> params= subit->second;
468 prev_bp[ind++]=params.backendParams;
470 prev_upperLimit=upperLimit;
472 it = predictionData.upper_bound(size);
474 range= predictionData.equal_range(size);
475 for(
int ind=0; ind<optionsCount; ind++)
477 plan.add(lowerLimit, prev_upperLimit, prev_bp[ind]);
478 std::cout<<lowerLimit<<
" --- "<<prev_upperLimit<<
" "<<convertBackendToStr(prev_bp[ind].backend)<<
" "<<prev_bp[ind].numOmpThreads<<
" "<<prev_bp[ind].maxThreads<<
" "<<prev_bp[ind].maxBlocks<<
"\n";
488 template <
typename Tx,
typename Ty>
489 ExecPlan& TuneData<Tx, Ty>::buildExecPlan()
491 #ifdef SKEPU_COMPOSE_PREDICTION
492 return buildExecPlanMultiEntries();
494 if(predictionData.empty())
499 BackEndParams bp, prev_bp;
502 int prev_upperLimit=-1;
503 int lowerLimit=1, upperLimit;
505 typename std::map< Tx, TuneParams<Ty> >::iterator it;
506 for(it = predictionData.begin(); it != predictionData.end(); ++it)
509 bp= (it->second.backendParams);
511 if(prev_upperLimit!=-1)
514 if(prev_bp.backend == bp.backend)
516 if(prev_bp.backend == OMP_BACKEND && (prev_bp.numOmpThreads == bp.numOmpThreads))
520 else if(prev_bp.backend == CPU_BACKEND)
522 else if((prev_bp.backend != OMP_BACKEND && prev_bp.backend != CPU_BACKEND) && prev_bp.maxThreads == bp.maxThreads && prev_bp.maxBlocks == bp.maxBlocks)
544 newLimit= ((upperLimit+prev_upperLimit)/2);
549 plan.add(lowerLimit, newLimit, prev_bp);
550 std::cout<<lowerLimit<<
" --- "<<newLimit<<
" "<<convertBackendToStr(prev_bp.backend)<<
" "<<prev_bp.numOmpThreads<<
" "<<prev_bp.maxThreads<<
" "<<prev_bp.maxBlocks<<
"\n";
552 lowerLimit= (newLimit+1);
556 prev_upperLimit=upperLimit;
558 plan.add(lowerLimit, prev_upperLimit, prev_bp);
559 std::cout<<lowerLimit<<
" --- "<<prev_upperLimit<<
" "<<convertBackendToStr(prev_bp.backend)<<
" "<<prev_bp.numOmpThreads<<
" "<<prev_bp.maxThreads<<
" "<<prev_bp.maxBlocks<<
"\n";
564 template <
typename Tx,
typename Ty>
565 ExecPlan& TuneData<Tx, Ty>::getExecPlan(Vector<Tx>& v1, Vector<Tx>& v2,
int percent)
569 if(predictionData.find(size) == predictionData.end())
571 std::cerr<<
"No Information for this size\n";
575 typedef typename std::map< Tx, TuneParams<Ty> >::iterator CIT;
576 std::pair<CIT,CIT> range;
577 range= predictionData.equal_range(size);
578 TuneParams<Ty> params;
579 TuneParams<Ty> opt_params;
580 for(CIT it=range.first; it!=range.second; it++)
582 TuneParams<Ty> params= it->second;
583 if(params.backend()==CL_BACKEND && percent==100)
587 if(v1.isVectorOnDevice_CL(envir->m_devices_CL.at(0)))
589 if(v2.isVectorOnDevice_CL(envir->m_devices_CL.at(0)))
593 else if (params.backend()==CU_BACKEND && percent==100)
596 if(v1.isVectorOnDevice_CU(0))
598 if(v2.isVectorOnDevice_CU(0))
606 else if(opt_params.getPredictionPercentage(percent) > params.getPredictionPercentage(percent))
611 plan.add(size-100, size+100, opt_params.backendParams);
616 template <
typename Tx,
typename Ty>
617 Ty TuneData<Tx, Ty>::getPrediction(Tx size,
int repetition)
620 typename std::map< Tx, TuneParams<Ty> >::iterator it=predictionData.find(size);
622 if(it==predictionData.end())
624 if( predictionData.size() <= 1)
629 for(it=predictionData.begin(); it!= predictionData.end(); it++)
635 double prev_pred= predictionData.at(it->first)->second.getPrediction(repetition);
636 double curr_pred= predictionData.at((it+1)->first)->second.getPrediction(repetition);
637 value= (((double)(curr_pred-prev_pred))/((
double)((it+1)->first - it->first)));
638 return ( prev_pred - ((it->first-size) * value));
642 double prev_pred= predictionData.at(prev_size)->second.getPrediction(repetition);
643 double curr_pred= predictionData.at(it->first)->second.getPrediction(repetition);
645 value= (((double)(curr_pred-prev_pred))/((
double)(it->first-prev_size)));
646 return (( (size-prev_size) * value) + prev_pred);
654 double prev_pred= predictionData.at((it-1)->first)->second.getPrediction(repetition);
655 double curr_pred= predictionData.at(it->first)->second.getPrediction(repetition);
657 value= (((double)(curr_pred-prev_pred))/((
double)(it->first - (it-1)->first)));
658 return (( (size - it->first) * value) + curr_pred);
661 return predictionData.at(size)->second.getPrediction(repetition);
667 template <
typename Tx,
typename Ty>
668 std::pair<Ty,Ty> TuneData<Tx, Ty>::getPredictionPair(Tx size)
670 std::cout<<
"In predictionPair\n";
671 std::pair<Ty, Ty> p(-1,-1);
672 typename std::map< Tx, TuneParams<Ty> >::iterator it=predictionData.find(size);
674 if(it==predictionData.end())
676 if( predictionData.size() <= 1)
680 std::pair<Ty, Ty> value;
681 for(it=predictionData.begin(); it!= predictionData.end(); it++)
688 typename std::map< Tx, TuneParams<Ty> >::iterator temp_it= it;
690 std::pair<Ty, Ty> prev_pred(predictionData.find(temp_it->first)->second.repeatPart, predictionData.find(temp_it->first)->second.fixedPart);
691 std::pair<Ty, Ty> curr_pred(predictionData.find((it)->first)->second.repeatPart, predictionData.find((it)->first)->second.fixedPart);
693 value.first = (((double)(curr_pred.first-prev_pred.first))/((
double)((it)->first - temp_it->first)));
694 value.second = (((double)(curr_pred.second-prev_pred.second))/((
double)((it)->first - temp_it->first)));
695 return std::pair<Ty,Ty>( prev_pred.first - ((temp_it->first-size) * value.first), prev_pred.second - ((temp_it->first-size) * value.second));
699 std::pair<Ty, Ty> prev_pred(predictionData.find(prev_size)->second.repeatPart, predictionData.find(prev_size)->second.fixedPart);
700 std::pair<Ty, Ty> curr_pred(predictionData.find(it->first)->second.repeatPart, predictionData.find(it->first)->second.fixedPart);
701 value.first = (((double)(curr_pred.first-prev_pred.first))/((
double)(it->first - prev_size)));
702 value.second = (((double)(curr_pred.second-prev_pred.second))/((
double)(it->first - prev_size)));
703 return std::pair<Ty,Ty>( prev_pred.first + ((size-prev_size) * value.first), prev_pred.second + ((size-prev_size) * value.second));
717 typename std::map< Tx, TuneParams<Ty> >::iterator temp_it= it;
720 std::pair<Ty, Ty> prev_pred(predictionData.find((it)->first)->second.repeatPart, predictionData.find((it)->first)->second.fixedPart);
721 std::pair<Ty, Ty> curr_pred(predictionData.find(temp_it->first)->second.repeatPart, predictionData.find(temp_it->first)->second.fixedPart);
722 value.first = (((double)(curr_pred.first-prev_pred.first))/((
double)(temp_it->first - (it)->first)));
723 value.second = (((double)(curr_pred.second-prev_pred.second))/((
double)(temp_it->first - (it)->first)));
724 return std::pair<Ty,Ty>( curr_pred.first + ((size-it->first) * value.first), curr_pred.second + ((size-prev_size) * value.second));
733 return std::pair<Ty,Ty>( (predictionData.find(size)->second.repeatPart), (predictionData.find(size)->second.fixedPart) );
740 template <
typename Tx,
typename Ty>
743 predictionData.clear();
754 template <
typename Tx,
typename Ty>
757 std::string _filename;
761 _filename = dataSetName +
".dat";
765 _filename = filename;
769 if(format == GNUPLOT)
771 writeGnuPlotFile(_filename, repeatition);
773 else if(format == PREDICTION_FILE)
775 savePrediction(_filename);
784 template <
typename Tx,
typename Ty>
787 std::ofstream file(filename.c_str());
788 int tabLength = axisNames.first.length()+20;
790 file<<std::fixed <<std::setprecision(5);
794 file<<
"# " <<dataSetName <<
"\n";
795 file<<
"# " <<std::setw(tabLength) <<axisNames.first <<std::setw(tabLength) <<axisNames.second <<
"_"<<repeatition<<
"\n";
798 for(
typename std::map< Tx, TuneParams<Ty> >::iterator it = predictionData.begin(); it != predictionData.end(); ++it)
800 TuneParams<Ty> params= it->second;
802 if(params.backendParams.backend==CPU_BACKEND)
803 file<<
" " <<std::setw(tabLength) <<it->first <<std::setw(tabLength) <<params.getPrediction(repeatition)<<std::setw(20)<< convertBackendToStr(params.backendParams.backend) <<
"\n";
805 else if(params.backendParams.backend==OMP_BACKEND)
806 file<<
" " <<std::setw(tabLength) <<it->first <<std::setw(tabLength) <<params.getPrediction(repeatition)<<std::setw(20)<< convertBackendToStr(params.backendParams.backend) <<std::setw(10)<< params.backendParams.numOmpThreads<<
"\n";
808 file<<
" " <<std::setw(tabLength) <<it->first <<std::setw(tabLength) <<params.getPrediction(repeatition)<<std::setw(20)<< convertBackendToStr(params.backendParams.backend) <<std::setw(10)<< params.backendParams.maxBlocks<< std::setw(10)<<params.backendParams.maxThreads <<
"\n";
823 template <
typename Tx,
typename Ty>
824 void TuneData<Tx, Ty>::savePrediction(
const std::string& filename)
826 std::ofstream file(filename.c_str());
828 file<<std::fixed <<std::setprecision(5);
832 for(
typename std::map< Tx, TuneParams<Ty> >::iterator it = predictionData.begin(); it != predictionData.end(); ++it)
834 TuneParams<Ty> params= it->second;
836 if(params.backendParams.backend==CPU_BACKEND)
837 file<<it->first <<
" " <<params.repeatPart <<
" " << params.fixedPart <<
" "<<
" "<< convertBackendToStr(params.backendParams.backend) <<
"\n";
839 else if(params.backendParams.backend==OMP_BACKEND)
840 file<<it->first <<
" " <<params.repeatPart <<
" " << params.fixedPart <<
" "<<
" "<< convertBackendToStr(params.backendParams.backend) <<
" "<< params.backendParams.numOmpThreads<<
"\n";
843 file<<it->first <<
" " <<params.repeatPart <<
" " << params.fixedPart <<
" "<< convertBackendToStr(params.backendParams.backend) <<
" "<< params.backendParams.maxBlocks<<
" "<<params.backendParams.maxThreads <<
"\n";
852 template <
typename Tx,
typename Ty>
853 void TuneData<Tx, Ty>::writeGnuPlotFileOMP(
const std::string& filename,
int threads)
855 std::ofstream file(filename.c_str());
856 int tabLength = axisNames.first.length()+20;
858 file<<std::fixed <<std::setprecision(5);
862 file<<
"# " <<dataSetName <<
"\n";
863 file<<
"# " <<std::setw(tabLength) <<axisNames.first <<std::setw(tabLength) <<axisNames.second <<
"_"<<threads<<
"\n";
866 for(
typename std::map< Tx, TuneParams<Ty> >::iterator it = predictionData.begin(); it != predictionData.end(); ++it)
868 TuneParams<Ty> params= it->second;
869 if(params.backendParams.backend==OMP_BACKEND)
870 file<<
" " <<std::setw(tabLength) <<it->first <<std::setw(tabLength) <<(params.repeatPart/threads + params.fixedPart.second*threads)<<std::setw(20)<< convertBackendToStr(params.backendParams.backend) <<std::setw(10)<< params.backendParams.numproc_omp<<
"\n";
883 template <
typename Tx,
typename Ty>
887 std::ifstream file(filename.c_str());
888 file>>std::fixed >>std::setprecision(5);
892 Tx vecSize, gs, bs, num_omp;
899 while (std::getline( file, s ))
901 std::istringstream ss(s);
907 ss>>vecSize>>repPart>>fixPart>>backend;
909 BackEnd be= convertStrToBackend(backend);
910 TuneParams<Ty> tp(repPart, fixPart, be);
912 if(be==skepu::OMP_BACKEND)
915 tp.backendParams.numOmpThreads=num_omp;
917 else if(be!=skepu::CPU_BACKEND)
920 tp.backendParams.maxBlocks=gs;
921 tp.backendParams.maxThreads=bs;
925 addData(vecSize, tp, repetition);
void loadPrediction(const std::string &filename, int repetition=1)
Definition: data_tune.h:884
BackEnd
Can be used to specify which backend to use.
Definition: environment.h:34
TuneData(const std::string &_dataSetName, const std::string &_axisNameX, const std::string &_axisNameY)
Definition: data_tune.h:187
void writeDataToFile(const std::string &filename="", int repeatition=1, DataExportFormat format=GNUPLOT)
Definition: data_tune.h:755
A vector container class, implemented as a wrapper for std::vector.
Definition: vector.h:61
A class that describes an execution plan.
Definition: exec_plan.h:47
void clear()
Definition: data_tune.h:741
Contains a class declaration for the Vector container.
A class that can be used to collect tuning data.
Definition: data_tune.h:109
static Environment * getInstance()
Definition: environment.inl:90
void addData(Tx x, TuneParams< Ty > params, int repetition=1)
Definition: data_tune.h:219
Can be used to specify properties for a backend.
Definition: exec_plan.h:19
Contains a class that stores information about which back ends to use when executing.