Small example to show use of Intel Math Kernel Library with PureBasic.
The original example is in C and from the MKL help.
It calls dgemm ("Computes a scalar-matrix-matrix product and adds the result to a scalar-matrix product")
and MKL memory allocation functions.
I added a call to mkl_get_version_string() to output the version of mkl_core.dll
Tested with 32bit and 64bit version of mkl_core.dll and PureBasic.
Code: Select all
EnableExplicit
DisableDebugger
OpenConsole()
PrototypeC Def_mkl_get_version_string(*buffer.Ascii, len.i)
PrototypeC.i Def_mkl_malloc (size.q,align.i)
PrototypeC Def_mkl_free (buffer.i)
PrototypeC.q Def_mkl_mem_stat (*nbuffers)
PrototypeC Def_mkl_free_buffers ()
PrototypeC Def_dgemm(transa.p-Ascii,transb.p-Ascii,*m,*n,*k,*alpha,*a,*lda,*b,*ldb,*beta,*c,*ldc)
If OpenLibrary(0,"mkl_core.dll")
Define mkl_get_version_string.Def_mkl_get_version_string = GetFunction(0,"mkl_serv_getversionstring")
Define mkl_malloc .Def_mkl_malloc = GetFunction(0,"mkl_serv_mkl_malloc")
Define mkl_free .Def_mkl_free = GetFunction(0,"mkl_serv_mkl_free")
Define mkl_mem_stat .Def_mkl_mem_stat = GetFunction(0,"mkl_serv_mkl_memstat")
Define mkl_free_buffers .Def_mkl_free_buffers = GetFunction(0,"mkl_serv_freebuffers")
Define dgemm .Def_dgemm = GetFunction(0,"mkl_blas_dgemm")
Else
PrintN("Can't open mkl_core.dll")
End
EndIf
Define buffer, Version$
buffer = AllocateMemory(200)
mkl_get_version_string(buffer,200)
Version$ = Trim(PeekS(buffer,200,#PB_Ascii))
PrintN( Version$ )
FreeMemory(buffer)
Structure mem
Array a.d(0)
Array b.d(0)
Array c.d(0)
EndStructure
Define mem.mem
Define.i n, i
Define.d alpha, beta
Define.q AllocatedBytes
Define.i N_AllocatedBuffers
alpha = 1.1 : beta = -1.2
n = 1000
mem\a() = mkl_malloc(n*n*SizeOf(Double),64)
mem\b() = mkl_malloc(n*n*SizeOf(Double),64)
mem\c() = mkl_malloc(n*n*SizeOf(Double),64)
For i = 0 To n*n
mem\a(i) = i+1
mem\b(i) = -i-1
mem\c(i) = 0.0
Next i
dgemm("N","N",@n,@n,@n,@alpha,mem\a(),@n,mem\b(),@n,@beta,mem\c(),@n)
AllocatedBytes = mkl_mem_stat(@N_AllocatedBuffers);
PrintN("AllocatedBytes : "+Str(AllocatedBytes))
PrintN("AllocatedBuffers: "+Str(N_AllocatedBuffers))
mkl_free_buffers()
AllocatedBytes = mkl_mem_stat(@N_AllocatedBuffers);
If AllocatedBytes > 0
PrintN("MKL memory leak!")
PrintN("fter mkl_free_buffers there are "+Str(AllocatedBytes)+" bytes in "+Str(N_AllocatedBuffers)+" buffers")
EndIf
mkl_free(mem\a())
mkl_free(mem\b())
mkl_free(mem\c())
PrintN("press ENTER")
Input()
Output with 32bit version:
Code: Select all
Intel(R) Math Kernel Library Version 10.3.3 Product Build 20110314 for 32-bit applications
AllocatedBytes : 1983872
AllocatedBuffers: 1
press ENTER
Output with 64bit version:
Code: Select all
Intel(R) Math Kernel Library Version 10.3.3 Product Build 20110314 for Intel(R) 64 architecture applications
AllocatedBytes : 2072960
AllocatedBuffers: 1
press ENTER
EDIT:
Here the static version that does not require the mkl_core.dll at runtime:
Code: Select all
EnableExplicit
DisableDebugger
OpenConsole()
ImportC "mkl_core.lib"
mkl_get_version_string(*buffer.Ascii, len.i) As "_mkl_serv_getversionstring"
mkl_malloc (size.q,align.i) As "_mkl_serv_mkl_malloc"
mkl_free (buffer.i) As "_mkl_serv_mkl_free"
mkl_mem_stat (*nbuffers) As "_mkl_serv_mkl_memstat"
mkl_free_buffers () As "_mkl_serv_freebuffers"
dgemm (transa.p-Ascii,transb.p-Ascii,*m,*n,*k,*alpha,*a,*lda,*b,*ldb,*beta,*c,*ldc) As "_mkl_blas_dgemm"
EndImport
;ImportC "mkl_intel_c.lib"
;EndImport
ImportC "mkl_sequential.lib"
EndImport
Define buffer, Version$
buffer = AllocateMemory(200)
mkl_get_version_string(buffer,200)
Version$ = Trim(PeekS(buffer,200,#PB_Ascii))
PrintN( Version$ )
FreeMemory(buffer)
Structure mem
Array a.d(0)
Array b.d(0)
Array c.d(0)
EndStructure
Define mem.mem
Define.i n, i
Define.d alpha, beta
Define.q AllocatedBytes
Define.i N_AllocatedBuffers
alpha = 1.1 : beta = -1.2
n = 1000
mem\a() = mkl_malloc(n*n*SizeOf(Double),64)
mem\b() = mkl_malloc(n*n*SizeOf(Double),64)
mem\c() = mkl_malloc(n*n*SizeOf(Double),64)
For i = 0 To n*n
mem\a(i) = i+1
mem\b(i) = -i-1
mem\c(i) = 0.0
Next i
dgemm("N","N",@n,@n,@n,@alpha,mem\a(),@n,mem\b(),@n,@beta,mem\c(),@n)
AllocatedBytes = mkl_mem_stat(@N_AllocatedBuffers);
PrintN("AllocatedBytes : "+Str(AllocatedBytes))
PrintN("AllocatedBuffers: "+Str(N_AllocatedBuffers))
mkl_free_buffers()
AllocatedBytes = mkl_mem_stat(@N_AllocatedBuffers);
If AllocatedBytes > 0
PrintN("MKL memory leak!")
PrintN("fter mkl_free_buffers there are "+Str(AllocatedBytes)+" bytes in "+Str(N_AllocatedBuffers)+" buffers")
EndIf
mkl_free(mem\a())
mkl_free(mem\b())
mkl_free(mem\c())
PrintN("press ENTER")
Input()
1st version is 11,5k but requires mkl_core.dll (6,7MB)
2nd version is 706k standalone