From 80176cd79093ad7b649bdf3faf3ffb2dff1690b5 Mon Sep 17 00:00:00 2001 From: Elizabeth <hashim.sharif91@gmail.com> Date: Tue, 8 Oct 2019 16:33:27 -0500 Subject: [PATCH] Implemented table outputter function --- .../build_pldi/table_generator.py | 95 ++++++++++++++----- 1 file changed, 70 insertions(+), 25 deletions(-) diff --git a/llvm/projects/hpvm-tensor-rt/build_pldi/table_generator.py b/llvm/projects/hpvm-tensor-rt/build_pldi/table_generator.py index e944de7d37..71f88fed3e 100644 --- a/llvm/projects/hpvm-tensor-rt/build_pldi/table_generator.py +++ b/llvm/projects/hpvm-tensor-rt/build_pldi/table_generator.py @@ -79,13 +79,16 @@ class TableGenerator: return op_name[ : underscore_ind], op_name[underscore_ind + 1 : ] def generate_table(self): - table = self.__build_nested_default_dict() + self.__table = self.__build_nested_default_dict() + self.__build_internal_table() + self.__output_table() + + def __build_internal_table(self): for results_file_name in os.listdir(self.__results_dir_name): print(results_file_name, self.__network_name) - # Ignore if it's the output file or if it's not a results file - if results_file_name == table_filename or \ - not results_file_name.startswith(self.__network_name): + # Ignore if it's not a results file + if results_file_name.startswith(self.__network_name): continue approx_type = self.__get_approximation_type(results_file_name) @@ -103,39 +106,81 @@ class TableGenerator: orig_op_name, conversion_type = self.__get_original_operation_name(op_name) print("f2h/h2f", orig_op_name, conversion_type) # Error bc original op name should ALWAYS be in the table - if orig_op_name not in table: + if orig_op_name not in self.__table: print("ERROR: Conversion found but original %s is not in the table" % orig_op_name) exit(1) - table[orig_op_name][conversion_type]["time"] = total_time - table[orig_op_name][conversion_type]["energy"] = total_energy + self.__table[orig_op_name][conversion_type]["time"] = total_time + self.__table[orig_op_name][conversion_type]["energy"] = total_energy # Create a new row in the dictionary else: - table[op_name][approx_type]["time"] = total_time - table[op_name][approx_type]["energy"] = total_energy + self.__table[op_name][approx_type]["time"] = total_time + self.__table[op_name][approx_type]["energy"] = total_energy results_file.close() - # Then output everything + def __output_table(self): # Copy ops file to results directory to use as empty table table_filename = "%s_tensors.txt" % self.__network_name table_file_path = os.path.join(self.__results_dir_name, table_filename) # TODO un hard code this - soc_operations_file_name = os.path.join("/home/nvidia/soc_simulator", \ - "%s_cifar10" % self.__network_name, "%s_ops.txt" % self.__network_name) - #shutil.copyfile(soc_operations_file_name, table_file_path) - - # Output in the order of everything in the file - # Conv1,1 = leave the same - # Next line: Conv1 --> find it - # don't need to copy the file over --> can use the original file as a reference - soc_operations_file = open(soc_operations_file_name, "r") - table_file = open(table_filename, "w") - for line in soc_operations_file: - if line.startswith("#"): # TODO variable - table_file.write(line) # Copy to table file - # Then write the new header for - + soc_operations_file_name = os.path.join("/home/nvidia/soc_simulator", "%s_cifar10" % self.__network_name, "%s_ops.txt" % self.__network_name) + + # Don't need to copy the file over --> can use the original file as a reference + soc_operations_file = open(soc_operations_file_name, "r") + table_file = open(table_filename, "w") + + # Read header line to get layer name and # operations in layer + # Get ops in each layer using the dict + # TODO possible for operations in the same layer to not have the same # of cols? + # Need to store a list of all 2nd level dict keys we go through! + # at the very end --> then generate the header and write everything in + + curr_line = soc_operations_file.readline().strip() + + while curr_line: + # First line is always the layers line (#layer_name,num_ops) + layer_name, num_ops = self.__parse_layer_info_line(curr_line) + + # Get each operation in the layer + ops_in_layer = [] + header = [] + + for op_in_layer_count in range(num_ops): + # Each line consists of operation name + curr_line = soc_operations_file.readline().strip() + + curr_op = [curr_line] # Join into a string later + operation_data = self.__table[curr_line] + # Iterate through time/energy data for each approx type + for approx_type in operation_data: + curr_op.append(operation_data[approx_type]["time"]) + curr_op.append(operation_data[approx_type]["time"]) + + # CRITICAL ASSUMPTION: All ops within a layer have the same # cols + # Only fill out the header once for the layer + if op_in_layer_count == 0: + header.append(approx_type) + + ops_in_layer.append(' '.join(curr_op)) + # Getting all operation rows and then writing everything because + # calls to write() are slow (memory vs time tradeoff) + print("%s" % ' '.join(header)) + print("%s" % '\n'.join(ops_in_layer)) + table_file.write("%s\n" % ' '.join(header)) + table_file.write("%s\n" % '\n'.join(ops_in_layer)) + + curr_line = soc_operations_file.readline().strip() + + def __parse_layer_info_line(self, layer_info_line): #layer_name,num_ops + comma_ind = layer_info_line.find(",") + return layer_info_line[layer_info_line.find("#") : comma_ind], int(layer_info_line[comma_ind + 1 : ]) + + def __generate_header(self, table): + # <approx type time/energy> <conversion type at very end> + # should the header be per tensor op or per layer? + # Try doing this per layer first + pass binary_dir_name = "/home/nvidia/Gitlab/hpvm/llvm/projects/hpvm-tensor-rt/build_pldi/mobilenet" num_iters = 1 -- GitLab