xref: /llvm-project/flang/cmake/modules/AddFlangOffloadRuntime.cmake (revision 076aac59acbe7555b922e77886e4428f1aa1cd0b)
1option(FLANG_EXPERIMENTAL_CUDA_RUNTIME
2  "Compile Fortran runtime as CUDA sources (experimental)" OFF
3  )
4
5option(FLANG_CUDA_RUNTIME_PTX_WITHOUT_GLOBAL_VARS
6  "Do not compile global variables' definitions when producing PTX library" OFF
7  )
8
9set(FLANG_LIBCUDACXX_PATH "" CACHE PATH "Path to libcu++ package installation")
10
11set(FLANG_EXPERIMENTAL_OMP_OFFLOAD_BUILD "off" CACHE STRING
12  "Compile Fortran runtime as OpenMP target offload sources (experimental). Valid options are 'off', 'host_device', 'nohost'")
13
14set(FLANG_OMP_DEVICE_ARCHITECTURES "all" CACHE STRING
15  "List of OpenMP device architectures to be used to compile the Fortran runtime (e.g. 'gfx1103;sm_90')")
16
17macro(enable_cuda_compilation name files)
18  if (FLANG_EXPERIMENTAL_CUDA_RUNTIME)
19    if (BUILD_SHARED_LIBS)
20      message(FATAL_ERROR
21        "BUILD_SHARED_LIBS is not supported for CUDA build of Fortran runtime"
22        )
23    endif()
24
25    enable_language(CUDA)
26
27    # TODO: figure out how to make target property CUDA_SEPARABLE_COMPILATION
28    # work, and avoid setting CMAKE_CUDA_SEPARABLE_COMPILATION.
29    set(CMAKE_CUDA_SEPARABLE_COMPILATION ON)
30
31    # Treat all supported sources as CUDA files.
32    set_source_files_properties(${files} PROPERTIES LANGUAGE CUDA)
33    set(CUDA_COMPILE_OPTIONS)
34    if ("${CMAKE_CUDA_COMPILER_ID}" MATCHES "Clang")
35      # Allow varargs.
36      set(CUDA_COMPILE_OPTIONS
37        -Xclang -fcuda-allow-variadic-functions
38        )
39    endif()
40    if ("${CMAKE_CUDA_COMPILER_ID}" MATCHES "NVIDIA")
41      set(CUDA_COMPILE_OPTIONS
42        --expt-relaxed-constexpr
43        # Disable these warnings:
44        #   'long double' is treated as 'double' in device code
45        -Xcudafe --diag_suppress=20208
46        -Xcudafe --display_error_number
47        )
48    endif()
49    set_source_files_properties(${files} PROPERTIES COMPILE_OPTIONS
50      "${CUDA_COMPILE_OPTIONS}"
51      )
52
53    if (EXISTS "${FLANG_LIBCUDACXX_PATH}/include")
54      # When using libcudacxx headers files, we have to use them
55      # for all files of F18 runtime.
56      include_directories(AFTER ${FLANG_LIBCUDACXX_PATH}/include)
57      add_compile_definitions(RT_USE_LIBCUDACXX=1)
58    endif()
59
60    # Add an OBJECT library consisting of CUDA PTX.
61    llvm_add_library(${name}PTX OBJECT PARTIAL_SOURCES_INTENDED ${files})
62    set_property(TARGET obj.${name}PTX PROPERTY CUDA_PTX_COMPILATION ON)
63    if (FLANG_CUDA_RUNTIME_PTX_WITHOUT_GLOBAL_VARS)
64      target_compile_definitions(obj.${name}PTX
65        PRIVATE FLANG_RUNTIME_NO_GLOBAL_VAR_DEFS
66        )
67    endif()
68  endif()
69endmacro()
70
71macro(enable_omp_offload_compilation files)
72  if (NOT FLANG_EXPERIMENTAL_OMP_OFFLOAD_BUILD STREQUAL "off")
73    # 'host_device' build only works with Clang compiler currently.
74    # The build is done with the CMAKE_C/CXX_COMPILER, i.e. it does not use
75    # the in-tree built Clang. We may have a mode that would use the in-tree
76    # built Clang.
77    #
78    # 'nohost' is supposed to produce an LLVM Bitcode library,
79    # and it has to be done with a C/C++ compiler producing LLVM Bitcode
80    # compatible with the LLVM toolchain version distributed with the Flang
81    # compiler.
82    # In general, the in-tree built Clang should be used for 'nohost' build.
83    # Note that 'nohost' build does not produce the host version of Flang
84    # runtime library, so there will be two separate distributable objects.
85    # 'nohost' build is a TODO.
86
87    if (NOT FLANG_EXPERIMENTAL_OMP_OFFLOAD_BUILD STREQUAL "host_device")
88      message(FATAL_ERROR "Unsupported OpenMP offload build of Flang runtime")
89    endif()
90    if (BUILD_SHARED_LIBS)
91      message(FATAL_ERROR
92        "BUILD_SHARED_LIBS is not supported for OpenMP offload build of Fortran runtime"
93        )
94    endif()
95
96    if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND
97        "${CMAKE_C_COMPILER_ID}" MATCHES "Clang")
98
99      set(all_amdgpu_architectures
100        "gfx700;gfx701;gfx801;gfx803;gfx900;gfx902;gfx906"
101        "gfx908;gfx90a;gfx90c;gfx940;gfx1010;gfx1030"
102        "gfx1031;gfx1032;gfx1033;gfx1034;gfx1035;gfx1036"
103        "gfx1100;gfx1101;gfx1102;gfx1103;gfx1150;gfx1151"
104        "gfx1152;gfx1153"
105        )
106      set(all_nvptx_architectures
107        "sm_35;sm_37;sm_50;sm_52;sm_53;sm_60;sm_61;sm_62"
108        "sm_70;sm_72;sm_75;sm_80;sm_86;sm_89;sm_90"
109        )
110      set(all_gpu_architectures
111        "${all_amdgpu_architectures};${all_nvptx_architectures}"
112        )
113      # TODO: support auto detection on the build system.
114      if (FLANG_OMP_DEVICE_ARCHITECTURES STREQUAL "all")
115        set(FLANG_OMP_DEVICE_ARCHITECTURES ${all_gpu_architectures})
116      endif()
117      list(REMOVE_DUPLICATES FLANG_OMP_DEVICE_ARCHITECTURES)
118
119      string(REPLACE ";" "," compile_for_architectures
120        "${FLANG_OMP_DEVICE_ARCHITECTURES}"
121        )
122
123      set(OMP_COMPILE_OPTIONS
124        -fopenmp
125        -fvisibility=hidden
126        -fopenmp-cuda-mode
127        --offload-arch=${compile_for_architectures}
128        # Force LTO for the device part.
129        -foffload-lto
130        )
131      set_source_files_properties(${files} PROPERTIES COMPILE_OPTIONS
132        "${OMP_COMPILE_OPTIONS}"
133        )
134
135      # Enable "declare target" in the source code.
136      set_source_files_properties(${files}
137        PROPERTIES COMPILE_DEFINITIONS OMP_OFFLOAD_BUILD
138        )
139    else()
140      message(FATAL_ERROR
141        "Flang runtime build is not supported for these compilers:\n"
142        "CMAKE_CXX_COMPILER_ID: ${CMAKE_CXX_COMPILER_ID}\n"
143        "CMAKE_C_COMPILER_ID: ${CMAKE_C_COMPILER_ID}")
144    endif()
145  endif()
146endmacro()
147