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 Executors.
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_STUBmacro. This will depend on the template parameters. For example, ifmy_new_kernelonly depends on theValueTypeused 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_OPERATIONmacro 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 aReferenceversion 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.