Skip to content

Commit

Permalink
Use CMake to obtain configuration information
Browse files Browse the repository at this point in the history
  • Loading branch information
henryleberre committed Nov 19, 2023
1 parent 1d4feb6 commit b2ff2a5
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 59 deletions.
8 changes: 7 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ option(MFC_SYSCHECK "Build syscheck" OFF)
option(MFC_DOCUMENTATION "Build documentation" OFF)
option(MFC_ALL "Build everything" OFF)

if (MFC_BUILD_ALL)
if (MFC_ALL)
set(MFC_PRE_PROCESS ON FORCE)
set(MFC_SIMULATION ON FORCE)
set(MFC_POST_PROCESS ON FORCE)
Expand Down Expand Up @@ -513,3 +513,9 @@ if (MFC_DOCUMENTATION)
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/docs/index.html"
DESTINATION "docs/mfc")
endif()

site_name(SITE_NAME)

configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/toolchain/cmake/configuration.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/configuration.txt")
30 changes: 30 additions & 0 deletions toolchain/cmake/configuration.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
CMake Configuration:

CMake v${CMAKE_VERSION} on ${SITE_NAME}

C : ${CMAKE_C_COMPILER_ID} v${CMAKE_C_COMPILER_VERSION} (${CMAKE_C_COMPILER})
Fortran : ${CMAKE_Fortran_COMPILER_ID} v${CMAKE_Fortran_COMPILER_VERSION} (${CMAKE_Fortran_COMPILER})

PRE_PROCESS : ${MFC_PRE_PROCESS}
SIMULATION : ${MFC_SIMULATION}
POST_PROCESS : ${MFC_POST_PROCESS}
SYSCHECK : ${MFC_SYSCHECK}
DOCUMENTATION : ${MFC_DOCUMENTATION}
ALL : ${MFC_ALL}

MPI : ${MFC_MPI}
OpenACC : ${MFC_OpenACC}

Fypp : ${FYPP_EXE}
Doxygen : ${DOXYGEN_EXECUTABLE}

Build Type : ${CMAKE_BUILD_TYPE}

Configuration Environment:

CC : $ENV{CC}
CXX : $ENV{CXX}
FC : $ENV{FC}
OMPI_CC : $ENV{OMPI_CC}
OMPI_CXX : $ENV{OMPI_CXX}
OMPI_FC : $ENV{OMPI_FC}
26 changes: 24 additions & 2 deletions toolchain/mfc/build.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import os, typing, dataclasses
import re, os, typing, dataclasses

from .common import MFCException, system, delete_directory, create_directory
from .state import ARG, CFG
Expand Down Expand Up @@ -70,7 +70,21 @@ def is_configured(self) -> bool:
return os.path.isfile(
os.sep.join([self.get_build_dirpath(), "CMakeCache.txt"])
)


def get_configuration_txt(self) -> dict | None:
if not self.is_configured():
return None

configpath = os.path.join(self.get_build_dirpath(), "configuration.txt")
if not os.path.exists(configpath):
return None

with open(configpath) as f:
return f.read()

return None


def build(self, history: typing.Set[str] = None):
if history is None:
history = set()
Expand Down Expand Up @@ -229,6 +243,14 @@ def clean_targets(targets: typing.Iterable[typing.Union[MFCTarget, str]]):
get_target(target).clean()


def get_configured_targets() -> typing.List[MFCTarget]:
r = []
for target in TARGETS:
if target.is_configured():
r.append(target)
return r


def build():
build_targets(ARG("targets"))

Expand Down
47 changes: 0 additions & 47 deletions toolchain/mfc/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,50 +240,3 @@ def get_cpuinfo():
else:
proc = "No CPU info found"
return "CPU Info: \n" + proc

def get_envinfo():
myenv = ['FC','CC','CXX','OMPI_FC', 'OMPI_CC', 'OMPI_CXX']
env = [f"{x} -> {os.getenv(x,' ')}" for x in myenv]
return "Environment Info: \n" + format_list_to_string(env)

def get_mpiinfo():
ret = ""
if (does_command_exist("mpif90")):
proc = subprocess.Popen(['which','mpif90'], stdout=subprocess.PIPE,universal_newlines=True)
out, err = proc.communicate()
ret = ret + "mpif90 -> " + out

if (does_command_exist("mpicc")):
proc = subprocess.Popen(['which','mpicc'], stdout=subprocess.PIPE,
universal_newlines=True)
out, err = proc.communicate()
ret = ret + "mpicc -> " + out
return "MPI Info: \n" + ret

def get_hostinfo():
if (does_command_exist("hostname")):
proc = subprocess.Popen(['hostname'], stdout=subprocess.PIPE,universal_newlines=True)
out, err = proc.communicate()
return "Hostname -> " + out
else:
return "No hostname info found"

def get_lockfile():
lockfile="build/lock.yaml"
if (os.path.isfile(lockfile)):
# found MFC lockfile
with open(lockfile,"r") as file:
lock = str(yaml.safe_load(file))
return "Lockfile: \n" + lock + "\n"
else:
return "No lockfile found"

def get_sysinfo():
time = "This file was created on: \n" + str(datetime.now())
host = get_hostinfo()
cpu = get_cpuinfo()
env = get_envinfo()
mod = "Modules: \n" + format_list_to_string(get_loaded_modules())
mpi = get_mpiinfo()
lock = get_lockfile()
return time + "\n\n" + host + "\n\n" + cpu + "\n\n" + env + "\n\n" + mod + "\n\n" + mpi + "\n\n" + lock
38 changes: 34 additions & 4 deletions toolchain/mfc/packer/pack.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import dataclasses, typing, os, re, math
import dataclasses, typing, sys, os, re, math

from .. import common
from ..build import get_configured_targets
from ..state import CFG
from ..common import MFCException
from datetime import datetime

from pathlib import Path

Expand Down Expand Up @@ -46,10 +49,37 @@ def save(self, filepath: str):

common.file_write(filepath, '\n'.join([ str(e) for e in sorted(self.entries.values(), key=lambda x: x.filepath) ]))

def save_metadata(self, filepath: str, sysinfo):
common.file_write(filepath, sysinfo)
metadata = f"""\
This file was created on {str(datetime.now())}.
def hash_NaNs(self) -> bool:
mfc.sh:
Invocation: {' '.join(sys.argv[1:])}
Lock: {CFG()}
"""

for target in get_configured_targets():
cfg = target.get_configuration_txt()

if cfg is None:
continue

metadata += f"""\
{target.name}:
{' '.join(cfg.splitlines(keepends=True))}
"""

metadata += f"""\
CPU:
{' '.join(common.get_cpuinfo().splitlines(keepends=True))}
"""

common.file_write(f"{filepath.rstrip('.txt')}-metadata.txt", metadata)

def has_NaNs(self) -> bool:
for entry in self.entries.values():
for double in entry.doubles:
if math.isnan(double):
Expand Down
7 changes: 2 additions & 5 deletions toolchain/mfc/test/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from .case import TestCase
from .cases import generate_cases
from .. import sched
from ..common import MFCException, does_command_exist, format_list_to_string, get_program_output, get_sysinfo
from ..common import MFCException, does_command_exist, format_list_to_string, get_program_output
from ..build import build_targets, HDF5, PRE_PROCESS, SIMULATION, POST_PROCESS

from ..packer import tol as packtol
Expand Down Expand Up @@ -160,16 +160,14 @@ def _handle_case(test: TestCase, devices: typing.Set[int]):
if err is not None:
raise MFCException(f"Test {test}: {err}")

if pack.hash_NaNs():
if pack.has_NaNs():
raise MFCException(f"Test {test}: NaNs detected in the case.")

golden_filepath = os.path.join(test.get_dirpath(), "golden.txt")
golden_meta_filepath = os.path.join(test.get_dirpath(), "golden-metadata.txt")
sysinfo = common.get_sysinfo()
if ARG("generate"):
common.delete_file(golden_filepath)
pack.save(golden_filepath)
pack.save_metadata(golden_meta_filepath,sysinfo)
else:
if not os.path.isfile(golden_filepath):
raise MFCException(f"Test {test}: The golden file does not exist! To generate golden files, use the '--generate' flag.")
Expand All @@ -182,7 +180,6 @@ def _handle_case(test: TestCase, devices: typing.Set[int]):
golden.set(pentry)

golden.save(golden_filepath)
pack.save_metadata(golden_meta_filepath,sysinfo)
else:
err, msg = packtol.compare(pack, packer.load(golden_filepath), packtol.Tolerance(tol, tol))
if msg is not None:
Expand Down

0 comments on commit b2ff2a5

Please sign in to comment.