How to use OpenACC_ACCEL_TARGET

Hi there,

I’m using OpenACC on a simple example. If I understand well the FindOpenACC machinery one should be able to pass to CMake the target architecture with the OpenACC_ACCEL_TARGET. I issue the following command

cmake ../ -DOpenACC_ACCEL_TARGET=tesla:cc60 -DCMAKE_C_COMPILER=pgcc -DCMAKE_CXX_COMPILER=pgc++

which seems not to work for me for a very simple reason. In the flags.cmake file for the ex7 target generated by cmake I find:

compile C with /mnt/data/pgi_compiler/linux86-64/19.10/bin/pgcc

C_FLAGS = “-acc -ta=tesla:cc60”

which results in this command that the pgi compiler cannot process because of the double quotes:

[ 50%] Building C object CMakeFiles/ex7.dir/example7.c.o
/mnt/data/pgi_compiler/linux86-64/19.10/bin/pgcc -DCOLS=3000 -DROWS=3000  "-acc -ta=tesla:cc60" -o CMakeFiles/ex7.dir/example7.c.o   -c /home/edo/GitHub/acceleration/OpenACC/example7.c
pgcc-Error-Unknown switch: -acc -ta=tesla:cc60

One workaround that I found was to pass the same target information in the CMAKE_C_FLAGS, but that’s not right as the flag is passed to every target of a project.

Am I doing something clearly wrong?

Thanks

Edo

I may be wrong but it seems to me that line 16 is incorrect and line 15 should be used instead. With line 16 you’re adding all the flags as one string and, since it contains spaces, CMake quotes them.

Thanks, but unfortunately there’s no difference with
line 15
target_compile_options(ex7 PRIVATE ${OpenACC_C_FLAGS})

or 16
target_compile_options(ex7 PRIVATE “${OpenACC_C_FLAGS}”)

Still the flags are passed quoted.

Thanks

Edo

According to https://cmake.org/cmake/help/latest/module/FindOpenACC.html, OpenACC_<lang>_FLAGS contains

OpenACC compiler flags for <lang> , separated by spaces.

This means that you can’t pass OpenACC_C_FLAGS as-is to target_compile_options, unless it contains a single flag. You first need to replace spaces by semicolons (to convert it to a list).

Thanks Alain!

What works is this (with PGI 19.10 compiler)

string(REPLACE " " "\;" OpenACC_C_FLAGS_LIST ${OpenACC_C_FLAGS})
string(REPLACE " " "\;" OpenACC_CXX_FLAGS_LIST ${OpenACC_CXX_FLAGS})

add_executable(ex7 example7.c)

add_definitions(-DROWS=3000 -DCOLS=3000)
target_compile_options(ex7 PRIVATE ${OpenACC_C_FLAGS_LIST})
target_link_libraries(ex7 PRIVATE ${OpenACC_CXX_FLAGS_LIST})

Thanks again

Edo

1 Like

CMake 3.16 introduced OpenACC_<lang>_OPTIONS so that you don’t need to the transformation of OpenACC_<lang>_FLAGS manually.

In addition 3.16 also introduced OpenACC::OpenACC_<lang> targets which would be my preferred way to get the correct compile options.

Thanks Robert,

I was busy writing the following when you wrote:

According to the documentation, with CMake >=3.16 one should use OpenACC_<lang>_OPTIONS rather than OpenACC_<lang>_FLAGS.

OpenACC_<lang>_OPTIONS: OpenACC compiler flags for <lang> , as a list. Suitable for usage with target_compile_options or target_link_options.

So, resuming, the preferred way is to use OpenACC_<lang>_OPTIONS if exists or if not create it. This is what I ended up doing:

cmake_minimum_required(VERSION 3.10 FATAL_ERROR)

set (LANGUAGES "C;CXX")
  
project(openacc_lesson LANGUAGES ${LANGUAGES})

#  cmake ../ -DOpenACC_ACCEL_TARGET==tesla:cc60 -DCMAKE_C_COMPILER=pgcc -DCMAKE_CXX_COMPILER=pgc++
find_package(OpenACC REQUIRED)




if (CMAKE_VERSION VERSION_LESS "3.16")
  
  foreach(lang IN LISTS LANGUAGES)
    
    
    string(REPLACE " " "\;" default_options ${OpenACC_${lang}_FLAGS})
    # message(WARNING "Creating OpenACC_${lang}_OPTIONS: ${default_options}")
    
    set(OpenACC_${lang}_OPTIONS ${default_options})
    message(STATUS "OpenACC ${lang} version " ${OpenACC_${lang}_VERSION})
    message(STATUS "OpenACC ${lang} flags " ${OpenACC_${lang}_FLAGS})
    
  endforeach()  

endif()




add_executable(ex7 example7.c)

add_definitions(-DROWS=3000 -DCOLS=3000)
target_compile_options(ex7 PRIVATE ${OpenACC_C_OPTIONS})
target_link_libraries(ex7 PRIVATE ${OpenACC_C_OPTIONS})