def check_case(case, caseroot): check_lockedfiles(caseroot) preview_namelists(case, dryrun=False) expect(case.get_value("BUILD_COMPLETE"), "Build complete is " "not True please rebuild the model by calling case.build") logger.info("Check case OK")
def pre_run_check(case): ############################################################################### # Pre run initialization code.. caseroot = case.get_value("CASEROOT") din_loc_root = case.get_value("DIN_LOC_ROOT") batchsubmit = case.get_value("BATCHSUBMIT") mpilib = case.get_value("MPILIB") rundir = case.get_value("RUNDIR") build_complete = case.get_value("BUILD_COMPLETE") # check for locked files. check_lockedfiles(case.get_value("CASEROOT")) logger.debug("check_lockedfiles OK") # check that build is done expect (build_complete, "BUILD_COMPLETE is not true\nPlease rebuild the model interactively") logger.debug("build complete is %s " %build_complete) # load the module environment... env_module = case.get_env("mach_specific") env_module.load_env_for_case(compiler=case.get_value("COMPILER"), debug=case.get_value("DEBUG"), mpilib=case.get_value("MPILIB")) # set environment variables # This is a requirement for yellowstone only if mpilib == "mpi-serial" and "MP_MPILIB" in os.environ: del os.environ["MP_MPILIB"] else: os.environ["MPILIB"] = mpilib if batchsubmit is None or len(batchsubmit) == 0: os.environ["LBQUERY"] = "FALSE" os.environ["BATCHQUERY"] = "undefined" elif batchsubmit == 'UNSET': os.environ["LBQUERY"] = "FALSE" os.environ["BATCHQUERY"] = "undefined" else: os.environ["LBQUERY"] = "TRUE" # create the timing directories, optionally cleaning them if needed. if not os.path.isdir(rundir): os.mkdir(rundir) if os.path.isdir(os.path.join(rundir,"timing")): shutil.rmtree(os.path.join(rundir,"timing")) os.makedirs(os.path.join(rundir,"timing","checkpoints")) # run preview namelists preview_namelists(case) # document process append_status("Run started ",caseroot=caseroot, sfile="CaseStatus") logger.info( "-------------------------------------------------------------------------") logger.info( " - To prestage required restarts, untar a restart.tar file into %s" %(rundir)) logger.info( " - Case input data directory (DIN_LOC_ROOT) is %s " %(din_loc_root)) logger.info( " - Checking for required input datasets in DIN_LOC_ROOT") logger.info( "-------------------------------------------------------------------------")
def case_build(caseroot, case=None, sharedlib_only=False, model_only=False): ############################################################################### t1 = time.time() expect(not (sharedlib_only and model_only), "Contradiction: both sharedlib_only and model_only") logger.info("sharedlib_only is %s" % sharedlib_only) logger.info("model_only is %s" % model_only) expect(os.path.isdir(caseroot), "'%s' is not a valid directory" % caseroot) os.chdir(caseroot) expect(os.path.exists("case.run"), "ERROR: must invoke case.setup script before calling build script ") case = Case() if case is None else case cimeroot = case.get_value("CIMEROOT") comp_classes = case.get_value("COMP_CLASSES").split(',') if not sharedlib_only: check_all_input_data(case) run_cmd("./Tools/check_lockedfiles --caseroot %s" % caseroot) # Retrieve relevant case data # This environment variable gets set for cesm Make and # needs to be unset before building again. if "MODEL" in os.environ.keys(): del os.environ["MODEL"] build_threaded = case.get_value("BUILD_THREADED") casetools = case.get_value("CASETOOLS") exeroot = case.get_value("EXEROOT") incroot = case.get_value("INCROOT") libroot = case.get_value("LIBROOT") sharedlibroot = case.get_value("SHAREDLIBROOT") complist = [] for comp_class in comp_classes: if comp_class == "DRV": comp_class = "CPL" ninst = 1 config_dir = None else: ninst = case.get_value("NINST_%s"%comp_class) config_dir = os.path.dirname(case.get_value("CONFIG_%s_FILE"%comp_class)) comp = case.get_value("COMP_%s"%comp_class) thrds = case.get_value("NTHRDS_%s"%comp_class) complist.append((comp_class.lower(), comp, thrds, ninst, config_dir )) os.environ["COMP_%s"%comp_class] = comp machines_file = case.get_value("MACHINES_SPEC_FILE") ocn_submodel = case.get_value("OCN_SUBMODEL") profile_papi_enable = case.get_value("PROFILE_PAPI_ENABLE") compiler = case.get_value("COMPILER") comp_interface = case.get_value("COMP_INTERFACE") mpilib = case.get_value("MPILIB") use_esmf_lib = case.get_value("USE_ESMF_LIB") debug = case.get_value("DEBUG") ninst_build = case.get_value("NINST_BUILD") smp_value = case.get_value("SMP_VALUE") clm_use_petsc = case.get_value("CLM_USE_PETSC") cism_use_trilinos = case.get_value("CISM_USE_TRILINOS") mpasli_use_albany = case.get_value("MPASLI_USE_ALBANY") clm_config_opts = case.get_value("CLM_CONFIG_OPTS") cam_config_opts = case.get_value("CAM_CONFIG_OPTS") pio_config_opts = case.get_value("PIO_CONFIG_OPTS") ninst_value = case.get_value("NINST_VALUE") mach = case.get_value("MACH") os_ = case.get_value("OS") # Load some params into env os.environ["CIMEROOT"] = cimeroot os.environ["CASETOOLS"] = casetools os.environ["EXEROOT"] = exeroot os.environ["INCROOT"] = incroot os.environ["LIBROOT"] = libroot os.environ["SHAREDLIBROOT"] = sharedlibroot os.environ["CASEROOT"] = caseroot os.environ["COMPILER"] = compiler os.environ["COMP_INTERFACE"] = comp_interface os.environ["NINST_VALUE"] = str(ninst_value) os.environ["BUILD_THREADED"] = stringify_bool(build_threaded) os.environ["MACH"] = mach os.environ["USE_ESMF_LIB"] = stringify_bool(use_esmf_lib) os.environ["MPILIB"] = mpilib os.environ["DEBUG"] = stringify_bool(debug) os.environ["OS"] = os_ os.environ["CLM_CONFIG_OPTS"] = clm_config_opts if clm_config_opts is not None else "" os.environ["CAM_CONFIG_OPTS"] = cam_config_opts if cam_config_opts is not None else "" os.environ["PIO_CONFIG_OPTS"] = pio_config_opts if pio_config_opts is not None else "" os.environ["OCN_SUBMODEL"] = ocn_submodel if ocn_submodel is not None else "" os.environ["PROFILE_PAPI_ENABLE"] = stringify_bool(profile_papi_enable) if profile_papi_enable is not None else "" os.environ["CLM_USE_PETSC"] = stringify_bool(clm_use_petsc) if clm_use_petsc is not None else "" os.environ["CISM_USE_TRILINOS"] = stringify_bool(cism_use_trilinos) if cism_use_trilinos is not None else "" os.environ["MPASLI_USE_ALBANY"] = stringify_bool(mpasli_use_albany) if mpasli_use_albany is not None else "" # This is a timestamp for the build , not the same as the testid, # and this case may not be a test anyway. For a production # experiment there may be many builds of the same case. lid = run_cmd("date +%y%m%d-%H%M%S") os.environ["LID"] = lid # Set the overall USE_PETSC variable to TRUE if any of the # XXX_USE_PETSC variables are TRUE. # For now, there is just the one CLM_USE_PETSC variable, but in # the future there may be others -- so USE_PETSC will be true if # ANY of those are true. use_petsc = clm_use_petsc case.set_value("USE_PETSC", use_petsc) os.environ["USE_PETSC"] = stringify_bool(use_petsc) # Set the overall USE_TRILINOS variable to TRUE if any of the # XXX_USE_TRILINOS variables are TRUE. # For now, there is just the one CISM_USE_TRILINOS variable, but in # the future there may be others -- so USE_TRILINOS will be true if # ANY of those are true. use_trilinos = False if cism_use_trilinos is None else cism_use_trilinos case.set_value("USE_TRILINOS", use_trilinos) os.environ["USE_TRILINOS"] = stringify_bool(use_trilinos) # Set the overall USE_ALBANY variable to TRUE if any of the # XXX_USE_ALBANY variables are TRUE. # For now, there is just the one MPASLI_USE_ALBANY variable, but in # the future there may be others -- so USE_ALBANY will be true if # ANY of those are true. use_albany = mpasli_use_albany case.set_value("USE_ALBANY", use_albany) os.environ["USE_ALBANY"] = stringify_bool(use_albany) # Load modules env_module = case._get_env("mach_specific") env_module.load_env_for_case(compiler=case.get_value("COMPILER"), debug=case.get_value("DEBUG"), mpilib=case.get_value("MPILIB")) # Need to flush case xml to disk before calling preview_namelists case.flush() if not sharedlib_only: preview_namelists(case) build_checks(case, build_threaded, comp_interface, use_esmf_lib, debug, compiler, mpilib, sharedlibroot, complist, ninst_build, smp_value) t2 = time.time() logs = [] if not model_only: logs = build_libraries(case, exeroot, caseroot, cimeroot, libroot, mpilib, lid, machines_file) if not sharedlib_only: logs.extend(build_model(case, build_threaded, exeroot, clm_config_opts, incroot, complist, lid, caseroot, cimeroot, use_esmf_lib, comp_interface)) if not sharedlib_only: post_build(case, logs) t3 = time.time() logger.info("Time spent not building: %f sec" % (t2 - t1)) logger.info("Time spent building: %f sec" % (t3 - t2))
def case_build(caseroot, case=None, testmode=False, sharedlib_only=False, model_only=False): ############################################################################### t1 = time.time() expect(not (sharedlib_only and model_only), "Contradiction: both sharedlib_only and model_only") logger.info("sharedlib_only is %s" % sharedlib_only) logger.info("model_only is %s" % model_only) expect(os.path.isdir(caseroot), "'%s' is not a valid directory" % caseroot) os.chdir(caseroot) expect(os.path.exists("case.run"), "ERROR: must invoke case.setup script before calling build script ") case = Case() if case is None else case testcase = case.get_value("TESTCASE") cimeroot = case.get_value("CIMEROOT") expect(not (testcase is not None and os.path.exists("%s/scripts/Testing/Testcases/%s_build.csh" % (cimeroot, testcase)) and not testmode), "%s build must be invoked via case.testbuild script" % testcase) if not sharedlib_only: check_all_input_data(case) run_cmd("./Tools/check_lockedfiles --caseroot %s" % caseroot) # Retrieve relevant case data build_threaded = case.get_value("BUILD_THREADED") casetools = case.get_value("CASETOOLS") exeroot = case.get_value("EXEROOT") incroot = case.get_value("INCROOT") libroot = case.get_value("LIBROOT") sharedlibroot = case.get_value("SHAREDLIBROOT") comp_atm = case.get_value("COMP_ATM") comp_lnd = case.get_value("COMP_LND") comp_ice = case.get_value("COMP_ICE") comp_ocn = case.get_value("COMP_OCN") comp_glc = case.get_value("COMP_GLC") comp_wav = case.get_value("COMP_WAV") comp_rof = case.get_value("COMP_ROF") compiler = case.get_value("COMPILER") comp_interface = case.get_value("COMP_INTERFACE") mpilib = case.get_value("MPILIB") use_esmf_lib = case.get_value("USE_ESMF_LIB") debug = case.get_value("DEBUG") ninst_build = case.get_value("NINST_BUILD") smp_value = case.get_value("SMP_VALUE") clm_use_petsc = case.get_value("CLM_USE_PETSC") cism_use_trilinos = case.get_value("CISM_USE_TRILINOS") mpasli_use_albany = case.get_value("MPASLI_USE_ALBANY") clm_config_opts = case.get_value("CLM_CONFIG_OPTS") cam_config_opts = case.get_value("CAM_CONFIG_OPTS") pio_config_opts = case.get_value("PIO_CONFIG_OPTS") ninst_value = case.get_value("NINST_VALUE") mach = case.get_value("MACH") os_ = case.get_value("OS") comp_cpl = case.get_value("COMP_CPL") machines_file = case.get_value("MACHINES_SPEC_FILE") ocn_submodel = case.get_value("OCN_SUBMODEL") profile_papi_enable = case.get_value("PROFILE_PAPI_ENABLE") nthrds_cpl = int(case.get_value("NTHRDS_CPL")) nthrds_atm = int(case.get_value("NTHRDS_ATM")) nthrds_lnd = int(case.get_value("NTHRDS_LND")) nthrds_ice = int(case.get_value("NTHRDS_ICE")) nthrds_ocn = int(case.get_value("NTHRDS_OCN")) nthrds_glc = int(case.get_value("NTHRDS_GLC")) nthrds_wav = int(case.get_value("NTHRDS_WAV")) nthrds_rof = int(case.get_value("NTHRDS_ROF")) # Load some params into env os.environ["CIMEROOT"] = cimeroot os.environ["CASETOOLS"] = casetools os.environ["EXEROOT"] = exeroot os.environ["INCROOT"] = incroot os.environ["LIBROOT"] = libroot os.environ["SHAREDLIBROOT"] = sharedlibroot os.environ["CASEROOT"] = caseroot os.environ["COMPILER"] = compiler os.environ["COMP_INTERFACE"] = comp_interface os.environ["NINST_VALUE"] = ninst_value os.environ["BUILD_THREADED"] = build_threaded os.environ["MACH"] = mach os.environ["USE_ESMF_LIB"] = use_esmf_lib os.environ["MPILIB"] = mpilib os.environ["DEBUG"] = debug os.environ["OS"] = os_ os.environ["COMP_CPL"] = comp_cpl os.environ["COMP_ATM"] = comp_atm os.environ["COMP_LND"] = comp_lnd os.environ["COMP_ICE"] = comp_ice os.environ["COMP_OCN"] = comp_ocn os.environ["COMP_GLC"] = comp_glc os.environ["COMP_WAV"] = comp_wav os.environ["COMP_ROF"] = comp_rof os.environ["CLM_CONFIG_OPTS"] = clm_config_opts if clm_config_opts is not None else "" os.environ["CAM_CONFIG_OPTS"] = cam_config_opts if cam_config_opts is not None else "" os.environ["PIO_CONFIG_OPTS"] = pio_config_opts if pio_config_opts is not None else "" os.environ["OCN_SUBMODEL"] = ocn_submodel if ocn_submodel is not None else "" os.environ["PROFILE_PAPI_ENABLE"] = profile_papi_enable if profile_papi_enable is not None else "" os.environ["CLM_USE_PETSC"] = clm_use_petsc if clm_use_petsc is not None else "" os.environ["CISM_USE_TRILINOS"] = cism_use_trilinos if cism_use_trilinos is not None else "" os.environ["MPASLI_USE_ALBANY"] = mpasli_use_albany if mpasli_use_albany is not None else "" # This is a timestamp for the build , not the same as the testid, # and this case may not be a test anyway. For a production # experiment there may be many builds of the same case. lid = run_cmd("date +%y%m%d-%H%M%S") os.environ["LID"] = lid # Set the overall USE_PETSC variable to TRUE if any of the # XXX_USE_PETSC variables are TRUE. # For now, there is just the one CLM_USE_PETSC variable, but in # the future there may be others -- so USE_PETSC will be true if # ANY of those are true. use_petsc = "TRUE" if clm_use_petsc == "TRUE" else "FALSE" case.set_value("USE_PETSC", use_petsc) os.environ["USE_PETSC"] = use_petsc # Set the overall USE_TRILINOS variable to TRUE if any of the # XXX_USE_TRILINOS variables are TRUE. # For now, there is just the one CISM_USE_TRILINOS variable, but in # the future there may be others -- so USE_TRILINOS will be true if # ANY of those are true. use_trilinos = "TRUE" if cism_use_trilinos == "TRUE" else "FALSE" case.set_value("USE_TRILINOS", use_trilinos) os.environ["USE_TRILINOS"] = use_trilinos # Set the overall USE_ALBANY variable to TRUE if any of the # XXX_USE_ALBANY variables are TRUE. # For now, there is just the one MPASLI_USE_ALBANY variable, but in # the future there may be others -- so USE_ALBANY will be true if # ANY of those are true. use_albany = "TRUE" if mpasli_use_albany == "TRUE" else "FALSE" case.set_value("USE_ALBANY", use_albany) os.environ["USE_ALBANY"] = use_albany # Load modules env_module = EnvModule(mach, compiler, cimeroot, caseroot, mpilib, debug) env_module.load_env_for_case() # Need to flush case xml to disk before calling preview_namelists case.flush() if not sharedlib_only: preview_namelists(case=case) build_checks(case, build_threaded, comp_interface, use_esmf_lib, debug, compiler, mpilib, sharedlibroot, nthrds_cpl, nthrds_atm, nthrds_lnd, nthrds_ice, nthrds_ocn, nthrds_glc, nthrds_wav, nthrds_rof, ninst_build, smp_value) t2 = time.time() logs = [] if not model_only: logs = build_libraries(exeroot, caseroot, cimeroot, libroot, mpilib, lid, machines_file) if sharedlib_only and comp_lnd == "clm" and not "clm4_0" in clm_config_opts: logging.info(" - Building clm4_5/clm5_0 Library ") esmfdir = "esmf" if use_esmf_lib == "TRUE" else "noesmf" sharedpath = os.environ["SHAREDPATH"] bldroot = os.path.join(sharedpath, comp_interface, esmfdir) objdir = os.path.join(bldroot, "lnd", "obj") libdir = os.path.join(bldroot, "lib") file_build = os.path.join(exeroot, "lnd.bldlog.%s" % lid) config_lnd_dir = os.path.dirname(case.get_value("CONFIG_LND_FILE")) results = [] for ndir in [bldroot, objdir, libdir]: if(not os.path.isdir(ndir)): os.makedirs(ndir) _build_model_thread(config_lnd_dir, caseroot, bldroot, "clm", file_build, exeroot, "lnd", "clm", objdir, incroot, results) if not sharedlib_only: logs.extend(build_model(case, build_threaded, exeroot, clm_config_opts, incroot, comp_atm, comp_lnd, comp_ice, comp_ocn, comp_glc, comp_wav, comp_rof, nthrds_atm, nthrds_lnd, nthrds_ice, nthrds_ocn, nthrds_glc, nthrds_wav, nthrds_rof, lid, caseroot, cimeroot, use_esmf_lib, comp_interface)) if not sharedlib_only: post_build(case, logs) t3 = time.time() logger.info("Time spent not building: %f sec" % (t2 - t1)) logger.info("Time spent building: %f sec" % (t3 - t2))
def _case_setup_impl(case, caseroot, casebaseid, clean=False, test_mode=False, reset=False): ############################################################################### os.chdir(caseroot) msg = "case.setup starting" append_status(msg, caseroot=caseroot, sfile="CaseStatus") cimeroot = os.environ["CIMEROOT"] # Check that $DIN_LOC_ROOT exists - and abort if not a namelist compare tests din_loc_root = case.get_value("DIN_LOC_ROOT") testcase = case.get_value("TESTCASE") expect(not (not os.path.isdir(din_loc_root) and testcase != "SBN"), "inputdata root is not a directory: \"$din_loc_root\" ") # Check that userdefine settings are specified before expanding variable for vid, value in case: expect(not (type(value) is str and "USERDEFINED_required_build" in value), "Parameter '%s' must be defined" % vid) # Create batch script if reset or clean: # Clean batch script backup_dir = "PESetupHist/b.%s" % time.strftime("%y%m%d-%H%M%S") if not os.path.isdir(backup_dir): os.makedirs(backup_dir) # back up relevant files for fileglob in ["case.run", "env_build.xml", "env_mach_pes.xml", "Macros*"]: for filename in glob.glob(fileglob): shutil.copy(filename, backup_dir) if os.path.exists("case.run"): os.remove("case.run") # only do the following if are NOT in testmode if not test_mode: # rebuild the models (even on restart) case.set_value("BUILD_COMPLETE", False) # backup and then clean test script if os.path.exists("case.test"): shutil.copy("case.test", backup_dir) os.remove("case.test") logger.info("Successfully cleaned test script case.test") if os.path.exists("case.testdriver"): shutil.copy("case.testdriver", backup_dir) os.remove("case.testdriver") logger.info("Successfully cleaned test script case.testdriver") logger.info("Successfully cleaned batch script case.run") logger.info("Successfully cleaned batch script case.run") logger.info("Some files have been saved to %s" % backup_dir) msg = "case.setup clean complete" append_status(msg, caseroot=caseroot, sfile="CaseStatus") if not clean: drv_comp = Component() models = drv_comp.get_valid_model_components() models.remove("DRV") mach, compiler, debug, mpilib = \ case.get_value("MACH"), case.get_value("COMPILER"), case.get_value("DEBUG"), case.get_value("MPILIB") expect(mach is not None, "xml variable MACH is not set") # Create Macros file only if it does not exist if not os.path.exists("Macros"): logger.debug("Creating Macros file for %s" % mach) compilers = Compilers(compiler=compiler, machine=mach, os_=case.get_value("OS"), mpilib=mpilib) compilers.write_macros_file() else: logger.debug("Macros script already created ...skipping") # Set tasks to 1 if mpi-serial library if mpilib == "mpi-serial": for vid, value in case: if vid.startswith("NTASKS_") and value != 1: case.set_value(vid, 1) # Check ninst. # In CIME there can be multiple instances of each component model (an ensemble) NINST is the instance of that component. # Save ninst in a dict to use later in apply_user_mods ninst = dict() for comp in models: comp_model = case.get_value("COMP_%s" % comp) ninst[comp_model] = case.get_value("NINST_%s" % comp) ntasks = case.get_value("NTASKS_%s" % comp) if ninst[comp_model] > ntasks: if ntasks == 1: case.set_value("NTASKS_%s" % comp, ninst[comp_model]) else: expect(False, "NINST_%s value %d greater than NTASKS_%s %d" % (comp, ninst[comp_model], comp, ntasks)) expect(not (case.get_value("BUILD_THREADED") and compiler == "nag"), "it is not possible to run with OpenMP if using the NAG Fortran compiler") if os.path.exists("case.run"): logger.info("Machine/Decomp/Pes configuration has already been done ...skipping") else: _check_pelayouts_require_rebuild(case, models) if os.path.exists("LockedFiles/env_build.xml"): os.remove("LockedFiles/env_build.xml") case.flush() check_lockedfiles() tm = TaskMaker(case) mtpn = case.get_value("MAX_TASKS_PER_NODE") pespn = case.get_value("PES_PER_NODE") # This is hardcoded because on yellowstone by default we # run with 15 pes per node # but pay for 16 pes per node. See github issue #518 if case.get_value("MACH") == "yellowstone": pespn = 16 pestot = tm.totaltasks if mtpn > pespn: pestot = pestot * (mtpn // pespn) case.set_value("COST_PES", tm.num_nodes*pespn) else: # reset cost_pes to totalpes case.set_value("COST_PES", 0) case.set_value("TOTALPES", pestot) # Compute cost based on PE count pval = 1 pcnt = 0 while pval < pestot: pval *= 2 pcnt += 6 # (scaling like sqrt(6/10)) pcost = 3 - pcnt / 10 # (3 is 64 with 6) # Compute cost based on DEBUG dcost = 3 if debug else 0 # Compute cost based on run length # For simplicity, we use a heuristic just based on STOP_OPTION (not considering # STOP_N), and only deal with options longer than ndays lcost = 0 if "nmonth" in case.get_value("STOP_OPTION"): # N months costs 30x as much as N days; since cost is based on log-base-2, add 5 lcost = 5 elif "nyear" in case.get_value("STOP_OPTION"): # N years costs 365x as much as N days; since cost is based on log-base-2, add 9 lcost = 9 estcost = pcost + dcost + lcost for cost in ["CCSM_CCOST", "CCSM_GCOST", "CCSM_TCOST", "CCSM_CCOST"]: estcost += case.get_value(cost) case.set_value("CCSM_PCOST", pcost) case.set_value("CCSM_ESTCOST", estcost) # create batch file logger.info("Creating batch script case.run") # Use BatchFactory to get the appropriate instance of a BatchMaker, # use it to create our batch scripts env_batch = case.get_env("batch") for job in env_batch.get_jobs(): input_batch_script = os.path.join(case.get_value("MACHDIR"), env_batch.get_value('template', subgroup=job)) if job == "case.test" and testcase is not None and not test_mode: logger.info("Writing %s script" % job) testscript = os.path.join(cimeroot, "scripts", "Testing", "Testcases", "%s_script" % testcase) # Short term fix to be removed when csh tests are removed if not os.path.exists(testscript): env_batch.make_batch_script(input_batch_script, job, case) elif job != "case.test": logger.info("Writing %s script" % job) env_batch.make_batch_script(input_batch_script, job, case) # Make a copy of env_mach_pes.xml in order to be able # to check that it does not change once case.setup is invoked logger.info("Locking file env_mach_pes.xml") case.flush() shutil.copy("env_mach_pes.xml", "LockedFiles") # Create user_nl files for the required number of instances if not os.path.exists("user_nl_cpl"): logger.info("Creating user_nl_xxx files for components and cpl") # loop over models for model in models: comp = case.get_value("COMP_%s" % model) logger.info("Building %s usernl files"%model) _build_usernl_files(case, model, comp) if comp == "cism": run_cmd_no_fail("%s/../components/cism/cime_config/cism.template %s" % (cimeroot, caseroot)) _build_usernl_files(case, "drv", "cpl") user_mods_path = case.get_value("USER_MODS_FULLPATH") if user_mods_path is not None: apply_user_mods(caseroot, user_mods_path=user_mods_path, ninst=ninst) elif case.get_value("TEST"): test_mods = parse_test_name(casebaseid)[6] if test_mods is not None: user_mods_path = os.path.join(case.get_value("TESTS_MODS_DIR"), test_mods) apply_user_mods(caseroot, user_mods_path=user_mods_path, ninst=ninst) # Run preview namelists for scripts logger.info("preview_namelists") preview_namelists(case) logger.info("See ./CaseDoc for component namelists") logger.info("If an old case build already exists, might want to run \'case.build --clean\' before building") # Create test script if appropriate # Short term fix to be removed when csh tests are removed if os.path.exists("env_test.xml"): if not os.path.exists("case.test"): logger.info("Starting testcase.setup") run_cmd_no_fail("./testcase.setup -caseroot %s" % caseroot) logger.info("Finished testcase.setup") msg = "case.setup complete" append_status(msg, caseroot=caseroot, sfile="CaseStatus") # Record env information env_module = case.get_env("mach_specific") env_module.make_env_mach_specific_file(compiler, debug, mpilib, "sh") env_module.make_env_mach_specific_file(compiler, debug, mpilib, "csh") with open("software_environment.txt", "w") as f: f.write(env_module.list_modules()) run_cmd_no_fail("echo -e '\n' >> software_environment.txt && \ env >> software_environment.txt")
def _case_setup_impl(case, caseroot, casebaseid, clean=False, test_mode=False, reset=False): ############################################################################### os.chdir(caseroot) msg = "case.setup starting" append_status(msg, caseroot=caseroot, sfile="CaseStatus") cimeroot = get_cime_root(case) # Check that $DIN_LOC_ROOT exists - and abort if not a namelist compare tests din_loc_root = case.get_value("DIN_LOC_ROOT") testcase = case.get_value("TESTCASE") expect(not (not os.path.isdir(din_loc_root) and testcase != "SBN"), "inputdata root is not a directory: \"$din_loc_root\" ") # Check that userdefine settings are specified before expanding variable for vid, value in case: expect(not (type(value) is str and "USERDEFINED_required_build" in value), "Parameter '%s' must be defined" % vid) # Create batch script if reset or clean: # Clean batch script backup_dir = "PESetupHist/b.%s" % time.strftime("%y%m%d-%H%M%S") if not os.path.isdir(backup_dir): os.makedirs(backup_dir) # back up relevant files for fileglob in ["case.run", "env_build.xml", "env_mach_pes.xml", "Macros*"]: for filename in glob.glob(fileglob): shutil.copy(filename, backup_dir) if os.path.exists("case.run"): os.remove("case.run") # only do the following if are NOT in testmode if not test_mode: # rebuild the models (even on restart) case.set_value("BUILD_COMPLETE", False) # backup and then clean test script if os.path.exists("case.test"): shutil.copy("case.test", backup_dir) os.remove("case.test") logger.info("Successfully cleaned test script case.test") if os.path.exists("case.testdriver"): shutil.copy("case.testdriver", backup_dir) os.remove("case.testdriver") logger.info("Successfully cleaned test script case.testdriver") logger.info("Successfully cleaned batch script case.run") logger.info("Successfully cleaned batch script case.run") logger.info("Some files have been saved to %s" % backup_dir) msg = "case.setup clean complete" append_status(msg, caseroot=caseroot, sfile="CaseStatus") if not clean: models = case.get_values("COMP_CLASSES") mach, compiler, debug, mpilib = \ case.get_value("MACH"), case.get_value("COMPILER"), case.get_value("DEBUG"), case.get_value("MPILIB") expect(mach is not None, "xml variable MACH is not set") # Create Macros file only if it does not exist if not os.path.exists("Macros"): logger.debug("Creating Macros file for %s" % mach) compilers = Compilers(compiler=compiler, machine=mach, os_=case.get_value("OS"), mpilib=mpilib) compilers.write_macros_file() else: logger.debug("Macros script already created ...skipping") # Set tasks to 1 if mpi-serial library if mpilib == "mpi-serial": for vid, value in case: if vid.startswith("NTASKS_") and value != 1: case.set_value(vid, 1) # Check ninst. # In CIME there can be multiple instances of each component model (an ensemble) NINST is the instance of that component. # Save ninst in a dict to use later in apply_user_mods ninst = dict() for comp in models: if comp == "DRV": continue comp_model = case.get_value("COMP_%s" % comp) ninst[comp_model] = case.get_value("NINST_%s" % comp) ntasks = case.get_value("NTASKS_%s" % comp) if ninst[comp_model] > ntasks: if ntasks == 1: case.set_value("NTASKS_%s" % comp, ninst[comp_model]) else: expect(False, "NINST_%s value %d greater than NTASKS_%s %d" % (comp, ninst[comp_model], comp, ntasks)) if os.path.exists("case.run"): logger.info("Machine/Decomp/Pes configuration has already been done ...skipping") else: _check_pelayouts_require_rebuild(case, models) if os.path.exists("LockedFiles/env_build.xml"): os.remove("LockedFiles/env_build.xml") case.flush() check_lockedfiles() env_mach_pes = case.get_env("mach_pes") pestot = env_mach_pes.get_total_tasks(models) logger.debug("at update TOTALPES = %s"%pestot) case.set_value("TOTALPES", pestot) thread_count = env_mach_pes.get_max_thread_count(models) if thread_count > 1: case.set_value("BUILD_THREADED", True) expect(not (case.get_value("BUILD_THREADED") and compiler == "nag"), "it is not possible to run with OpenMP if using the NAG Fortran compiler") cost_pes = env_mach_pes.get_cost_pes(pestot, thread_count, machine=case.get_value("MACH")) case.set_value("COST_PES", cost_pes) # create batch file logger.info("Creating batch script case.run") # Use BatchFactory to get the appropriate instance of a BatchMaker, # use it to create our batch scripts env_batch = case.get_env("batch") num_nodes = env_mach_pes.get_total_nodes(pestot, thread_count) tasks_per_node = env_mach_pes.get_tasks_per_node(pestot, thread_count) for job in env_batch.get_jobs(): input_batch_script = os.path.join(case.get_value("MACHDIR"), env_batch.get_value('template', subgroup=job)) if job == "case.test" and testcase is not None and not test_mode: logger.info("Writing %s script" % job) testscript = os.path.join(cimeroot, "scripts", "Testing", "Testcases", "%s_script" % testcase) # Short term fix to be removed when csh tests are removed if not os.path.exists(testscript): env_batch.make_batch_script(input_batch_script, job, case, pestot, tasks_per_node, num_nodes, thread_count) elif job != "case.test": logger.info("Writing %s script from input template %s" % (job, input_batch_script)) env_batch.make_batch_script(input_batch_script, job, case, pestot, tasks_per_node, num_nodes, thread_count) # Make a copy of env_mach_pes.xml in order to be able # to check that it does not change once case.setup is invoked logger.info("Locking file env_mach_pes.xml") case.flush() logger.debug("at copy TOTALPES = %s"%case.get_value("TOTALPES")) shutil.copy("env_mach_pes.xml", "LockedFiles") # Create user_nl files for the required number of instances if not os.path.exists("user_nl_cpl"): logger.info("Creating user_nl_xxx files for components and cpl") # loop over models for model in models: comp = case.get_value("COMP_%s" % model) logger.info("Building %s usernl files"%model) _build_usernl_files(case, model, comp) if comp == "cism": run_cmd_no_fail("%s/../components/cism/cime_config/cism.template %s" % (cimeroot, caseroot)) _build_usernl_files(case, "drv", "cpl") user_mods_path = case.get_value("USER_MODS_FULLPATH") if user_mods_path is not None: apply_user_mods(caseroot, user_mods_path=user_mods_path, ninst=ninst) elif case.get_value("TEST"): test_mods = parse_test_name(casebaseid)[6] if test_mods is not None: user_mods_path = os.path.join(case.get_value("TESTS_MODS_DIR"), test_mods) apply_user_mods(caseroot, user_mods_path=user_mods_path, ninst=ninst) # Run preview namelists for scripts logger.info("preview_namelists") preview_namelists(case) logger.info("See ./CaseDoc for component namelists") logger.info("If an old case build already exists, might want to run \'case.build --clean\' before building") # Create test script if appropriate # Short term fix to be removed when csh tests are removed if os.path.exists("env_test.xml"): if not os.path.exists("case.test"): logger.info("Starting testcase.setup") run_cmd_no_fail("./testcase.setup -caseroot %s" % caseroot) logger.info("Finished testcase.setup") msg = "case.setup complete" append_status(msg, caseroot=caseroot, sfile="CaseStatus") # Record env information env_module = case.get_env("mach_specific") env_module.make_env_mach_specific_file(compiler, debug, mpilib, "sh") env_module.make_env_mach_specific_file(compiler, debug, mpilib, "csh") with open("software_environment.txt", "w") as f: f.write(env_module.list_modules()) run_cmd_no_fail("echo -e '\n' >> software_environment.txt && \ env >> software_environment.txt")