Пример #1
0
def _stage_runtime_inputs(build_dir, no_pnetcdf):
    """Stage CTSM and LILAC runtime inputs

    Args:
    build_dir (str): path to build directory
    no_pnetcdf (bool): if True, use netcdf rather than pnetcdf
    """
    os.makedirs(os.path.join(build_dir, _RUNTIME_INPUTS_DIRNAME))

    inputdata_dir = _xmlquery('DIN_LOC_ROOT', build_dir)
    fill_template_file(path_to_template=os.path.join(_PATH_TO_TEMPLATES,
                                                     'ctsm_template.cfg'),
                       path_to_final=os.path.join(build_dir,
                                                  _RUNTIME_INPUTS_DIRNAME,
                                                  'ctsm.cfg'),
                       substitutions={'INPUTDATA': inputdata_dir})

    fill_template_file(path_to_template=os.path.join(_PATH_TO_TEMPLATES,
                                                     'lilac_in_template'),
                       path_to_final=os.path.join(build_dir,
                                                  _RUNTIME_INPUTS_DIRNAME,
                                                  'lilac_in'),
                       substitutions={'INPUTDATA': inputdata_dir})

    pio_stride = _xmlquery('MAX_MPITASKS_PER_NODE', build_dir)
    if no_pnetcdf:
        pio_typename = 'netcdf'
        # pio_rearranger = 1 is generally more efficient with netcdf (see
        # https://github.com/ESMCI/cime/pull/3732#discussion_r508954806 and the following
        # discussion)
        pio_rearranger = 1
    else:
        pio_typename = 'pnetcdf'
        pio_rearranger = 2
    fill_template_file(path_to_template=os.path.join(
        _PATH_TO_TEMPLATES, 'lnd_modelio_template.nml'),
                       path_to_final=os.path.join(build_dir,
                                                  _RUNTIME_INPUTS_DIRNAME,
                                                  'lnd_modelio.nml'),
                       substitutions={
                           'PIO_REARRANGER': pio_rearranger,
                           'PIO_STRIDE': pio_stride,
                           'PIO_TYPENAME': pio_typename
                       })

    shutil.copyfile(src=os.path.join(path_to_ctsm_root(), 'cime_config',
                                     'usermods_dirs', 'lilac', 'user_nl_ctsm'),
                    dst=os.path.join(build_dir, _RUNTIME_INPUTS_DIRNAME,
                                     'user_nl_ctsm'))

    make_link(
        _PATH_TO_MAKE_RUNTIME_INPUTS,
        os.path.join(build_dir, _RUNTIME_INPUTS_DIRNAME,
                     'make_runtime_inputs'))

    make_link(
        _PATH_TO_DOWNLOAD_INPUT_DATA,
        os.path.join(build_dir, _RUNTIME_INPUTS_DIRNAME,
                     'download_input_data'))
Пример #2
0
def _make_testroot(testroot, testid_base, dry_run):
    """Make the testroot directory at the given location, as well as a link in the current
    directory
    """
    if os.path.exists(testroot):
        raise RuntimeError("{} already exists".format(testroot))
    logger.info("Making directory: %s", testroot)
    if not dry_run:
        os.makedirs(testroot)
        make_link(testroot, _get_testdir_name(testid_base))
Пример #3
0
def _stage_runtime_inputs(build_dir, no_pnetcdf):
    """Stage CTSM and LILAC runtime inputs

    Args:
    build_dir (str): path to build directory
    no_pnetcdf (bool): if True, use netcdf rather than pnetcdf
    """
    os.makedirs(os.path.join(build_dir, _RUNTIME_INPUTS_DIRNAME))

    inputdata_dir = _xmlquery('DIN_LOC_ROOT', build_dir)
    fill_template_file(path_to_template=os.path.join(_PATH_TO_TEMPLATES,
                                                     'ctsm_template.cfg'),
                       path_to_final=os.path.join(build_dir,
                                                  _RUNTIME_INPUTS_DIRNAME,
                                                  'ctsm.cfg'),
                       substitutions={'INPUTDATA': inputdata_dir})

    fill_template_file(path_to_template=os.path.join(_PATH_TO_TEMPLATES,
                                                     'lilac_in_template'),
                       path_to_final=os.path.join(build_dir,
                                                  _RUNTIME_INPUTS_DIRNAME,
                                                  'lilac_in'),
                       substitutions={'INPUTDATA': inputdata_dir})

    pio_stride = _xmlquery('MAX_MPITASKS_PER_NODE', build_dir)
    if no_pnetcdf:
        pio_typename = 'netcdf'
    else:
        pio_typename = 'pnetcdf'
    fill_template_file(path_to_template=os.path.join(
        _PATH_TO_TEMPLATES, 'lnd_modelio_template.nml'),
                       path_to_final=os.path.join(build_dir,
                                                  _RUNTIME_INPUTS_DIRNAME,
                                                  'lnd_modelio.nml'),
                       substitutions={
                           'PIO_STRIDE': pio_stride,
                           'PIO_TYPENAME': pio_typename
                       })

    shutil.copyfile(src=os.path.join(path_to_ctsm_root(), 'cime_config',
                                     'usermods_dirs', 'lilac', 'user_nl_ctsm'),
                    dst=os.path.join(build_dir, _RUNTIME_INPUTS_DIRNAME,
                                     'user_nl_ctsm'))

    make_link(
        _PATH_TO_MAKE_RUNTIME_INPUTS,
        os.path.join(build_dir, _RUNTIME_INPUTS_DIRNAME,
                     'make_runtime_inputs'))

    make_link(
        _PATH_TO_DOWNLOAD_INPUT_DATA,
        os.path.join(build_dir, _RUNTIME_INPUTS_DIRNAME,
                     'download_input_data'))
Пример #4
0
def _build_case(build_dir):
    """Build the CTSM library and its dependencies

    Args:
    build_dir (str): path to build directory
    """
    # We want user to see output from the build command, so we use subprocess.check_call
    # rather than run_cmd_output_on_error.

    # See comment in _create_case for why we use case_dir in both the path to the command
    # and in the cwd argument to check_call.
    case_dir = _get_case_dir(build_dir)
    try:
        subprocess.check_call(
            [os.path.join(case_dir, 'case.build'), '--sharedlib-only'],
            cwd=case_dir)
    except subprocess.CalledProcessError:
        abort(
            'ERROR building CTSM or its dependencies - see above for details')

    make_link(os.path.join(case_dir, 'bld', 'ctsm.mk'),
              os.path.join(build_dir, 'ctsm.mk'))
Пример #5
0
def _create_case(cime_path,
                 build_dir,
                 compiler,
                 machine=None,
                 build_debug=False,
                 build_with_openmp=False,
                 inputdata_path=None):
    """Create a case that can later be used to build the CTSM library and its dependencies

    Args:
    cime_path (str): path to root of cime
    build_dir (str): path to build directory
    compiler (str): compiler to use
    machine (str or None): name of machine or None
        If None, we assume we're using an on-the-fly machine port
        Otherwise, machine should be the name of a machine known to cime
    build_debug (bool): if True, build with flags for debugging
    build_with_openmp (bool): if True, build with OpenMP support
    inputdata_path (str or None): path to existing inputdata directory on this machine
        If None, we use the machine's default DIN_LOC_ROOT
    """
    # Note that, for some commands, we want to suppress output, only showing the output if
    # the command fails; for these we use run_cmd_output_on_error. For other commands,
    # there should be no output in general; for these, we directly use
    # subprocess.check_call or similar.

    # Also note that, for commands executed from the case directory, we specify the path
    # to the case directory both in the command itself and in the cwd argument. We do the
    # former in case dot isn't in the user's path; we do the latter in case the commands
    # require you to be in the case directory when you execute them.

    case_dir = _get_case_dir(build_dir)
    xmlchange = os.path.join(case_dir, 'xmlchange')

    if machine is None:
        machine_args = [
            '--machine', _MACH_NAME, '--extra-machines-dir',
            os.path.join(build_dir, _MACHINE_CONFIG_DIRNAME)
        ]
    else:
        machine_args = ['--machine', machine]

    create_newcase_cmd = [
        os.path.join(cime_path, 'scripts', 'create_newcase'),
        '--output-root',
        build_dir,
        '--case',
        case_dir,
        '--compset',
        _COMPSET,
        '--res',
        _RES,
        '--compiler',
        compiler,
        '--driver',
        'nuopc',
        # Project isn't used for anything in the LILAC workflow, but it
        # still needs to be specified on machines that expect it.
        '--project',
        'UNSET',
        '--run-unsupported'
    ]
    create_newcase_cmd.extend(machine_args)
    if inputdata_path:
        create_newcase_cmd.extend(['--input-dir', inputdata_path])
    run_cmd_output_on_error(create_newcase_cmd,
                            errmsg='Problem creating CTSM case directory')

    subprocess.check_call([xmlchange, 'LILAC_MODE=on'], cwd=case_dir)
    if build_debug:
        subprocess.check_call([xmlchange, 'DEBUG=TRUE'], cwd=case_dir)
    if build_with_openmp:
        subprocess.check_call([xmlchange, 'FORCE_BUILD_SMP=TRUE'],
                              cwd=case_dir)

    run_cmd_output_on_error([os.path.join(case_dir, 'case.setup')],
                            errmsg='Problem setting up CTSM case directory',
                            cwd=case_dir)

    make_link(os.path.join(case_dir, 'bld'), os.path.join(build_dir, 'bld'))
    if machine is not None:
        # For a pre-existing machine, the .env_mach_specific files are likely useful to
        # the user. Make sym links to these with more intuitive names.
        for extension in ('sh', 'csh'):
            make_link(
                os.path.join(case_dir,
                             '.env_mach_specific.{}'.format(extension)),
                os.path.join(build_dir,
                             'ctsm_build_environment.{}'.format(extension)))