Raw File
"""
Post run I/O processing
"""
import os
from CIME.XML.standard_module_setup import *
from CIME.utils                     import new_lid, run_and_log_case_status

logger = logging.getLogger(__name__)

###############################################################################
def _convert_adios_to_nc(case):
###############################################################################
    """
    Converts all ADIOS output files for the case to NetCDF format
    """
    env_mach_specific = case.get_env('mach_specific')
  
    # Create the ADIOS convertion tool command,
    # "<EXEROOT>/adios2pio-nm.exe --idir=<RUNDIR>"
    # The command converts all ADIOS BP files in <RUNDIR> to
    # NetCDF files

    # The ADIOS conversion tool is installed in EXEROOT
    exeroot = case.get_value("EXEROOT")
    adios_conv_tool_name = "adios2pio-nm.exe"
    adios_conv_tool_exe = os.path.join(exeroot, adios_conv_tool_name)

    # The ADIOS output files should be in RUNDIR
    rundir = case.get_value("RUNDIR")

    adios_conv_tool_args = "--idir=" + rundir
    adios_conv_tool_cmd = adios_conv_tool_exe + " " + adios_conv_tool_args

    # Replace logfile name, "e3sm.log.*" with "e3sm_adios_post_io.log.*"
    # The logfile name is part of the run command suffix
    adios_conv_tool_cmd_suffix = env_mach_specific.get_value("run_misc_suffix")
    adios_conv_tool_cmd_suffix = adios_conv_tool_cmd_suffix.replace(
                                  "e3sm.log", "e3sm_adios_post_io.log")

    is_batch = case.get_value("BATCH_SYSTEM")

    # Set up the LID (used as unique id for log names etc via $LID)
    lid = new_lid(case=case)

    # For batch jobs the number of nodes/processes for post processing need
    # to be determined before the post run job is launched
    # (i.e., via config_workflow.xml)
    if is_batch == "none":
      # Reset the total number of tasks to 1/4th for the conversion job
      CONV_JOB_SCALE_FACTOR = 1.0/4.0
      CONV_JOB_MIN_TOTAL_TASKS = 1
      CONV_JOB_MAX_TOTAL_TASKS = 1024
      env_mach_pes = case.get_env("mach_pes")
      case.thread_count = 1
      case.total_tasks = max(min(int(case.total_tasks * CONV_JOB_SCALE_FACTOR), CONV_JOB_MAX_TOTAL_TASKS), CONV_JOB_MIN_TOTAL_TASKS)
      case.cores_per_task = 1
      case.tasks_per_node = env_mach_pes.get_tasks_per_node(case.total_tasks, case.thread_count)
      case.num_nodes, case.spare_nodes = env_mach_pes.get_total_nodes(case.total_tasks, case.thread_count)
      case.num_nodes += case.spare_nodes

    # Get the current mpirun command (for e3sm.exe)
    cmd = case.get_mpirun_cmd(allow_unresolved_envvars=False)

    # Create mpirun command for the ADIOS conversion tool
    # Replace run_exe and run_misc_suffix in mpirun command
    # with ADIOS convertion tool command and suffix
    run_exe = env_mach_specific.get_value("run_exe", resolved=True)
    run_exe = case.get_resolved_value(run_exe);
    run_misc_suffix = env_mach_specific.get_value("run_misc_suffix")
    cmd = cmd.replace(run_exe, adios_conv_tool_cmd)
    cmd = cmd.replace(run_misc_suffix, adios_conv_tool_cmd_suffix)
    logger.info("Run command for ADIOS post processing is : {}".format(cmd))

    # Load the environment
    case.load_env(reset=True)

    run_func = lambda: run_cmd(cmd, from_dir=rundir)[0]

    # Run the modified case
    success = run_and_log_case_status(run_func,
                "ADIOS to NetCDF conversion",
                caseroot=case.get_value("CASEROOT"),
                is_batch=(is_batch != "none"))

    return success

###############################################################################
def case_post_run_io(self):
###############################################################################
    """
    I/O Post processing :
    1. Convert ADIOS output files, if any, to NetCDF
    """
    success = True
    has_adios = False
    self.load_env(job="case.post_run_io")
    component_classes = self.get_values("COMP_CLASSES")
    # Check if user chose "adios" as the iotype for any component
    for compclass in component_classes:
        key = "PIO_TYPENAME_{}".format(compclass)
        pio_typename = self.get_value(key)
        if pio_typename == "adios":
            has_adios = True
            break
    if has_adios:
        logger.info("I/O post processing for ADIOS starting")
        success = _convert_adios_to_nc(self)
        logger.info("I/O post processing for ADIOS completed")
    else:
        logger.info("No I/O post processing required")

    return success
back to top