LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Issue for interfacing OneDNN DLL

Solved!
Go to solution

Hi,

 

I'm trying to interface with the Intel OneDNN library through their DLL.
This library is contained in the OneAPI Base Toolkit which can be downloaded from the Intel website at this address: https://www.intel.com/content/www/us/en/developer/tools/oneapi/base-toolkit.html#gs.4tk3q4
I managed to call the first necessary functions (creation of an engine and a stream) however when creating a memory descriptor my LabVIEW program crashes.
I checked several times the function declaration and the parameters to be sent but nothing happened.
The best I can do is to get error 2 (equivalent to invalid arguments), the rest of the time I have a crash of LabVIEW during the call.

 

Here is what my VI looks like (you can find it in attachment):

 

coco82_1-1656413007666.png

I used this page to fill in the parameter values: https://oneapi-src.github.io/oneDNN/page_getting_started_cpp.html

If you look for the definition of the functions they are C:\Program Files (x86)\Intel\oneAPI\dnnl\2022.1.0\cpu_iomp\include\oneapi\dnl\dnnl.h

 

 

0 Kudos
Message 1 of 4
(807 Views)

Do you see the first unwired input terminal on your node? That's a pointer to a data structure of type dnnl_memory_desc_t.

 

So you pass an uninitialized pointer to nothing and want the function to initialize it. Instant crash is the best outcome you can have with that!

 

typedef struct {
    int ndims;
    dnnl_dims_t dims;
    dnnl_data_type_t data_type;
    dnnl_dims_t padded_dims;
    dnnl_dims_t padded_offsets;
    dnnl_dim_t offset0;
    dnnl_format_kind_t format_kind;
    union {
        dnnl_blocking_desc_t blocking;
        dnnl_wino_desc_t wino_desc;
        dnnl_rnn_packed_desc_t rnn_packed_desc;
        // ... other descriptions possible
    } format_desc;
    dnnl_memory_extra_desc_t extra;
} dnnl_memory_desc_t;

This is the definition of the structure, that's a lot more than nothing, and you need to provide a large enough memory space for the init function to write its descriptor data into.

 

Now in C you could simply do a 

ptr = malloc(sizeof(dnnl_memory_desc_t));

but in LabVIEW that is harder. Unless when the OneAPI has an exported C function to allocate such a memory descriptor for you, things will start to get hairy. 

You would have to hand calculate the size of the memory structure , which can be also different depending on target platform such as 32-bit and 64-bit, and allocate a pointer of that size in LabVIEW.

Rolf Kalbermatter
My Blog
0 Kudos
Message 2 of 4
(776 Views)

First of all, thank you for your answer.

 

"Do you see the first unwired input terminal on your node? ", yes but as you say "So you pass an uninitialized pointer to nothing and want the function to initialize it.", that's exactly what I expected from this function.

The first functions that I managed to interface such as the creation of the engine (dnnl_engine_create) which is also a pointer to a data structure of type dnnl_engine_t.

 

create_engine.png

 And for this function I didn't have to fill the pointer since it's up to the function to send me back a pointer correct to the structure.

That's why I thought it would be similar for the function on which I have problems.

 

Anyway, I tried to initialize a pointer to enter it in the function (voluntarily with an extremely large value imagining that it would be sufficient for the data contained in this structure), however, this did not solve my crash problem.
Could initializing a pointer with a too big value be a problem? (I would think not, except that it would waste memory unnecessarily)

 

initialize_pointer_test.png

0 Kudos
Message 3 of 4
(760 Views)
Solution
Accepted by topic author coco82

I can immediately see two indications (note they are not guarantees, the only way to be sure is to read and fully understand the API documentation:

 

- The naming convention: One function has the word "create" in it, the other uses "init". And yes it's just a convention and its naming scheme is as good or bad as the experience of the developers involved (unless they are into obfuscation as a hobby).

 

- The function declaration passes both as a pointer value but for the engine_create function it returns an opaque pointer. It's content is unknown and inaccessible to the caller. It could be an index into an internal array of structure in the library, a pointer to a memory structure or a file handle, you can't know, and don't need to care. It's a Handle to an engine as the dnnl API defines it and that's it.

The parameter you pass to dnnl_memory_desc_init...() is a pointer to a structure. The function couldn't even allocate that structure as it could not return the pointer to the caller through a single referenced variable. For that the parameter would need to be double referenced:

 

func(.., memory_desc_t **desc, ..)

 

 

Rolf Kalbermatter
My Blog
0 Kudos
Message 4 of 4
(731 Views)