def load(err_path): make_sure_path_exists(err_path) file_path = os.path.join(err_path, "error.dat") if not os.path.isfile(file_path): raise ValueError("No file!") err_list = [] with open(file_path, 'r') as f: for line in f.readlines(): el = line.split() err_list.append({'N': float(el[0]), 'rho': float(el[1]), 'energy': float(el[2]), 'u': float(el[3])}) return err_list
def create_ref(engineOptionDict, icond_path, input_path, ref_path): ''' test = dict() test['nSDD'] = (1, 1) test['nSDS'] = 1 test['SDSgeom'] = 'line' test['nThreads'] = 1 nCoresPerSDD = 1 ''' # Get case path, where to find the data to build the case. if os.path.isdir(ref_path): return print("Reference case does not exist, create it.") # Build case. print(COLOR_BLUE + "Building reference case data" + COLOR_ENDC) qty_name_list = build_case(icond_path, input_path) # Split case for SDDs print(COLOR_BLUE + "Splitting case data 1x1" + COLOR_ENDC) split_path = sdd.split_case(input_path, 1, 1, qty_name_list) # Add exec options io.write_exec_options(split_path, 1, 1, 1, 1, 'line', 1, 0, 1) # Copying exec_options and scheme_info in input path too copyfile(os.path.join(input_path, 'scheme_info.dat'), os.path.join(split_path, 'scheme_info.dat')) # Building output paths (the engine cannot create them itself) rmtree(ref_path, ignore_errors=True) copytree(split_path, ref_path) # To get the same SDD directories. # Compile (if needed) engine and call it print(COLOR_BLUE + "Compiling engine" + COLOR_ENDC) engine = Engine(engineOptionDict) print(COLOR_BLUE + "Calling engine" + COLOR_ENDC) engine.run(split_path, ref_path, 1, 1, 1) # Merge back io.make_sure_path_exists(ref_path) print(COLOR_BLUE + "Merging final data for reference" + COLOR_ENDC) sdd.merge_domain(ref_path, ref_path) for q_str in qty_name_list: sdd.merge_quantity(ref_path, ref_path, q_str) rmtree(os.path.join(ref_path, "sdd0"), ignore_errors=True)
def split_case(domain_dir, nSDD_X, nSDD_Y, qty_name_list): output_dir = os.path.join(domain_dir, str(nSDD_X) + "x" + str(nSDD_Y)) if os.path.isdir(output_dir): print("Split already exists") return output_dir io.make_sure_path_exists(output_dir) start = timer() sdd_to_coords = split_domain(domain_dir, output_dir, nSDD_X, nSDD_Y) end = timer() print("Time to split domain %s second(s)" % int((end - start))) split_bc(domain_dir, output_dir) for q_str in qty_name_list: start = timer() split_quantity(domain_dir, output_dir, q_str, sdd_to_coords) end = timer() print("Time to split quantity", q_str, "%s second(s)" % int( (end - start))) return output_dir
def merge_domain(split_dir, output_dir): domain_shortinfo = open(os.path.join(split_dir, "domain.info"), 'r') line_domain = domain_shortinfo.readline() line_split = line_domain.split() domain_shortinfo.close() io.make_sure_path_exists(output_dir) domain_f = open(os.path.join(output_dir, "domain.dat"), 'w+') domain_f.write("2D cartesian ") domain_f.write(" ".join([st for st in line_split[:4]]) + "\n") nSDD_X = int(line_split[4]) nSDD_Y = int(line_split[5]) for x in range(nSDD_X): for y in range(nSDD_Y): # Writing SDD file SDDid = y * nSDD_X + x SDDpath = os.path.join(split_dir, 'sdd' + str(SDDid)) with open(os.path.join(SDDpath, 'sdd.dat'), 'r') as file_stream: line_split = file_stream.readline().split() BL_X = int(line_split[0]) BL_Y = int(line_split[1]) line_split = file_stream.readline().split() SDD_Nx = int(line_split[0]) SDD_Ny = int(line_split[1]) for i in range(SDD_Nx): for j in range(SDD_Ny): line_split = file_stream.readline().split() uid = line_split[0] coordX_SDD = int(line_split[1]) coordY_SDD = int(line_split[2]) domain_f.write(uid + " " + str(BL_X + coordX_SDD) + " " + str(BL_Y + coordY_SDD) + "\n") domain_f.close()
def build_case(case_path, output_dir, force_build=False): ''' Build all physical/numerical data from case ''' # If the directory does not exist, then build: if not os.path.isdir(output_dir): force_build = True io.make_sure_path_exists(output_dir) if not force_build: last_modif = os.path.getmtime(os.path.join(case_path, 'chars.py')) case_build_dir = os.path.join( os.path.dirname(os.path.realpath(__file__)), 'initial_condition') for f in os.listdir(case_build_dir): if f.endswith(".py"): last_modif = max( last_modif, os.path.getmtime(os.path.join(case_build_dir, f))) if last_modif < os.path.getctime(output_dir): print('case already built') sys.path.append(case_path) import chars qtyList = chars.quantityList del sys.path[-1] del sys.modules["chars"] del chars return list(qtyList) print("Case path:", case_path) sys.path.append(case_path) # Reload chars also else, you build the case with the wrong characteristics import chars as case reload(case) coords_to_uid = io.gen_coords_to_uid(case.Nx, case.Ny) coords_to_bc = dict() quantityDict = dict() case.buildme(quantityDict, coords_to_uid, coords_to_bc) # Merging uid and bc dictionaries coords_to_uid_bc = io.gen_coords_to_uid_bc(case.Nx, case.Ny, case.BClayer) ds = [coords_to_uid_bc, coords_to_bc] coords_to_uid_and_bc = dict() for coord in coords_to_bc: coords_to_uid_and_bc[coord] = tuple(d.get(coord) for d in ds) rmtree(output_dir, ignore_errors=True) io.make_sure_path_exists(output_dir) # Write scheme info io.write_scheme_info(output_dir, case.T, case.CFL, case.gamma) # Write domain io.write_domain(output_dir, case.lx, case.ly, case.Nx, case.Ny, coords_to_uid, case.BClayer) # Write boundary conditions io.write_bc(output_dir, coords_to_uid_and_bc) # Write quantities and boundary conditions if necessary for q_name, q in quantityDict.items(): io.write_quantity(output_dir, q_name, q) # Use quantity list from the characteristics. q_name_list = list(case.quantityList) # Del case and chars del sys.path[-1] del sys.modules["chars"] del case # Return path to case directory return q_name_list
def launch_test(tmp_dir, engineOptionDict, case_name, test, compare_with_ref, fastref, forceref, forcebuild): # Check values for pure sequential test. if engineOptionDict['compiler'] != 'mpi': if test['nSDD'][0] != 1 or test['nSDD'][1] != 1: print('Cannot start a test in pure sequential mode with these options.') sys.exit(1) # If specific options are given, they replace the default ones. if 'precision' in test: engineOptionDict['precision'] = test['precision'] if 'rounding' in test: engineOptionDict['rounding'] = test['rounding'] # Define paths project_name = engineOptionDict['project_name'] case_path_suffix = get_case_path_suffix(project_name, case_name) icond_path = os.path.join(config.case_ic, case_path_suffix) input_path = os.path.join(config.case_input, case_path_suffix, "init") refer_path = os.path.join(config.case_ref, case_path_suffix, get_ref_name(engineOptionDict['precision'], engineOptionDict['rounding'])) # Delete reference to trigger a new computation. if forceref == True: rmtree(refer_path, ignore_errors=True) if fastref == True: # Don't check if you want only to build the ref. compare_with_ref = False if os.path.isdir(refer_path): print("Reference for case does exist already, return.") return None, 0 # Don't create or compare with reference if rounding mode is random: non sense. if fastref == True or compare_with_ref == True: if engineOptionDict['rounding'] == 'random' or engineOptionDict['rounding'] == 'average': print('Rounding mode not allowed to create a reference.') sys.exit(1) # Start time start = timer() # Build case print(COLOR_BLUE + "Building case data" + COLOR_ENDC) qty_name_list = build_case(icond_path, input_path, forcebuild) # Manage number of SDD nSDD_X = test['nSDD'][0] nSDD_Y = test['nSDD'][1] # Split case for SDDs into tmp directory print(COLOR_BLUE + "Splitting case data " + str(nSDD_X) + "x" + str(nSDD_Y) + COLOR_ENDC) split_path = sdd.split_case(input_path, nSDD_X, nSDD_Y, qty_name_list) # Add exec options io.write_exec_options(split_path, nSDD_X * nSDD_Y, nSDD_X, nSDD_Y, test['nSDS'], test['SDSgeom'], test['nThreads'], test['nCommonSDS'], test['nCoresPerSDD']) # Copying exec_options and scheme_info in input path too copyfile(os.path.join(input_path, 'scheme_info.dat'), os.path.join(split_path, 'scheme_info.dat')) # Building output paths (the engine cannot create them itself) output_path = os.path.join(tmp_dir, project_name, case_name, "final") rmtree(output_path, ignore_errors=True) copytree(split_path, output_path) # Compile (if needed) engine and call it print(COLOR_BLUE + "Compiling engine" + COLOR_ENDC) engine = Engine(engineOptionDict, engineOptionDict['must_compile']) print(COLOR_BLUE + "Calling engine" + COLOR_ENDC) run_option = [] if compare_with_ref == True or fastref == True or engineOptionDict['rounding'] != None else ['--dry'] engine.run(split_path, output_path, engineOptionDict['node_number'], nSDD_X * nSDD_Y, int(np.ceil(test['nCoresPerSDD'])), run_option) end = timer() # Now, look for differences, if any. if compare_with_ref == True: print(COLOR_BLUE + "Merging final data" + COLOR_ENDC) sdd.merge_domain(output_path, output_path) for q_str in qty_name_list: sdd.merge_quantity(output_path, output_path, q_str) # Getting/building reference for the case create_ref(engineOptionDict, icond_path, input_path, refer_path) # Now actually compare. result, qty, error_data = check_test(output_path, refer_path, qty_name_list, engineOptionDict['precision']) if result: print("Compared with reference: OK.") else: print("Compared with reference: ERROR, different result for quantity " + qty) sys.exit(1) if fastref == True: print(COLOR_BLUE + "Merging final data" + COLOR_ENDC) io.make_sure_path_exists(refer_path) sdd.merge_domain(output_path, refer_path) for q_str in qty_name_list: sdd.merge_quantity(output_path, refer_path, q_str) # Export error norm if engineOptionDict['rounding'] != None and engineOptionDict['rounding'] != 'nearest': print(COLOR_BLUE + "Merging final data" + COLOR_ENDC) sdd.merge_domain(output_path, refer_path) # Merge everything first. for q_str in qty_name_list: sdd.merge_quantity(output_path, refer_path, q_str) # Then compute the errors. err = script.error_norm.compute(refer_path, qty_name_list, test['solver']) # Save errors in ref path. if err is not None: script.error_norm.save(refer_path, err) return output_path, int((end - start) * 1000)
def split_domain(domain_dir, output_dir, nSDD_X, nSDD_Y): io.make_sure_path_exists(output_dir) domain_f = open(os.path.join(domain_dir, 'domain.dat'), 'r') line_split = domain_f.readline().split() domain_lx = line_split[2] domain_ly = line_split[3] domain_Nx = int(line_split[4]) domain_Ny = int(line_split[5]) BClayer = int(line_split[6]) SDD_Nx = domain_Nx // nSDD_X SDD_Ny = domain_Ny // nSDD_Y # Writing short domain info domain_shortinfo = open(os.path.join(output_dir, 'domain.info'), 'w+') domain_shortinfo.write(domain_lx + " " + domain_ly +\ " " + str(domain_Nx) + " " + str(domain_Ny) +\ " " + str(nSDD_X) + " " + str(nSDD_Y) + " " + str(BClayer) + "\n") domain_shortinfo.close() sdd_to_coords = dict() for SDDid in range(nSDD_X * nSDD_Y): sdd_to_coords[SDDid] = list() # Now iterating through all coords of domain for line in domain_f.readlines(): line_split = line.split() uid = int(line_split[0]) coordX = int(line_split[1]) coordY = int(line_split[2]) x = coordX // SDD_Nx y = coordY // SDD_Ny BL_X = SDD_Nx * x BL_Y = SDD_Ny * y # SDD id is known based on coords SDDid = y * nSDD_X + x sdd_to_coords[SDDid].append((uid, coordX - BL_X, coordY - BL_Y)) # Closing all streams domain_f.close() # We build for each SDD a file stream that will be updated through # iterations on the domain data for x in range(nSDD_X): for y in range(nSDD_Y): # Writing SDD file SDDid = y * nSDD_X + x SDDpath = os.path.join(output_dir, 'sdd' + str(SDDid)) io.make_sure_path_exists(SDDpath) # Writing bottom-left coords on domain BL_X = SDD_Nx * x BL_Y = SDD_Ny * y with open(os.path.join(SDDpath, 'sdd.dat'), 'w+') as file_stream: file_stream.write(str(BL_X) + " " + str(BL_Y) + "\n") file_stream.write(str(SDD_Nx) + " " + str(SDD_Ny) + "\n") # Finally writing uid on domain and position on SDD for c in sdd_to_coords[SDDid]: file_stream.write("%s %s %s\n" % (c[0], c[1], c[2])) return sdd_to_coords
def save(err_path, err): make_sure_path_exists(err_path) with open(os.path.join(err_path, "error.dat"), 'a+') as f: # f.write("%s\t%s\t%s\t%s\n" % (err['N'], err['rho'], err['energy'], err['u'])) f.write("%s\t%s\t%s\t%s\n" % (err['N'], err['rho'], 0., 0.))
def runTestBattery(engineOptionDict, testBattery): if args.test == True: return tmp_dir = config.tmp_dir project_name = engineOptionDict['project_name'] # Checkt that all cases do exist for cn in testBattery: if not case_exist(project_name, cn): print('Test', project_name, cn, "doesn't exist") sys.exit(1) for cn, testList in testBattery.items(): # Init results dir io.make_sure_path_exists( os.path.join(config.results_dir, project_name, cn)) restultTag = datetime.datetime.now().strftime("%Y%m%dT%H%M%S") results_path = os.path.join( config.results_dir, project_name, cn, 'data-' + args.jobname + '-' + restultTag + '.csv') # Launch tests and compare results print(COLOR_BLUE + "Start seeking optimal with case: " + COLOR_ENDC + project_name + '/' + cn) # Cleaning tmp directory for new case rmtree(tmp_dir, ignore_errors=True) for test in testList: # Launching runs for the test perf_for_allruns = [] variant_info = None for n in range(test['nRuns']): # Check results and compare to reference (one check for all runs). if not args.nocheck and n == test['nRuns'] - 1: compare_with_ref = True else: compare_with_ref = False # Launch Test tmp_test_path, exec_time = launch_test( tmp_dir, engineOptionDict, cn, test, compare_with_ref, args.fastref, args.forceref, args.forcebuild) if tmp_test_path is None: # This test was not performed. continue totalSDDNumber = test['nSDD'][0] * test['nSDD'][1] # Variant info variant_info = io.read_variant_info(tmp_test_path, totalSDDNumber) # Perfs info perf_info = io.read_perf_info(tmp_test_path, totalSDDNumber) endTime = datetime.datetime.now().strftime("%Y%m%dT%H%M%S") print("endTime:", endTime) print("Total ExecTime:", exec_time) print("Results for test: " + str(test) + " on run " + str(n) + " on " + str(test['nCoresPerSDD']) + " core(s).") perf_for_allruns.append( make_perf_data(tmp_test_path, exec_time, perf_info, endTime)) print("perf_for_allruns", perf_for_allruns) # Join results if variant_info is not None: join_result_data(results_path, variant_info, perf_for_allruns, test['nCoresPerSDD'], test['machine']) # Finally print(COLOR_GREEN + "\nTest successfully passed\n" + COLOR_ENDC)