perfkitbenchmarker/linux_benchmarks/scimark2_benchmark.py (133 lines of code) (raw):

# Copyright 2015 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. # # Contributed by: Zi Shen Lim. """Runs SciMark2. Original documentation & code: http://math.nist.gov/scimark2/ SciMark2 is a Java (and C) benchmark for scientific and numerical computing. It measures several computational kernels and reports a composite score in approximate Mflops (Millions of floating point operations per second). """ import logging import re from perfkitbenchmarker import configs from perfkitbenchmarker import errors from perfkitbenchmarker import regex_util from perfkitbenchmarker import sample from perfkitbenchmarker.linux_packages import scimark2 BENCHMARK_NAME = 'scimark2' BENCHMARK_CONFIG = """ scimark2: description: Runs SciMark2 vm_groups: default: vm_spec: *default_dual_core """ def GetConfig(user_config): return configs.LoadConfig(BENCHMARK_CONFIG, user_config, BENCHMARK_NAME) def CheckPrerequisites(benchmark_config): pass def Prepare(benchmark_spec): """Install SciMark2 on the target vm. Args: benchmark_spec: The benchmark specification. Contains all data that is required to run the benchmark. """ vms = benchmark_spec.vms vm = vms[0] logging.info('Preparing SciMark2 on %s', vm) vm.Install('scimark2') def Run(benchmark_spec): """Run SciMark2 on the target vm. Args: benchmark_spec: The benchmark specification. Contains all data that is required to run the benchmark. Returns: A list of sample.Sample objects. """ vms = benchmark_spec.vms vm = vms[0] logging.info('Running SciMark2 on %s', vm) samples = [] # Run the Java and C benchmarks twice each, once with defaults and # once with the "-large" flag to use a larger working set size. # # Since the default output is not very parsing-friendly, print an # extra header to identify the tests. This must match # RESULT_START_REGEX as used below. cmds = [ '(echo ";;; Java small"; cd {} && java -cp {} {})'.format( scimark2.PATH, scimark2.JAVA_JAR, scimark2.JAVA_MAIN ), '(echo ";;; C small"; cd {} && ./scimark2)'.format(scimark2.C_SRC), '(echo ";;; Java large"; cd {} && java -cp {} {} -large)'.format( scimark2.PATH, scimark2.JAVA_JAR, scimark2.JAVA_MAIN ), '(echo ";;; C large"; cd {} && ./scimark2 -large)'.format( scimark2.C_SRC ), ] for cmd in cmds: stdout, _ = vm.RemoteCommand(cmd) samples.extend(ParseResults(stdout)) return samples def Cleanup(unused_benchmark_spec): pass def ParseResults(results): """Result parser for SciMark2. Sample Results (C version): ** ** ** SciMark2 Numeric Benchmark, see http://math.nist.gov/scimark ** ** for details. (Results can be submitted to pozo@nist.gov) ** ** ** Using 2.00 seconds min time per kenel. Composite Score: 1596.04 FFT Mflops: 1568.64 (N=1024) SOR Mflops: 1039.98 (100 x 100) MonteCarlo: Mflops: 497.64 Sparse matmult Mflops: 1974.39 (N=1000, nz=5000) LU Mflops: 2899.56 (M=100, N=100) (Yes, "kenel" is part of the original output.) Sample Results (Java version): SciMark 2.0a Composite Score: 1731.4467627163242 FFT (1024): 996.9938397943672 SOR (100x100): 1333.5328291027124 Monte Carlo : 724.5221517116782 Sparse matmult (N=1000, nz=5000): 1488.18620413327 LU (100x100): 4113.998788839592 java.vendor: Oracle Corporation java.version: 1.7.0_75 os.arch: amd64 os.name: Linux os.version: 3.16.0-25-generic Args: results: SciMark2 result. Returns: A list of sample.Sample objects. """ result_start_regex = re.compile( r""" ^ ;;; \s+ (\S+) #1: Language ("C" or "Java") \s+ (\S+) #2: Size ("small" or "large") """, re.VERBOSE | re.MULTILINE, ) score_regex = re.compile( r""" ^ (Composite \s+ Score) : \s+ (\d+ \. \d+) """, re.VERBOSE | re.MULTILINE, ) result_regex_c = re.compile( r""" ^ ( .+? ) \s+ #1: Test name Mflops: \s+ ( \d+ \. \d+ ) #2: Test score ( \s+ \( .+? \) )? #3: Optional test details """, re.VERBOSE | re.MULTILINE, ) result_regex_java = re.compile( r""" ^ ( .+? ) #1: Test name : \s+ ( \d+ \. \d+ ) #2: Test score """, re.VERBOSE | re.MULTILINE, ) platform_regex = re.compile( r""" ^ ( \w+ \. \w+ ) #1: Property name : \s+ ( .* ) #2: Property value """, re.VERBOSE | re.MULTILINE, ) def FindBenchStart(results, start_index=0): m = result_start_regex.search(results, start_index) if m is None: return -1, None, None return m.start(), m.group(1), m.group(2) def ExtractPlatform(result, benchmark_language): """Retrieves platform data from the result string.""" metadata = {} meta_start = None if benchmark_language == 'C': pass elif benchmark_language == 'Java': for m in platform_regex.finditer(result): if meta_start is None: meta_start = m.start() metadata[m.group(1)] = m.group(2) return metadata, meta_start def ExtractScore(result): m = score_regex.search(result) if m is None: raise errors.Benchmarks.RunError('scimark2: Cannot find score in output.') label = m.group(1) score = float(m.group(2)) return score, label, m.end() def ExtractResults(result, benchmark_language): """Retrieves data points from the result string.""" datapoints = [] if benchmark_language == 'C': for groups in regex_util.ExtractAllMatches(result_regex_c, result): metric = '{} {}'.format(groups[0].strip(), groups[2].strip()) metric = metric.strip().strip(':') # Extra ':' in 'MonteCarlo:'. value = float(groups[1]) datapoints.append((metric, value)) elif benchmark_language == 'Java': for groups in regex_util.ExtractAllMatches(result_regex_java, result): datapoints.append((groups[0].strip(), float(groups[1]))) return datapoints # Find start positions for all the test results. tests = [] test_start_pos = 0 while True: start_index, benchmark_language, benchmark_size = FindBenchStart( results, test_start_pos ) if start_index == -1: break tests.append((start_index, benchmark_language, benchmark_size)) test_start_pos = start_index + 1 # Now loop over individual tests collecting samples. samples = [] for test_num, test_details in enumerate(tests): start_index, benchmark_language, benchmark_size = test_details # Get end index - either start of next test, or None for the last test. end_index = None if test_num + 1 < len(tests): end_index = tests[test_num + 1][0] result = results[start_index:end_index] metadata = { 'benchmark_language': benchmark_language, 'benchmark_size': benchmark_size, } # Assume that the result consists of overall score followed by # specific scores and then platform metadata. # Get the metadata first since we need that to annotate samples. platform_metadata, meta_start = ExtractPlatform(result, benchmark_language) metadata.update(platform_metadata) # Get the overall score. score, label, score_end = ExtractScore(result) samples.append(sample.Sample(label, score, 'Mflops', metadata)) # For the specific scores, only look at the part of the string # bounded by score_end and meta_start to avoid adding extraneous # items. The overall score and platform data would match the # result regex. datapoints = ExtractResults( result[score_end:meta_start], benchmark_language ) for metric, value in datapoints: samples.append(sample.Sample(metric, value, 'Mflops', metadata)) return samples