Quantcast
Channel: Intel® oneAPI Math Kernel Library & Intel® Math Kernel Library
Viewing all articles
Browse latest Browse all 2652

1D convolution of a 3D array using Intel MKL

$
0
0

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[i]);

    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.


Viewing all articles
Browse latest Browse all 2652

Trending Articles