diff --git a/llvm/projects/soc_simulator/src/driver.py b/llvm/projects/soc_simulator/src/driver.py index b685170da40c17dc45b7258cbbe2166ac52736fc..895a72d9e90f1a0559716944d598cb410e8d0d9b 100644 --- a/llvm/projects/soc_simulator/src/driver.py +++ b/llvm/projects/soc_simulator/src/driver.py @@ -3,62 +3,82 @@ import os import subprocess import sys -def build_nested_default_dict(): - return defaultdict(build_nested_default_dict) - -def is_conv(operation_name): - return operation_name.startswith("Conv") - -def is_nml(operation_name): - return operation_name.startswith("NML") - -def is_fc(operation_name): - return operation_name.startswith("FC") - -# NOTE: Use an OrderedDict if we want to search by operation name -# Using a list bc we care about the order the data is read in -# since it corresponds to the data in the configuration file -tensor_layers = [] -def parse_tensor_layer_file(layer_filename): - if not os.path.isfile(layer_filename): - print("ERROR: %s was not found." % layer_filename) - exit(1) - - layer_file = open(layer_filename, "r") - for line in layer_file: - layer_data = line.strip().split(',') - layer_name = layer_data[0] - - tensor_layer = defaultdict(str) - tensor_layer["Name"] = layer_name - - if is_conv(layer_name): - tensor_layer["N"] = float(layer_data[1]) - tensor_layer["Cin"] = float(layer_data[2]) - tensor_layer["H"] = float(layer_data[3]) - tensor_layer["W"] = float(layer_data[4]) - tensor_layer["Cout"] = float(layer_data[5]) - tensor_layer["Kh"] = float(layer_data[7]) - tensor_layer["Kw"] = float(layer_data[8]) - tensor_layer["Sh"] = float(layer_data[9]) - tensor_layer["Sw"] = float(layer_data[10]) - - elif is_fc(layer_name): - tensor_layer["RA"] = float(layer_data[1]) - tensor_layer["CA"] = float(layer_data[2]) - tensor_layer["RB"] = float(layer_data[3]) - tensor_layer["CB"] = float(layer_data[4]) - - elif not is_nml(layer_name): # TODO should we store data for NMLs? - print("ERROR: Invalid layer name %s" % layer_name) - exit(1) - - tensor_layers.append(tensor_layer) - layer_file.close() - +class Driver: + def driver(self): + self.parse_tensor_layer_file() + #self.parse_tensor_table() + #self.run_simulations() + #self.display_results() + + def __init__(self, layer_filename, table_filename, config_filename, results_filename): + self.__layer_filename = layer_filename + self.__table_filename = table_filename + self.__config_filename = config_filename + self.__results_filename = results_filename + + # NOTE: Use an OrderedDict if we want to search by operation name + # Using a list bc we care about the order the data is read in + # since it corresponds to the data in the configuration file + self.__tensor_layers = [] + + @staticmethod + def is_conv(operation_name): + return operation_name.startswith("Conv") + + @staticmethod + def is_nml(operation_name): + return operation_name.startswith("NML") + + @staticmethod + def is_fc(operation_name): + return operation_name.startswith("FC") + + def driver(self): + self.parse_tensor_layer_file() + #self.parse_tensor_table() + #self.run_simulations() + #self.display_results() + + def parse_tensor_layer_file(self): + if not os.path.isfile(self.__layer_filename): + print("ERROR: %s was not found." % self.__layer_filename) + exit(1) + + layer_file = open(self.__layer_filename, "r") + for line in layer_file: + layer_data = line.strip().split(',') + layer_name = layer_data[0] + + tensor_layer = defaultdict(str) + tensor_layer["Name"] = layer_name + + if Driver.is_conv(layer_name): + tensor_layer["N"] = float(layer_data[1]) + tensor_layer["Cin"] = float(layer_data[2]) + tensor_layer["H"] = float(layer_data[3]) + tensor_layer["W"] = float(layer_data[4]) + tensor_layer["Cout"] = float(layer_data[5]) + tensor_layer["Kh"] = float(layer_data[7]) + tensor_layer["Kw"] = float(layer_data[8]) + tensor_layer["Sh"] = float(layer_data[9]) + tensor_layer["Sw"] = float(layer_data[10]) + + elif Driver.is_fc(layer_name): + tensor_layer["RA"] = float(layer_data[1]) + tensor_layer["CA"] = float(layer_data[2]) + tensor_layer["RB"] = float(layer_data[3]) + tensor_layer["CB"] = float(layer_data[4]) + + elif not Driver.is_nml(layer_name): # TODO should we store data for NMLs? + print("ERROR: Invalid layer name %s" % layer_name) + exit(1) + + self.__tensor_layers.append(tensor_layer) + layer_file.close() + ''' # [layer_name][operation_name][cols] # Operation names need to be stored in order of insertion -tensor_table = defaultdict(lambda: list(defaultdict(str))) + tensor_table = defaultdict(lambda: list(defaultdict(str))) def parse_tensor_table(table_filename): if not os.path.isfile(table_filename): @@ -115,7 +135,7 @@ def get_approx_type(approx_type): return "fp32" return "promise" -def is_promise(config_layer): +def Driver.is_promise(config_layer): # TODO overhead in call to split? return float(config_layer.split(' ')[0]) < fp16_swing @@ -128,8 +148,8 @@ def quantize(curr_layer, prev_layer, h2f_f2h_operation_ind, layer_data): layer_name = layer_data["Name"] - # NOTE: Ignoring logic where curr == promise or prev == promise bc - # smartDMA is always true so we'd return near the beginning of the method + # NOTE: Ignoring logic where curr == promise or prev == promise bc + # smartDMA is always true so we'd return near the beginning of the method # Get h2f/f2h data using the first tensor operation in the layer # (which is why order matters in the tensor table) @@ -148,14 +168,14 @@ def run_promise_simulation(swing, layer_data): layer_name = layer_data["Name"] patch_factor = 1 - if is_conv(layer_name): + if Driver.is_conv(layer_name): rows_a = layer_data["N"] * layer_data["H"] * layer_data["W"] \ - / (layer_data["Sh"] * layer_data["Sw"]) + / (layer_data["Sh"] * layer_data["Sw"]) cols_a = layer_data["Cin"] * layer_data["Kh"] * layer_data["Kw"] rows_b = cols_a cols_b = layer_data["Cout"] patch_factor = layer_data["Kh"] * layer_data["Kw"] - elif is_fc(layer_name): + elif Driver.is_fc(layer_name): rows_a = layer_data["RA"] cols_a = layer_data["CA"] rows_b = cols_a @@ -164,8 +184,8 @@ def run_promise_simulation(swing, layer_data): print("PROMISE can't run whatever this layer is.") exit(1) #print("[%f x %f] x [%f x %f] : %f" % (rows_a, cols_a, rows_b, cols_b, swing)) - # Run promise simulator - # TODO need to print time and energy in the ptm runner so we can pipe it + # Run promise simulator + # TODO need to print time and energy in the ptm runner so we can pipe it output = subprocess.Popen(["./ptm", str(rows_a), str(cols_a), str(rows_b), \ str(cols_b), str(patch_factor), str(swing)], \ stdout = subprocess.PIPE, stderr = subprocess.PIPE).communicate()[0] @@ -215,7 +235,7 @@ def run_simulations(config_filename): layer_data = tensor_layers[layer_ind] # layer layer_name = layer_data["Name"] - if is_promise(config_layer): + if Driver.is_promise(config_layer): print("Running layer %s on PROMISE" % layer_name) curr_layer = ApproxTypes.PROMISE quant_time, quant_energy = quantize(curr_layer, prev_layer, 0, layer_data) @@ -282,12 +302,9 @@ def driver(tensor_layers_file, tensor_table_file, conf_file, output_file): parse_tensor_table(tensor_table_file) run_simulations(conf_file) display_results(output_file) - +''' if __name__ == "__main__": if len(sys.argv) != 5: print("Usage: python driver.py <layer info> <tensor info> <configurations> <results file>") exit(1) - test_layers_file = "/home/nvidia/Gitlab/hpvm/llvm/projects/hpvm-tensor-rt/build_mobilenet/mobilenet_layers.txt" - test_table_file = "/home/nvidia/Gitlab/hpvm/llvm/projects/hpvm-tensor-rt/build_pldi/mobilenet_results/mobilenet_tensors.txt" - test_conf_file = "/home/nvidia/Gitlab/hpvm/llvm/projects/hpvm-tensor-rt/build_mobilenet/mobilenet_conf2.txt" - driver(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4]) + Driver(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4]).driver()