Skip to content

Commit

Permalink
Add OpenFOAM benchmark.
Browse files Browse the repository at this point in the history
Tested:
Manually running
./blaze-bin/cloud/performance/artemis/artemis --benchmarks=openfoam --run_stage=provision,prepare,run\

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=273370055
  • Loading branch information
tohaowu committed Oct 10, 2019
1 parent 3c65f1c commit 9c5f6c2
Show file tree
Hide file tree
Showing 4 changed files with 369 additions and 0 deletions.
30 changes: 30 additions & 0 deletions perfkitbenchmarker/data/openfoam.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1

mQENBFeGXxcBCACpBHAlBk67MVnHtLux0eI/gJuo5eTSLzQd4TYXgLbOXs8aCEH1
7JKAS24m2KwtcqBwTfW+wb54b0HHzJn81Zpmd7JXt/6oX4wZHTXMED9/P893UHOI
sC5e1O9BzDQ4J1Ot4SMMRElNZyxdcbqGTvp+t67xrBqG1ZoXO4WYfUemNT+I4xrs
xzguKVvL+yWB8hHZ6JpzScC3xQM9JSL7Gzmv6NvXkr+fDw6Ct/aUdB3PjbSlINKC
4sTfQRvokE6nf7SVMqiPTDup+E1DLLfzvUJSxoCGc34wbiuA5ThqE11Y4DiLZaLe
r3V03nbEJY2T1cGExS7njMs3uFiICovfWdmXABEBAAG0KE9wZW5GT0FNIEZvdW5k
YXRpb24gPGFkbWluQG9wZW5mb2FtLm9yZz6JATcEEwEKACEFAleGXxcCGwMFCwkI
BwMFFQoJCAsFFgMCAQACHgECF4AACgkQbA2scosp2BdYdAf+K1+RfWZZSZBwqpPR
MNvV8RkpQ5k7m68NdFRha6cmxCnFJwyw7EJrI0ZXrnz+VstmTvTt05a2ml3MvMdK
WBZs0/dA3LuqYLjGCPCDB5iu5w/sVCXyawZejoe/X3/ODRDgUiJ1LCKQbhwHqNda
yIH7gBYdmy3bzjncm5lYn/Jxw42qAOog/Lnwrru5EIeTyNWrk495KEjTasb9L31I
61G5oEkZsoDk6kPIf93lHBzey60wyc3dU6jQAbnjCB1PvcQP12uv8MK0bO6E5TKS
BYj/W3wayzaU/FD7NIbCbsHqc1rDNDutp3Y6B5z3tP3bSJ70FfoWfGWuuPG6uEJy
W5EHUbkBDQRXhl8XAQgAxQnYD9yvl19ULD3el+vhwUb+xIj2gkpyCfP3g6as68OR
6QsHfYyFrLxBCroGb/fx4AT240ikErplgYThr+fwVl8CXyWtdrgrUwU8DopTTiTN
xYxbxklljp8ZO8rJNPpIWJBTIUSZv+2sd+LrkcEocZ0tWsUoshlc3iBYtmiO+HbW
9yAxKHOkA3eooSZHERs8BIQ+ZLhv3x5FB73jbMYOIB0dqU2GrbDvFBnKx9AWheCd
JsOAlAlGnNcyI4ZDdJ33DozCUgalxmTMGrfPyCvz9zqKm1gQsscmrNFij/F9TeNY
+oEjRoXwwnyM5YiexMcxhLp2NPjagFU0lNS8gCFy2QARAQABiQEfBBgBCgAJBQJX
hl8XAhsMAAoJEGwNrHKLKdgXShUH/1rUNk9MvoZ9HBdvm7/z70J64cnNPjIwPuhO
5FMihCMmnsESjCgzrP6rVDOma4psf7fwEe8m1cltl8gVQ1cZIo2LO/0XnbBeo9b9
hA+RqtKz9IZYqNzbvGxEbkhMf6O/TDSFmJpAueh8D3/Dgcrvya0bflkwoGl7RDKu
Iq68v4Ri1s4LAq8RCIsB85NKds2vLIAuMrhbhtwYEVgalPotMMHX/MMrKL5T95Ac
/GuySu+Yk7kmfrFq0SIzP1BFGv+l84ke18zMu0ssGHVGY0eaEEpO2aude+HhMJqD
+PmSM0ZDHsJu4It2PIIGtgGWfai9ddXOI2+z8W6ugsKr/tq7Sik=
=DlyX
-----END PGP PUBLIC KEY BLOCK-----
208 changes: 208 additions & 0 deletions perfkitbenchmarker/linux_benchmarks/openfoam_benchmark.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
# Copyright 2019 PerfKitBenchmarker Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""OpenFOAM Benchmark.
OpenFOAM is a C++ toolbox for the development of customized numerical solvers,
and pre-/post-processing utilities for the solution of continuum mechanics
problems, most prominently including computational fluid dynamics.
https://openfoam.org/
This benchmark runs a motorbike simulation that is popularly used to measure
scalability of OpenFOAM across multiple cores. Since this is a complex
computation, make sure to use a compute-focused machine-type that has multiple
cores before attempting to run.
# TODO(user): Add support for multiple vms.
"""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import datetime
import logging
import posixpath
import time

from perfkitbenchmarker import configs
from perfkitbenchmarker import flags
from perfkitbenchmarker import sample
from perfkitbenchmarker.linux_packages import openfoam


_DEFAULT_CASE = 'motorbike'
_CASE_PATHS = {
'motorbike': 'tutorials/incompressible/simpleFoam/motorBike'
}
assert _DEFAULT_CASE in _CASE_PATHS


FLAGS = flags.FLAGS
flags.DEFINE_enum(
'openfoam_case', _DEFAULT_CASE,
sorted(list(_CASE_PATHS.keys())), 'Name of the Openfoam case to run.')


BENCHMARK_NAME = 'openfoam'
BENCHMARK_CONFIG = """
openfoam:
description: Runs a Openfoam benchmarks.
vm_groups:
default:
vm_spec:
GCP:
machine_type: c2-standard-8
zone: us-east1-c
boot_disk_size: 100
Azure:
machine_type: Standard_F8s_v2
zone: eastus2
AWS:
machine_type: c5.2xlarge
zone: us-east-1f
boot_disk_size: 100
os_type: ubuntu1604
vm_count: null
"""
_BENCHMARK_RUN_PATH = '$HOME/Openfoam/${USER}-7/run'


def GetConfig(user_config):
"""Returns the configuration of a benchmark."""
return configs.LoadConfig(BENCHMARK_CONFIG, user_config, BENCHMARK_NAME)


def Prepare(benchmark_spec):
"""Prepares the VMs and other resources for running the benchmark.
This is a good place to download binaries onto the VMs, create any data files
needed for a benchmark run, etc.
Args:
benchmark_spec: The benchmark spec for this sample benchmark.
"""
vm = benchmark_spec.vms[0]
vm.Install('openfoam')
vm.RemoteCommand('mkdir -p %s' % _BENCHMARK_RUN_PATH)
vm.RemoteCommand('cp -r {case_path} {run_path}'.format(
case_path=posixpath.join(openfoam.OPENFOAM_ROOT,
_CASE_PATHS[FLAGS.openfoam_case]),
run_path=_BENCHMARK_RUN_PATH))


def _AsSeconds(input_time):
"""Convert time from formatted string to seconds.
Input format: 4m1.419s
Args:
input_time: The time to parse to a float.
Returns:
A float representing the time in seconds.
"""
parsed = time.strptime(input_time, '%Mm%S.%fs')
return datetime.timedelta(minutes=parsed.tm_min,
seconds=parsed.tm_sec).total_seconds()


def _GetSample(line):
"""Parse a single output line into a performance sample.
Input format:
real 4m1.419s
Args:
line: A single line from the Openfoam timing output.
Returns:
A single performance sample, with times in ms.
"""
runtime_category, runtime_output = line.split()
runtime_seconds = _AsSeconds(runtime_output)
logging.info('Runtime of %s seconds from [%s, %s]',
runtime_seconds, runtime_category, runtime_output)
runtime_category = 'time_' + runtime_category
return sample.Sample(runtime_category, runtime_seconds, 'seconds')


def _GetSamples(output):
"""Parse the output and return performance samples.
Output is in the format:
real 4m1.419s
user 23m11.198s
sys 0m25.274s
Args:
output: The output from running the Openfoam benchmark.
Returns:
A list of performance samples.
"""
return [_GetSample(line) for line in output.strip().splitlines()]


def _GetOpenfoamVersion(vm):
"""Get the installed OpenFOAm version from the vm."""
return vm.RemoteCommand('source {}/etc/bashrc && echo $WM_PROJECT_VERSION'
.format(openfoam.OPENFOAM_ROOT))[0]


def _GetOpenmpiVersion(vm):
"""Get the installed OpenMPI version from the vm."""
return vm.RemoteCommand('mpirun -version')[0].split()[3]


def Run(benchmark_spec):
"""Runs the benchmark and returns a dict of performance data.
It must be possible to run the benchmark multiple times after the Prepare
stage.
Args:
benchmark_spec: The benchmark spec for the OpenFOAM benchmark.
Returns:
A list of performance samples.
"""
vm = benchmark_spec.vms[0]
run_cmd = [
'source %s/etc/bashrc' % openfoam.OPENFOAM_ROOT,
'cd %s/motorBike' % _BENCHMARK_RUN_PATH,
'./Allclean',
'time ./Allrun'
]
_, run_output = vm.RemoteCommand(' && '.join(run_cmd))
common_metadata = {
'case': FLAGS.openfoam_case,
'openfoam_version': _GetOpenfoamVersion(vm),
'openmpi_version': _GetOpenmpiVersion(vm)
}
samples = _GetSamples(run_output)
for result in samples:
result.metadata.update(common_metadata)
return samples


def Cleanup(benchmark_spec):
"""Cleans up after the benchmark completes.
The state of the VMs should be equivalent to the state before Prepare was
called.
Args:
benchmark_spec: The benchmark spec for the OpenFOAM benchmark.
"""
del benchmark_spec
57 changes: 57 additions & 0 deletions perfkitbenchmarker/linux_packages/openfoam.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Copyright 2019 PerfKitBenchmarker Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Module containing OpenFOAM installation and cleanup functions.
OpenFOAM is a C++ toolbox for the development of customized numerical solvers,
and pre-/post-processing utilities for the solution of continuum mechanics
problems, most prominently including computational fluid dynamics.
OpenFOAM foundation: https://openfoam.org/.
Instructions for installing OpenFOAM: https://openfoam.org/download/7-ubuntu/.
"""

from __future__ import absolute_import
from __future__ import division
from __future__ import google_type_annotations
from __future__ import print_function

import logging


PACKAGE_NAME = 'openfoam'


OPENFOAM_ROOT = '/opt/openfoam7'


"""Needed for downloading OpenFOAM."""
_OPENFOAM_REPOSITORY_URL = 'http://dl.openfoam.org/ubuntu'
_OPENFOAM_REPOSITORY_KEY = 'openfoam.key'


def YumInstall(vm):
del vm
raise NotImplementedError()


def AptInstall(vm):
"""Install OpenFOAM https://openfoam.org/download/7-ubuntu/."""
logging.info('Installing OpenFOAM via apt')
remote_key_file = '/tmp/openfoam.key'
vm.PushDataFile(_OPENFOAM_REPOSITORY_KEY, remote_key_file)
vm.RemoteCommand('sudo apt-key add {0}; rm {0}'.format(remote_key_file))
vm.RemoteCommand('sudo add-apt-repository {}'
.format(_OPENFOAM_REPOSITORY_URL))
vm.RemoteCommand('sudo apt-get -y update')
vm.RemoteCommand('sudo apt-get -y install openfoam7')
74 changes: 74 additions & 0 deletions tests/linux_benchmarks/openfoam_benchmark_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Copyright 2019 PerfKitBenchmarker Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Tests for openfoam_benchmark."""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import unittest

import mock
from perfkitbenchmarker import sample
from perfkitbenchmarker import test_util
from perfkitbenchmarker.linux_benchmarks import openfoam_benchmark
from tests import pkb_common_test_case


class OpenfoamBenchmarkTest(pkb_common_test_case.PkbCommonTestCase,
test_util.SamplesTestMixin):

def setUp(self):
super(OpenfoamBenchmarkTest, self).setUp()
self.mock_vm = mock.Mock()
self.benchmark_spec = mock.Mock(vms=[self.mock_vm])

@mock.patch.object(openfoam_benchmark, '_GetOpenmpiVersion',
return_value='1.10.2')
@mock.patch.object(openfoam_benchmark, '_GetOpenfoamVersion',
return_value='7')
def testRunReturnsCorrectlyParsedSamples(self,
mock_getopenfoamversion,
mock_getmpiversion):
# Run with mocked output data
self.mock_vm.RemoteCommand.return_value = None, '\n'.join(
['real 4m1.419s', 'user 23m11.198s', 'sys 0m25.274s'])
samples = openfoam_benchmark.Run(self.benchmark_spec)

# Verify command is what we expected to run
run_cmd = [
'source /opt/openfoam7/etc/bashrc',
'cd $HOME/Openfoam/${USER}-7/run/motorBike',
'./Allclean',
'time ./Allrun'
]
self.mock_vm.RemoteCommand.assert_called_with(' && '.join(run_cmd))

# Verify sample equality
expected_metadata = {
'case': 'motorbike',
'openfoam_version': '7',
'openmpi_version': '1.10.2'
}
unit = 'seconds'
self.assertSamplesEqualUpToTimestamp(
sample.Sample('time_real', 241.0, unit, expected_metadata), samples[0])
self.assertSamplesEqualUpToTimestamp(
sample.Sample('time_user', 1391.0, unit, expected_metadata), samples[1])
self.assertSamplesEqualUpToTimestamp(
sample.Sample('time_sys', 25.0, unit, expected_metadata), samples[2])

if __name__ == '__main__':
unittest.main()

0 comments on commit 9c5f6c2

Please sign in to comment.