Esempio n. 1
0
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;
	}
}
Esempio n. 2
0
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);
	}
}