Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compile as cmake language #555

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions docs/source/building.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,20 @@ There are numerous device backends, options, and architecture-specific optimizat
````
which activates the OpenMP backend. All the options controlling device backends, options, architectures, and third-party libraries (TPLs) are given in [CMake Keywords](../keywords).

## Separate Compilation via CMake Language
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know it is now from you, but I am wondering why "separate compilation"?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's technically "separable compilation" and was introduced in kokkos/kokkos#3136 with meaning such as "the compilation settings can be different for every target; they are separable".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no hard feelings about this. My line of reasoning was: Currently we don't offer the possibility to separate the compilation but rather we kind of force the separation when Kokkos_ENABLE_COMPILE_AS_CMAKE_LANGUAGE=ON, as the source files and targets that use kokkos will require to have properties set by cmake manually or might not compile

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand, but most people will read this as "it is the way to do libraries." Separable is slightly better.


Kokkos supports separating the compilation of source files using Kokkos from others. This is controlled similar to a CMake language. The feature requires Kokkos to be compiled with the keyword `Kokkos_ENABLE_COMPILE_AS_CMAKE_LANGUAGE=ON`. The availability of the feature can be checked via `find_package(Kokkos COMPONENTS separable_compilation)`.
JBludau marked this conversation as resolved.
Show resolved Hide resolved
The `kokkos_compilation` CMake function marks files in the application's source that contain Kokkos code to be compiled with the correct compiler and flags.
Copy link
Contributor

@nilsvu nilsvu Jan 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you clarify here how kokkos_compilation interacts with linking the Kokkos::kokkos target?

Specifically, I have a library target with GPU kernels that should be compiled with nvcc, and an executable target that should be compiled with plain gcc (because it's a pain to keep the whole code compatible with nvcc). Can I link the executable target with Kokkos::kokkos (e.g. so I can call Kokkos::initialize) without triggering it to be compiled with nvcc? I want to do this:

# Kernels library (compile with nvcc)
add_library(mykernels ...)
# Need to link kokkos for kernels obviously
target_link_libraries(mykernels PRIVATE Kokkos::kokkos)
# Compile kernels with nvcc
kokkos_compilation(TARGET mykernels)

# Executable (compile with gcc)
add_executable(myexec main.cpp)
# Use some kokkos functions and launch kernels in executable
target_link_libraries(myexec PRIVATE mykernels Kokkos::kokkos)
# Will myexec compile with gcc or nvcc now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In it's current state kokkos_compilation is not working as it would imply.

To get what you want to work you would need to separate your Kokkos dependent files into a subdirectory, create a library, wrap our interfaces and then link this library to Kokkos with PRIVATE. An example can be found here.

But you can not call Kokkos::initialize directly in your main with this. As soon as you use anything from the Kokkos interface you will need to compile with the compiler Kokkos was compiled with. A lot of the code in Kokkos is templated and can only be fully instantiated by the compiler if it know how you use it in your code.
Does this clarify it a bit?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the clarification! So does this mean only targets that I have marked with kokkos_compilation should link Kokkos::kokkos? That would be helpful to add to the docs I think.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kokkos_compilation as a function is only useful if you do find_package(Kokkos COMPONENTS separable_compilation). But in that case: yes.

But I guess the question if you want to separate the compilation mainly depends on what classes you use in the interfaces of your functions (which translates to INTERFACE?PUBLIC vs. PRIVATE in target_link_libraries).

````cmake
# this function is provided to easily select which files use the same compiler as Kokkos
# GLOBAL --> all files
# TARGET --> all files in a target
# SOURCE --> specific source files
# DIRECTORY --> all files in directory
# PROJECT --> all files/targets in a project/subproject
kokkos_compilation(SOURCE example.cpp)
````
The example in `examples/cmake_build_installed_kk_as_language` can help get you started.

## Known Issues<a name="KnownIssues"></a>

Expand All @@ -61,6 +75,9 @@ which activates the OpenMP backend. All the options controlling device backends,

* In a mixed C++/Fortran code, CMake will use the C++ linker by default. If you override this behavior and use Fortran as the link language, the link may break because Kokkos adds linker flags expecting the linker to be C++. Prior to CMake 3.18, Kokkos has no way of detecting in downstream projects that the linker was changed to Fortran. From CMake 3.18, Kokkos can use generator expressions to avoid adding flags when the linker is not C++. Note: Kokkos will not add any linker flags in this Fortran case. The user will be entirely on their own to add the appropriate linker flags.

### MSVC
* Building an application that uses Kokkos with Microsoft Visual Studio and the `Cuda` backend enabled, requires the use of the CMake language feature, see [Separate Compilation](#separate-compilation-via-cmake-language).

## Raw Makefile

Raw Makefiles are only supported via inline builds. See below.
Expand Down
4 changes: 4 additions & 0 deletions docs/source/keywords.rst
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,10 @@ General options
* Aggressively vectorize loops
* ``OFF``

* * ``Kokkos_ENABLE_COMPILE_AS_CMAKE_LANGUAGE``
* Enables Kokkos behaving like a CMake language, see `Separate Compilation <building.html#separate-compilation-via-cmake-language>`_.
* ``OFF``

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* * ``Kokkos_ENABLE_COMPILE_AS_CMAKE_LANGUAGE``
* Use native CMake language support
* Analogous to CUDA/HIP as CMake language
* ``OFF``

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This must be three lines not four for rendering the table correctly.

Debugging
---------
.. list-table::
Expand Down
Loading