SkePU  1.2
 All Classes Namespaces Files Functions Variables Enumerations Friends Macros Groups Pages
data_tune.h
Go to the documentation of this file.
1 
4 #ifndef DATA_TUNE_H
5 #define DATA_TUNE_H
6 
7 #include <string>
8 #include <iostream>
9 #include <map>
10 
11 #include <utility>
12 #include <fstream>
13 #include <algorithm> // uses for converting string to uppercase or lower case using transform algorithm
14 #include <iomanip>
15 
16 #include <skepu/vector.h>
17 #include "exec_plan.h"
18 
19 #include <iostream>
20 
21 
22 
23 
24 namespace skepu
25 {
26 
27 template<typename T>
28 struct TuneParams
29 {
30  TuneParams() {}
31  TuneParams(T repPart, T fixPart, BackEnd be, int gs, int bs): repeatPart(repPart), fixedPart(fixPart)
32  {
33  backendParams.backend=be;
34  backendParams.maxThreads=bs;
35  backendParams.maxBlocks=gs;
36  }
37 
38  TuneParams(T repPart, T fixPart, BackEnd be, int num_omp=1): repeatPart(repPart), fixedPart(fixPart)
39  {
40  backendParams.backend=be;
41  backendParams.numOmpThreads=num_omp;
42  }
43 
44  T getPrediction(int repetition=1)
45  {
46  return (repeatPart*repetition) + fixedPart;
47  }
48 
49  T getPredictionPercentage(int percent=100, int repetition=1)
50  {
51  return (repeatPart*repetition) + (fixedPart* ((double)percent/100.0f));
52  }
53 
54  BackEnd backend()
55  {
56  return backendParams.backend;
57  }
58  int maxBlocks()
59  {
60  return backendParams.maxBlocks;
61  }
62  int maxThreads()
63  {
64  return backendParams.maxThreads;
65  }
66  int numOmpThreads()
67  {
68  return backendParams.numOmpThreads;
69  }
70 
71  void backend(BackEnd be)
72  {
73  backendParams.backend=be;
74  }
75  void maxBlocks(int mb)
76  {
77  backendParams.maxBlocks=mb;
78  }
79  void maxThreads(int mt)
80  {
81  backendParams.maxThreads=mt;
82  }
83  void numOmpThreads(int numTrd)
84  {
85  backendParams.numOmpThreads=numTrd;
86  }
87 
88  BackEndParams backendParams;
89 
90  T fixedPart;
91  T repeatPart;
92  double time;
93 };
94 
108 template <typename Tx, typename Ty>
109 class TuneData
110 {
111 
112 public:
113  TuneData(const std::string& _dataSetName, const std::string& _axisNameX, const std::string& _axisNameY);
114 
115  void addData(Tx x, TuneParams<Ty> params, int repetition=1);
116  void clear();
117  void writeDataToFile(const std::string& filename = "", int repeatition=1, DataExportFormat format = GNUPLOT);
118 
119  ExecPlan& getExecPlan(Vector<Tx>& v1, Vector<Tx>& v2, int percent=100);
120 
121  Ty getPrediction(Tx index, int repeatition=1);
122 
123 
124  void loadPrediction(const std::string& filename, int repetition=1);
125 
126  friend std::ostream& operator <<(std::ostream &os, TuneData& tunedata)
127  {
128  os<<"MapDataSet Size:"<<tunedata.predictionData.size()<<"\n";
129  int tabLength = 10;
130  for(typename std::map< Tx, TuneParams<Ty> >::iterator it = tunedata.predictionData.begin(); it != tunedata.predictionData.end(); ++it)
131  {
132  TuneParams<Ty> params= it->second;
133  BackEndParams bp=params.backendParams;
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";
138  else
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";
140  }
141  return os;
142  }
143 
144  void writeGnuPlotFileOMP(const std::string& filename,int threads=1);
145 
146  ExecPlan& buildExecPlan();
147 
148  void changeRepeatPart(std::pair<int, Ty> newRep[], int size);
149  void changeRepeatPart_NoAvg(std::pair<int, Ty> newRep[], int size);
150 
151  std::pair<Ty,Ty> getPredictionPair(Tx size);
152 
153 private:
154 
155  ExecPlan& buildExecPlanMultiEntries();
156 
157  skepu::ExecPlan plan;
158  std::string dataSetName;
159  std::pair<std::string, std::string> axisNames;
160 
161  //std::map< Tx, std::pair<Ty, Ty> > dataSet;
162 
163 #ifdef SKEPU_COMPOSE_PREDICTION
164  std::multimap< Tx, TuneParams<Ty> > predictionData;
165 #else
166  std::map< Tx, TuneParams<Ty> > predictionData;
167 #endif
168 
169 
170  std::string convertBackendToStr(BackEnd be);
171  BackEnd convertStrToBackend(std::string str);
172  void writeGnuPlotFile(const std::string& filename,int repeatition=1);
173 
174  void savePrediction(const std::string& filename);
175 
176 
177 };
178 
186 template <typename Tx, typename Ty>
187 TuneData<Tx, Ty>::TuneData(const std::string& _dataSetName, const std::string& _axisNameX, const std::string& _axisNameY)
188 {
189  dataSetName = _dataSetName;
190  axisNames.first = _axisNameX;
191  axisNames.second = _axisNameY;
192 }
193 
200 // template <typename Tx, typename Ty>
201 // void TuneData<Tx, Ty>::addData(Tx size, Ty repeatPart, Ty fixedPart)
202 // {
203 // typename std::map< Tx, TuneParams<Ty> >::iterator it=predictionData.find(size);
204 // if(it!=predictionData.end()) // if already prediction exist for this case
205 // {
206 // if((it->second.repeatPart + it->second.fixedPart) > (repeatPart + fixedPart)) // if new one is optimal than previous
207 // {
208 // predictionData.erase(it);
209 // }
210 // else
211 // return;
212 // }
213 // dataSet.insert(std::make_pair(size, std::make_pair(repeatPart, fixedPart)));
214 // return;
215 // }
216 
217 
218 template <typename Tx, typename Ty>
219 void TuneData<Tx, Ty>::addData(Tx size, TuneParams<Ty> params, int repetition)
220 {
221 #ifndef SKEPU_COMPOSE_PREDICTION
222  typename std::map< Tx, TuneParams<Ty> >::iterator it=predictionData.find(size);
223  if(it!=predictionData.end()) // if already prediction exist for this case
224  {
225  TuneParams<Ty> org_p= it->second;
226  if( org_p.getPrediction(repetition) > params.getPrediction(repetition)) // if new one is optimal than previous
227  {
228  predictionData.erase(it);
229  }
230  else
231  return;
232 
233  }
234 #endif
235 // comment above to add this as an alternative choice
236  predictionData.insert(std::make_pair(size, params));
237  return;
238 
239  // std::cout<<params.backend<<"---"<<convertBackendToStr(params.backend)<<"\n";
240 }
241 
242 template <typename Tx, typename Ty>
244 {
245  std::string retval("CPU_BACKEND"); // default, if not match any other case
246 
247  switch(be)
248  {
249  case CL_BACKEND:
250  retval= std::string("CL_BACKEND");
251  break;
252  case CLM_BACKEND:
253  retval= std::string("CLM_BACKEND");
254  break;
255  case CU_BACKEND:
256  retval= std::string("CU_BACKEND");
257  break;
258  case CUM_BACKEND:
259  retval= std::string("CUM_BACKEND");
260  break;
261  case OMP_BACKEND:
262  retval= std::string("OMP_BACKEND");
263  break;
264  case CPU_BACKEND:
265  retval= std::string("CPU_BACKEND");
266  break;
267  }
268  return retval;
269 }
270 
271 template <typename Tx, typename Ty>
272 BackEnd TuneData<Tx, Ty>::convertStrToBackend(std::string str)
273 {
274  std::transform(str.begin(), str.end(), str.begin(), ::toupper); // to convert in upper case to avoid any erroneous mismatch just because of case
275 // std::cout<<">>>>"<<str<<"<<<<<";
276 
277  if(str=="CL_BACKEND")
278  return CL_BACKEND;
279  else if(str=="CLM_BACKEND")
280  return CLM_BACKEND;
281  else if(str=="CU_BACKEND")
282  return CU_BACKEND;
283  else if(str=="CUM_BACKEND")
284  return CUM_BACKEND;
285  else if(str=="OMP_BACKEND")
286  return OMP_BACKEND;
287  else if(str=="CPU_BACKEND")
288  return CPU_BACKEND;
289 
290  return CPU_BACKEND; // default, if not match any other case
291 }
292 
293 
294 template <typename Tx, typename Ty>
295 void TuneData<Tx, Ty>::changeRepeatPart(std::pair<int, Ty> newRep[], int size)
296 {
297  double ratio;
298  double *ratios = new double[size];
299  for(int i=0; i<size; i++)
300  {
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";
304  }
305  double avgRatio=0.0;
306  for(int i=0; i<size; i++)
307  {
308  avgRatio += ratios[i];
309  }
310  avgRatio /= size; // calculate average
311  std::cout<<"AvgRatio: "<<avgRatio<<"\n";
312 
313  // now modify all predictions.........
314  typename std::map< Tx, TuneParams<Ty> >::iterator it;
315  for(it=predictionData.begin(); it!=predictionData.end(); it++)
316  {
317  std::cout<<"Before: "<<it->second.repeatPart;
318  it->second.repeatPart = ((double)(it->second.repeatPart)/avgRatio);
319  std::cout<<" After: "<<it->second.repeatPart<<"\n";
320  }
321 }
322 
323 
324 
325 
326 
327 
328 template <typename Tx, typename Ty>
329 void TuneData<Tx, Ty>::changeRepeatPart_NoAvg(std::pair<int, Ty> newRep[], int size)
330 {
331  double ratio;
332 
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++)
336  {
337  if(i!=0) // not first one
338  lower = ((prev_upper == -1) ? ((newRep[i].first + newRep[(i-1)].first)/2) : (prev_upper+1) );
339  else
340  lower = 1;
341 
342  if(i!=(size-1))
343  upper = (newRep[i].first + newRep[(i+1)].first)/2;
344  else
345  upper = newRep[i].first +1;
346 
347 
348  std::pair<Ty, Ty> p= getPredictionPair(newRep[i].first);
349  ratio= (double)p.first/newRep[i].second;
350 
351  rangesRatio.insert(std::make_pair(std::make_pair(lower, upper), ratio));
352 
353  std::cout<<"First for loop: "<<p.first<<" "<<newRep[i].second<<" ratio:"<<ratio<<" "<<newRep[i].first<<" "<<lower<<" --- "<<upper<<"\n";
354 
355  prev_upper = upper;
356  }
357 
358  typename std::map< Tx, TuneParams<Ty> >::iterator it, prev_it, nxt_it;
359 
360  for(it=predictionData.begin(); it!=predictionData.end(); it++)
361  {
362  std::map< std::pair<int, int>, double >::iterator ratio_it;
363  for(ratio_it = rangesRatio.begin(); ratio_it != rangesRatio.end(); ++ratio_it)
364  {
365  if(it->first >= ratio_it->first.first && it->first <= ratio_it->first.second)
366  {
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";
370  break;
371  }
372  }
373  }
374 }
375 
376 
377 
378 template <typename Tx, typename Ty>
379 ExecPlan& TuneData<Tx, Ty>::buildExecPlanMultiEntries()
380 {
381  if(predictionData.empty())
382  return plan; // no entry
383 
384  plan.clear();
385 
386  BackEndParams bp;//, prev_bp;
387  int optionsCount=predictionData.count(predictionData.begin()->first);
388  BackEndParams *prev_bp=new BackEndParams[optionsCount];
389  int size;
390  bool finish;
391  int prev_upperLimit=-1;
392  int lowerLimit=1, upperLimit;
393 
394  typedef typename std::map< Tx, TuneParams<Ty> >::iterator CIT;
395  std::pair<CIT,CIT> range;
396 
397  typename std::map< Tx, TuneParams<Ty> >::iterator it;
398  for(it = predictionData.begin(); it != predictionData.end();)
399  {
400 
401  size=it->first;
402  bp= (it->second.backendParams);
403 
404 // std::cout<<size<<" "<<convertBackendToStr(bp.backend)<<" "<<bp.numOmpThreads<<" "<<bp.maxThreads<<" "<<bp.maxBlocks<<"\n";
405 
406  upperLimit=size;
407  if(prev_upperLimit!=-1) // not first iteration
408  {
409 
410  if(prev_bp[0].backend == bp.backend)
411  {
412  if(prev_bp[0].backend == OMP_BACKEND && (prev_bp[0].numOmpThreads == bp.numOmpThreads))
413  {
414  finish=false;
415  }
416  else if(prev_bp[0].backend == CPU_BACKEND)
417  finish=false;
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)
419  finish=false;
420  else
421  {
422 // std::cout<<"Hello inner else\n";
423  finish=true;
424  }
425  }
426  else
427  {
428 // std::cout<<"Hello outer else\n";
429  finish=true;
430  }
431  }
432  else
433  finish=false;
434 
435  if(finish)
436  {
437  int newLimit;
438 // if(prev_upperLimit != -1)
439 
440  newLimit= ((upperLimit+prev_upperLimit)/2);
441 // std::cout<<upperLimit<<" "<<prev_upperLimit<<" "<<newLimit<<"\n";
442  /* else
443  newLimit= upperLimit;*/
444 
445 
446  range= predictionData.equal_range(size);
447  TuneParams<Ty> params;
448  int ind=0;
449  for(CIT subit=range.first; subit!=range.second; subit++)
450  {
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";
454  prev_bp[ind++]; //=params.backendParams;
455  }
456  finish=false;
457  lowerLimit= (newLimit+1);
458  }
459 // if(it==predictionData.end())
460 // break;
461 // it++;
462  range= predictionData.equal_range(size);
463  TuneParams<Ty> params;
464  int ind=0;
465  for(CIT subit=range.first; subit!=range.second; subit++)
466  {
467  TuneParams<Ty> params= subit->second;
468  prev_bp[ind++]=params.backendParams;
469  }
470  prev_upperLimit=upperLimit;
471 
472  it = predictionData.upper_bound(size); // go to next key
473  }
474  range= predictionData.equal_range(size);
475  for(int ind=0; ind<optionsCount; ind++)
476  {
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";
479  }
480 
481 // std::cout<<lowerLimit<<" --- "<<prev_upperLimit<<" "<<convertBackendToStr(prev_bp.backend)<<" "<<prev_bp.numOmpThreads<<" "<<prev_bp.maxThreads<<" "<<prev_bp.maxBlocks<<"\n";
482  return plan;
483 
484 }
485 
486 
487 
488 template <typename Tx, typename Ty>
489 ExecPlan& TuneData<Tx, Ty>::buildExecPlan()
490 {
491 #ifdef SKEPU_COMPOSE_PREDICTION
492  return buildExecPlanMultiEntries();
493 #endif
494  if(predictionData.empty())
495  return plan; // no entry
496 
497  plan.clear();
498 
499  BackEndParams bp, prev_bp;
500  int size;
501  bool finish;
502  int prev_upperLimit=-1;
503  int lowerLimit=1, upperLimit;
504 
505  typename std::map< Tx, TuneParams<Ty> >::iterator it;
506  for(it = predictionData.begin(); it != predictionData.end(); ++it)
507  {
508  size=it->first;
509  bp= (it->second.backendParams);
510  upperLimit=size;
511  if(prev_upperLimit!=-1) // not first iteration
512  {
513 
514  if(prev_bp.backend == bp.backend)
515  {
516  if(prev_bp.backend == OMP_BACKEND && (prev_bp.numOmpThreads == bp.numOmpThreads))
517  {
518  finish=false;
519  }
520  else if(prev_bp.backend == CPU_BACKEND)
521  finish=false;
522  else if((prev_bp.backend != OMP_BACKEND && prev_bp.backend != CPU_BACKEND) && prev_bp.maxThreads == bp.maxThreads && prev_bp.maxBlocks == bp.maxBlocks)
523  finish=false;
524  else
525  {
526 // std::cout<<"Hello inner else\n";
527  finish=true;
528  }
529  }
530  else
531  {
532 // std::cout<<"Hello outer else\n";
533  finish=true;
534  }
535  }
536  else
537  finish=false;
538 
539  if(finish)
540  {
541  int newLimit;
542 // if(prev_upperLimit != -1)
543 
544  newLimit= ((upperLimit+prev_upperLimit)/2);
545 // std::cout<<upperLimit<<" "<<prev_upperLimit<<" "<<newLimit<<"\n";
546  /* else
547  newLimit= upperLimit;*/
548 
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";
551  finish=false;
552  lowerLimit= (newLimit+1);
553  }
554 
555  prev_bp=bp;
556  prev_upperLimit=upperLimit;
557  }
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";
560  return plan;
561 
562 }
563 
564 template <typename Tx, typename Ty>
565 ExecPlan& TuneData<Tx, Ty>::getExecPlan(Vector<Tx>& v1, Vector<Tx>& v2, int percent)
566 {
567  plan.clear();
568  int size=v1.size();
569  if(predictionData.find(size) == predictionData.end())
570  {
571  std::cerr<< "No Information for this size\n"; // Inter- or extra-polations
572  return plan;
573  }
574 
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++)
581  {
582  TuneParams<Ty> params= it->second;
583  if(params.backend()==CL_BACKEND && percent==100)
584  {
585 #ifdef SKEPU_OPENCL
586  Environment<Tx> *envir=Environment<Tx>::getInstance();
587  if(v1.isVectorOnDevice_CL(envir->m_devices_CL.at(0)))
588  percent-=50;
589  if(v2.isVectorOnDevice_CL(envir->m_devices_CL.at(0)))
590  percent-=50;
591 #endif
592  }
593  else if (params.backend()==CU_BACKEND && percent==100)
594  {
595 #ifdef SKEPU_CUDA
596  if(v1.isVectorOnDevice_CU(0))
597  percent-=50;
598  if(v2.isVectorOnDevice_CU(0))
599  percent-=50;
600 #endif
601  }
602  if(it==range.first)
603  {
604  opt_params=params;
605  }
606  else if(opt_params.getPredictionPercentage(percent) > params.getPredictionPercentage(percent))
607  {
608  opt_params=params;
609  }
610  }
611  plan.add(size-100, size+100, opt_params.backendParams);
612 
613  return plan;
614 }
615 
616 template <typename Tx, typename Ty>
617 Ty TuneData<Tx, Ty>::getPrediction(Tx size, int repetition)
618 {
619 
620  typename std::map< Tx, TuneParams<Ty> >::iterator it=predictionData.find(size);
621 
622  if(it==predictionData.end()) // if prediction does not exist for this case
623  {
624  if( predictionData.size() <= 1) // if only one item, cannot predict
625  return -1;
626 
627  int prev_size=-1;
628  double value;
629  for(it=predictionData.begin(); it!= predictionData.end(); it++)
630  {
631  if(size < it->first)
632  {
633  if(prev_size==-1) // less than first item
634  {
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));
639  }
640  else
641  {
642  double prev_pred= predictionData.at(prev_size)->second.getPrediction(repetition);
643  double curr_pred= predictionData.at(it->first)->second.getPrediction(repetition);
644 
645  value= (((double)(curr_pred-prev_pred))/((double)(it->first-prev_size)));
646  return (( (size-prev_size) * value) + prev_pred);
647  }
648 
649  }
650  prev_size=it->first;
651  }
652  // if greater than even the last item
653  it--;
654  double prev_pred= predictionData.at((it-1)->first)->second.getPrediction(repetition);
655  double curr_pred= predictionData.at(it->first)->second.getPrediction(repetition);
656 
657  value= (((double)(curr_pred-prev_pred))/((double)(it->first - (it-1)->first)));
658  return (( (size - it->first) * value) + curr_pred);
659  }
660 
661  return predictionData.at(size)->second.getPrediction(repetition);
662 }
663 
664 
665 
666 
667 template <typename Tx, typename Ty>
668 std::pair<Ty,Ty> TuneData<Tx, Ty>::getPredictionPair(Tx size)
669 {
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);
673 
674  if(it==predictionData.end()) // if prediction does not exist for this case
675  {
676  if( predictionData.size() <= 1) // if only one item, cannot predict
677  return p;
678 
679  int prev_size=-1;
680  std::pair<Ty, Ty> value;
681  for(it=predictionData.begin(); it!= predictionData.end(); it++)
682  {
683  if(size < it->first)
684  {
685  if(prev_size==-1) // less than first item
686  {
687 
688  typename std::map< Tx, TuneParams<Ty> >::iterator temp_it= it; // no operator + overload in iterator so need to do this agly stuff
689  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);
692 
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));
696  }
697  else
698  {
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));
704 
705 // double prev_pred= predictionData.at(prev_size)->second.getPrediction(repetition);
706 // double curr_pred= predictionData.at(it->first)->second.getPrediction(repetition);
707 //
708 // value= (((double)(curr_pred-prev_pred))/((double)(it->first-prev_size)));
709 // return (( (size-prev_size) * value) + prev_pred);
710  }
711 
712  }
713  prev_size=it->first;
714  }
715  // if greater than even the last item
716  it--;
717  typename std::map< Tx, TuneParams<Ty> >::iterator temp_it= it; // no operator + overload in iterator so need to do this agly stuff
718  it--;
719 
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));
725 
726 // double prev_pred= predictionData.at((it-1)->first)->second.getPrediction(repetition);
727 // double curr_pred= predictionData.at(it->first)->second.getPrediction(repetition);
728 //
729 // value= (((double)(curr_pred-prev_pred))/((double)(it->first - (it-1)->first)));
730 // return (( (size - it->first) * value) + curr_pred);
731  }
732 
733  return std::pair<Ty,Ty>( (predictionData.find(size)->second.repeatPart), (predictionData.find(size)->second.fixedPart) );
734 }
735 
736 
740 template <typename Tx, typename Ty>
742 {
743  predictionData.clear();
744 }
745 
746 
747 
754 template <typename Tx, typename Ty>
755 void TuneData<Tx, Ty>::writeDataToFile(const std::string& filename, int repeatition, DataExportFormat format)
756 {
757  std::string _filename;
758 
759  if(filename.empty())
760  {
761  _filename = dataSetName + ".dat";
762  }
763  else
764  {
765  _filename = filename;
766  }
767 
768  //Call right exporter
769  if(format == GNUPLOT)
770  {
771  writeGnuPlotFile(_filename, repeatition);
772  }
773  else if(format == PREDICTION_FILE)
774  {
775  savePrediction(_filename);
776  }
777 }
778 
784 template <typename Tx, typename Ty>
785 void TuneData<Tx, Ty>::writeGnuPlotFile(const std::string& filename,int repeatition)
786 {
787  std::ofstream file(filename.c_str());
788  int tabLength = axisNames.first.length()+20;
789  file<<std::left;
790  file<<std::fixed <<std::setprecision(5);
791  if(file.is_open())
792  {
793  //First add name and axis names as comments
794  file<<"# " <<dataSetName <<"\n";
795  file<<"# " <<std::setw(tabLength) <<axisNames.first <<std::setw(tabLength) <<axisNames.second <<"_"<<repeatition<<"\n";
796 
797  //Add data in two columns
798  for(typename std::map< Tx, TuneParams<Ty> >::iterator it = predictionData.begin(); it != predictionData.end(); ++it)
799  {
800  TuneParams<Ty> params= it->second;
801 
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";
804 
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";
807  else
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";
809  }
810 
811  file.close();
812  }
813 }
814 
815 
816 
817 
823 template <typename Tx, typename Ty>
824 void TuneData<Tx, Ty>::savePrediction(const std::string& filename)
825 {
826  std::ofstream file(filename.c_str());
827  file<<std::left;
828  file<<std::fixed <<std::setprecision(5);
829  if(file.is_open())
830  {
831  //Add data in two columns
832  for(typename std::map< Tx, TuneParams<Ty> >::iterator it = predictionData.begin(); it != predictionData.end(); ++it)
833  {
834  TuneParams<Ty> params= it->second;
835 
836  if(params.backendParams.backend==CPU_BACKEND)
837  file<<it->first <<" " <<params.repeatPart << " " << params.fixedPart << " "<<" "<< convertBackendToStr(params.backendParams.backend) <<"\n";
838 
839  else if(params.backendParams.backend==OMP_BACKEND)
840  file<<it->first <<" " <<params.repeatPart << " " << params.fixedPart << " "<<" "<< convertBackendToStr(params.backendParams.backend) <<" "<< params.backendParams.numOmpThreads<<"\n";
841 
842  else
843  file<<it->first <<" " <<params.repeatPart << " " << params.fixedPart << " "<< convertBackendToStr(params.backendParams.backend) <<" "<< params.backendParams.maxBlocks<< " "<<params.backendParams.maxThreads <<"\n";
844  }
845 
846  file.close();
847  }
848 }
849 
850 
851 
852 template <typename Tx, typename Ty>
853 void TuneData<Tx, Ty>::writeGnuPlotFileOMP(const std::string& filename,int threads)
854 {
855  std::ofstream file(filename.c_str());
856  int tabLength = axisNames.first.length()+20;
857  file<<std::left;
858  file<<std::fixed <<std::setprecision(5);
859  if(file.is_open())
860  {
861  //First add name and axis names as comments
862  file<<"# " <<dataSetName <<"\n";
863  file<<"# " <<std::setw(tabLength) <<axisNames.first <<std::setw(tabLength) <<axisNames.second <<"_"<<threads<<"\n";
864 
865  //Add data in two columns
866  for(typename std::map< Tx, TuneParams<Ty> >::iterator it = predictionData.begin(); it != predictionData.end(); ++it)
867  {
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";
871  }
872 
873  file.close();
874  }
875 }
876 
877 
883 template <typename Tx, typename Ty>
884 void TuneData<Tx, Ty>::loadPrediction(const std::string& filename, int repetition)
885 {
886 
887  std::ifstream file(filename.c_str());
888  file>>std::fixed >>std::setprecision(5);
889 
890  std::string s;
891 // char ch;
892  Tx vecSize, gs, bs, num_omp;
893  Ty fixPart, repPart;
894 
895  if(file.is_open())
896  {
897 // predictionData.clear();
898 
899  while (std::getline( file, s ))
900  {
901  std::istringstream ss(s);
902 
903  std::string backend;
904  //bool final = true;
905 
906 
907  ss>>vecSize>>repPart>>fixPart>>backend;//>>gs>>bs;
908 
909  BackEnd be= convertStrToBackend(backend);
910  TuneParams<Ty> tp(repPart, fixPart, be);
911 
912  if(be==skepu::OMP_BACKEND)
913  {
914  ss>>num_omp;
915  tp.backendParams.numOmpThreads=num_omp;
916  }
917  else if(be!=skepu::CPU_BACKEND) // if not CPU
918  {
919  ss>>gs>>bs; // no char for int
920  tp.backendParams.maxBlocks=gs;
921  tp.backendParams.maxThreads=bs;
922  }
923  //ss>>vecSize>>ch>>fixPart>>ch>>gs>>bs;
924  //predictionData.insert(std::make_pair(vecSize, tp));
925  addData(vecSize, tp, repetition);
926 
927  }
928  file.close();
929  }
930 }
931 
932 
933 } // end namespace
934 
935 #endif
936 
937 
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.