Help with try_run() and CMAKE_FLAGS

All,

I’m trying to figure out how to test if a compiler flag runs on a processor. The issue is that I’m porting some code from Intel chips to AMD Rome chips and I’ve found that if I compile (using Intel Fortran) with -xCORE-AVX2, code will compile fine on the Rome chips, but not run:

$ cat bobo.F90
program test
   real :: x
end program test
$ ifort -xCORE-AVX2 bobo.F90
$ echo $?
0
$ ./a.out

Please verify that both the operating system and the processor support Intel(R) X87, CMOV, MMX, FXSAVE, SSE, SSE2, SSE3, SSSE3, SSE4_1, SSE4_2, MOVBE, POPCNT, AVX, F16C, FMA, BMI, LZCNT and AVX2 instructions.

$ echo $?
1

Our CMake files for this project have assume “If Intel Fortran, use this flag” but now I need to be more subtle. So to test some things, I made up a simple CMake tester thinking this would be a way to test:

cmake_minimum_required (VERSION 3.17)

project(testflag Fortran)

set(XCORE_FLAG "-xCORE-AVX2")

try_run(
   RUN_RESULT_VAR COMPILE_RESULT_VAR
   ${CMAKE_CURRENT_BINARY_DIR}/test ${CMAKE_CURRENT_LIST_DIR}/bobo.F90
   CMAKE_FLAGS "-DCMAKE_Fortran_FLAGS:STRING=${XCORE_FLAG}"
   COMPILE_OUTPUT_VARIABLE COMPILE_OUTPUT
   RUN_OUTPUT_VARIABLE RUN_OUTPUT
   )

message("COMPILE_RESULT_VAR = ${COMPILE_RESULT_VAR}")
message("COMPILE_OUTPUT     = ${COMPILE_OUTPUT}")
message("RUN_RESULT_VAR = ${RUN_RESULT_VAR}")
message("RUN_OUTPUT     = ${RUN_OUTPUT}")

But when I run:

...
COMPILE_RESULT_VAR = TRUE
COMPILE_OUTPUT     = Change Dir: /home3/mathomp4/RomeTest/CMakeTest/build/test/CMakeFiles/CMakeTmp

Run Build Command(s):/usr/bin/gmake cmTC_cefe8/fast && gmake: Warning: File 'Makefile' has modification time 0.0021 s in the future
/usr/bin/gmake  -f CMakeFiles/cmTC_cefe8.dir/build.make CMakeFiles/cmTC_cefe8.dir/build
gmake[1]: Entering directory '/home3/mathomp4/RomeTest/CMakeTest/build/test/CMakeFiles/CMakeTmp'
Building Fortran object CMakeFiles/cmTC_cefe8.dir/bobo.F90.o
/nasa/intel/Compiler/2020.4.304/compilers_and_libraries_2020.4.304/linux/bin/intel64/ifort    -c /home3/mathomp4/RomeTest/CMakeTest/bobo.F90 -o CMakeFiles/cmTC_cefe8.dir/bobo.F90.o
Linking Fortran executable cmTC_cefe8
/nobackupp16/gmao_SIteam/cmake/cmake-3.17.1/bin/cmake -E cmake_link_script CMakeFiles/cmTC_cefe8.dir/link.txt --verbose=1
/nasa/intel/Compiler/2020.4.304/compilers_and_libraries_2020.4.304/linux/bin/intel64/ifort      CMakeFiles/cmTC_cefe8.dir/bobo.F90.o  -o cmTC_cefe8
gmake[1]: Leaving directory '/home3/mathomp4/RomeTest/CMakeTest/build/test/CMakeFiles/CMakeTmp'
gmake: warning:  Clock skew detected.  Your build may be incomplete.


RUN_RESULT_VAR = 0
RUN_OUTPUT     =
...

So the -xCORE-AVX2 flag was never passed in and it passed. After reading internet a bit I tried this:

try_run(
   RUN_RESULT_VAR COMPILE_RESULT_VAR
   ${CMAKE_CURRENT_BINARY_DIR}/test ${CMAKE_CURRENT_LIST_DIR}/bobo.F90
   COMPILE_DEFINITIONS "${XCORE_FLAG}"
   COMPILE_OUTPUT_VARIABLE COMPILE_OUTPUT
   RUN_OUTPUT_VARIABLE RUN_OUTPUT
   )

where I “hijacked” COMPILE_DEFINITIONS and:

COMPILE_RESULT_VAR = TRUE
COMPILE_OUTPUT     = Change Dir: /home3/mathomp4/RomeTest/CMakeTest/build/test/CMakeFiles/CMakeTmp

Run Build Command(s):/usr/bin/gmake cmTC_f89a4/fast && gmake: Warning: File 'Makefile' has modification time 0.0029 s in the future
/usr/bin/gmake  -f CMakeFiles/cmTC_f89a4.dir/build.make CMakeFiles/cmTC_f89a4.dir/build
gmake[1]: Entering directory '/home3/mathomp4/RomeTest/CMakeTest/build/test/CMakeFiles/CMakeTmp'
gmake[1]: Warning: File 'CMakeFiles/cmTC_f89a4.dir/progress.make' has modification time 0.0043 s in the future
Building Fortran object CMakeFiles/cmTC_f89a4.dir/bobo.F90.o
/nasa/intel/Compiler/2020.4.304/compilers_and_libraries_2020.4.304/linux/bin/intel64/ifort   -xCORE-AVX2 -c /home3/mathomp4/RomeTest/CMakeTest/bobo.F90 -o CMakeFiles/cmTC_f89a4.dir/bobo.F90.o
Linking Fortran executable cmTC_f89a4
/nobackupp16/gmao_SIteam/cmake/cmake-3.17.1/bin/cmake -E cmake_link_script CMakeFiles/cmTC_f89a4.dir/link.txt --verbose=1
/nasa/intel/Compiler/2020.4.304/compilers_and_libraries_2020.4.304/linux/bin/intel64/ifort      CMakeFiles/cmTC_f89a4.dir/bobo.F90.o  -o cmTC_f89a4
gmake[1]: warning:  Clock skew detected.  Your build may be incomplete.
gmake[1]: Leaving directory '/home3/mathomp4/RomeTest/CMakeTest/build/test/CMakeFiles/CMakeTmp'
gmake: warning:  Clock skew detected.  Your build may be incomplete.


RUN_RESULT_VAR = 1
RUN_OUTPUT     =
Please verify that both the operating system and the processor support Intel(R) X87, CMOV, MMX, FXSAVE, SSE, SSE2, SSE3, SSSE3, SSE4_1, SSE4_2, MOVBE, POPCNT, AVX, F16C, FMA, BMI, LZCNT and AVX2 instructions.

So, I can get it to do what I want (aka fail)…but only in a way that seems wrong to me. Obviously I did the wrong thing with CMAKE_FLAGS and misread:

Specify flags of the form -DVAR:TYPE=VALUE to be passed to the cmake command-line used to drive the test build.

What is the right way to do this?

@brad.king It seems that try_run could use with a COMPILE_OPTIONS argument?

One can use CheckSourceRuns with the CMAKE_REQUIRED_FLAGS setting.

It is implemented with try_run using an undocumented -DCOMPILE_DEFINITIONS=<flags> entry in CMAKE_FLAGS. One can see in the implementation that the value of the COMPILE_DEFINITIONS variable gets appended to CMAKE_<LANG>_FLAGS in the generated test project.

@brad.king Ah. I didn’t know about CheckSourceRuns! I will stare at it and try it out. (Warning: I might be back here to ask “what did I break now?” :slight_smile:)

Unfortunately, it might be a bit before I can require CMake 3.19 (supercomputing cluster modules move slowly!), but I suppose I can use the try_run hack on older CMake’s. Time to make a macro().

(That is, unless there is a CMake way to figure out if I’m on AMD Rome instead of, say, an Intel Cascade Lake? I’m pretty sure there isn’t a simple built-in way to check “CMAKE_CPU_TYPE” or the like.)