Skip to content

Add a kernel function and use it in core

Tobias Ribizel edited this page Apr 26, 2021 · 4 revisions

Add a kernel function and use it in core


Short Summary

  • core/<xxx_kernels.hpp>: the definition of kernel
  • core/xxx.cpp: the registration and usage of kernel
  • core/device_hooks/common_kernels.inc.cpp: the dummy kernel for non-compiled module
  • <module>/<xxx.suffix>: the implementation of kernel

fill_array example

Add fill_array(std::shared_ptr<const DefaultExecutor> exec, ValueType * data, size_type num_entries, ValueType val). Each kernel function used in core needs the ginkgo executor as the first input argument such that Ginkgo can use it to dispatch the kernel to different implementation on different modules. The DefaultExecutor will be correct executor (<module>Executor) in corresponding namespace (gko::kernels::<module>) we will use

#define GKO_DECLARE_FILL_ARRAY_KERNEL(ValueType)                           \
    void fill_array(std::shared_ptr<const DefaultExecutor> exec,           \
                    ValueType *data, size_type num_entries, ValueType val)

, which has the form #define unique_macro(template argument) function_definition. We define the macro (GKO_DECLARE_FILL_ARRAY_KERNEL) such that we can reuse it in another file. Moreover, we need to add the kernel macro into GKO_DECLARE_ALL_TEMPLATES like following for kernel definition.

#define GKO_DECLARE_ALL_TEMPLATES             \
    template <typename ValueType>             \
    GKO_DECLARE_FILL_ARRAY_KERNEL(ValueType); \
    ...
// the last one DECLARE does not need ;

namespace module {

    GKO_DECLARE_ALL_AS_TEMPLATES;

}
GKO_REGISTER_OPERATION(fill_array, components::fill_array);

GKO_REGISTER_OPERATION(name, actual kernel) will give the executor->run(make_name(arguments)) in this core.

Note. Need to instantiate all core functions itself or the corresponding class. We only instantiate Array<type>::fill function here, but we can also instantiate the class to instantiate all member(core) function of the class like core/matrix/coo.cpp

Ginkgo can select which module should be compiled, so we need to have some dummy kernel to complete compilation and throw the GKO_NOT_COMPILED informative error message.

template <typename IndexType>
GKO_DECLARE_FILL_ARRAY_KERNEL(IndexType)
GKO_NOT_COMPILED(GKO_HOOK_MODULE);
GKO_INSTANTIATE_FOR_EACH_TEMPLATE_TYPE(GKO_DECLARE_FILL_ARRAY_KERNEL);

, which has the form

<template of function>
<the predefined kernel macro with templated argument>
GKO_NOT_COMPILED(GKO_HOOK_MODULE);
<instantiate macro>(the predefined kernel macro name)

Ginkgo already has several instantiate macros, which is declared in include/ginkgo/core/base/types.hpp Usual instantiate method:

  • GKO_INSTANTIATE_FOR_EACH_VALUE_TYPE: all ValueType
  • GKO_INSTANTIATE_FOR_EACH_INDEX_TYPE: all IndexType
  • GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE: all pairs (ValueType, IndexType)
  • GKO_INSTANTIATE_FOR_EACH_TEMPLATE_TYPE: all type ValueType + IndexType + size_type

<module>/components/fill_array.suffix

We use reference/components/fill_array.cpp here. Implement the kernel normally and need to instantiate the implementation by <instantiate macro>(the predefined kernel macro name)

Clone this wiki locally