blob: fb4ddb8060ac98e4b07addd02e4203afa7c8e9ba [file] [log] [blame]
# 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}-target)
if (NOT TARGET ${VALIDATOR})
file(GLOB_RECURSE _validator_sources "${SRC_DIR}/image_validator/*.c")
add_executable(${VALIDATOR} ${_validator_sources})
target_link_libraries(${VALIDATOR} m)
set_target_properties(${VALIDATOR} PROPERTIES COMPILE_FLAGS "-DSPEC")
add_dependencies(${VALIDATOR} timeit-target)
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 ${SRC_DIR}/*.f ${SRC_DIR}/*.F ${SRC_DIR}/*.f90 ${SRC_DIR}/*.F90)
endif ()
llvm_test_executable(${PROG} ${_sources})
if (TARGET ${VALIDATOR})
add_dependencies(${PROG} ${VALIDATOR})
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()