Intel® Distribution of OpenVINO™ Toolkit
Community assistance about the Intel® Distribution of OpenVINO™ toolkit, OpenCV, and all aspects of computer vision-related on Intel® platforms.

How to specify custom kernel function parameters

Deepak_C_R
Beginner
2,138 Views

I am trying to create a custom kernel by referring to cnn_custom_kernel sample code.

For the oclCropMD custom kernel function following thing are specified int the cnn_custom_kernel_module.cpp file.

    vx_enum param_types_crop[] = { VX_TYPE_TENSOR,VX_TYPE_UINT32, VX_TYPE_UINT32, VX_TYPE_TENSOR};
    vx_enum param_directions_crop[] = { VX_INPUT,  VX_INPUT, VX_INPUT, VX_OUTPUT };
    vx_kernel oclKernel = vxAddDeviceKernelIntel(
                                  context,
                                  "com.intel.cnn.sample.crop", 
                                  VX_KERNEL_CNN_OCL_CUSTOM_CROPMD,   
                                  kernelLibrary,                 
                                  "oclCropMD",                    
                                  4,                       // number of OpenVX Kernel parameters
                                  param_types_crop,        // Types of parameters: array
                                  param_directions_crop,   // Directions for each parameter: array
                                  VX_BORDER_UNDEFINED,       
                                  oclCropValidator,   
                                  oclCropInitialize,      
                                  oclCropDeinitialize    
    );

 

In the above code how the 4 values (types) are specified in vx_enum param_types_crop array (how they found the parameter type).

How it will change when we are defining a new custom kernel ?

Also in custom_cnn.cl following thing are specified.

kernel void oclCropMD
(
        const __global float* input, // Pointer to data
        int     num_dims_in, //number of tensor dimensions
        const __global int* dims_in, // tensor dims
        const __global int* stride_in, // tensor strides in bytes for each dim, step between two neighbor voxels

        uint     offset_x,
        uint     offset_y,

        __global float* output, // Pointer to data
        int     num_dims_out, //number of tensor dimensions
        const __global int* dims_out, // tensor dims
        const __global int* stride_out // tensor strides in bytes for each dim, step between two neighbor voxels
)

In the above custom kernel function how these parameter are specified ? (For different custom kernel functions arguments are different, how they are determining the number of input arguments and types) How we can find the parameters that need to be passed to custom kernel function ?.

 

 

 

 

 

 

 

 

 

 

 

0 Kudos
10 Replies
Stav_S_Intel
Employee
2,138 Views

Hi Deepak,

please refer to "VAD Developer guide"- you will find a "Developing user kernels" chapter. 

This chapter specifies how to use the wizard to create the header for custom kernel and define the variables. 

If something is unclear- please let me know. 

Regards.

Stav

0 Kudos
Deepak_C_R
Beginner
2,138 Views

Hi Stav,

Using MO how I can do that ?. In this post you have mentioned that I need to use only MO to do these things. If I am using VAD I will get all the parameters inside the code generated by VAD. You have provided this link to create a custom kernel using MO, but I couldn't find any documentation to find the parameters that need to be passed to custom kernel.

(My aim is to create a custom layer and call it instead of the original one.)

0 Kudos
Stav_S_Intel
Employee
2,138 Views

Deepak, 

Yes, now that i understand what you are doing- lets discuss the original question in this thread. it is a great sample to look at. the first batch of code you published is the definition in OpenVX- there you need (since you are writing the custom layer) to update the number of parameters you would define and the types- not sure what you meant by how- you define an array with the types of your parameters just like in the example.then, you need to define which of them are inputs and which are outputs and supply the OpenVX validation, initialization and deinitialization functions you should supply with it. 

In the lower part of your code-where you define the code for your layer you need to be consistant  with the definitions you defined as the writer.. 

Regards,

Stav

0 Kudos
Deepak_C_R
Beginner
2,138 Views

My aim is to call a custom layer instead of the original one. I think ModelOptimizer will automatically link the custom layer I wrote based on the code and the XML files present.

In the cnn_custom_kernel example there are two custom kernels: oclCropMD() and oclDeconvMD().

The oclCropMD signature is given as:

kernel void oclCropMD
(
        const __global float* input, // Pointer to data
        int     num_dims_in, //number of tensor dimensions
        const __global int* dims_in, // tensor dims
        const __global int* stride_in, // tensor strides in bytes for each dim, step between two neighbor voxels

        uint     offset_x,
        uint     offset_y,

        __global float* output, // Pointer to data
        int     num_dims_out, //number of tensor dimensions
        const __global int* dims_out, // tensor dims
        const __global int* stride_out // tensor strides in bytes for each dim, step between two neighbor voxels
)

 

And oclDeconvMD() given as

kernel void oclDeconvMD
(
        const __global float* input, // Pointer to data
        int     num_dims_in, //number of tensor dimensions
        const __global int* dims_in, // tensor dims
        const __global int* stride_in, // tensor strides in bytes for each dim, step between two neighbor voxels

        const __global float* ptr_weights, // Pointer to data
        int     num_dims_weights, //number of tensor dimensions
        const __global int* dims_weights, // tensor dims
        const __global int* stride_weights, // tensor strides in bytes for each dim, step between two neighbor voxels

        const __global float* ptr_bias, // Pointer to data
        int     num_dims_bias, //number of tensor dimensions
        const __global int* dims_bias, // tensor dims
        const __global int* stride_bias, // tensor strides in bytes for each dim, step between two neighbor voxels

        int     stride_x,
        int     stride_y,
        int     pad_x,
        int     pad_y,

        __global float* output, // Pointer to data
        int     num_dims_out, //number of tensor dimensions
        const __global int* dims_out, // tensor dims
        const __global int* stride_out // tensor strides in bytes for each dim, step between two neighbor voxels
)

Here these two functions have different parameters. How they have determined the parameters that are there in the function signature ?.

(When I have used VAD these parameters were already there and I just need to write the code inside the function)

If I am writing a new custom kernel function how I will write the arguments in that ?

 

 

 

 

0 Kudos
Stav_S_Intel
Employee
2,138 Views

Hi Deepak,

So again, i am not sure we are on the same page- the header for the custom layer including the inputs, depends on your implementation- what your custom layer needs as inputs and outputs. you are the one who is writing and implementing it, just like in caffe, you were the one defining the code and defining the inputs and outputs, it is the same issue here.

VAD gives a suggestion to common custom kernel, but again it is not set in stone and you need to edit it according to your needs... 

 

Regards,

Stav

0 Kudos
Deepak_C_R
Beginner
2,138 Views

Suppose if we are not defining oclCropMD() custom kernel, it would have called original caffe function which does the same thing. Can you provide the function declaration of that caffe function ?.

(For example the oclCropMD() is called from caffe code, how the caffe function is able to understand the parameters defined inside the oclCropMD())

 

0 Kudos
Stav_S_Intel
Employee
2,138 Views

Hi, 

You need to define Custom layers in caffe as well when you do your training, than you define them (in the same way. up to your implementation)  in MO to carry on with the pipeline... 

 

Regards,

Stav

0 Kudos
Deepak_C_R
Beginner
2,138 Views

I am sorry,I didn't understand it.

In cnn_custom_kernel sample there is oclDeconvMD() custom kernel, from where call to this function is happening ?. (Can you provide the cpp  file which does this)

0 Kudos
Stav_S_Intel
Employee
2,138 Views

Hi Deepak, 

You do not have access to the call to the function as it is internal.

 

Regards,

Stav

0 Kudos
Deepak_C_R
Beginner
2,138 Views

Hi,

I understood how to specify parameter

Each VX_TYPE_TESNSOR  in param_types_crop is converted to 4 openCL kernel arguments: { global dtype* ptr, int num_dims, int* dims, int* strides ptr }.

We are binding values with the params using following functions:

bindInputTesnsor(), bindOutputTensor() etc.. which is done setCropValues().

 

 

0 Kudos
Reply