Intel® oneAPI Math Kernel Library
Ask questions and share information with other developers who use Intel® Math Kernel Library.
7073 Discussions

1D convolution of a 3D array using Intel MKL

A2009
Beginner
1,059 Views

I have a 3D array which is stored in a columnwise fashion.

for( int k = 0; k < nTop; k++ ) // Loop through the tops. 
    for( int j = 0; j < nCol; j++ ) // Loop through the columns. 
        for( int i = 0; i < nRow; i++ ) // Loop through the rows 
        { 
            ijk = i + nRow * j + nRow * nCol * k; 
            my3Darray[ ijk ] = 1.0; 
        }

I want to apply three different 1D kernels of size 2x1 across all the rows, all the columns, and all the tops of my 3D array separately and one after another. 

To be able to use Intel MKL, I read the MKL documentation which describes creating a new convolution or correlation task descriptor for multidimensional case. I carefully read "Mathematical Notation and Definitions" that talks about the notations used for convolution. I also read the example file named vslsconv_2d_auto.c. I am lost in the implementation of 1D convolution to a 3D array. 

The following code is my understanding from the documentation in a simple C code, which is the modified version of the example file vslsconv_2d_auto.c. In my code, I am trying to apply 1D convolution with kernel = [-1 1] on all the rows of the 3D array and get the convolved result which has the same size as the input. My array has a general size of nRow×nCol×nTop. In the example code below, I chose the size to be 3×4×5.

int main()
{

    VSLConvTaskPtr task;

    int nRow = 3, nCol = 4, nTop = 5;
    double *x = new double[nRow*nCol*nTop];

    int n1Ker = 2, n2Ker = 1;
    double *kernel = new double[ n1Ker*n2Ker ];

    double *xConvolved = new double[(nRow+n1Ker)*(nCol+n2Ker)*nTop];

    MKL_INT xshape[3]  = {nRow, nCol, nTop};
    MKL_INT convolved_shape[3] = {nRow, nCol, nTop};
    MKL_INT kernel_shape[2]= {2,1};
    
    MKL_INT rank=3;

    int status;

    for( int i = 0; i < nRow*nCol*nTop; i++ )
        x[ i ] = 1;
    
    kernel[ 0 ] = -1; kernel[ 1 ] =  1;

    int mode = VSL_CONV_MODE_AUTO;

    /* Create task descriptor (create descriptor of problem) */
    status = vsldConvNewTask(&task, mode, rank, xshape, kernel_shape, convolved_shape);
    if( status != VSL_STATUS_OK ){
    printf("ERROR: creation of job failed, exit with %d\n", status);
    return 1;}

    /* Execute task (Calculate 2 dimension convolution of two arrays)  */
    status = vsldConvExec(task, x, NULL, kernel, NULL, xConvolved, NULL);
    if( status != VSL_STATUS_OK ){
    printf("ERROR: job status bad, exit with %d\n", status);
    return 1;}
    
    /* Delete task object (delete descriptor of problem) */
    status = vslConvDeleteTask(&task);
    if( status != VSL_STATUS_OK ){
    printf("ERROR: failed to delete task object, exit with %d\n", status);
    return 1;}
    
    for( int i = 0; i < nRow*nCol*nTop; i++)
    printf("%f\n", xConvolved); 
    
    delete[] x;
    delete[] xConvolved;
    delete[] kernel;

    return 0;
}

After running the code, I get the following error:

ERROR: job status bad, exit with -2312

I would be thankful if my colleagues in the forum could let me know how I can fix this issue and help me find out how to correctly get 1D convolution of a 3D array on its rows, columns, or tops.

0 Kudos
1 Reply
Dmitry_B_Intel
Employee
1,059 Views

Hi,

When you do a rank=3 convolution on an array, that means all three shapes (x, y, and z) have rank=3. It is a error to give rank=2 kernel_shape to the task constructor, and this error cannot be reported by the constructor.

The shape of the output for convolution should span range [Rmin...Rmax], or [ 0..nRow-1+n1Ker-1, 0..nCol-1+n2Ker-1, ...], according to the "Mathematical Notation and Definitions" subsection of MKL Reference Manual. The definition of convolved_shape does not conform to this rule.

Thanks
Dima

 

0 Kudos
Reply