Hybrid Query Processing Engine for Coprocessing in Database Systems
HyPE
|
00001 //default includes 00002 #include <limits> 00003 00004 #include <config/global_definitions.hpp> 00005 00006 #include <core/operation.hpp> 00007 00008 #include <plugins/optimization_criterias/response_time.hpp> 00009 00010 00011 00012 #ifdef DUMP_ESTIMATIONS 00013 #include <fstream> 00014 #endif 00015 00016 //#define TIMESTAMP_BASED_LOAD_ADAPTION 00017 //#define PROBABILITY_BASED_LOAD_ADAPTION 00018 //#define LOAD_MODIFICATOR_BASED_LOAD_ADAPTION 00019 00020 using namespace std; 00021 00022 namespace hype 00023 { 00024 namespace core 00025 { 00026 00027 ResponseTime::ResponseTime(const std::string& name_of_operation) : OptimizationCriterion_Internal(name_of_operation,std::string("Response Time")) 00028 { 00029 //OptimizationCriterionFactorySingleton::Instance().Register("Response Time",&ResponseTime::create); 00030 } 00031 00032 const SchedulingDecision ResponseTime::getOptimalAlgorithm_internal(const Tuple& input_values, Operation& op, DeviceTypeConstraint dev_constr) 00033 { 00034 00035 /* 00036 std::vector<AlgorithmPtr> alg_ptrs = op.getAlgorithms(); 00037 00038 00039 00040 for(int i=0;i<alg_ptrs.size();i++){ 00041 //if(!quiet && verbose) 00042 cout << "Algorithm: " << alg_ptrs[i]->getName() << " In Training Phase: " << alg_ptrs[i]->inTrainingPhase() << endl; 00043 #ifdef TIMESTAMP_BASED_LOAD_ADAPTION 00044 //FEATURE: Timestamp based load adaption (triggers retraining) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00045 //if algorithm was not executed for a long time (Configuration::maximal_time_where_algorithm_was_not_choosen times), retrain algorithm 00046 if(alg_ptrs[i]->getTimeOfLastExecution()+Configuration::maximal_time_where_algorithm_was_not_choosen<op.getCurrentTimestamp()){ 00047 cout << "Operation execution number: " << op.getCurrentTimestamp() << endl; 00048 alg_ptrs[i]->retrain(); 00049 } 00050 #endif 00051 #ifdef LOAD_MODIFICATOR_BASED_LOAD_ADAPTION 00052 //FEATURE: Load Modification factor based load adaption %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00053 if(alg_ptrs[i]->getLoadChangeEstimator().getLoadModificator()>2 00054 || alg_ptrs[i]->getLoadChangeEstimator().getLoadModificator()<0.5f){ //execution times increased by factor of 2 -> sifnificant load change, retrain all algorithms? 00055 cout << "Operation execution number: " << op.getCurrentTimestamp() << "\tAlgorithm: " << alg_ptrs[i]->getName() << "\t" 00056 << "Significant load change confirmed: " << alg_ptrs[i]->getLoadChangeEstimator().getLoadModificator() << endl; 00057 } 00058 #endif 00059 //train algorithms in round robin manner 00060 if(alg_ptrs[i]->inTrainingPhase()){ 00061 return SchedulingDecision(alg_ptrs[i]->getName(),EstimatedTime(-1),input_values); 00062 } 00063 00064 if(alg_ptrs[i]->inRetrainingPhase()){ 00065 return SchedulingDecision(alg_ptrs[i]->getName(),EstimatedTime(alg_ptrs[i]->getEstimatedExecutionTime(input_values)),input_values); 00066 }// 00067 } 00068 */ 00069 //assert(dev_constr==stemod::ANY_DEVICE); 00070 if(!quiet && verbose && debug) { 00071 if(dev_constr==hype::CPU_ONLY) { 00072 cout << "only CPU algorithms allowed for operation'" << op.getName() << "' !" << endl; 00073 } else if(dev_constr==hype::GPU_ONLY) { 00074 cout << "only GPU algorithms allowed for operation'" << op.getName() << "' !" << endl; 00075 } 00076 } 00077 00078 std::vector<AlgorithmPtr> alg_ptrs = op.getAlgorithms(); 00079 00080 double min_time=std::numeric_limits<double>::max(); 00081 AlgorithmPtr optimal_algorithm; 00082 00083 for(unsigned int i=0; i<alg_ptrs.size(); ++i) { 00084 double t_est = alg_ptrs[i]->getEstimatedExecutionTime(input_values).getTimeinNanoseconds(); 00085 if( (dev_constr==hype::CPU_ONLY && alg_ptrs[i]->getDeviceSpecification().getDeviceType()==hype::CPU) 00086 || (dev_constr==hype::GPU_ONLY && alg_ptrs[i]->getDeviceSpecification().getDeviceType()==hype::GPU) 00087 || (dev_constr==hype::ANY_DEVICE) ) 00088 if(t_est<min_time) { 00089 min_time=t_est; 00090 optimal_algorithm=alg_ptrs[i]; 00091 } 00092 } 00093 00094 assert(optimal_algorithm!=NULL); 00095 if(!quiet && verbose) cout << "Choosing " << optimal_algorithm->getName() << " for operation " << op.getName() << endl; 00096 return SchedulingDecision(*optimal_algorithm,EstimatedTime(min_time),input_values); 00097 00098 00099 /* 00100 std::map<double,std::string> map_execution_times_to_algorithm_name = op.getEstimatedExecutionTimesforAlgorithms(input_values); 00101 if(map_execution_times_to_algorithm_name.empty()) { 00102 std::cout << "FATAL ERROR! no algorithm to choose from!!!" << std::endl; 00103 std::cout << "File: " << __FILE__ << " Line: " << __LINE__ << std::endl; 00104 exit(-1); 00105 } 00106 std::map<double,std::string>::iterator it; 00107 double min_time=std::numeric_limits<double>::max(); 00108 cout << "AlgorithmMap: " << endl; 00109 for(it=map_execution_times_to_algorithm_name.begin(); it!=map_execution_times_to_algorithm_name.end(); ++it) { 00110 cout << "Algorithm: '" << it->second << "' Estimated Execution Time: " << it->first << endl; 00111 } 00112 00113 for(it=map_execution_times_to_algorithm_name.begin(); it!=map_execution_times_to_algorithm_name.end(); ++it) { 00114 if(!quiet && verbose) 00115 cout << "Algorithm: '" << it->second << "' Estimated Execution Time: " << it->first << endl; 00116 00117 cout << "number_of algoritms" << map_execution_times_to_algorithm_name.size() << endl; 00118 00119 if(dev_constr==stemod::CPU_ONLY) { 00120 cout << "only CPU algorithms allowed!" << endl; 00121 } 00122 00123 if(dev_constr==stemod::GPU_ONLY) { 00124 cout << "only GPU algorithms allowed!" << endl; 00125 } 00126 00127 cout << "DEBUG: CPU_ONLY "<< bool((dev_constr==stemod::CPU_ONLY && op.getAlgorithm(it->second)->getComputeDevice()==stemod::CPU)) 00128 << " GPU_ONLY " << bool((dev_constr==stemod::GPU_ONLY && op.getAlgorithm(it->second)->getComputeDevice()==stemod::GPU)) << endl; 00129 00130 if( (dev_constr==stemod::CPU_ONLY && op.getAlgorithm(it->second)->getComputeDevice()==stemod::CPU) 00131 || (dev_constr==stemod::GPU_ONLY && op.getAlgorithm(it->second)->getComputeDevice()==stemod::GPU) 00132 || (dev_constr==stemod::ANY_DEVICE) ) 00133 if(it->first<min_time) { 00134 min_time=it->first; 00135 } 00136 00137 #ifdef DUMP_ESTIMATIONS 00138 std::string path = "output/"; 00139 path+=op.getName()+"/"; 00140 path+=it->second+".estimations"; 00141 fstream file(path.c_str(),fstream::out | fstream::app); 00142 for(unsigned int i=0; i<input_values.size(); ++i) { 00143 file << input_values[i] << ","; 00144 } 00145 file << it->first << "," << it->second << endl; 00146 file.close(); 00147 #endif 00148 } 00149 00150 if(min_time==std::numeric_limits<double>::max()) { 00151 std::cout << "No suitable Algorithm found that fullfills specified contrained: " << std::endl; 00152 exit(0); 00153 } 00154 00155 #ifdef PROBABILITY_BASED_LOAD_ADAPTION 00156 //FEATURE: probability based load adaption (pick optimal algorithm in X% of all cases and pick another one in the other cases) %%%%%%%%%%%%%%%%%%%%%%%%%%% 00157 // if(rand()%5000==0){ 00158 // for(it=map_execution_times_to_algorithm_name.begin();it!=map_execution_times_to_algorithm_name.end();it++){ 00159 // if(!quiet && verbose) cout << "Algorithm: '" << it->second << "' Estimated Execution Time: " << it->first << endl; 00160 // cout << "Recoice: " << << endl; 00161 // if(!(it->first<min_time)){ 00162 // min_time=it->first; 00163 // } 00164 // } 00165 // } 00166 #endif 00167 // 00168 00169 std::string name_of_algorithm = map_execution_times_to_algorithm_name[min_time]; 00170 AlgorithmPtr pointer_to_choosen_algorithm=op.getAlgorithm(name_of_algorithm); 00171 assert(pointer_to_choosen_algorithm!=NULL); 00172 if(!quiet && verbose) cout << "Choosing " << name_of_algorithm << " for operation " << op.getName() << endl; 00173 return SchedulingDecision(*pointer_to_choosen_algorithm,EstimatedTime(min_time),input_values); 00174 */ 00175 } 00176 00177 }; //end namespace core 00178 }; //end namespace hype