From f1a9efcac5743e05fc4e1dbc53c08f69ec19d5a8 Mon Sep 17 00:00:00 2001 From: qiaolongfei Date: Wed, 20 Dec 2017 17:18:21 +0800 Subject: [PATCH] add kernel hint design --- doc/design/kernel_hint_design.md | 54 ++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 doc/design/kernel_hint_design.md diff --git a/doc/design/kernel_hint_design.md b/doc/design/kernel_hint_design.md new file mode 100644 index 00000000000..1ccab168449 --- /dev/null +++ b/doc/design/kernel_hint_design.md @@ -0,0 +1,54 @@ +## Problem +In PaddlePaddle's [Design](https://github.com/PaddlePaddle/Paddle/blob/develop/doc/design/switch_kernel.md), one Operator may have multiple kernels. Users may have some personal preference to choose a certain type of kernel for an operator, such as `force_cpu` to use a CPU kernel, `use_cudnn` to choose a CUDNN kernel, we need to provide a way for a user to do this. + +In the current design, we use KernelType to describe one kernel. + +```cpp +struct KernelType { + Place place_; + DataType data_type_; + LayoutType layout_; +}; +``` + `place_` `data_type_` and `layout_` can come from the input tensor of the operator, `GetActualKernelType(inputs)` use inputs to infer the proper kernel key that fit the incoming data, user can not config it. + +The design also provides a virtual method `GetExpectedKernelType` that user can overload and choose the KernelType they want to use. + +so, we should send the information user defined in proto to `GetExpectedKernelType` for choosing a kernel. + +The problem is, how should we define and send the information for `GetExpectedKernelType` to use? + +## Solution +1, Do nothing, let the user add the information they want to operator‘s attribute and get them inside `GetExpectedKernelType`, this can work right. But there is a little problem that users may define many kinds of hints for the same purpose, such as `force_cpu`, `use_cpu`, `CPU` for CPU kernel, and `use_cudnn`, `force_cudnn`, `cudnn_kernel` for use of CUDNN kernel. + +2, Pre-define all the needed option and use a single attr key such as `kernel_hint` for the user, this is not so flexible if the user wants to define some more kind of hint. + + +To provide enough flexibility while avoiding confusion definition, we can predefine some options, such as `force_cpu`, `use_cudnn`, `use_mkldnn` for a user to choose. + +```cpp +const std::string kNonHint = ""; +const std::string kForceCPU = "force_cpu"; +const std::string kUseCUDNN = "use_cudnn"; +const std::string kUseMKLDNN = "use_mkldnn"; + +KernelType GetExpectedKernelTyp() { + // "kernel_hint" is a user defined attribute name + if (Attr("kernel_hint") == kForceCPU) { + return KernelType(CPUPlace, ...) + } else { + ... + } +} +``` + +In Python code + +```python +def xx_layer(..., kernel_hint=None): + layer_helper = ... + layer_helper .append_op( + type="xx", + # "kernel_hint" should be the same with the attr name in CPP + attr={"kernel_hint": kernel_hint or ""}) +``` -- GitLab