- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ditto, I have been successful with IPP and C# (where I was led by some kind person to samples), but not yet with MKL.
There seems to be no downloadable samples for MKL?
Hvard
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
http://www.dnanalytics.net/, it might give you some
ideas.
Feel free to email at marcus@cuda.org if you have any questions.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here's how we do at CenterSpace Software. The data blocks are C# wrappers of double arrays. The offset is into the array. Basically, you statically link the mkl libraries, pin a pointer to your double array and call MKL.
- Trevor
#using
#using
#include
#include "mkl.h"
# define BLAS_PREFIX(x) x
# define BLAS_ARGUMENT(x) &##x
# define INTEGER int
using namespace CenterSpace::NMath::Core;
namespace CenterSpace
{
namespace NMath
{
namespace Kernel
{
public ref class DotNetBlas
{
public:
// Deep copy of vector
static void copy( INTEGER n, FloatDataBlock x, INTEGER xOffset, INTEGER incx, FloatDataBlock y, INTEGER yOffset, INTEGER incy )
{
pin_ptr
pin_ptr
if ( n > 0 ) {
xOffset += AdjustVectorOffset( n, incx, x.Offset );
yOffset += AdjustVectorOffset( n, incy, y.Offset );
xptr = &( x.Data[xOffset] );
yptr = &( y.Data[yOffset] );
BLAS_PREFIX(scopy)( BLAS_ARGUMENT(n), xptr, BLAS_ARGUMENT(incx), yptr, BLAS_ARGUMENT(incy) );
}
}
}
}
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
OK, I've gotten it to work in a C# and Visual Studio IDE environment. (I was hung up for a while on getting the PATH environment variable set properly).
I'd like to know the reason why you create a separate class and "wrapper" functions. That is, in your example, you have access structured like this:
public sealed class DFTI
{
/** DFTI DftiCreateDescriptor wrapper */
public static int DftiCreateDescriptor(ref IntPtr desc,
int precision, int domain, int dimention, int length)
{
return DFTINative.DftiCreateDescriptor(ref desc,
precision, domain, dimention, length);
}
...
[SuppressUnmanagedCodeSecurity]
internal sealed class DFTINative
{
/** DFTI native DftiCreateDescriptor declaration */
[DllImport("mkl.dll", CallingConvention=CallingConvention.Cdecl,
ExactSpelling=true, SetLastError=false)]
internal static extern int DftiCreateDescriptor(ref IntPtr desc,
int precision, int domain, int dimention, int length);
Since the wrapper functions simply pass their arguments through unchanged, what is the benefit of the wrapper functions? Why is it better for the parts of the code that use this function to DFTI.DftiCreateDescriptor, rather than calling DFTINative.DftiCreateDescriptor directly themselves?
I assume it has something or other to do with containment of unsafe code, but I'd like to understand it better... and understand whether it is truly making the code safer.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here is one piece of sample code you can use. "mkl_custom.dll" is a custom build mkl lib.
#region PInvoke calls
// CBLAS
[DllImport(@"mkl_custom.dll", ExactSpelling = true, SetLastError = false,
CallingConvention = CallingConvention.Cdecl)]
internal static extern void cblas_dcopy(int n, [In] double[] x, int incX,
[In, Out] double[] y, int incY);
#endregion PInvoke calls
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You may also refer a new KB posted on this topic from the below url.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
We are using P/Invoke to write a wrapper around some of the BLAS and LAPACK routines in MKL. Since P/Invoke requires a DLL, we couldn't call the MKL lib files directly. We wrote a simple wrapper DLL that we make P/Invoke calls to. You can get the source from
https://www.digichip.in/, it might give you some
ideas.
Feel free to email at marcus@cuda.org if you have any questions.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I essentially have written wrappers for all functions that have been interest me. One such minimalistic wrapper is in the class VSL below. Wrapper is pure C#, the main application is in Windows Forms paradigm. There I created a form with three buttons and a RichTextView to see the output.
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace Lognorm_bug
{
public partial class Form1 : Form
{
int i, len = 1000;
float[] rnd;
float div = 0.42466090014401f; // div=1/(2sqrt(2ln(2)))
uint seed;
IntPtr stream;
int status;
public Form1()
{
InitializeComponent();
seed = (uint)(DateTime.Now.Ticks / 10000L);
stream = new IntPtr();
status = VSL.vslNewStream(ref stream, VSL.BRNG.MT19937, seed);
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
VSL.vslDeleteStream(ref stream);
}
private void button0_Click(object sender, EventArgs e)
{
IntPtr stream = new IntPtr();
rnd = new float[len];
status = VSL.vslNewStream(ref stream, VSL.BRNG.MT19937, seed);
status = VSL.vsRngGaussian(VSL.RNG_METHOD.GAUSSIAN_BOXMULLER, stream, len, rnd, 20f, 1f);
status = VSL.vsRngWeibull(VSL.RNG_METHOD.WEIBULL_ICDF, stream, len, rnd, 3f, 0f, 20f);
// Lognormal generator has a bug. All numbers need to be divided by 10,000,000 and the displacement (b) needs to be added after the call
status = VSL.vsRngLognormal(VSL.RNG_METHOD.LOGNORMAL_ICDF, stream, len, rnd, 20f, 0.8f, 0f, 1f);
VSL.vslDeleteStream(ref stream);
}
private void button1_Click(object sender, EventArgs e)
{
rnd = new float[len];
status = VSL.vsRngGaussian(VSL.RNG_METHOD.GAUSSIAN_BOXMULLER, stream, len, rnd, 20f, 1f * div);
Print();
}
private void button2_Click(object sender, EventArgs e)
{
rnd = new float[len];
status = VSL.vsRngWeibull(VSL.RNG_METHOD.WEIBULL_ICDF, stream, len, rnd, 3f, 0f, 20f);
Print();
}
private void button3_Click(object sender, EventArgs e)
{
rnd = new float[len];
status = VSL.vsRngLognormal(VSL.RNG_METHOD.LOGNORMAL_ICDF, stream, len, rnd, 20f, 0.8f, 0f, 1f);
Print();
}
private void Print()
{
rxView.Clear();
for (i = 0; i < 20; i++)
rxView.AppendText(rnd[i].ToString("F1") + "\n");
}
}
public sealed class VSL
{
private VSL() { }
#region Constants
public sealed class BRNG
{
public static int INC = 1 << 20;
public static int MCG31 = INC;
public static int R250 = (MCG31 + INC);
public static int MRG32K3A = (R250 + INC);
public static int MCG59 = (MRG32K3A + INC);
public static int WH = (MCG59 + INC);
public static int SOBOL = (WH + INC);
public static int NIEDERR = (SOBOL + INC);
public static int MT19937 = (NIEDERR + INC);
}
public sealed class RNG_METHOD
{
public static int ACCURACY_FLAG = (1 << 30);
public static int GAUSSIAN_BOXMULLER = 0;
public static int WEIBULL_ICDF = 0;
public static int LOGNORMAL_BOXMULLER2 = 0;
public static int LOGNORMAL_ICDF = 1;
public static int LOGNORMAL_BOXMULLER2_ACCURATE = LOGNORMAL_BOXMULLER2 | ACCURACY_FLAG;
public static int LOGNORMAL_ICDF_ACCURATE = LOGNORMAL_ICDF | ACCURACY_FLAG;
}
#endregion
#region Random number generator wrappers
const string libName = "mkl_rt.dll";
[DllImport(libName, EntryPoint = "vslNewStream", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, SetLastError = true)]
public static extern int vslNewStream(ref IntPtr stream, int brng, uint seed);
[DllImport(libName, EntryPoint = "vslDeleteStream", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, SetLastError = true)]
public static extern int vslDeleteStream(ref IntPtr stream);
[DllImport(libName, EntryPoint = "vsRngGaussian", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, SetLastError = true)]
public static extern int vsRngGaussian(int method, IntPtr stream, int count, [Out]float[] r, float mean, float stdev);
[DllImport(libName, EntryPoint = "vsRngWeibull", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, SetLastError = true)]
public static extern int vsRngWeibull(int method, IntPtr stream, int count, [Out]float[] r, float alpha, float a, float beta);
[DllImport(libName, EntryPoint = "vsRngLognormal", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, SetLastError = true)]
public static extern int vsRngLognormal(int method, IntPtr stream, int count, [Out]float[] r, float a, float sigma, float b, float beta);
#endregion
}
}

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page