I would like to use the ArrayFire library to run multiple artificial neural networks on the GPU in parallel.
Since I am mainly a C# developer I tried to realize it via SiaNet. But I encountered the problem that SiaNet can only run one neural network at a time.
This is because SiaNet and the C# API of ArrayFire do not implement the batchFunc
function.
I wanted to make up for this and built my own little library.
There I call the batchFunc
function and want to build an API which can be called from C# with PInvokes.
The problem is that I can only use af_array
from C#, but the batchFunc
function can only process af::array
. Therefore I need to convert one into the other.
My MatrixMultiply
function, to have a function that I can pass batchFunc
:
af::array MatrixMultiply(const af::array &lhs, const af::array &rhs) {
return matmul(lhs, rhs);
}
My PInvoke friendly function:
af_err BatchMatmul(af_array *out, const af::array lhs, const af::array rhs) {
try
{
*out = &(af::batchFunc(lhs, rhs, MatrixMultiply));
return AF_SUCCESS;
}
catch (af::exception& e) {
fprintf(stderr, "%s\n", e.what());
return AF_ERR_BATCH;
}
}
As I call it on C# side:
[DllImport("BatchOpsWrapperLib.dll", ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
public static extern af_err BatchMatmul(out IntPtr array_out, IntPtr array_lhs, IntPtr array_rhs);
I have hardly or not at all worked with C/C++ so far and would like to ask you for help here.
Edit: This is my reworked new function:
af_err BatchMatmul(af_array *out, const af_array lhs, const af_array rhs)
{
try
{
af_array retainedLhs = 0;
af_array retainedRhs = 0;
af_retain_array(&retainedLhs, lhs);
af_retain_array(&retainedRhs, rhs);
af_array resultHandle = 0;
af_retain_array(&resultHandle, af::batchFunc(af::array(retainedLhs),
af::array(retainedRhs),
MatrixMultiply).get());
*out = resultHandle;
return AF_SUCCESS;
}
catch (af::exception& e) {
fprintf(stderr, "%s\n", e.what());
return AF_ERR_BATCH;
}
}
An af::array
instance has a method .get()
, from which you can retrieve an af_array
instance.
af::array some_array = ...;
af_array c_array = some_array.get();
You can also construct an af::array
from an af_array
using af::array(some_af_array)
.
af::array another_array = af::array(c_array);`