notuning_wtuning.py 8.14 KB
import os, sys, argparse
import numpy
import matplotlib.pyplot as plt
import json
from pylab import *
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.patches import Rectangle
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from sets import Set

from common import *

def get_energy(frontiers_data, cpu_freq, mem_freq, sample):
	for point in frontiers_data["data"][sample]:
		if point["cpu_freq"] == cpu_freq:
			if point["mem_freq"] == mem_freq:
				return point["energy"]

def get_performance(frontiers_data, cpu_freq, mem_freq, sample):
	for point in frontiers_data["data"][sample]:
		if point["cpu_freq"] == cpu_freq:
			if point["mem_freq"] == mem_freq:
				return point["performance"]

def get_aggr_energy(frontiers_data, cpu_freq, mem_freq):
	for point in frontiers_data["data"]:
		if point["cpu_freq"] == cpu_freq:
			if point["mem_freq"] == mem_freq:
				return point["energy"]

def get_aggr_performance(frontiers_data, cpu_freq, mem_freq):
	for point in frontiers_data["data"]:
		if point["cpu_freq"] == cpu_freq:
			if point["mem_freq"] == mem_freq:
				return point["performance"]

def get_no_tuning_energy_performance(args, budget, bmark):
	dir_path = args.input_dir

	# finding points with 3% threshold of target budget/inefficiency
	thresh = 3

	bmarkDirPath = os.path.join(os.path.join(dir_path, "aggr_data"), bmark)
	frontiers_file = os.path.join(bmarkDirPath, "frontiers.json")
	frontiers_data = json.loads(open(frontiers_file).read())

	filtered_data=[]
	for point in frontiers_data["data"]:
		#filtering all those points which have inefficiency with error% of the budget
		if point["inefficiency"] <= budget:
			filtered_data.append(point)
		elif (point["inefficiency"] - budget) * 100 / budget <= thresh:
			filtered_data.append(point)

		#finding the point with highest performance among filtered data
	optimal_point = filtered_data[0]
	for point in filtered_data:
		if point["speedup"] > optimal_point["speedup"]:
			optimal_point = point

	energy = get_aggr_energy(frontiers_data, optimal_point["cpu_freq"], optimal_point["mem_freq"])
	performance = get_aggr_performance(frontiers_data, optimal_point["cpu_freq"], optimal_point["mem_freq"])
	energy = energy/1e6
	performance = performance/1e6 

	return (optimal_point, energy, performance)

def energy_time(args, budget_list, cluster_thresh, perf_cost, energy_cost):
	dir_path = args.input_dir
	output_dir_path = args.output_dir

	benchmarks, labels = get_benchmarks(args)
#	benchmarks =['gobmk']
	#plot constants
	cpuflist = get_cpu_freq_plot_list(args)
	memflist = get_mem_freq_plot_list(args)

	# finding points with 3% threshold of target budget/inefficiency
	thresh = 3
	energy_data = [ [] for thresh in budget_list]
	performance_data = [ [] for thresh in budget_list]
	for bmark in benchmarks:
		data = []
		for budget_index, budget in enumerate(budget_list):
			print "Inefficiency Budget: "+str(budget)+" Benchmark: "+bmark
			
			aggr_opt_point, energy_notuning, performance_notuning = get_no_tuning_energy_performance(args, budget, bmark)
			print "no.tuning: performance (ms): "+str(performance_notuning)+" energy(mJ): "+str(energy_notuning)

			bmarkDirPath = os.path.join(os.path.join(dir_path, "per_sample_data"), bmark)
			frontiers_file = os.path.join(bmarkDirPath, "per_sample_frontiers.json")
			frontiers_data = json.loads(open(frontiers_file).read())

			data_to_plot=[]
			sample_points=[]
			cpu_rectangle_points=[]
			for data in frontiers_data["data"]:
				filtered_data=[]
				#filtering all those points which have inefficiency with error% of the budget
				for point in data:
					if point["inefficiency"] <= budget:
						filtered_data.append(point)
					elif (point["inefficiency"] - budget) * 100 / budget <= thresh:
						filtered_data.append(point)

				#finding the point with highest performance among filtered data
				optimal_point = filtered_data[0]
				for point in filtered_data:
					if point["speedup"] > optimal_point["speedup"]:
						optimal_point = point

				local_rect_points=[]
				for point in filtered_data:
					if (optimal_point["speedup"] - point["speedup"]) < 0:
						print "something is wrong!"

					if (optimal_point["speedup"] - point["speedup"]) * 100 / optimal_point["speedup"] <= cluster_thresh:
						data_to_plot.append(point)
						sample_points.append(frontiers_data["data"].index(data))
						local_rect_points.append(point)

			cpufpoints = [cpuf for cpuf in [data_to_plot[sample]["cpu_freq"] for sample in range(len(data_to_plot))]]
			memfpoints = [memf for memf in [data_to_plot[sample]["mem_freq"] for sample in range(len(data_to_plot))]]
			samplepoints = sample_points

			#print cpufpoints
			#print memfpoints
			#print samplepoints
			#Total number of transitions
			num_transitions = 0.0
			#Available settings for (CPU, MEM)
			settings_available = Set()
			index = 0
			current_sample = -1
			length = 1
			lengths = []
			prev_tr_sample = 0
			energy = 0
			performance = 0
			aggr_energy = 0
			aggr_performance = 0
			idx = 0
			while index < len( samplepoints ):
				current_sample = samplepoints[index]

				#Construct the current settings
				current_settings = Set()
				while index < len( samplepoints ) and samplepoints[index] == current_sample:
					current_settings.add((cpufpoints[index],memfpoints[index]))
					index = index + 1

				#Compute the common points between current and what is available
				common_points  = current_settings.intersection(settings_available)

				if (len(common_points) == 0 or index == len( samplepoints )):
				# find the point with highest cpu and mem freq
					if (current_sample !=0 ):
						optimal_point = settings_available.pop()
						settings_available.add(optimal_point)
						for point in settings_available:
							if point[0] > optimal_point[0]:
								optimal_point = point
							elif point[0] == optimal_point[0]:
								if point[1] > optimal_point[1]:
									optimal_point = point
						done = 0
						while done == 0 or idx == len(samplepoints) -1:
							energy += get_energy(frontiers_data,optimal_point[0], optimal_point[1], idx)
							performance += get_performance(frontiers_data,optimal_point[0], optimal_point[1], idx)
							aggr_energy += get_energy(frontiers_data, aggr_opt_point["cpu_freq"], aggr_opt_point["mem_freq"], idx)
							aggr_performance += get_performance(frontiers_data,	aggr_opt_point["cpu_freq"], aggr_opt_point["mem_freq"], idx)
							if aggr_energy < energy:
								print "unexpected!"
					#		print "("+str(optimal_point[0])+", "+str(optimal_point[1])+", "+str(energy)+", "+str(performance)+")  "+"("+str(aggr_opt_point["cpu_freq"])+", "+str(aggr_opt_point["mem_freq"])+", "+str(aggr_energy)+", "+str(aggr_performance)+")  "
							if idx == samplepoints[index-2]:
								done = 1
							idx += 1

						prev_tr_sample = samplepoints[index-2]

				# When there are no common points, transition
				if (len(common_points) == 0):
					settings_available = current_settings #all current settings are now available
					#Ignore the transition if it's the first sample
					if (current_sample!=0):
						num_transitions += 1
				else: # Continue with the common points
					settings_available = common_points

				# Record the length if we need to transition or we are at the end
				if (len(common_points) == 0 or index == len( samplepoints )):
					#Ignore the length if the transition is for the first sample
					if (current_sample!=0):
						lengths.append(length)
					#reset the length
					length = 1
				else: #otherwise, just increment the length
					length += 1

			energy = (energy + (num_transitions * energy_cost))/1e6
			performance = (performance +(num_transitions * perf_cost))/1e6 
			energy_data[budget_index].append(energy)
			performance_data[budget_index].append(performance)
			aggr_energy = (aggr_energy + (num_transitions * energy_cost))/1e6
			aggr_performance = (aggr_performance +(num_transitions * perf_cost))/1e6 
			print "no.tuning(cum): performance (ms): "+str(aggr_performance)+"energy(mJ): "+str(aggr_energy)
			print "w.tuning: performance (ms): "+str(performance)+" energy(mJ): "+str(energy) +"\n"

def main(argv):
	args = parse(argv)

	for thresh in [0.0]:
		energy_time(args, [1.0], thresh, 0, 0)
#		energy_time(args, [1.0,1.1, 1.2, 1.3,1.6,3.0], thresh, 0, 0)

if __name__ == "__main__":
	main(sys.argv)