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

Calling mkl_malloc in C#

Ryan_Deering
Beginner
1,376 Views
I am using the MKL libraries in C# to build an application that uses various BLAS, LAPACK, VML, and VSL functions in a 64-bit environment. I have been using the C# double[] array and the fixed keyword to call into the MKL functions. In profiling the code, I have found the CLR memory allocation is a significant portion of the calculation time. As an alternative, I am investigating the use of mkl_malloc. Unfortunately, I have been unable to successfully call into mkl_malloc. I get the following exception:

Exception has been thrown by the target of an invocation.
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

Can anyone give me advice on how to call into mkl_malloc from C# or whether this is impossible?

Thanks,
Ryan Deering

Here is sample code that illustrates the issue:

using System;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace MKLMalloc
{
[TestClass]
public unsafe class UnitTest1
{
[TestMethod]
public void MallocFree()
{
void* ptr = MKL.mkl_malloc(1,8);
MKL.mkl_free(ptr);
}
}

public static unsafe class MKL
{
private const string mkl = "mkl_rt.dll";

[DllImport(mkl)]
public static extern void* mkl_malloc(Int32 size, int alignment);

[DllImport(mkl)]
public static extern void mkl_free(void* ptr);
}
}

0 Kudos
1 Solution
Vladimir_Koldakov__I
New Contributor III
1,376 Views

Ryan,

The correct way of using memory functions in C# is to call MKL_malloc and MKL_free.

Though calling mkl_malloc/mkl_free is ok for C (see example), these names are just defines in the header file mkl_service.h:

#define mkl_malloc MKL_malloc
#define mkl_free MKL_free

You can also use mkl_malloc/mkl_free but with Fortran calling conventions as references.

Ive prepared a small suite with the both approaches. It is based on the example files from the article Using Intel MKL in your C# program.

mkl_malloc.zip

Thanks,
Vladimir

View solution in original post

0 Kudos
6 Replies
barragan_villanueva_
Valued Contributor I
1,376 Views
Hi,

MKL_malloc for C/C++ is declared as void *MKL_malloc(size_t size, int alignment)
so on Intel64 in should be used from C# as
public static extern void* mkl_malloc(Int64 size, int alignment);
0 Kudos
Ryan_Deering
Beginner
1,376 Views
Thanks for the suggestion. I tried using

public static extern void* mkl_malloc(Int64 size, int alignment);

but I still get the same exception. I've been banging my head against a wall with this one. Any other suggestions?

Ryan
0 Kudos
barragan_villanueva_
Valued Contributor I
1,376 Views
Ryan,

Could you please create small C# testcase to reproduce it on our side?
BTW, did you look at artticle: Using Intel MKL in your C# program
0 Kudos
Ryan_Deering
Beginner
1,376 Views
Victor,

Below is a test case using NUnit. My workaround for now is using Marshal.AllocHGlobal and Marshal.FreeHGlobal instead of mkl_malloc and mkl_free as can be seen in MarshalTest below.

I have looked at the examples in the article you provided, but there are no examples of using mkl_malloc in C# that I could find. An example of why I want to use a malloc function is for random number generation. The default behavior of C# new double is to fill the array with 0. When filling an array with random numbers with VSL, there is no need to fill it with zeroes first. Filling with zeros added around 40% overhead to random number generation compared to using Marshal.AllocHGlobal which allocates memory but does not initialize.

Let me know if you need me to attach files or if the code snippet is not enough to investigate. I have the MKL redistributables in my PATH and use NUnit available at http://www.nunit.org/?p=download. The test runner also needs to be a 64-bit executable. I am using MKL version 10.3.2.1.

Thanks,
Ryan


---------------------------------------


using System;
using System.Runtime.InteropServices;
using NUnit.Framework;

namespace MKLMalloc
{
[TestFixture]
public class UnitTest2
{
[Test]
public unsafe void MallocFree()
{
Int64 size = 1000;
void* ptr = MKL_NUnit.mkl_malloc(size*sizeof(double), 8); //fails
MKL_NUnit.mkl_free(ptr);
}

[Test]
public unsafe void MarshalTest()
{
int i = 1000;
IntPtr ptr = Marshal.AllocHGlobal(i*sizeof(double)); //works
Marshal.FreeHGlobal(ptr);
}

}

public static unsafe class MKL_NUnit
{
private const string mkl = "mkl_rt.dll";

[DllImport(mkl)]
public static extern void* mkl_malloc(Int64 size, int alignment);

[DllImport(mkl)]
public static extern void mkl_free(void* ptr);
}
}
0 Kudos
Vladimir_Koldakov__I
New Contributor III
1,377 Views

Ryan,

The correct way of using memory functions in C# is to call MKL_malloc and MKL_free.

Though calling mkl_malloc/mkl_free is ok for C (see example), these names are just defines in the header file mkl_service.h:

#define mkl_malloc MKL_malloc
#define mkl_free MKL_free

You can also use mkl_malloc/mkl_free but with Fortran calling conventions as references.

Ive prepared a small suite with the both approaches. It is based on the example files from the article Using Intel MKL in your C# program.

mkl_malloc.zip

Thanks,
Vladimir

0 Kudos
Ryan_Deering
Beginner
1,376 Views
Vladimir,

I got my tests working after seeing the differences between the utility functions that use MKL_ and mkl_.

Thanks,
Ryan
0 Kudos
Reply