#! /usr/bin/env python
# -*- coding: utf-8 -*-

import sys
from re import search
import datetime
from os.path import basename

"""
This script generates a graph that represents the overhead
involved in synchronisation operations
"""

usage="""
	This generates an output file for each value of number-of-threads that give the number of all runs.
	As an input it expects a result file which is generated by the overhead_result_calc.py script.
	The file extension of the result file has to be ".meas".
	It is expected that the output directory's path is meaningful, such as machine-name, date, and so on
	Usage:
		%s [result files] [path to output dir]
""" % sys.argv[0]

if len(sys.argv) < 3:
	print usage
	sys.exit(0)

result_filenames = sys.argv[1:-1]
output_dir_path = sys.argv[-1]

for result_filename in result_filenames:
	#open input file
	try:
		result_file = open(result_filename,"r")
	except:
		print "Cannot open result file %s" % result_filename
		sys.exit(1)
	
	#parse(evaluate) result file
	try:
		exec(result_file.read())
	except:
		print "Cannot parse result file: %s" % result_filename
		result_file.close()
		sys.exit(1)
	result_file.close()
	
	#check for file extension
	result_filename = basename(result_filename)
	if search("\.meas$",result_filename) == None:
		print "Wrong file extension! Has to be '.meas'"
		sys.exit(1)
	
	output = output_dir_path + "/" + result_filename.replace(".meas",".result")
	#open gnuplot output
	try:
		gnuplot_output = open(output,"w")
	except IOError:
		print "Cannot open output file %s" % output
		result_file.close()
		sys.exit(1)

	table_header = "# %20s\t%20s\t%20s\t%20s\t%20s\t%20s\t%20s\t%20s\n" % (
							 "<iters per task>",
							 "<total exe cycles>",
							 "<total work cyc>",
							 "<one task cyc>",
							 "<total overhead cyc>",
							 "<num syncs>",
							 "<overhead per Sync cyc>",
							 "<Exe/Work ratio>")

	#write header to file
	gnuplot_output.writelines(["# Output file name: %s\n" % data_filename,
							"# Date of Run: %s\n" % date_of_run,
							"# Number of Cores: %d\n" % NUM_CORES,
							"# Number of Threads: %f per Core, %d total\n" % (threads_per_core, totalThreads),
							table_header,
							"# " + (len(table_header)-3)*"-" + "\n"])

	#Now print the results out
	for workload_iterations_in_task in ITERS_PER_TASK_TABLE:
		results = array_of_results[workload_iterations_in_task]

		#take shortest run
		results.sort(lambda x,y: cmp(x["total_exe_cycles"],y["total_exe_cycles"]))
		total_workcycles = results[0]["total_workcycles"]
		total_exe_cycles  = results[0]["total_exe_cycles"]
		#exeCycles_workCycles_ratio = results[0]["exeCycles_workCycles_ratio"]

		#Calculate numbers
		overhead             = total_exe_cycles - total_workcycles
		total_syncs          = totalThreads * TASKS_PER_THREAD * 2
		overhead_per_sync    = float(overhead) / float(total_syncs)
		cycles_of_task       = float(total_workcycles) / float(TASKS_PER_THREAD * totalThreads)
		overhead_per_core    = float(overhead) / NUM_CORES
		workcycles_per_core  = total_workcycles / NUM_CORES
	
		# The 2 is in there because we have two sync operations in one per outer iteration
		exeCycles_workCycles_ratio = float(total_workcycles+float(overhead)/2)/float(total_workcycles)

		gnuplot_output.write("%20d\t%20d\t%20d\t%20f\t%20d\t%20d\t%20f\t%20f\n" % (
						  workload_iterations_in_task,
						  total_exe_cycles,
						  total_workcycles,
						  cycles_of_task,
						  overhead,
						  total_syncs,
						  overhead_per_sync,
						  exeCycles_workCycles_ratio))

	gnuplot_output.close();
