int main (int argc, char** argv) { FloorPlanner fp; samples_data_type temp_samples; samples_data_type power_samples; double avg_power, avg_temp; double std_dev_power, std_dev_temp; double cur_power_dev, cur_temp_dev; double cov; double corr; double avg_corr; int count_corr; // construct a trivial random generator engine from a time-based seed: unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); std::default_random_engine random_generator(seed); std::cout << std::endl; std::cout << "Thermal Side-Channel Leakage Verification: Determine Entropy and Correlation of Power and Thermal Maps" << std::endl; std::cout << "------------------------------------------------------------------------------------------------------" << std::endl; std::cout << "WARNING: File handling implicitly assumes that the dimensions of power and thermal maps are all the same, both within HotSpot and Corblivar; parsing and calculation will most likely fail if there are dimension mismatches!" << std:: endl; std::cout << std::endl; // parse program parameter, config file, and further files IO::parseParametersFiles(fp, argc, argv); // parse blocks IO::parseBlocks(fp); // parse nets IO::parseNets(fp); // generate DAG (directed acyclic graph) for SL-STA (system-level static timing analysis) fp.initTimingPowerAnalyser(); // init Corblivar core CorblivarCore corb = CorblivarCore(fp.getLayers(), fp.getBlocks().size()); // parse alignment request IO::parseAlignmentRequests(fp, corb.editAlignments()); // init thermal analyzer, only reasonable after parsing config file fp.initThermalAnalyzer(); // init routing-utilization analyzer fp.initRoutingUtilAnalyzer(); // no solution file found; error if (!fp.inputSolutionFileOpen()) { std::cout << "Corblivar> "; std::cout << "ERROR: Solution file required for call of " << argv[0] << std::endl << std::endl; exit(1); } // required solution file found; parse from file, and generate layout and all data such as power and thermal maps // // read from file IO::parseCorblivarFile(fp, corb); // assume read in data as currently best solution corb.storeBestCBLs(); // overall cost is not determined; cost cannot be determined since no // normalization during SA search was performed // // generates also all required files fp.finalize(corb, false); std::cout << std::endl; // allocate vectors for (int layer = 0; layer < fp.getLayers(); layer++) { power_samples.emplace_back(samples_data_layer_type()); temp_samples.emplace_back(samples_data_layer_type()); } // generate power data and gather related HotSpot simulation temperature data // for (unsigned sampling_iter = 0; sampling_iter < SAMPLING_ITERATIONS; sampling_iter++) { std::cout << std::endl; std::cout << "Sampling iteration: " << (sampling_iter + 1) << "/" << SAMPLING_ITERATIONS << std::endl; std::cout << "------------------------------" << std::endl; // first, randomly vary power densities in blocks // for (Block const& b : fp.getBlocks()) { // restore original value, used as mean for Gaussian distribution of power densities b.power_density_unscaled = b.power_density_unscaled_back; // calculate new power value, based on Gaussian distribution std::normal_distribution<double> gaussian(b.power_density_unscaled, b.power_density_unscaled * MEAN_TO_STD_DEV_FACTOR); b.power_density_unscaled = gaussian(random_generator); if (DBG) { std::cout << "Block " << b.id << ":" << std::endl; std::cout << " Original power = " << b.power_density_unscaled_back << std::endl; std::cout << " New random power = " << b.power_density_unscaled << std::endl; } } // second, generate new power maps // fp.editThermalAnalyzer().generatePowerMaps(fp.getLayers(), fp.getBlocks(), fp.getOutline(), fp.getPowerBlurringParameters()); // copy data from Corblivar power maps into local data structure power_samples // for (int layer = 0; layer < fp.getLayers(); layer++) { for (unsigned x = 0; x < ThermalAnalyzer::THERMAL_MAP_DIM; x++) { for (unsigned y = 0; y < ThermalAnalyzer::THERMAL_MAP_DIM; y++) { power_samples[layer][x][y][sampling_iter] = fp.getThermalAnalyzer().getPowerMapsOrig()[layer][x][y].power_density; } } } // third, run HotSpot on this new map // // generate new ptrace file first writeHotSpotPtrace(fp); // HotSpot.sh system call system(std::string("./HotSpot.sh " + fp.getBenchmark() + " " + std::to_string(fp.getLayers())).c_str()); // fourth, read in the new HotSpot results into local data structure temp_samples // parseHotSpotFiles(fp, sampling_iter, temp_samples); if (DBG) { std::cout << "Printing gathered power/temperature data for sampling iteration " << sampling_iter << std::endl; std::cout << std::endl; for (int layer = 0; layer < fp.getLayers(); layer++) { std::cout << " Layer " << layer << std::endl; std::cout << std::endl; for (unsigned x = 0; x < ThermalAnalyzer::THERMAL_MAP_DIM; x++) { for (unsigned y = 0; y < ThermalAnalyzer::THERMAL_MAP_DIM; y++) { std::cout << " Power[" << x << "][" << y << "]: " << power_samples[layer][x][y][sampling_iter] << std::endl; std::cout << " Temp [" << x << "][" << y << "]: " << temp_samples[layer][x][y][sampling_iter] << std::endl; } } } } } // calculate avg Pearson correlation over all bins // std::cout << std::endl; std::cout << "Sampling results" << std::endl; std::cout << "----------------" << std::endl; for (int layer = 0; layer < fp.getLayers(); layer++) { // dbg output if (DBG) { std::cout << std::endl; std::cout << "Pearson correlations on layer " << layer << std::endl; std::cout << std::endl; } avg_corr = 0.0; count_corr = 0; for (unsigned x = 0; x < ThermalAnalyzer::THERMAL_MAP_DIM; x++) { for (unsigned y = 0; y < ThermalAnalyzer::THERMAL_MAP_DIM; y++) { avg_power = avg_temp = 0.0; cov = std_dev_power = std_dev_temp = 0.0; corr = 0.0; // first pass: determine avg values // for (unsigned sampling_iter = 0; sampling_iter < SAMPLING_ITERATIONS; sampling_iter++) { avg_power += power_samples[layer][x][y][sampling_iter]; avg_temp += temp_samples[layer][x][y][sampling_iter]; } avg_power /= SAMPLING_ITERATIONS; avg_temp /= SAMPLING_ITERATIONS; // dbg output if (DBG) { std::cout << "Bin: " << x << ", " << y << std::endl; std::cout << " Avg power: " << avg_power << std::endl; std::cout << " Avg temp: " << avg_temp << std::endl; } // second pass: determine covariance and standard deviations // for (unsigned sampling_iter = 0; sampling_iter < SAMPLING_ITERATIONS; sampling_iter++) { // deviations of current values from avg values cur_power_dev = power_samples[layer][x][y][sampling_iter] - avg_power; cur_temp_dev = temp_samples[layer][x][y][sampling_iter] - avg_temp; // covariance cov += cur_power_dev * cur_temp_dev; // standard deviation, calculate its sqrt later on std_dev_power += std::pow(cur_power_dev, 2.0); std_dev_temp += std::pow(cur_temp_dev, 2.0); } cov /= SAMPLING_ITERATIONS; std_dev_power /= SAMPLING_ITERATIONS; std_dev_temp /= SAMPLING_ITERATIONS; std_dev_power = std::sqrt(std_dev_power); std_dev_temp = std::sqrt(std_dev_temp); // calculate Pearson correlation: covariance over product of standard deviations // corr = cov / (std_dev_power * std_dev_temp); // consider only valid correlations values if (!std::isnan(corr)) { avg_corr += corr; count_corr++; } // dbg output if (DBG) { std::cout << " Correlation: " << corr << std::endl; if (std::isnan(corr)) { std::cout << " NAN, because of zero power; to be skipped" << std::endl; } } } } avg_corr /= count_corr; std::cout << "Avg Pearson correlations over all bins on layer " << layer << ": " << avg_corr << std::endl; } }
int main (int argc, char** argv) { FloorPlanner fp; bool done; cout << endl; cout << "Corblivar: Corner Block List for Varied [Block] Alignment Requests" << endl; cout << "----- 3D floorplanning tool v 1.1.1 ------------------------------" << endl << endl; // set IO mode IO::mode = IO::Mode::REGULAR; // parse program parameter, config file, and further files IO::parseParametersFiles(fp, argc, argv); // parse blocks IO::parseBlocks(fp); // parse nets IO::parseNets(fp); // init Corblivar core CorblivarCore corb = CorblivarCore(fp.getLayers(), fp.getBlocks().size()); // parse alignment request IO::parseAlignmentRequests(fp, corb.editAlignments()); // init thermal analyzer, only reasonable after parsing config file fp.initThermalAnalyzer(); // non-regular run; read in solution file // (TODO) adapt if further optimization of read in data is desired if (fp.inputSolutionFileOpen()) { if (fp.logMin()) { cout << "Corblivar> "; cout << "Handling given solution file ..." << endl << endl; } // read from file IO::parseCorblivarFile(fp, corb); // assume read in data as currently best solution corb.storeBestCBLs(); // overall cost is not determined; cost cannot be determined since no // normalization during SA search was performed fp.finalize(corb, false); } // regular run; perform floorplanning else { // generate new, random data set corb.initCorblivarRandomly(fp.logMed(), fp.getLayers(), fp.getBlocks(), fp.powerAwareBlockHandling()); if (fp.logMin()) { cout << "Corblivar> "; cout << "Performing SA floorplanning optimization ..." << endl << endl; } // perform SA; main handler done = fp.performSA(corb); if (fp.logMin()) { cout << "Corblivar> "; if (done) { cout << "Done, floorplanning was successful" << endl << endl; } else { cout << "Done, floorplanning was _not_ successful" << endl << endl; } } // finalize: generate output files, final logging fp.finalize(corb); } }