Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Ryan_Deering
Beginner
251 Views

Calling mkl_malloc in C#

Jump to solution
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
251 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

6 Replies
barragan_villanueva_
Valued Contributor I
251 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);
Ryan_Deering
Beginner
251 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
barragan_villanueva_
Valued Contributor I
251 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
Ryan_Deering
Beginner
251 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);
}
}
Vladimir_Koldakov__I
New Contributor III
252 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

Ryan_Deering
Beginner
251 Views
Vladimir,

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

Thanks,
Ryan
Reply