Пример #1
0
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
Пример #2
0
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)
Пример #3
0
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
Пример #4
0
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()
Пример #5
0
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
Пример #6
0
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)
Пример #7
0
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
Пример #8
0
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.))
Пример #9
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)