v0.0.11
- made IprCluster target host work. This target host provides access to intel ifort and intel mkl packages, which are available as environment modules. - added a unit test that validates the IprCluster (only works on ipr cluster node) - also improved unit tests to use TMPDIR environment variable if present, in order to avoid permission issues in case the test is run by different users on the same system. - made the benchmark display an error in case starbench fails work related to [https://bugzilla.ipr.univ-rennes.fr/show_bug.cgi?id=3958]
This commit is contained in:
parent
2f2ebdcf35
commit
7d019f74dd
|
@ -22,7 +22,16 @@ pipeline {
|
|||
sh """#!/bin/bash
|
||||
set -o errexit
|
||||
source ${IPRBENCH_VENV_PATH}/bin/activate &&
|
||||
python -m unittest
|
||||
python -m unittest ./test
|
||||
"""
|
||||
}
|
||||
}
|
||||
stage('testing (tests that only work on ipr cluster nodes)') {
|
||||
steps {
|
||||
sh """#!/bin/bash
|
||||
set -o errexit
|
||||
source ${IPRBENCH_VENV_PATH}/bin/activate &&
|
||||
python -m unittest ./ci/test_iprcluster.py
|
||||
"""
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
"""tests specific for IPR cluster
|
||||
"""
|
||||
import unittest
|
||||
import logging
|
||||
import subprocess
|
||||
import json
|
||||
from pathlib import Path
|
||||
from shutil import rmtree
|
||||
from os import getenv
|
||||
from iprbench.core import ResultsDbParams, HostTypeId
|
||||
from cocluto.SimpaDbUtil import SshAccessedMysqlDb
|
||||
|
||||
|
||||
def test_resultsdb(resultsdb_params: ResultsDbParams, results_root_path: Path):
|
||||
results_db_type = resultsdb_params['type']
|
||||
logging.info('testing resultsdb %s', results_db_type)
|
||||
logging.info('resultsdb_params : %s', json.dumps(resultsdb_params))
|
||||
results_dir = results_root_path / results_db_type
|
||||
if results_dir.exists():
|
||||
rmtree(results_dir)
|
||||
results_dir.mkdir(parents=True)
|
||||
benchmark_id = 'mamul1'
|
||||
benchmark_config = {
|
||||
'fortran_compiler': 'ifort:<default>',
|
||||
'blas_library': 'intelmkl:<default>',
|
||||
'matrix_size': 1024,
|
||||
'num_loops': 10,
|
||||
'num_cores': 2,
|
||||
'launcher': 'iprbench.unittest.iprcluster',
|
||||
}
|
||||
target_system_type_id = HostTypeId('fr.univ-rennes.ipr.cluster-node')
|
||||
command = f'iprbench-run --benchmark-id \'{benchmark_id}\' --config \'{json.dumps(benchmark_config)}\' --results-dir {results_dir} --resultsdb-params \'{json.dumps(resultsdb_params)}\' --target-system-type-id "{target_system_type_id}"'
|
||||
subprocess.run(command, shell=True, check=True, executable='/bin/bash')
|
||||
|
||||
|
||||
class IprClusterTestCase(unittest.TestCase):
|
||||
|
||||
results_root_dir: Path
|
||||
|
||||
def setUp(self) -> None: # pylint: disable=useless-parent-delegation
|
||||
self.results_root_dir = Path(f'{getenv("TMPDIR", default="/tmp")}/iprbenchs/test_results/resultsdb')
|
||||
if self.results_root_dir.exists():
|
||||
rmtree(self.results_root_dir)
|
||||
self.results_root_dir.mkdir(parents=True)
|
||||
return super().setUp()
|
||||
|
||||
def test_sqlserver(self):
|
||||
db_server_fqdn = 'iprbenchsdb.ipr.univ-rennes1.fr'
|
||||
db_user = 'test_iprbenchw'
|
||||
db_name = 'test_iprbenchs'
|
||||
ssh_user = 'test_iprbenchw'
|
||||
sql_backend = SshAccessedMysqlDb(db_server_fqdn, db_user, db_name, ssh_user)
|
||||
if sql_backend.table_exists('mamul1'):
|
||||
sql_backend.delete_table('mamul1')
|
||||
resultsdb_params = {
|
||||
'type': 'sqlserver-viassh-database',
|
||||
'db_server_fqdn': db_server_fqdn,
|
||||
'db_user': db_user,
|
||||
'db_name': db_name,
|
||||
'ssh_user': ssh_user
|
||||
}
|
||||
test_resultsdb(resultsdb_params, self.results_root_dir)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
unittest.main()
|
|
@ -85,7 +85,9 @@ class HiBench(IBenchmark):
|
|||
if len(env_vars_bash_commands) > 0:
|
||||
shell_command += f'{env_vars_bash_commands} && '
|
||||
shell_command += f'{get_proxy_env_vars()} starbench --source-tree-provider \'{source_tree_provider}\' --num-cores {num_cores} --output-dir={output_dir} --cmake-path={cmake_path} {" ".join([f"--cmake-option={option}" for option in cmake_options])} --benchmark-command=\'{benchmark_command}\' --output-measurements={output_measurements_file_path}'
|
||||
subprocess.run(shell_command, shell=True, check=True, executable='/bin/bash')
|
||||
completed_process = subprocess.run(shell_command, shell=True, check=False, executable='/bin/bash') # for some reason, module is only found when executable is /bin/bash
|
||||
if completed_process.returncode != 0:
|
||||
assert False, f'the shell command "{shell_command}" failed. See details in {output_dir}'
|
||||
measurements: BenchmarkMeasurements = {}
|
||||
starbench_results = StarbenchResults(output_measurements_file_path)
|
||||
|
||||
|
|
|
@ -76,7 +76,9 @@ class MaMul1(IBenchmark):
|
|||
shell_command += f'{env_vars_bash_commands} && '
|
||||
shell_command += f'starbench --source-tree-provider \'{source_tree_provider}\' --num-cores {num_cores} --output-dir={output_dir} --cmake-path=/usr/bin/cmake {" ".join([f"--cmake-option={option}" for option in cmake_options])} --benchmark-command=\'{" ".join(benchmark_command)}\' --output-measurements={output_measurements_file_path}'
|
||||
logging.debug('shell_command = "%s"', shell_command)
|
||||
subprocess.run(shell_command, shell=True, check=True, encoding='/bin/bash')
|
||||
completed_process = subprocess.run(shell_command, shell=True, check=False, executable='/bin/bash') # for some reason, module is only found when executable is /bin/bash
|
||||
if completed_process.returncode != 0:
|
||||
assert False, f'the shell command "{shell_command}" failed. See details in {output_dir}'
|
||||
measurements: BenchmarkMeasurements = {}
|
||||
starbench_results = StarbenchResults(output_measurements_file_path)
|
||||
measurements['duration_avg'] = starbench_results.get_average_duration()
|
||||
|
|
|
@ -40,7 +40,7 @@ class HibenchResultsParser():
|
|||
|
||||
# module-whatis Sets the Environment to use the Intel Math Kernel Libraries version 2020.0.1
|
||||
# setenv MKLROOT /opt/intel/compilers_and_libraries_2020.1.217/linux/mkl
|
||||
lib_info['lib_name'] = 'mkl'
|
||||
lib_info['lib_name'] = 'intelmkl'
|
||||
lib_info['lib_version'] = '2020.0.1'
|
||||
break
|
||||
elif path.find('/usr/lib/libblas.so') != -1:
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
from typing import Set
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import re
|
||||
|
||||
EnvModule = str # eg compilers/ifort/latest
|
||||
|
||||
|
||||
def get_available_modules() -> Set[EnvModule]:
|
||||
available_modules = set()
|
||||
completed_process = subprocess.run('module avail --terse', executable='/bin/bash', shell=True, capture_output=True, check=True) # for some reason, module is only found when executable is /bin/bash
|
||||
# (iprbench.venv) graffy@alambix50:/opt/ipr/cluster/work.local/graffy/bug3958/iprbench.git$ module avail --terse
|
||||
# /usr/share/modules/modulefiles:
|
||||
# compilers/ifort/15.0.2
|
||||
# compilers/ifort/17.0.1
|
||||
# ...
|
||||
# lib/mpi/intelmpi/2021.13.0
|
||||
# lib/mpi/intelmpi/latest
|
||||
# module-git
|
||||
# module-info
|
||||
# modules
|
||||
# null
|
||||
stdout = completed_process.stdout.decode('utf-8')
|
||||
for line in stdout.splitlines():
|
||||
if not re.search(r'\:$', line): # ignore the directories such as '/usr/share/modules/modulefiles:'
|
||||
available_modules.add(EnvModule(line))
|
||||
return available_modules
|
||||
|
||||
|
||||
def get_module_file_path(env_module: EnvModule) -> Path:
|
||||
# graffy@alambix-frontal:~$ module help compilers/ifort/latest
|
||||
# -------------------------------------------------------------------
|
||||
# Module Specific Help for /usr/share/modules/modulefiles/compilers/ifort/latest:
|
||||
|
||||
# Provides the same functionality as the command '/opt/intel/oneapi-2024.2.1/compiler/latest/env/vars.sh intel64'
|
||||
# -------------------------------------------------------------------
|
||||
module_file_path = None
|
||||
completed_process = subprocess.run(f'module help {env_module}', executable='/bin/bash', shell=True, capture_output=True, check=True) # for some reason, module is only found when executable is /bin/bash
|
||||
stdout = completed_process.stdout.decode('utf-8')
|
||||
for line in stdout.splitlines():
|
||||
match = re.match(r'^Module Specific Help for (?P<module_file_path>[^:]+):', line)
|
||||
if match:
|
||||
module_file_path = Path(match['module_file_path'])
|
||||
break
|
||||
if module_file_path is None:
|
||||
raise ValueError(f'failed to find the file path of the environment module {env_module}')
|
||||
return module_file_path
|
|
@ -3,6 +3,8 @@ import subprocess
|
|||
import re
|
||||
from pathlib import Path
|
||||
from .core import ITargetHost, PackageId, PackageVersion, HostTypeId
|
||||
from .envmodules import EnvModule, get_available_modules, get_module_file_path
|
||||
# import logging
|
||||
|
||||
|
||||
DebianPackageVersion = str # a version string, as in debian package versions, eg 4:9.3.0-1ubuntu2
|
||||
|
@ -20,7 +22,7 @@ class DebianHost(ITargetHost):
|
|||
package_version = self.get_installed_package_version(package_id)
|
||||
return package_version
|
||||
|
||||
def get_package_activation_command(self, package_id: str, package_version: str) -> str:
|
||||
def get_package_activation_command(self, package_id: PackageId, package_version: str) -> str:
|
||||
current_version = self.get_package_default_version(package_id)
|
||||
if current_version != package_version:
|
||||
raise ValueError(f'{package_id} version {package_version} not available: only {package_id} version {current_version} is available on this host')
|
||||
|
@ -161,20 +163,49 @@ class IprClusterNode(DebianHost):
|
|||
def get_host_type_id(self) -> HostTypeId:
|
||||
return HostTypeId('fr.univ-rennes.ipr.cluster-node')
|
||||
|
||||
def get_latest_version_for_env_module(self, package_env_module: str):
|
||||
def get_latest_version_for_env_module(self, package_env_module: str) -> PackageVersion:
|
||||
# package_env_module: eg compilers/ifort
|
||||
# graffy@alambix-frontal:~$ module help compilers/ifort/latest
|
||||
# -------------------------------------------------------------------
|
||||
# Module Specific Help for /usr/share/modules/modulefiles/compilers/ifort/latest:
|
||||
|
||||
# Provides the same functionality as the command '/opt/intel/oneapi-2024.2.1/compiler/latest/env/vars.sh intel64'
|
||||
# -------------------------------------------------------------------
|
||||
# graffy@alambix-frontal:~$ ls -l /usr/share/modules/modulefiles/compilers/ifort/latest
|
||||
# lrwxrwxrwx 1 root root 9 18 nov. 02:11 /usr/share/modules/modulefiles/compilers/ifort/latest -> 2021.13.1
|
||||
raise NotImplementedError()
|
||||
|
||||
def get_package_default_version(self, package_id: str) -> str:
|
||||
if package_id == 'ifort':
|
||||
return self.get_latest_version_for_env_module('compilers/ifort')
|
||||
available_modules = get_available_modules()
|
||||
shortcut_env_module = EnvModule(f'{package_env_module}/latest')
|
||||
if shortcut_env_module not in available_modules:
|
||||
raise ValueError(f'failed to find {shortcut_env_module} amongst available environment modules')
|
||||
# logging.debug('available_modules = %s', available_modules)
|
||||
shortcut_file_path = get_module_file_path(shortcut_env_module)
|
||||
# logging.debug('shortcut_file_path = %s', shortcut_file_path)
|
||||
assert shortcut_file_path.is_symlink(), f'unexpected case: {shortcut_file_path} is expected to be a symbolic link to an actual version of {package_env_module}'
|
||||
real_file_path = shortcut_file_path.resolve() # eg /usr/share/modules/modulefiles/compilers/ifort/2021.13.1
|
||||
# logging.debug('real_file_path = %s', real_file_path)
|
||||
version = real_file_path.name
|
||||
match = re.match(r'^[0-9]+\.[0-9]+\.[0-9]$', version)
|
||||
assert match, f'unexpected format for version: {version} for module file path {real_file_path}'
|
||||
return PackageVersion(version)
|
||||
|
||||
def get_package_default_version(self, package_id: PackageId) -> PackageVersion:
|
||||
env_modules_packages = self._get_env_modules_packages()
|
||||
if package_id in env_modules_packages.keys():
|
||||
return self.get_latest_version_for_env_module(env_modules_packages[package_id])
|
||||
else:
|
||||
return super().get_package_default_version(package_id)
|
||||
|
||||
def get_package_activation_command(self, package_id: PackageId, package_version: str) -> str:
|
||||
env_modules_packages = self._get_env_modules_packages()
|
||||
if package_id in env_modules_packages.keys():
|
||||
env_module = EnvModule(f'{env_modules_packages[package_id]}/{package_version}')
|
||||
assert env_module in get_available_modules(), f'environment module "{env_module}" is not one of the available modules on this system'
|
||||
return f'module load {env_module}'
|
||||
else:
|
||||
return super().get_package_activation_command(package_id, package_version)
|
||||
|
||||
def _get_env_modules_packages(self) -> Dict[PackageId, str]:
|
||||
""" gets list packages available as environment modules"""
|
||||
return {
|
||||
PackageId('ifort'): 'compilers/ifort',
|
||||
PackageId('intelmkl'): 'lib/mkl',
|
||||
}
|
||||
|
||||
def _get_package_env_module_root(self, package_id: PackageId) -> str:
|
||||
return self._get_env_modules_packages()[package_id]
|
||||
|
|
|
@ -1 +1 @@
|
|||
__version__ = '0.0.10'
|
||||
__version__ = '0.0.11'
|
||||
|
|
|
@ -6,6 +6,7 @@ import subprocess
|
|||
import json
|
||||
from pathlib import Path
|
||||
from shutil import rmtree
|
||||
from os import getenv
|
||||
from iprbench.core import ResultsDbParams, HostTypeId
|
||||
from cocluto.SimpaDbUtil import SshAccessedMysqlDb
|
||||
|
||||
|
@ -37,7 +38,7 @@ class ResultsDbTestCase(unittest.TestCase):
|
|||
results_root_dir: Path
|
||||
|
||||
def setUp(self) -> None: # pylint: disable=useless-parent-delegation
|
||||
self.results_root_dir = Path('/tmp/iprbenchs/test_results/resultsdb')
|
||||
self.results_root_dir = Path(f'{getenv("TMPDIR", default="/tmp")}/iprbenchs/test_results/resultsdb')
|
||||
if self.results_root_dir.exists():
|
||||
rmtree(self.results_root_dir)
|
||||
self.results_root_dir.mkdir(parents=True)
|
||||
|
|
Loading…
Reference in New Issue