Adding Kernels to Ginkgo¶
A Ginkgo kernel is a piece of an algorithm that will get dispatched to an Executor
.
Let’s look at how to add a new kernel and make sure that it can run on all Executor
s.
As an example, assume we want to add my_new_kernel
to be used in TheModifiedSolver
.
Adding a new Ginkgo kernel will touch several parts of the code:
In the relevant header file where you are adding the kernel (here, it would be
core/solver/[the_modified_solver]_kernels.hpp
), declare the new kernel and add a new macro for it withGKO_DECLARE_[NAMESPACE]_[KERNEL_NAME]
.In
core/device_hooks/common_kernels.inc.cpp
, find the correct namespace forTheModifiedSolver
. In that section, use the relevantGKO_STUB
macro. This will depend on the template parameters. For example, ifmy_new_kernel
only depends on theValueType
used in the solver, then we would useGKO_STUB_VALUE_TYPE(GKO_DECLARE_THE_MODIFIED_SOLVER_MY_NEW_KERNEL);
.In the core file where the kernel will be used (here,
core/solver/[the_modified_solver].cpp
), register the kernel withGKO_REGISTER_OPERATION(my_new_kernel, the_modified_solver::my_new_kernel);
. TheGKO_REGISTER_OPERATION
macro inserts the necessary code to allow you to run the kernel with
exec->run(the_modified_solver::make_my_new_kernel(...))
Finally, we have to write the definition(s) of the kernel for the backends. We will always have, at minimum, two versions of the kernel (one in
Reference
, and one for the other backends), but we could have separate versions for all backends. In this example, we would add aReference
version to the relevant kernels file inreference/solver
, and to other backends as necessary. In each file where we add a version of the new kernel, we follow the definition with the relevant version of theGKO_INSTANTIATE_FOR_EACH_
macro to instantiate the kernel.We also want to add tests for our new kernel. First, we add a test against a known solution/expected outcome to
reference/test/solver/[the_modified_solver]_kernels.cpp
. Then, we add a test comparing the other backends toReference
. For a unified kernel incommon/unified
, this test would go intest/solver/[the_modified_solver]_kernels.cpp
. Tests for specialized backend implementations belong in `[backend]/test/solver/[the_modified_solver]_kernels.cpp``.
In the next section, we will give more details about creating unified kernels in Ginkgo.