| # SPEC CPU 2017 |
| # https://www.spec.org/cpu2017/Docs/ |
| |
| include(External) |
| include(CopyDir) |
| include(Host) |
| |
| # Search for SPEC CPU 2017 root directory. |
| llvm_externals_find(TEST_SUITE_SPEC2017_ROOT "speccpu2017" "SPEC CPU2017") |
| if (NOT TEST_SUITE_SPEC2017_ROOT) |
| return () |
| endif () |
| |
| # Print warnings once only, even if included multiple times. |
| if (NOT TARGET speccpu2017_dummy) |
| |
| file(READ ${TEST_SUITE_SPEC2017_ROOT}/version.txt VERSION) |
| if (VERSION VERSION_LESS 1.0.1) |
| message(WARNING |
| "Expected SPEC2017 version 1.0.1 or newer, found ${VERSION}") |
| endif () |
| |
| # SPEC supports three "run types": ref, train and test. |
| set(_available_run_types test train ref) |
| if (NOT TEST_SUITE_RUN_TYPE IN_LIST _available_run_types) |
| message(FATAL_ERROR |
| "TEST_SUITE_RUN_TYPE must be 'train', 'test' or 'ref' for SPEC") |
| endif() |
| |
| add_custom_target(speccpu2017_dummy) |
| endif () |
| |
| |
| # Set the variables an common compile flags for a SPEC CPU 2017 benchmark. |
| # |
| # SPEED/RATE Kind of benchmark suite |
| # |
| # ORIGIN Allows the reuse of sourec files, input data, and reference |
| # output from another benchmark. |
| macro (speccpu2017_benchmark) |
| cmake_parse_arguments(_arg "SPEED;RATE" "ORIGIN" "" ${ARGN}) |
| |
| # If BENCHMARK is set, another benchmark inherits from this benchark. |
| # The relevant variables are already set in this case. |
| if (NOT DEFINED BENCHMARK) |
| |
| get_filename_component(BENCHMARK "${CMAKE_CURRENT_SOURCE_DIR}" NAME) |
| string(SUBSTRING ${BENCHMARK} 0 3 BENCHMARK_NO) |
| set(PROG ${BENCHMARK}) |
| |
| if (_arg_SPEED) |
| set(BENCHMARK_SUITE_TYPE speed) |
| set(SPEED ON) |
| set(SUFFIX s) |
| elseif (_arg_RATE) |
| set(BENCHMARK_SUITE_TYPE rate) |
| set(RATE ON) |
| set(SUFFIX r) |
| else () |
| message(FATAL_ERROR "Must define the benchmark type (RATE or SPEED)") |
| endif () |
| |
| if (DEFINED _arg_ORIGIN) |
| set(ORIGIN ${_arg_ORIGIN}) |
| else () |
| set(ORIGIN ${BENCHMARK}) |
| endif () |
| |
| set(BENCHMARK_DIR "${TEST_SUITE_SPEC2017_ROOT}/benchspec/CPU/${BENCHMARK}") |
| set(ORIGIN_DIR "${TEST_SUITE_SPEC2017_ROOT}/benchspec/CPU/${ORIGIN}") |
| |
| |
| set(SRC_DIR "${ORIGIN_DIR}/src") |
| |
| set(DATA_DIR "${BENCHMARK_DIR}/data") |
| if (NOT EXISTS "${DATA_DIR}") |
| set(DATA_DIR "${ORIGIN_DIR}/data") |
| endif () |
| |
| set(DATA_all_DIR "${DATA_DIR}/all") |
| set(DATA_test_DIR "${DATA_DIR}/test") |
| set(DATA_train_DIR "${DATA_DIR}/train") |
| |
| set(DATA_ref_DIR "${DATA_DIR}/refrate") |
| if (SPEED AND EXISTS "${DATA_DIR}/refspeed") |
| set(DATA_ref_DIR "${DATA_DIR}/refspeed") |
| endif () |
| |
| set(INPUT_all_DIR "${DATA_all_DIR}/input") |
| set(OUTPUT_all_DIR "${DATA_all_DIR}/output") |
| |
| set(INPUT_test_DIR "${DATA_test_DIR}/input") |
| set(OUTPUT_test_DIR "${DATA_test_DIR}/output") |
| |
| set(INPUT_train_DIR "${DATA_train_DIR}/input") |
| set(OUTPUT_train_DIR "${DATA_train_DIR}/output") |
| |
| set(INPUT_ref_DIR "${DATA_ref_DIR}/input") |
| set(OUTPUT_ref_DIR "${DATA_ref_DIR}/output") |
| |
| # Create benchmark working directories. |
| foreach (_run_type IN LISTS TEST_SUITE_RUN_TYPE) |
| set(RUN_${_run_type}_DIR "${CMAKE_CURRENT_BINARY_DIR}/run_${_run_type}") |
| file(MAKE_DIRECTORY ${RUN_${_run_type}_DIR}) |
| endforeach () |
| |
| |
| # Mandatory flags |
| add_definitions(-DSPEC -DSPEC_CPU -DNDEBUG) |
| |
| if (RATE) |
| # rate benchmarks never use parallelism |
| add_definitions(-DSPEC_AUTO_SUPPRESS_OPENMP) |
| endif () |
| |
| # Portability flags |
| if (ENDIAN STREQUAL "little") |
| add_definitions(-DSPEC_AUTO_BYTEORDER=0x12345678) |
| elseif (ENDIAN STREQUAL "big") |
| add_definitions(-DSPEC_AUTO_BYTEORDER=0x87654321) |
| endif () |
| |
| check_type_size("long long" SIZEOF_LONG_LONG) |
| check_type_size("long" SIZEOF_LONG) |
| check_type_size("int" SIZEOF_INT) |
| if (CMAKE_SIZEOF_VOID_P EQUAL 4 AND SIZEOF_LONG_LONG EQUAL 8 AND SIZEOF_LONG EQUAL 4 AND SIZEOF_INT EQUAL 4) |
| add_definitions(-DSPEC_ILP32) |
| elseif (CMAKE_SIZEOF_VOID_P EQUAL 8 AND SIZEOF_LONG_LONG EQUAL 8 AND SIZEOF_LONG EQUAL 4 AND SIZEOF_INT EQUAL 4) |
| add_definitions(-DSPEC_P64) |
| elseif (CMAKE_SIZEOF_VOID_P EQUAL 8 AND SIZEOF_LONG_LONG EQUAL 8 AND SIZEOF_LONG EQUAL 8 AND SIZEOF_INT EQUAL 4) |
| add_definitions(-DSPEC_LP64) |
| elseif (CMAKE_SIZEOF_VOID_P EQUAL 8 AND SIZEOF_LONG_LONG EQUAL 8 AND SIZEOF_LONG EQUAL 8 AND SIZEOF_INT EQUAL 8) |
| add_definitions(-DSPEC_ILP64) |
| else () |
| message(FATAL_ERROR "SPEC CPU 2017 unsupported data model (supported: ILP32/LLP64/LP64/ILP64)") |
| endif () |
| |
| if (TARGET_OS STREQUAL "Linux") |
| add_definitions(-DSPEC_LINUX) # 526.blender_r |
| endif () |
| |
| if(ARCH STREQUAL "x86" AND TARGET_OS STREQUAL "Linux") |
| if (CMAKE_SIZEOF_VOID_P EQUAL 8) |
| # Linux x86_64 |
| add_definitions(-DSPEC_LINUX_X64) # perlbench |
| elseif (CMAKE_SIZEOF_VOID_P EQUAL 4) |
| # Linux x86 |
| add_definitions(-DSPEC_ILP32) |
| add_definitions(-D_FILE_OFFSET_BITS=64) |
| add_definitions(-DSPEC_LINUX_I32) # perlbench |
| endif () |
| elseif (ARCH STREQUAL "AArch64" AND TARGET_OS STREQUAL "Linux" AND CMAKE_SIZEOF_VOID_P EQUAL 8) |
| # Linux ARM |
| add_definitions(-DSPEC_LINUX_AARCH64) |
| elseif (ARCH STREQUAL "x86" AND TARGET_OS STREQUAL "Windows") |
| # Windows x86/x64 |
| else () |
| message("ARCH: ${ARCH}") |
| message("TARGET_OS: ${TARGET_OS}") |
| message("CMAKE_SIZEOF_VOID_P: ${CMAKE_SIZEOF_VOID_P}") |
| message(FATAL_ERROR |
| "Don't know portability flags for SPEC CPU 2017 on this platform") |
| endif () |
| |
| # No OpenMP for the moment, even for the _s suites. |
| add_definitions(-DSPEC_SUPPRESS_OPENMP) |
| |
| endif () |
| endmacro() |
| |
| |
| # Reuse the CMakeLists.txt of another benchmark. |
| macro(speccpu2017_inherit _origin_path) |
| include("${_origin_path}/CMakeLists.txt") |
| endmacro () |
| |
| |
| # Add include directories relative to SRC_DIR. |
| macro (speccpu2017_add_include_dirs) |
| foreach(_dirname ${ARGN}) |
| get_filename_component(_absdirname "${_dirname}" ABSOLUTE BASE_DIR ${SRC_DIR}) |
| include_directories("${_absdirname}") |
| endforeach() |
| endmacro () |
| |
| |
| # Add a "RUN:" line. |
| # |
| # RUN_TYPE (test,train or ref) |
| # Only run if this TEST_SUITE_RUN_TYPE is is selected. |
| # |
| # SUITE_TYPE (rate or speed) |
| # Only run in the _r or _s benchmark suites. |
| # |
| # WORKDIR Working dir for the executable to run in. |
| # "input" means the dataset source directory. Does not require |
| # copying the input data to the rundir, but the benchmark |
| # must not write data there. |
| # If not defined, the run_{run_type} directory is chosen. |
| # |
| # STDOUT Write the benchmark's stdout into this file in the rundir. |
| # |
| # STDERR Write the benchmark's stderr into this file in the rundir. |
| # |
| # ARGN Benchmark's command line arguments |
| macro (speccpu2017_run_test) |
| cmake_parse_arguments(_arg |
| "" "RUN_TYPE;SUITE_TYPE;WORKDIR;STDOUT;STDERR" "" ${ARGN}) |
| |
| if ((NOT DEFINED _arg_SUITE_TYPE) OR |
| (BENCHMARK_SUITE_TYPE IN_LIST _arg_SUITE_TYPE)) |
| if ((NOT DEFINED _arg_RUN_TYPE) OR |
| (_arg_RUN_TYPE IN_LIST TEST_SUITE_RUN_TYPE)) |
| |
| set(_stdout) |
| if (DEFINED _arg_STDOUT) |
| set(_stdout > "${RUN_${_arg_RUN_TYPE}_DIR}/${_arg_STDOUT}") |
| endif () |
| |
| set(_stderr) |
| if (DEFINED _arg_STDERR) |
| set(_stderr 2> "${RUN_${_arg_RUN_TYPE}_DIR}/${_arg_STDERR}") |
| endif () |
| |
| set(_executable) |
| if (NOT DEFINED _arg_WORKDIR) |
| set(_workdir "${RUN_${_arg_RUN_TYPE}_DIR}") |
| |
| # perlbench, xalancbmk need to be invoked with relative paths |
| # (SPEC made modifications that prepend another path to find the rundir) |
| file(RELATIVE_PATH _executable |
| "${_workdir}" "${CMAKE_CURRENT_BINARY_DIR}/${PROG}") |
| set (_executable EXECUTABLE "${_executable}") |
| elseif (_arg_WORKDIR STREQUAL "input") |
| set(_workdir "${INPUT_${_arg_RUN_TYPE}_DIR}") |
| else () |
| set(_workdir "${_arg_WORKDIR}") |
| endif () |
| |
| llvm_test_run( |
| ${_arg_UNPARSED_ARGUMENTS} ${_stdout} ${_stderr} |
| RUN_TYPE ${_arg_RUN_TYPE} |
| WORKDIR "${_workdir}" |
| ${_executable} |
| ) |
| endif () |
| endif () |
| endmacro () |
| |
| |
| # Compare an image file to a reference image. |
| macro(speccpu2017_validate_image _imgfile _cmpfile _outfile) |
| cmake_parse_arguments(_carg "" "RUN_TYPE" "SUITE_TYPE" ${ARGN}) |
| |
| set(VALIDATOR imagevalidate_${BENCHMARK_NO}) |
| if (NOT TARGET ${VALIDATOR}-host) |
| file(GLOB_RECURSE _validator_sources "${SRC_DIR}/image_validator/*.c") |
| llvm_add_host_executable( |
| ${VALIDATOR}-host ${VALIDATOR} ${_validator_sources} |
| LDFLAGS -lm |
| CPPFLAGS -DSPEC |
| ) |
| endif () |
| |
| if ((NOT DEFINED _carg_SUITE_TYPE) OR (${BENCHMARK_SUITE_TYPE} IN_LIST _carg_SUITE_TYPE)) |
| get_filename_component(_basename "${_imgfile}" NAME_WE) |
| get_filename_component(_ext "${_imgfile}" EXT) |
| llvm_test_verify( |
| cd "${RUN_${_carg_RUN_TYPE}_DIR}" && |
| "${CMAKE_CURRENT_BINARY_DIR}/${VALIDATOR}" ${_carg_UNPARSED_ARGUMENTS} |
| "${_imgfile}" "${DATA_${_carg_RUN_TYPE}_DIR}/compare/${_cmpfile}" |
| > ${RUN_${_carg_RUN_TYPE}_DIR}/${_outfile} |
| RUN_TYPE ${_carg_RUN_TYPE} |
| ) |
| endif () |
| endmacro () |
| |
| # Add a "VERIFY:" line that compares all of the benchmark's reference outputs |
| # with files in the rundir. |
| macro(speccpu2017_verify_output) |
| cmake_parse_arguments(_arg |
| "IGNORE_WHITESPACE" "ABSOLUTE_TOLERANCE;RELATIVE_TOLERANCE" "" ${ARGN}) |
| |
| set(_abstol) |
| if (DEFINED _arg_ABSOLUTE_TOLERANCE) |
| set(_abstol -a "${_arg_ABSOLUTE_TOLERANCE}") |
| endif () |
| |
| set(_reltol) |
| if (DEFINED _arg_RELATIVE_TOLERANCE) |
| set(_reltol -r "${_arg_RELATIVE_TOLERANCE}") |
| endif () |
| |
| set(_ignorewhitespace) |
| if (DEFINED _arg_IGNORE_WHITESPACE) |
| set(_ignorewhitespace "-i") |
| endif () |
| |
| foreach (_runtype IN LISTS TEST_SUITE_RUN_TYPE ITEMS all) |
| file(GLOB_RECURSE _reffiles "${OUTPUT_${_runtype}_DIR}/*") |
| foreach (_reffile IN LISTS _reffiles) |
| file(RELATIVE_PATH _relfile "${OUTPUT_${_runtype}_DIR}" "${_reffile}") |
| set(_outfile "${RUN_${_runtype}_DIR}/${_relfile}") |
| llvm_test_verify(RUN_TYPE ${_runtype} |
| "${FPCMP}" ${_abstol} ${_reltol} ${_ignorewhitespace} |
| "${_reffile}" "${_outfile}" |
| ) |
| endforeach () |
| endforeach () |
| endmacro() |
| |
| |
| # Add a SPEC CPU 2017 benchmark. |
| # |
| # Must be used after speccpu2017_run_test, speccpu2017_validate_image |
| # and speccpu2017_verify_output because those add lines to the |
| # ${BENCHMARK}.test file that is written here. |
| macro(speccpu2017_add_executable) |
| set(_sources ${ARGN}) |
| if (_sources) |
| set(_sources) |
| foreach(_filename ${ARGN}) |
| get_filename_component(_absfilename "${_filename}" |
| ABSOLUTE BASE_DIR ${SRC_DIR}) |
| list(APPEND _sources "${_absfilename}") |
| endforeach() |
| else () |
| file(GLOB_RECURSE _sources |
| ${SRC_DIR}/*.c ${SRC_DIR}/*.cpp ${SRC_DIR}/*.cc ${SRC_DIR}/*.C) |
| endif () |
| |
| llvm_test_executable(${PROG} ${_sources}) |
| |
| if (TARGET ${VALIDATOR}-host) |
| add_dependencies(${PROG} ${VALIDATOR}-host) |
| endif () |
| endmacro() |
| |
| |
| # Copy the input data to the rundir. |
| # |
| # Can often be avoided by either passing an absolute path to the file in the |
| # input dir, or using the input dir as working directory and specify the output |
| # file as an absolute path to the rundir. |
| macro(speccpu2017_prepare_rundir) |
| foreach (_runtype IN LISTS TEST_SUITE_RUN_TYPE) |
| if (EXISTS "${INPUT_all_DIR}") |
| llvm_copy_dir(${PROG} "${RUN_${_runtype}_DIR}" "${INPUT_all_DIR}") |
| endif () |
| llvm_copy_dir(${PROG} "${RUN_${_runtype}_DIR}" "${INPUT_${_runtype}_DIR}") |
| endforeach () |
| endmacro() |