diff --git a/hpvm/projects/hpvm-tensor-rt/tensor_runtime/src/hpvm-rt-controller.cpp b/hpvm/projects/hpvm-tensor-rt/tensor_runtime/src/hpvm-rt-controller.cpp index bea66370ba073490fe7970014f1005f123e58988..038924a9494041318fe5bb52adbcf591e0d04608 100644 --- a/hpvm/projects/hpvm-tensor-rt/tensor_runtime/src/hpvm-rt-controller.cpp +++ b/hpvm/projects/hpvm-tensor-rt/tensor_runtime/src/hpvm-rt-controller.cpp @@ -3,25 +3,28 @@ // //===----------------------------------------------------------------------===// // -// This file contains code for that allows the tensor runtime to adapt -// in response to external changes in conditions (such as frequency changes) -// by helping to choose correct approximation configurations. It also provides -// routines for the rest of the runtime to get performance and energy profiling. +// This file contains code for HPVM Dynamic Approximation Control. +// +// The runtime controller: +// * Reads in the configuration file passed to the HPVM binary +// * Contructs a Pareto Curve +// * Based on the selected Mode it switches configurations at runtime +// +// Author: Maria Kotsifakou // //===----------------------------------------------------------------------===// + +#define llvm_hpvm_invokeRtControl_BASE llvm_hpvm_invokeRtControl +//#define llvm_hpvm_invokeRtControl_ADJUST_PR llvm_hpvm_invokeRtControl +//#define llvm_hpvm_invokeRtControl_ITERATE llvm_hpvm_invokeRtControl + + + #include "hpvm-rt-controller.h" #include "global_data.h" #include <fstream> -//-------- Functionality to read and update frequency on Jetson board -------// -/*const char* available_freqs[] = {"140250000", "229500000", "318750000", - "408000000", "497250000", "586500000", - "675750000", "765000000", "854250000", - "943500000", "1032750000", "1122000000", - "1211250000", "1300500000"}; - -*/ const int available_freqs[] = { 140250000, // 0 @@ -40,52 +43,6 @@ const int available_freqs[] = { 1300500000 // 13 }; -/*void updateJetsonGPUFreq(int freq_level) { - - if (freq_level < 0 || freq_level > 13) { - printf("ERROR: Provide freq level between {0, 13} \n\n\n"); - abort(); - } - - const char* freq_val = available_freqs[freq_level]; - printf("freq-val[0] = %s \n", freq_val); - - FILE* max_file = - fopen("/sys/devices/17000000.gp10b/devfreq/17000000.gp10b/max_freq", "w+"); - if (max_file == NULL) { - printf("Could not min_freq file \n"); - } - fwrite(freq_val, strlen(freq_val), 1, max_file); - fclose(max_file); - - FILE* min_file = - fopen("/sys/devices/17000000.gp10b/devfreq/17000000.gp10b/min_freq", "w+"); - if (min_file == NULL){ - printf("Could not min_freq file \n"); - abort(); - } - fwrite(freq_val, strlen(freq_val), 1, min_file); - fclose(min_file); -} - -unsigned long int readJetsonGPUFreq() { - FILE* cur_freq_file = - fopen("/sys/devices/17000000.gp10b/devfreq/17000000.gp10b/cur_freq", "r"); -// fopen("/sys/devices/17000000.gp10b/devfreq/17000000.gp10b/min_freq", "r"); - if (cur_freq_file == NULL) { - printf("Could not open cur_freq file \n"); - } - - char buf[50]; - char* ptr; - - fread(buf, 50, 1, cur_freq_file); - unsigned long cur_freq = strtoul(buf, &ptr, 10); - fclose(cur_freq_file); - return cur_freq; -} - -*/ // Sets frequency void setFreq(unsigned freq_index) { @@ -346,8 +303,8 @@ ProfileInfo::ProfileInfo() in_iteration(false) {} Slowdowns::Slowdowns() { - idx = 0; + idx = 0; std::ifstream s_in("slowdowns.txt"); if (!s_in) { DEBUG("slowdowns file not found. Initializing slowdowns randomly.\n"); @@ -446,12 +403,8 @@ void RuntimeController::init(const char *Cstr) { // compute3DParetoConfigurationPoints(); Not using 3D curve INFO("Speedup Configurations\n"); printConfigurations(SpeedupConfigurations); - // INFO("Energy Configurations\n"); - // printConfigurations(EnergyConfigurations); - // INFO("3D Configurations\n"); - // printConfigurations(ThreeDCurveConfigurations); - configurationIdx = - 0; // TODO: initialize using pareto curve - findTargetConfiguration ? + + configurationIdx = 0; Configurations = &SpeedupConfigurations; // Initializations for different runtime control strategies @@ -461,10 +414,8 @@ void RuntimeController::init(const char *Cstr) { // Pseudo random variable (when we did few experiments) // or true random numbers for probabilistic control pseudo_rd = 0.0; - std::random_device - rd; // Will be used to obtain a seed for the random number engine - generator = - std::mt19937(rd()); // Standard mersenne_twister_engine seeded with rd() + std::random_device rd; // Will be used to obtain a seed for the random number engine + generator = std::mt19937(rd()); // Standard mersenne_twister_engine seeded with rd() distr = std::uniform_real_distribution<>(0.0, 1.0); g_freq = available_freqs[13]; @@ -575,6 +526,7 @@ std::pair<double, double> RuntimeController::fc_profile( const unsigned num_rows_a, const unsigned num_cols_a, const unsigned num_rows_b, const unsigned num_cols_b, const unsigned voltage_swing, const unsigned patch_factor) { + return (promise ? promise->fc_profile(num_rows_a, num_cols_a, num_rows_b, num_cols_b, voltage_swing, patch_factor) : std::make_pair(0.0, 0.0)); @@ -585,6 +537,7 @@ std::pair<double, double> RuntimeController::conv_profile( const unsigned c_out, const unsigned c_in, const unsigned k_h, const unsigned k_w, const unsigned s_h, const unsigned s_w, const unsigned voltage_swing, const unsigned patch_factor) { + return (promise ? promise->conv_profile(n, c, h, w, c_out, c_in, k_h, k_w, s_h, s_w, voltage_swing, patch_factor) : std::make_pair(0.0, 0.0)); @@ -595,6 +548,7 @@ RuntimeController::RuntimeController() { configurationIdx = 0; FIL = new FrequencyIndexList({13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}, 10); + #ifdef ACTIVE_PROFILING PI = new ProfileInfo(); profiler = new Profiler(); @@ -1052,20 +1006,7 @@ void RuntimeController::computeParetoConfigurationPoints() { start_idx = end_idx; } - // All elements in InitialConfigurations whose index is in Indices are no - // longer needed. - // for (std::vector<unsigned>::iterator idx_it = Indices.begin(), idx_e = - // Indices.end(); - // idx_it != idx_e; ++idx_it) { - // std::map<std::string, NodeConfiguration * > ConfSetup = - // InitialConfigurations[*idx_it].setup; - // for (std::map<std::string, NodeConfiguration* >::const_iterator it = - // ConfSetup.begin(); - // it != ConfSetup.end(); ++it) { - // delete it->second; - // } - // } - // InitialConfigurations.clear(); + } void RuntimeController::compute3DParetoConfigurationPoints() { @@ -1196,24 +1137,24 @@ void RuntimeController::findTargetConfiguration(float goal, // Assigning one of Pareto configs to 'Configurations' class attribute Configurations = &SpeedupConfigurations; low_it = - std::lower_bound(Configurations->begin(), Configurations->end() - 1, - goal, ConfigurationLessThan_SP()); + std::lower_bound(Configurations->begin(), Configurations->end() - 1, + goal, ConfigurationLessThan_SP()); configurationIdx = low_it - Configurations->begin(); break; } case ENERGY: { Configurations = &EnergyConfigurations; low_it = - std::lower_bound(Configurations->begin(), Configurations->end() - 1, - goal, ConfigurationLessThan_E()); + std::lower_bound(Configurations->begin(), Configurations->end() - 1, + goal, ConfigurationLessThan_E()); configurationIdx = low_it - Configurations->begin(); break; } case ACCURACY_LOSS: { Configurations = &SpeedupConfigurations; low_it = - std::lower_bound(Configurations->begin(), Configurations->end() - 1, - goal, ConfigurationLessThan_AL()); + std::lower_bound(Configurations->begin(), Configurations->end() - 1, + goal, ConfigurationLessThan_AL()); if ((*low_it)->accuracyLoss > goal) --low_it; configurationIdx = low_it - Configurations->begin(); @@ -1373,13 +1314,6 @@ uint32_t *hpvm_rt_readLabelsBatch_cached(const char *labels_file, int start, fclose(file); } - // int num_labels = end - start; - // uint32_t* labels = (uint32_t*) malloc(sizeof(uint32_t) * num_labels); - // for (unsigned i = start; i < end; i++) { - // labels[i-start] = labels_from_file[i]; - // } - // return labels; - // Return pointer to labels return &labels_from_file[start]; } @@ -1536,7 +1470,6 @@ extern "C" void llvm_hpvm_invokeRtControl_ADJUST(void *result, const char *str, RC->reset_profiler(); RC->addToCurrentIterationConfigTime(pinfo2.first); RC->addToCurrentIterationConfigEnergy(pinfo2.second); - //* */ INFO("current iteration time = %f, current iteration energy = %f\n", current_iteration_time, current_iteration_energy); @@ -1547,7 +1480,8 @@ extern "C" void llvm_hpvm_invokeRtControl_ADJUST(void *result, const char *str, } extern "C" void llvm_hpvm_invokeRtControl_ADJUST_PR(void *result, - const char *str, int start, + const char *str, + int start, int end) { uint32_t *labels_cached = hpvm_rt_readLabelsBatch_cached(str, start, end); @@ -1590,8 +1524,7 @@ extern "C" void llvm_hpvm_invokeRtControl_ADJUST_PR(void *result, RC->reset_profiler(); RC->addToCurrentIterationConfigTime(pinfo2.first); RC->addToCurrentIterationConfigEnergy(pinfo2.second); - //* */ - + INFO("current iteration time = %f, current iteration energy = %f\n", current_iteration_time, current_iteration_energy); INFO("target speedup = %lf\n\n", target_speedup); @@ -1709,6 +1642,7 @@ extern "C" void llvm_hpvm_invokeRtControl_RAND(void *result, const char *str, template <typename T> static void writeVectorToFile(const char *path, const std::vector<T> &vec) { + std::ofstream of(path, std::ofstream::out | std::ofstream::app); if (!of.good()) ERROR("Cannot write to %s file", path);