diff --git a/External/SPEC/CFP2017speed/628.pop2_s/CMakeLists.txt b/External/SPEC/CFP2017speed/628.pop2_s/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/External/SPEC/CFP2017speed/628.pop2_s/CMakeLists.txt @@ -0,0 +1,168 @@ +# https://www.spec.org/cpu2017/Docs/benchmarks/628.pop2_s.html +include(../../SpecCPU2017.cmake) +if (NOT TEST_SUITE_SPEC2017_ROOT) + return () +endif () + +ninja_required() + +speccpu2017_benchmark(SPEED) + +# Check if compiler can support big-endian IO format, if true proceed +# otherwise, return immediately. This is due to some binary input +# files stored in big-endian format +if (ENDIAN STREQUAL "little") + # GCC + check_fortran_compiler_flag("-fconvert=big-endian" SUPPORTS_FCONVERT_BIG_ENDIAN) + # Intel + check_fortran_compiler_flag("-convert big_endian" SUPPORTS_CONVERT_BIG_ENDIAN) + # Flang + # TBD + if (NOT SUPPORTS_FCONVERT_BIG_ENDIAN) + elseif (NOT SUPPORTS_CONVERT_BIG_ENDIAN) + else () + message(WARN "628.pop2_s not supported. No way to read big-endian binary IO on little-endian architecture.") + return () + endif () +endif () + +macro(pop2_prepare_rundir) + # Re-use the speccpu2017_prepare_rundir but then implement an input + # file fix at the end. input file for pop2 is hard-coded to drv_in, + # but actual filename in SPEC2017 benchmark input directory is + # drv_in.in. The SPEC perl run script renames the file as well. + speccpu2017_prepare_rundir() + foreach (_runtype IN LISTS TEST_SUITE_RUN_TYPE) + llvm_copy(${PROG} "${RUN_${_runtype}_DIR}/drv_in" "${INPUT_${_runtype}_DIR}/drv_in.in") + endforeach () +endmacro() + +speccpu2017_add_include_dirs( + ${CMAKE_CURRENT_BINARY_DIR} + ${SRC_DIR} + ${SRC_DIR}/netcdf/include +) + +# pop2 has Fortran sources that need to be processed with specpp and C +# sources that do not require it. + +# Compiler definitions affect C and *.f90 files, but not *.F90 files. +add_definitions( + -D_MPISERIAL + -D_NETCDF + -D_USEBOX + -DCCSMCOUPLED=1 + -DNO_SHR_VMATH + -DBLCKX=50 + -DBLCKY=4 + -DMXBLCKS=58 + -DNO_GETTIMEOFDAY + -DSPEC_CASE_FLAG +) + + +## test ######################################################################## + +speccpu2017_run_test(RUN_TYPE test) + +## train ####################################################################### + +speccpu2017_run_test(RUN_TYPE train) + +## ref ######################################################################### + +speccpu2017_run_test(RUN_TYPE ref) + +################################################################################ + +# SPEC Test has both absolute and relative tolerance with same order +speccpu2017_verify_output(IGNORE_WHITESPACE ABSOLUTE_TOLERANCE 0.03 RELATIVE_TOLERANCE 0.03) + +# *.F90 files are preprocessed with specpp and written to the CMake build +# directory. We only list C sources files and Fortran files that don't +# need to be preprocessed below. +speccpu2017_add_executable( + netcdf/attr.c + netcdf/dim.c + netcdf/error.c + netcdf/fort-attio.c + netcdf/fort-control.c + netcdf/fort-dim.c + netcdf/fort-genatt.c + netcdf/fort-geninq.c + netcdf/fort-genvar.c + netcdf/fort-lib.c + netcdf/fort-misc.c + netcdf/fort-v2compat.c + netcdf/fort-var1io.c + netcdf/fort-varaio.c + netcdf/fort-vario.c + netcdf/fort-varmio.c + netcdf/fort-varsio.c + netcdf/libvers.c + netcdf/nc.c + netcdf/ncx.c + netcdf/posixio.c + netcdf/putget.c + netcdf/string.c + netcdf/v1hpg.c + netcdf/v2i.c + netcdf/var.c + netcdf/netcdf.f90 + netcdf/typeSizes.f90 + mpi.c + send.c + recv.c + collective.c + req.c + list.c + handles.c + comm.c + group.c + time.c + pack.c + get_zeits.c + pnetcdfversion.c + topology.c + f_wrappers.c + GPTLget_memusage.c + GPTLprint_memusage.c + GPTLutil.c + shr_jlcp.c + shr_vmath_fwrap.c + threadutil.c +) + +# Preprocess *.F90 with specpp and add sources to target +file(GLOB POP2_F90_SRCS ${SRC_DIR}/*.F90) +list(REMOVE_ITEM POP2_F90_SRCS ${SRC_DIR}/test.F90) + +speccpu2017_run_specpp( + SPECPP_SRCS ${POP2_F90_SRCS} SPECPP_DEFS + -D_MPISERIAL + -D_NETCDF + -D_USEBOX + -DCCSMCOUPLED=1 + -DNO_SHR_VMATH + -DBLCKX=50 + -DBLCKY=4 + -DMXBLCKS=58 + -DNO_GETTIMEOFDAY + -I${SRC_DIR}/netcdf/include +) + + +# Several compiler options below for C and Fortran +set_property(TARGET ${PROG} PROPERTY C_STANDARD 99) + +if (SUPPORTS_FALLOW_ARGUMENT_MISMATCH) + target_compile_options(${PROG} PRIVATE $<$:-fallow-argument-mismatch>) +endif () + +if (SUPPORTS_FCONVERT_BIG_ENDIAN) # GCC + target_compile_options(${PROG} PRIVATE $<$:-fconvert=big-endian>) +elseif (SUPPORTS_CONVERT_BIG_ENDIAN) # Intel + target_compile_options(${PROG} PRIVATE $<$:-convert big_endian>) +endif () + +pop2_prepare_rundir() diff --git a/External/SPEC/CFP2017speed/CMakeLists.txt b/External/SPEC/CFP2017speed/CMakeLists.txt --- a/External/SPEC/CFP2017speed/CMakeLists.txt +++ b/External/SPEC/CFP2017speed/CMakeLists.txt @@ -6,7 +6,7 @@ if (TEST_SUITE_FORTRAN) #add_subdirectory(621.wrf_s) # Fortran, C add_subdirectory(627.cam4_s) # Fortran, C - #add_subdirectory(628.pop2_s) # Fortran, C + add_subdirectory(628.pop2_s) # Fortran, C endif () add_subdirectory(638.imagick_s) # C add_subdirectory(644.nab_s) # C diff --git a/External/SPEC/SpecCPU2017.cmake b/External/SPEC/SpecCPU2017.cmake --- a/External/SPEC/SpecCPU2017.cmake +++ b/External/SPEC/SpecCPU2017.cmake @@ -106,53 +106,56 @@ endforeach () - # Mandatory flags - add_definitions(-DSPEC -DSPEC_CPU -DNDEBUG) + # Mandatory SPEC definitions + set(SPEC_COMMON_DEFS) + list(APPEND SPEC_COMMON_DEFS "-DSPEC;-DSPEC_CPU;-DNDEBUG") if (RATE) # rate benchmarks never use parallelism - add_definitions(-DSPEC_AUTO_SUPPRESS_OPENMP) + list(APPEND SPEC_COMMON_DEFS "-DSPEC_AUTO_SUPPRESS_OPENMP") endif () # Portability flags + # SPEC_AUTO_BYTEORDER_value variable is used for Fortran tests that use specpp if (ENDIAN STREQUAL "little") - add_definitions(-DSPEC_AUTO_BYTEORDER=0x12345678) + list(APPEND SPEC_COMMON_DEFS "-DSPEC_AUTO_BYTEORDER=0x12345678") elseif (ENDIAN STREQUAL "big") - add_definitions(-DSPEC_AUTO_BYTEORDER=0x87654321) + list(APPEND SPEC_COMMON_DEFS "-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) + # SPEC_PTR_TYPE variable is used for Fortran tests that use specpp 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) + list(APPEND SPEC_COMMON_DEFS "-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) + list(APPEND SPEC_COMMON_DEFS "-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) + list(APPEND SPEC_COMMON_DEFS "-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) + list(APPEND "-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 + list(APPEND SPEC_COMMON_DEFS "-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 + list(APPEND SPEC_COMMON_DEFS "-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 + list(APPEND SPEC_COMMON_DEFS "-DSPEC_ILP32") + list(APPEND SPEC_COMMON_DEFS "-D_FILE_OFFSET_BITS=64") + list(APPEND SPEC_COMMON_DEFS "-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) + list(APPEND SPEC_COMMON_DEFS "-DSPEC_LINUX_AARCH64") elseif (ARCH STREQUAL "x86" AND TARGET_OS STREQUAL "Windows") # Windows x86/x64 else () @@ -164,7 +167,14 @@ endif () # No OpenMP for the moment, even for the _s suites. - add_definitions(-DSPEC_SUPPRESS_OPENMP) + list(APPEND SPEC_COMMON_DEFS "-DSPEC_SUPPRESS_OPENMP") + + # Add SPEC_COMMON_DEFS + add_definitions(${SPEC_COMMON_DEFS}) + + # Used by cam4, pop2, and wrf tests for portability + # https://gcc.gnu.org/gcc-10/porting_to.html + check_fortran_compiler_flag("-fallow-argument-mismatch" SUPPORTS_FALLOW_ARGUMENT_MISMATCH) endif () endmacro() @@ -351,3 +361,34 @@ llvm_copy_dir(${PROG} "${RUN_${_runtype}_DIR}" "${INPUT_${_runtype}_DIR}") endforeach () endmacro() + +# Run specpp on all Fortran files, but do not do it recursively. +# https://www.spec.org/cpu2017/Docs/specpp.html +# specpp is needed due to legacy use of filepp by climate/weather codes. +macro(speccpu2017_run_specpp) + cmake_parse_arguments(_arg "" "" "SPECPP_SRCS;SPECPP_DEFS" ${ARGN}) + set(_specpp_bin ${TEST_SUITE_SPEC2017_ROOT}/bin/specpp) + # Add common specpp arguments used by all SPEC CPU 2017 tests. + # -U__FILE__ is included as a work around. Source files uses _FILE_ + # as the filename without the path, but a few source files have a + # typo and use __FILE__ instead which is an absolute path. So specpp + # fails to do a replacement with just the filename (i.e. without the + # path as intended). This is usually a benign error, but __FILE__ + # can lead to a deeply nested directory due CMake's build + # directories. As a result, the source file line length becomes + # incredibly long, so you end up with a ridiculously long line that + # some compilers, like GCC, are unable to compile. + set(ARG_COMMON -w -U__FILE__ ${SPEC_COMMON_DEFS} -DSPEC_CASE_FLAG -I${SRC_DIR}) + + foreach(_absfilename ${_arg_SPECPP_SRCS}) + # message("Adding to source ${_absfilename} to target ${PROG}") + get_filename_component(_filename ${_absfilename} NAME) + add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${_filename}" + COMMAND "${_specpp_bin}" ${ARG_COMMON} ${_arg_SPECPP_DEFS} "${_absfilename}" > "${CMAKE_CURRENT_BINARY_DIR}/${_filename}" + DEPENDS "${_absfilename}" + VERBATIM + ) + target_sources(${PROG} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/${_filename}") + endforeach () +endmacro()