diff options
author | Joel Goddard <joel.goddard@linaro.org> | 2021-09-29 11:45:08 +0100 |
---|---|---|
committer | Joel Goddard <joel.goddard@linaro.org> | 2021-10-26 17:11:59 +0100 |
commit | 2168b405d833758539db3ec97dcde65e6de8c019 (patch) | |
tree | fc6a6880ebeae60bf80a3cb27a4522b186e54344 | |
parent | 91b031361bed631f3264e8721da5e0c0e3aca419 (diff) | |
download | art-external-benchmarks-2168b405d833758539db3ec97dcde65e6de8c019.tar.gz |
Add script to setup Java Matrix Benchmark
Added a script to install Java Matrix benchmarks including a patch and
warapper class.
Test: ./setup_javamatrix.sh -d <path to linaro aosp>
Change-Id: Icf71465071185648e37aeefcb3c91a9a57cbb9bc
-rw-r--r-- | javamatrix/.gitignore | 3 | ||||
-rw-r--r-- | javamatrix/README | 22 | ||||
-rw-r--r-- | javamatrix/benchmarks/javamatrix/EjmlBench.java | 219 | ||||
-rw-r--r-- | javamatrix/framework/javamatrix/BenchBase.java | 212 | ||||
-rwxr-xr-x | javamatrix/setup_javamatrix.sh | 179 |
5 files changed, 635 insertions, 0 deletions
diff --git a/javamatrix/.gitignore b/javamatrix/.gitignore new file mode 100644 index 0000000..075dd0d --- /dev/null +++ b/javamatrix/.gitignore @@ -0,0 +1,3 @@ +lib/ +javamatrix_src/ +.class
\ No newline at end of file diff --git a/javamatrix/README b/javamatrix/README new file mode 100644 index 0000000..d34fcae --- /dev/null +++ b/javamatrix/README @@ -0,0 +1,22 @@ +## Java Matrix Benchmark + +### Summary + + This implementation can install the Java Matrix Benchmarks + (https://github.com/lessthanoptimal/Java-Matrix-Benchmark) into the + linaro tree. + The currently supported libraries are: + * EJML (https://github.com/lessthanoptimal/ejml) + +### Prerequisits + + Ensure Java version is Java 8 either by setting JAVA_HOME or changing + default Java. + +### Installation + + `./setup_javamatix.sh -d <PATH_TO_LINARO_TREE>` + +### Uninstalling + + `./setup_javamatix.sh -d <PATH_TO_LINARO_TREE> -u`
\ No newline at end of file diff --git a/javamatrix/benchmarks/javamatrix/EjmlBench.java b/javamatrix/benchmarks/javamatrix/EjmlBench.java new file mode 100644 index 0000000..0b0e46a --- /dev/null +++ b/javamatrix/benchmarks/javamatrix/EjmlBench.java @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2021 Linaro Limited. 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. + * + */ + +package benchmarks.javamatrix; + +import java.util.EnumSet; + +public class EjmlBench extends BenchBase { + + private static String FACTORY_STRING = "jmatbench.ejml.EjmlAlgorithmFactory"; + private static long SEED = -559038737; + + // All CaseTypes other than TRANSPOSE_TALL and TRANSPOSE_WIDE as those are not + // supported by this library. + private static EnumSet<CaseType> CASE_TYPES = EnumSet.complementOf( + EnumSet.of(CaseType.TRANSPOSE_TALL, CaseType.TRANSPOSE_WIDE)); + + // Cannot guarantee sizes over 500 will work for Ejml due to memory limitations + private static int[] SIZES = new int[] {5, 50, 500}; + + public EjmlBench() { + super(FACTORY_STRING, SEED, CASE_TYPES, SIZES); + } + + public void timeMult___5(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.MULT, 5); + } + + public void timeMult__50(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.MULT, 50); + } + + public void timeMult_500(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.MULT, 500); + } + + public void timeAdd___5(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.ADD, 5); + } + + public void timeAdd__50(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.ADD, 50); + } + + public void timeAdd_500(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.ADD, 500); + } + + public void timeTransposeSquare___5(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.TRANSPOSE_SQUARE, 5); + } + + public void timeTransposeSquare__50(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.TRANSPOSE_SQUARE, 50); + } + + public void timeTransposeSquare_500(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.TRANSPOSE_SQUARE, 500); + } + + public void timeScale___5(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.SCALE, 5); + } + + public void timeScale__50(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.SCALE, 50); + } + + public void timeScale_500(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.SCALE, 500); + } + + public void timeDet___5(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.DET, 5); + } + + public void timeDet__50(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.DET, 50); + } + + public void timeDet_500(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.DET, 500); + } + + public void timeInvert___5(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.INVERT, 5); + } + + public void timeInvert__50(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.INVERT, 50); + } + + public void timeInvert_500(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.INVERT, 500); + } + + public void timeInvertSymmPosDef___5(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.INVERT_SYMM_POS_DEF, 5); + } + + public void timeInvertSymmPosDef__50(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.INVERT_SYMM_POS_DEF, 50); + } + + public void timeInvertSymmPosDef_500(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.INVERT_SYMM_POS_DEF, 500); + } + + public void timeSvd___5(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.SVD, 5); + } + + public void timeSvd__50(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.SVD, 50); + } + + public void timeSvd_500(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.SVD, 500); + } + + public void timeChol___5(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.CHOL, 5); + } + + public void timeChol__50(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.CHOL, 50); + } + + public void timeChol_500(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.CHOL, 500); + } + + public void timeMultTransB___5(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.MULT_TRANS_B, 5); + } + + public void timeMultTransB__50(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.MULT_TRANS_B, 50); + } + + public void timeMultTransB_500(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.MULT_TRANS_B, 500); + } + + public void timeSolveExact___5(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.SOLVE_EXACT, 5); + } + + public void timeSolveExact__50(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.SOLVE_EXACT, 50); + } + + public void timeSolveExact_500(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.SOLVE_EXACT, 500); + } + + public void timeSolveOver___5(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.SOLVE_OVER, 5); + } + + public void timeSolveOver__50(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.SOLVE_OVER, 50); + } + + public void timeSolveOver_500(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.SOLVE_OVER, 500); + } + + public void timeQr___5(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.QR, 5); + } + + public void timeQr__50(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.QR, 50); + } + + public void timeQr_500(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.QR, 500); + } + + public void timeLu___5(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.LU, 5); + } + + public void timeLu__50(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.LU, 50); + } + + public void timeLu_500(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.LU, 500); + } + + public void timeEigSymm___5(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.EIG_SYMM, 5); + } + + public void timeEigSymm__50(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.EIG_SYMM, 50); + } + + public void timeEigSymm_500(int iters) { + super.timeRuntimeBenchmark(iters, CaseType.EIG_SYMM, 500); + } + +} diff --git a/javamatrix/framework/javamatrix/BenchBase.java b/javamatrix/framework/javamatrix/BenchBase.java new file mode 100644 index 0000000..556d7d3 --- /dev/null +++ b/javamatrix/framework/javamatrix/BenchBase.java @@ -0,0 +1,212 @@ +/* + * Copyright (C) 2021 Linaro Limited. 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. + * + */ + +package benchmarks.javamatrix; + +import java.util.Arrays; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +import jmbench.tools.runtime.FactoryRuntimeEvaluationCase; +import jmbench.tools.runtime.RuntimeBenchmarkConfig; +import jmbench.tools.runtime.RuntimeEvaluationCase; +import jmbench.tools.runtime.RuntimeEvaluationTest; + +public abstract class BenchBase { + + public enum CaseType { + MULT, + ADD, + TRANSPOSE_SQUARE, + TRANSPOSE_TALL, + TRANSPOSE_WIDE, + SCALE, + DET, + INVERT, + INVERT_SYMM_POS_DEF, + SVD, + CHOL, + MULT_TRANS_B, + SOLVE_EXACT, + SOLVE_OVER, + QR, + LU, + EIG_SYMM, + } + + private class BenchMapKey { + public CaseType caseType; + public int size; + + public BenchMapKey(CaseType caseType, int size) { + this.caseType = caseType; + this.size = size; + } + + @Override + public boolean equals(Object obj) { + if (obj.getClass() != BenchMapKey.class) { + return false; + } + BenchMapKey other = (BenchMapKey) obj; + return (caseType.equals(other.caseType)) && + (size == other.size); + } + + @Override + public int hashCode() { + return Objects.hash(caseType, size); + } + } + + private FactoryRuntimeEvaluationCase factory; + private String factoryString; + private long seed; + private int[] sizes; + + private Map<BenchMapKey, RuntimeEvaluationTest> testMap; + + public BenchBase(String factoryString, long seed, EnumSet<CaseType> caseTypes, int[] sizes) { + this.seed = seed; + this.factoryString = factoryString; + this.sizes = sizes; + factory = createEvaluationCasesFactory(factoryString); + + // Create and fill a hashmap of EvaluationTests ready to run + testMap = new HashMap<BenchMapKey, RuntimeEvaluationTest>(); + for (CaseType caseType: caseTypes) { + for (int size: sizes) { + RuntimeEvaluationTest test = createEvaluationTest(caseType, size); + prepareEvaluationTest(test); + BenchMapKey key = new BenchMapKey(caseType, size); + testMap.put(key, test); + } + } + } + + // Helper function to perform a full timing function for a specific CaseType + // and size of matrix. + // iters: number of iterations to perform. + // caseType: enum specifying which case of the benchmark to perform. + // size: the size of matrix to use for the benchmark case + // must be one of the sizes passed to the constructor. + public void timeRuntimeBenchmark(int iters, CaseType caseType, int size) { + for (int i = 0; i < iters; i++) { + try { + RuntimeEvaluationTest test = + getEvaluationTest(caseType, size); + test.evaluate(); + } catch (RuntimeException e) { + e.printStackTrace(); + } + } + } + + // Creates the factory used to build the test cases for the benchmark library. + // factoryString: the name of the class to use as a factory. + // + // returns: factory used for generating evaluationCases. + private FactoryRuntimeEvaluationCase createEvaluationCasesFactory(String factoryString) { + // Create dummy configuration. This would normally be used to specify which + // cases to use and the size of the matricies but that functionality has + // been bypassed. + RuntimeBenchmarkConfig config = new RuntimeBenchmarkConfig(); + return new FactoryRuntimeEvaluationCase(factoryString,config); + } + + // Get an EvaluationTest ready to run. + // Initializes and generates the required matrices. + private void prepareEvaluationTest(RuntimeEvaluationTest test) { + test.setRandomSeed(seed); + test.init(); + test.setupTest(); + } + + // Get a pre-generated EvaluationTest. + // caseType: enum specifying the case of the benchmark. + // size: the size of matrix to use for the test. + // + // return: the EvaluationTest for that case and size. + private RuntimeEvaluationTest getEvaluationTest(CaseType caseType, + int size) { + BenchMapKey key = new BenchMapKey(caseType, size); + return testMap.get(key); + } + + // Create an EvaluationTest for a particular case at a particular size. + // caseType: enum specifying the case of the benchmark. + // size: the size of matrix to use for the test. + // + // return: an EvaluationTest that contains all the details to run a test. + private RuntimeEvaluationTest createEvaluationTest(CaseType caseType, int size) { + RuntimeEvaluationCase eCase = createEvaluationCase(caseType); + RuntimeEvaluationTest test = new RuntimeEvaluationTest(); + test.setDimen(size); + test.setNameAlgorithm(eCase.getNameAlgorithm()); + test.setClassFactory(eCase.getClassFactory()); + test.setGenerator(eCase.getGenerator()); + return test; + } + + // Create a new evaluation case for a particular case of the benchmark. + // caseType: enum specifying the case of the benchmark. + // + // returns: an EvaluationCase that is required for a EvaluationTest. + private RuntimeEvaluationCase createEvaluationCase(CaseType caseType) { + switch (caseType) { + case MULT: + return factory.createMatrixMult(factoryString); + case ADD: + return factory.createMatrixAdd(factoryString); + case TRANSPOSE_SQUARE: + return factory.createTransposeSquare(factoryString); + case TRANSPOSE_TALL: + return factory.createTransposeTall(factoryString); + case TRANSPOSE_WIDE: + return factory.createTransposeWide(factoryString); + case SCALE: + return factory.createScale(factoryString); + case DET: + return factory.createDeterminant(factoryString); + case INVERT: + return factory.createInvert(factoryString); + case INVERT_SYMM_POS_DEF: + return factory.createInvertSymmPosDef(factoryString); + case SVD: + return factory.createSVD(factoryString); + case CHOL: + return factory.createCholesky(factoryString); + case MULT_TRANS_B: + return factory.createMultTranB(factoryString); + case SOLVE_EXACT: + return factory.createSolveEq(factoryString); + case SOLVE_OVER: + return factory.createSolveOver(factoryString); + case QR: + return factory.createQR(factoryString); + case LU: + return factory.createLU(factoryString); + case EIG_SYMM: + return factory.createEigSymm(factoryString); + default: + return null; + } + } + +} diff --git a/javamatrix/setup_javamatrix.sh b/javamatrix/setup_javamatrix.sh new file mode 100755 index 0000000..777dec3 --- /dev/null +++ b/javamatrix/setup_javamatrix.sh @@ -0,0 +1,179 @@ +#!/bin/bash +# +# Copyright (C) 2021 Linaro Limited. 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. + +unset AOSP_DIR + +readonly local_path="$(dirname "$0")" +source "${local_path}/../utils/utils.sh" + +JAVA_MATRIX_REPO="https://github.com/lessthanoptimal/Java-Matrix-Benchmark.git" +JAVA_MATRIX_REVISION="d35413e02208733c30b468b89864df3677ce1949" + +# List of the directory of each library to use +SUPPORTED_LIBS=("ejml") + +# Setup variables with relative locations for both the local and +# destination directories +setup_dir_vars() { + readonly REL_BENCHMARK="benchmarks" + readonly REL_FRAMEWORK="framework" + readonly REL_LIB="${REL_BENCHMARK}/lib" + + readonly JM_BENCHMARK="${local_path}/${REL_BENCHMARK}" + readonly JM_FRAMEWORK="${local_path}/${REL_FRAMEWORK}" + readonly JM_LIB="${local_path}/${REL_LIB}" + readonly JM_LIB_PREFIX="java-matrix-benchmark_" + readonly JM_SRC="${local_path}/javamatrix_src" + + readonly EXT_DIR="${AOSP_DIR}/benchmarks" + readonly EXT_BENCHMARK="${EXT_DIR}/${REL_BENCHMARK}/javamatrix" + readonly EXT_FRAMEWORK="${EXT_DIR}/${REL_FRAMEWORK}/javamatrix" + readonly EXT_LIB="${EXT_DIR}/${REL_LIB}" +} + +readonly usage="Usage: $(basename "$0") -d dest_dir [-u] +Setup Java Matrix binaries and workloads runners into a provided +destination directory. + +Options: + -h Show this help message. + -d Path to the AOSP tree root. + -u Uninstall. +" + +MODE="install" + +# Parse the commandline arguments. +# Requires command line options to be passed to function with "$@". +parse_args() { + while getopts ":hd:u" option; do + if [[ ${OPTARG} == -* ]]; then + exit_with_error "Option -${option} requires an argument." >&2 + fi + case "${option}" in + h) info "${usage}"; exit ;; + d) AOSP_DIR="${OPTARG}" + ;; + u) MODE="uninstall" ;; + \?) + error "Illegal option: -${OPTARG}" >&2 + error "${usage}" + exit 1 + ;; + :) + exit_with_error "Option -${OPTARG} requires an argument." >&2 + ;; + esac + done + validade_args +} + +# Check whether the arguments parsed are valid. +validade_args() { + if [[ -z "${AOSP_DIR}" ]]; then + exit_with_error "Please, use -d argument to specify the location of Linaro tree." + fi + + if [[ ! -d "${AOSP_DIR}" ]]; then + exit_with_error "The directory ${AOSP_DIR} does not exist. Please specify a valid path" \ + "to your Linaro tree." + fi +} + +# Prepare the benchmark to be copied to the destination. +# Download and builds the benchmark. +# Organises the files to ease copy. +setup_javamatrix() { + CURRENT_ROOT="${PWD}" + + cleandir "${JM_SRC}" + pushd "${JM_SRC}" + + info "Cloning ${JAVA_MATRIX_REPO} at commit ${JAVA_MATRIX_REVISION}" + safe git clone "${JAVA_MATRIX_REPO}" "./" + safe git reset --hard "${JAVA_MATRIX_REVISION}" + + build_javamatrix + + popd + + setup_lib_folder +} + +# Build the libraries and the main benchmark jars. +build_javamatrix() { + safe ./gradlew createRuntimeJars + safe ./gradlew benchmarkJar +} + +# Copy the library jars and the main benchmark jar into the local lib directory. +setup_lib_folder() { + cleandir "${JM_LIB}" + safe cp "${JM_SRC}/benchmark.jar" "${JM_LIB}/${JM_LIB_PREFIX}main.jar" + for LIBRARY in "${SUPPORTED_LIBS[@]}"; do + for FILE in "${JM_SRC}/external/${LIBRARY}/runtimeLibs/"*".jar"; do + safe cp -n "${FILE}" "${JM_LIB}/${JM_LIB_PREFIX}$(basename ${FILE})" + done + done + + # Remove extra copy of main. + safe rm "${JM_LIB}/${JM_LIB_PREFIX}main-0.12-SNAPSHOT.jar" +} + +# Copy the local files into the destination directory. +copy_to_benchmarks() { + info "Copying to ${EXT_DIR}" + safe cp -r "${JM_BENCHMARK}" "${JM_FRAMEWORK}" "${EXT_DIR}" +} + +install() { + info "Installing benchmark" + setup_javamatrix + copy_to_benchmarks +} + +uninstall() { + info "Cleaning up external" + # Collect the path of every javamatrix folder. + TO_REMOVE=("${EXT_BENCHMARK}" + "${EXT_FRAMEWORK}" + "${EXT_LIB}/${JM_LIB_PREFIX}"*) + + # Remove all of the files from the external directory. + for REMOVE_PATH in "${TO_REMOVE[@]}"; do + if [[ -f "${REMOVE_PATH}" || -d "${REMOVE_PATH}" ]]; then + info "Removing ${REMOVE_PATH}" + safe rm -r "${REMOVE_PATH}" + elif [[ "${MODE}" = "uninstall" ]]; then + info "Tried to remove ${REMOVE_PATH} but it did not exist" + fi + done +} + +main() { + parse_args "$@" + validate_java + setup_dir_vars + uninstall + if [[ "${MODE}" = "uninstall" ]]; then + info "Finished ${MODE}" + exit + fi + install + info "Finished ${MODE}" +} + +main "$@"
\ No newline at end of file |