Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / thirdparty / clDNN / kernel_selector / core / actual_kernels / convolution / convolution_kernel_tutorial.cpp
1 /*
2 // Copyright (c) 2016 Intel Corporation
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 */
16
17 #include "convolution_kernel_tutorial.h"
18
19 namespace kernel_selector {
20
21         // Step 0: 
22         //
23         // take a look on convolution_kernel_tutorial.h 
24     
25     ParamsKey ConvolutionKernel_Tutorial::GetSupportedKey() const
26     {
27         // Step 1:
28         // - Update the features supported by the kernel below
29
30         ParamsKey k;
31         
32         // Supported data type
33         k.EnableInputDataType(Datatype::F16);
34         k.EnableInputDataType(Datatype::F32);
35         k.EnableOutputDataType(Datatype::F16);
36         k.EnableOutputDataType(Datatype::F32);
37         k.EnableInputWeightsType(WeightsType::F16);
38         k.EnableInputWeightsType(WeightsType::F32);
39
40         // Supported layout
41         k.EnableInputLayout(DataLayout::bfyx);
42         k.EnableOutputLayout(DataLayout::bfyx);
43         k.EnableInputLayout(DataLayout::yxfb);
44         k.EnableOutputLayout(DataLayout::yxfb);
45
46         // Supported tensor offset/pitch/padding
47         k.EnableTensorOffset();
48         k.EnableTensorPitches();
49         k.EnableBatching();
50
51         // Supported convolution extra data
52         k.EnableDilation();
53         k.EnableBiasPerFeature();
54         k.EnableBiasPerOutput();
55         k.EnableNonBiasTerm();
56
57         // Supported convolution which get a split index and uses it as a view on the input/output
58         k.EnableSplitSupport();
59
60         // Supported convoltuion with depth separable optimization flag
61         k.EnableDepthwiseSeparableOpt();
62
63         return k;
64     }
65
66 #ifdef BASIC_TUTORIAL
67
68     KernelsData ConvolutionKernel_Tutorial::GetKernelsData(const Params& /*params*/, const optional_params& /*options*/) const
69     {
70         return{};
71
72         // Step 2:
73         // - Uncomment and update the following lines
74
75         // assert(params.GetType() == KernelType::CONVOLUTION && options.GetType() == KernelType::CONVOLUTION);
76         //
77         // const uint32_t numOfkernels = 1;
78         // KernelData kd = KernelData::Default<ConvolutionParams>(params, numOfkernels);
79         // ConvolutionParams& newParams = *static_cast<ConvolutionParams*>(kd.params.get());
80         // const ConvolutionOptionalParams& optParams = static_cast<const ConvolutionOptionalParams&>(options);
81         // auto& kernel = kd.kernels[0];
82         
83
84         // Step 3:
85         // - make sure that the input weights tensor fit to this kernel needs. 
86         //   in case it's not and the flag "optParams.allowWeightsReorder" set to "true", please update
87         //   the member "kd.weightsReorderParams" with the right OpenCL/CPU kernel which will be used to reorder the 
88         //   weights in the loading time.
89         //   you have three options:
90         //   - provide a cpu code - inherit from "CPUKernel" and implement "Execute" function.
91         //      (by default the input layout of CPU kernel is simple bfyx, and clDNN will reorder it for you before calling to Execute function)
92         //   - provide a GPU code by filling clKernelData.
93         //   - use existing layouts which clDNN support and use the auxiliary function "UpdateWeightsParams"
94
95
96         // Step 4:
97         // - make sure that the input tensor fits to this kernel's needs. 
98         //   make sure that you have the proper padding area with a proper padding value, and a proper alignment.
99         //   currently Convolution in clDNN doesn't allow the kernel to ask reordering
100
101
102         // Step 5:
103         // - fill "kernel.kernelString"
104         //   - fill "kernel.kernelString->str"                  - the source of the kernel. 
105         //     please use "db.get(kernelName)" in case you use "*.cl" file which located under "kernel_selector\core\cl_kernels\".
106         //   - fill "kernel.kernelString->jit"                  - Dynamic jit of this params. 
107         //   - fill "kernel.kernelString->options"              - options which pass to cl program build functions (like "-cl-no-subgroup-ifp")
108         //   - fill "kernel.kernelString->entry_point"          - kernel entry point 
109         //   - fill "kernel.kernelString->batch_compilation"    - A flag that allow clDNN kernel to compile this kernel as a part of a program
110         //                                                        NOTE: this can only be used if you prevent symbol conflicts with other kernels (#undef is done automatically by clDNN)
111
112
113         // Step 6:
114         // - fill "kernel.WorkGroupSizes" - local/global work group sizes for OpenCL kernel
115
116
117         // Step 7:
118         // - fill "kernel.arguments" - which describe the argument of the kernel. 
119         //   in this tutorial you can use:
120         //     kernel.arguments.push_back({ ArgumentDescriptor::Types::INPUT, 0 }); // "0" mean index of the input in case of multiple inputs.
121         //     kernel.arguments.push_back({ ArgumentDescriptor::Types::OUTPUT, 0 });
122         //     kernel.arguments.push_back({ ArgumentDescriptor::Types::WEIGHTS, 0 });
123         //     kernel.arguments.push_back({ ArgumentDescriptor::Types::BIAS, 0 });
124         //
125         //   in case that you have more than one kernel, you probably need an intermediate buffers.
126         //   in order to support that you have to describe the buffer size in kd.internalBufferSizes and add a kernel argument like:
127         //     kernel.arguments.push_back({ ArgumentDescriptor::Types::INTERNAL_BUFFER, <index to kd.internalBufferSize> });
128
129
130         // Step 8:
131         // - estimate the kernel's execution time. currently it's under development so please use FORCE_PRIORITY_<X> - lower is better.
132
133
134         // return{ kd };
135     }
136
137 #else
138
139     ConvolutionKernel_Tutorial::Parent::DispatchData ConvolutionKernel_Tutorial::SetDefault(const convolution_params& params, int autoTuneIndex) const
140     {
141         DispatchData runInfo = Parent::SetDefault(params, autoTuneIndex);
142
143         // Step 2:
144         //
145         // Init runInfo, and set kernel efficiency
146         runInfo.effiency = TUTORIAL_PRIORITY;
147
148         return runInfo;
149     }
150
151     bool ConvolutionKernel_Tutorial::Validate(const Params& p, const optional_params& o) const
152     {
153         if (!Parent::Validate(p, o))
154         {
155             return false;
156         }
157
158         // Step 3:
159         // 
160         // Validate this kernel support params and optional params. use:
161         // const ConvolutionParams& params = static_cast<const ConvolutionParams&>(p);
162         // const ConvolutionOptionalParams& options = static_cast<const ConvolutionOptionalParams&>(o);
163
164         return true;
165     }
166
167     JitConstants ConvolutionKernel_Tutorial::GetJitConstants(const convolution_params& params, const DispatchData& kd) const
168     {
169         auto jit = Parent::GetJitConstants(params, kd);
170         jit.AddConstant(MakeJitConstant("ADVANCED_TUTORIAL", ""));
171
172         // Step 4:
173         // 
174         // Add you own jit constants. for example
175         // jit.AddConstant(MakeJitConstant("<MY_CONST>", <my val>));
176         // - "my val" can be most of KernelSelector/C++ common types
177
178         return jit;
179     }
180
181     KernelsData ConvolutionKernel_Tutorial::GetKernelsData(const Params& params, const optional_params& options) const
182     {
183         return GetTunedKernelsDataByIndex(params, options);
184     }
185
186 #endif
187 }