"""
Interface to the config_pes.xml file. This class inherits from GenericXML.py
"""
from CIME.XML.standard_module_setup import *
from CIME.XML.generic_xml import GenericXML
from CIME.XML.files import Files
from CIME.utils import expect
logger = logging.getLogger(__name__)
[docs]
class Pes(GenericXML):
def __init__(self, infile, files=None):
"""
initialize a files object given input pes specification file
"""
if files is None:
files = Files()
schema = files.get_schema("PES_SPEC_FILE")
logger.debug("DEBUG: infile is {}".format(infile))
GenericXML.__init__(self, infile, schema=schema)
[docs]
def find_pes_layout(self, grid, compset, machine, pesize_opts="M", mpilib=None):
opes_ntasks = {}
opes_nthrds = {}
opes_rootpe = {}
opes_pstrid = {}
oother_settings = {}
other_settings = {}
append = {}
o_grid_nodes = []
comments = None
# Get any override nodes
overrides = self.get_optional_child("overrides")
ocomments = None
if overrides is not None:
o_grid_nodes = self.get_children("grid", root=overrides)
(
opes_ntasks,
opes_nthrds,
opes_rootpe,
opes_pstrid,
oother_settings,
append,
ocomments,
) = self._find_matches(
o_grid_nodes, grid, compset, machine, pesize_opts, True
)
# Get all the nodes
grid_nodes = self.get_children("grid")
if o_grid_nodes:
gn_set = set(grid_nodes)
ogn_set = set(o_grid_nodes)
gn_set.difference_update(ogn_set)
grid_nodes = list(gn_set)
(
pes_ntasks,
pes_nthrds,
pes_rootpe,
pes_pstrid,
other_settings,
os_append,
comments,
) = self._find_matches(grid_nodes, grid, compset, machine, pesize_opts, False)
pes_ntasks.update(opes_ntasks)
pes_nthrds.update(opes_nthrds)
pes_rootpe.update(opes_rootpe)
pes_pstrid.update(opes_pstrid)
other_settings.update(oother_settings)
os_append.update(append)
if ocomments is not None:
comments = ocomments
if mpilib == "mpi-serial":
for i in iter(pes_ntasks):
pes_ntasks[i] = 1
for i in iter(pes_rootpe):
pes_rootpe[i] = 0
for i in iter(pes_pstrid):
pes_pstrid[i] = 0
logger.info("Pes setting: grid is {} ".format(grid))
logger.info("Pes setting: compset is {} ".format(compset))
logger.info("Pes setting: tasks is {} ".format(pes_ntasks))
logger.info("Pes setting: threads is {} ".format(pes_nthrds))
logger.info("Pes setting: rootpe is {} ".format(pes_rootpe))
logger.info("Pes setting: pstrid is {} ".format(pes_pstrid))
logger.info("Pes other settings: {}".format(other_settings))
logger.info("Pes other settings append: {}".format(os_append))
if comments is not None:
logger.info("Pes comments: {}".format(comments))
return (
pes_ntasks,
pes_nthrds,
pes_rootpe,
pes_pstrid,
other_settings,
os_append,
comments,
)
def _find_matches(
self, grid_nodes, grid, compset, machine, pesize_opts, override=False
):
grid_choice = None
mach_choice = None
compset_choice = None
pesize_choice = None
max_points = -1
pes_ntasks, pes_nthrds, pes_rootpe, pes_pstrid, other_settings, append = (
{},
{},
{},
{},
{},
{},
)
pe_select = None
comment = None
for grid_node in grid_nodes:
grid_match = self.get(grid_node, "name")
if grid_match == "any" or re.search(grid_match, grid):
mach_nodes = self.get_children("mach", root=grid_node)
for mach_node in mach_nodes:
mach_match = self.get(mach_node, "name")
if mach_match == "any" or re.search(mach_match, machine):
pes_nodes = self.get_children("pes", root=mach_node)
for pes_node in pes_nodes:
pesize_match = self.get(pes_node, "pesize")
compset_match = self.get(pes_node, "compset")
if (
pesize_match == "any"
or (
pesize_opts is not None
and pesize_match == pesize_opts
)
) and (
compset_match == "any"
or re.search(compset_match, compset)
):
points = (
int(grid_match != "any") * 3
+ int(mach_match != "any") * 7
+ int(compset_match != "any") * 2
+ int(pesize_match != "any")
)
if override and points > 0:
for node in self.get_children(root=pes_node):
vid = self.name(node)
logger.info("vid is {}".format(vid))
if "comment" in vid:
comment = self.text(node)
elif "ntasks" in vid:
for child in self.get_children(root=node):
pes_ntasks[
self.name(child).upper()
] = int(self.text(child))
elif "nthrds" in vid:
for child in self.get_children(root=node):
pes_nthrds[
self.name(child).upper()
] = int(self.text(child))
elif "rootpe" in vid:
for child in self.get_children(root=node):
pes_rootpe[
self.name(child).upper()
] = int(self.text(child))
elif "pstrid" in vid:
for child in self.get_children(root=node):
pes_pstrid[
self.name(child).upper()
] = int(self.text(child))
# if the value is already upper case its something else we are trying to set
else:
other_settings[vid] = self.text(node)
append[vid] = self.get(
node, "append", default="false"
)
else:
if points > max_points:
pe_select = pes_node
max_points = points
mach_choice = mach_match
grid_choice = grid_match
compset_choice = compset_match
pesize_choice = pesize_match
elif points == max_points:
logger.warning(
"mach_choice {} mach_match {}".format(
mach_choice, mach_match
)
)
logger.warning(
"grid_choice {} grid_match {}".format(
grid_choice, grid_match
)
)
logger.warning(
"compset_choice {} compset_match {}".format(
compset_choice, compset_match
)
)
logger.warning(
"pesize_choice {} pesize_match {}".format(
pesize_choice, pesize_match
)
)
logger.warning("points = {:d}".format(points))
expect(
False,
"More than one PE layout matches given PE specs",
)
if not override:
for node in self.get_children(root=pe_select):
vid = self.name(node)
logger.debug("vid is {}".format(vid))
if "comment" in vid:
comment = self.text(node)
elif "ntasks" in vid:
for child in self.get_children(root=node):
pes_ntasks[self.name(child).upper()] = int(self.text(child))
elif "nthrds" in vid:
for child in self.get_children(root=node):
pes_nthrds[self.name(child).upper()] = int(self.text(child))
elif "rootpe" in vid:
for child in self.get_children(root=node):
pes_rootpe[self.name(child).upper()] = int(self.text(child))
elif "pstrid" in vid:
for child in self.get_children(root=node):
pes_pstrid[self.name(child).upper()] = int(self.text(child))
# if the value is already upper case its something else we are trying to set
elif vid == self.name(node):
text = self.text(node).strip()
if len(text):
other_settings[vid] = self.text(node)
if grid_choice != "any" or logger.isEnabledFor(logging.DEBUG):
logger.info("Pes setting: grid match is {} ".format(grid_choice))
if mach_choice != "any" or logger.isEnabledFor(logging.DEBUG):
logger.info("Pes setting: machine match is {} ".format(mach_choice))
if compset_choice != "any" or logger.isEnabledFor(logging.DEBUG):
logger.info("Pes setting: compset_match is {} ".format(compset_choice))
if pesize_choice != "any" or logger.isEnabledFor(logging.DEBUG):
logger.info("Pes setting: pesize match is {} ".format(pesize_choice))
return (
pes_ntasks,
pes_nthrds,
pes_rootpe,
pes_pstrid,
other_settings,
append,
comment,
)