Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add LAMMPS tests to EESSI test-suite #131

Merged
merged 39 commits into from
Aug 14, 2024
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
9a86786
add lammps files for running bench mark
Mar 28, 2024
b80e3f2
add lammps.py test
Apr 2, 2024
f07c81a
implement lammps sanity check
Apr 3, 2024
d0818d0
update assign_tasks_per_compute_unit
Apr 3, 2024
78c3780
fix line too long
Apr 3, 2024
332c5fd
clean up code
Apr 3, 2024
3e2f1af
remove example scripts
Apr 4, 2024
b7d1548
update source files and add rhodo test
Apr 4, 2024
0656d2f
clean up lammps.py
Apr 4, 2024
e777ddb
clean up lammps.py
Apr 4, 2024
8a8f838
add gpu support to lj test
Apr 16, 2024
afe68b1
add gpu support to lj test
Apr 16, 2024
868375a
update rhodo test
Apr 17, 2024
36a5dbf
make rhod test compatible with kokkos gpu package
Apr 17, 2024
cd93e6c
fix style
Apr 17, 2024
fbffb2d
fix style
Apr 17, 2024
aaadf7d
fix style
Apr 17, 2024
0db87cd
dedplicate overlapping parts in LAMMPS tests
Apr 18, 2024
3d47b60
fix style
Apr 18, 2024
c0b95c7
updata executable opts
Apr 18, 2024
b025d04
fix style
Apr 18, 2024
79b02bf
add ReadMe for LAMMPS test
Apr 19, 2024
98099ea
add check of neighbors to sanity check
Jun 14, 2024
0edf80e
add sanity-check for number of neighbours
Jun 14, 2024
dac699c
update lammps test
Aug 5, 2024
5b89fd2
Merge branch 'main' into LAMMPS_test
Aug 5, 2024
9acd2e5
Use hook
Aug 5, 2024
485aafa
make linter happy
Aug 5, 2024
fbadd82
get other Performance idicators
Aug 7, 2024
acd7da0
Merge branch 'main' into LAMMPS_test
Aug 7, 2024
4cbacb5
use timestep/s as a performance metric
Aug 7, 2024
03ed65d
add check for total energy
Aug 8, 2024
15fb164
add check for total energy of lj test
Aug 9, 2024
dd8a821
add check for total energy of rhodo test
Aug 9, 2024
65f0c3b
add test for GPU package
Aug 9, 2024
e6b4b5d
add test for GPU package
Aug 9, 2024
7bd0131
add test for GPU package
Aug 9, 2024
d2bf54d
add binding hook
Aug 12, 2024
f6b2c5a
add memory usage to lammps test
Aug 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions eessi/testsuite/tests/apps/lammps/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## Rhodo test

The test requires a data file which was sourced from, https://github.com/lammps/lammps/blob/stable_2Aug2023_update2/bench/data.rhodo.

Checksum: 9b14e259b99b8a28ebbfd86715524c415f82cd5912c164c3827991ac32f23863
163 changes: 163 additions & 0 deletions eessi/testsuite/tests/apps/lammps/lammps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
"""
This module tests the binary 'lmp' in available modules containing substring 'LAMMPS'.
The tests come from the lammps github repository (https://github.com/lammps/lammps/)
"""

import reframe as rfm
import reframe.utility.sanity as sn

from eessi.testsuite import hooks, utils
from eessi.testsuite.constants import * # noqa


class EESSI_LAMMPS_base(rfm.RunOnlyRegressionTest):
scale = parameter(SCALES.keys())
valid_prog_environs = ['default']
valid_systems = ['*']
time_limit = '30m'
device_type = parameter([DEVICE_TYPES[CPU], DEVICE_TYPES[GPU]])

# Parameterize over all modules that start with LAMMPS
module_name = parameter(utils.find_modules('LAMMPS'))

# Set sanity step
@deferrable
laraPPr marked this conversation as resolved.
Show resolved Hide resolved
def assert_lammps_openmp_treads(self):
'''Assert that OpenMP thread(s) per MPI task is set'''
n_threads = sn.extractsingle(
r'^ using (?P<threads>[0-9]+) OpenMP thread\(s\) per MPI task', self.stdout, 'threads', int)
utils.log(f'OpenMP thread(s) is {n_threads}')

return sn.assert_eq(n_threads, self.num_cpus_per_task)

@deferrable
def assert_lammps_processor_grid(self):
'''Assert that the processor grid is set correctly'''
grid = list(sn.extractall(
'^ (?P<x>[0-9]+) by (?P<y>[0-9]+) by (?P<z>[0-9]+) MPI processor grid', self.stdout, tag=['x', 'y', 'z']))
n_cpus = int(grid[0][0]) * int(grid[0][1]) * int(grid[0][2])

return sn.assert_eq(n_cpus, self.num_tasks)

@deferrable
def assert_run(self):
'''Assert that the test calulated the right number of neighbours'''
regex = r'^Loop time of (?P<perf>[.0-9]+) on [0-9]+ procs for 100 steps with (?P<atoms>\S+) atoms'
n_atoms = sn.extractsingle(regex, self.stdout, 'atoms', int)

return sn.assert_eq(n_atoms, 32000)

@performance_function('img/s')
laraPPr marked this conversation as resolved.
Show resolved Hide resolved
def perf(self):
regex = r'^(?P<perf>[.0-9]+)% CPU use with [0-9]+ MPI tasks x [0-9]+ OpenMP threads'
Copy link
Collaborator

@smoors smoors Aug 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesn't look right, this is the %CPU usage.

performance should be one of the following:

Performance: 0.823 ns/day, 29.175 hours/ns, 4.761 timesteps/s, 152.338 katom-step/s

Copy link
Collaborator Author

@laraPPr laraPPr Aug 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Performance: 205379.307 tau/day, 475.415 timesteps/s, 15.213 Matom-step/s this than?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

your line comes from the lj test, while mine comes from the rhodo test.
let's take timesteps/s, as this unit is available for both tests?

Copy link
Collaborator Author

@laraPPr laraPPr Aug 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've now added tau/day for lj and ns/day for rhodo but I can also take the timesteps

Copy link
Collaborator

@smoors smoors Aug 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i just checked, and both tau/day for lj and ns/day for rhodo scale in exactly the same way as timesteps/s, so it doesn't really matter.

i do have a slight preference for timesteps/s as it is easy to understand. otherwise, can you add a comment explaining what exactly tau/day means?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also do not know what tau/day is and google does not have a ready explanation. So changed it to the timesteps/s for lj and rhodo

return sn.extractsingle(regex, self.stdout, 'perf', float)

@run_after('init')
def run_after_init(self):
"""hooks to run after init phase"""

# Filter on which scales are supported by the partitions defined in the ReFrame configuration
hooks.filter_supported_scales(self)

hooks.filter_valid_systems_by_device_type(self, required_device_type=self.device_type)

hooks.set_modules(self)

# Set scales as tags
hooks.set_tag_scale(self)

@run_after('setup')
def run_after_setup(self):
"""hooks to run after the setup phase"""
if self.device_type == 'cpu':
hooks.assign_tasks_per_compute_unit(test=self, compute_unit=COMPUTE_UNIT['CPU'])
elif self.device_type == 'gpu':
laraPPr marked this conversation as resolved.
Show resolved Hide resolved
hooks.assign_tasks_per_compute_unit(test=self, compute_unit=COMPUTE_UNIT['GPU'])
else:
raise NotImplementedError(f'Failed to set number of tasks and cpus per task for device {self.device_type}')

# Set OMP_NUM_THREADS environment variable
hooks.set_omp_num_threads(self)


@rfm.simple_test
class EESSI_LAMMPS_lj(EESSI_LAMMPS_base):
tags = {TAGS['CI']}

sourcesdir = 'src/lj'
executable = 'lmp -in in.lj'

@deferrable
def check_number_neighbors(self):
'''Assert that the test calulated the right number of neighbours'''
regex = r'^Total # of neighbors = (?P<neigh>\S+)'
n_neigh = sn.extractsingle(regex, self.stdout, 'neigh', int)

return sn.assert_eq(n_neigh, 1202833)

@sanity_function
def assert_sanity(self):
'''Check all sanity criteria'''
return sn.all([
self.assert_lammps_openmp_treads(),
self.assert_lammps_processor_grid(),
self.assert_run(),
self.check_number_neighbors(),
])

@run_after('setup')
def set_executable_opts(self):
"""Set executable opts based on device_type parameter"""
num_default = 0 # If this test already has executable opts, they must have come from the command line
hooks.check_custom_executable_opts(self, num_default=num_default)
if not self.has_custom_executable_opts:
# should also check if the lammps is installed with kokkos.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reminder for me to also look at this one again

# Because this exutable opt is only for that case.
if self.device_type == "gpu":
self.executable_opts += [
f'-kokkos on t {self.num_cpus_per_task} g {self.num_gpus_per_node}',
'-suffix kk',
'-package kokkos newton on neigh half',
]
utils.log(f'executable_opts set to {self.executable_opts}')
laraPPr marked this conversation as resolved.
Show resolved Hide resolved


@rfm.simple_test
class EESSI_LAMMPS_rhodo(EESSI_LAMMPS_base):
sourcesdir = 'src/rhodo'
readonly_files = ["data.rhodo"]
executable = 'lmp -in in.rhodo'

@deferrable
def check_number_neighbors(self):
'''Assert that the test calulated the right number of neighbours'''
regex = r'^Total # of neighbors = (?P<neigh>\S+)'
n_neigh = sn.extractsingle(regex, self.stdout, 'neigh', int)

return sn.assert_eq(n_neigh, 12028093)

@sanity_function
def assert_sanity(self):
'''Check all sanity criteria'''
return sn.all([
self.assert_lammps_openmp_treads(),
self.assert_lammps_processor_grid(),
self.assert_run(),
self.check_number_neighbors(),
])

@run_after('setup')
def set_executable_opts(self):
"""Set executable opts based on device_type parameter"""
num_default = 0 # If this test already has executable opts, they must have come from the command line
hooks.check_custom_executable_opts(self, num_default=num_default)
if not self.has_custom_executable_opts:
# should also check if the lammps is installed with kokkos.
# Because this exutable opt is only for that case.
if self.device_type == "gpu":
self.executable_opts += [
f'-kokkos on t {self.num_cpus_per_task} g {self.num_gpus_per_node}',
'-suffix kk',
'-package kokkos newton on neigh half',
]
utils.log(f'executable_opts set to {self.executable_opts}')
30 changes: 30 additions & 0 deletions eessi/testsuite/tests/apps/lammps/src/lj/in.lj
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# 3d Lennard-Jones melt

variable x index 1
variable y index 1
variable z index 1

variable xx equal 20*$x
variable yy equal 20*$y
variable zz equal 20*$z

units lj
atom_style atomic

lattice fcc 0.8442
region box block 0 ${xx} 0 ${yy} 0 ${zz}
create_box 1 box
create_atoms 1 box
mass 1 1.0

velocity all create 1.44 87287 loop geom

pair_style lj/cut 2.5
pair_coeff 1 1 1.0 1.0 2.5

neighbor 0.3 bin
neigh_modify delay 0 every 20 check no

fix 1 all nve

run 100
Loading
Loading