Dynamic Compilation

Functions used to compile on demand the Kokkos functions needed.

This mechanism allows to create new methods without degrading performance (after method invalidation).

Only functions operating on views are dynamically compiled, the rest are compiled with the wrapper library.

Compilation is not thread-safe and must be done by a single process (and single thread) at once. This is ensured by compilation_lock.

Kokkos.DynamicCompilation.@compile_and_callMacro
@compile_and_call(method, args, compile)

If has_specialization(method, args) then invoke method, otherwise compile is executed. In both cases, method is invoked through Base.invokelatest.

This handles the following case:

function my_method(@nospecialize(x))
    return @compile_and_call(my_method, x, begin #= ... =# end)
end

function my_program(x)
    my_method(x)  # Will compile
    my_method(x)
end

Here the second invocation of my_method is still done in the same world in which my_program was invoked, even though the first invocation increased the global world counter. Therefore, we need to ensure method has not been specialized in the latest world before trying to compile.

source
Kokkos.DynamicCompilation.compile_and_loadFunction
compile_and_load(current_module, cmake_target; kwargs...)

Check if the library of cmake_target compiled with kwargs exists, if not compile it, then load it.

The library is a CxxWrap module, which is then loaded into current_module in the sub-module Impl<number> with '<number>' the total count of calls to compile_and_load in this Julia session.

source
Kokkos.DynamicCompilation.call_more_specificFunction
call_more_specific(func, args)

Call func with args with Base.invokelatest(func, args...), but only if there is a specialized method for the arguments (an error is raised otherwise).

After calling compile_and_load from a @nospecialize method meant to define a new method specialized for args, this function will prevent infinite recursion if the new method is not applicable to args.

source
Kokkos.DynamicCompilation.compilation_lockFunction
compilation_lock(func)

Asserts that only a single process (and single thread) is compiling at once.

By default, there is only a lock on tasks of the current process.

If MPI.jl is loaded, a PID lock file is also used (see FileWatching.Pidfile, or Pidfile.jl before 1.9). Lock files have the advantage that no collective MPI operations are needed, however they only work if all MPI ranks share the same filesystem, and if this is not the case then there is no need for lock files. This can be overloaded with the JULIA_KOKKOS_USE_COMPILATION_LOCK_FILE environment variable.

Note that it is not the current process' ID that is used in the PID lock file, since PID are not guaranteed to be unique in a MPI application. Instead a random 32-bit number is used, constant for this process.

source