Преобразование af::array в af_array и обратно

Я хотел бы использовать библиотеку ArrayFire для параллельного запуска нескольких искусственных нейронных сетей на графическом процессоре.

Поскольку я в основном разработчик C#, я попытался реализовать это через SiaNet. Но я столкнулся с проблемой, что SiaNet может одновременно запускать только одну нейронную сеть.

Это связано с тем, что SiaNet и C# API ArrayFire не реализуют batchFunc.

Я хотел компенсировать это и создал свою маленькую библиотеку. Там я вызываю функцию batchFunc и хочу создать API, который можно вызывать из C# с помощью PInvokes.

Проблема в том, что я могу использовать только af_array из C#, а функция batchFunc может обрабатывать только af::array. Поэтому мне нужно преобразовать одно в другое.

Моя функция MatrixMultiply, чтобы иметь функцию, которую я могу передать batchFunc:

af::array MatrixMultiply(const af::array &lhs, const af::array &rhs) {
    return matmul(lhs, rhs);
}

Моя дружественная функция PInvoke:

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;
    }
}

Как я называю это на стороне С#:

[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);

До сих пор я почти или совсем не работал с C/C++ и хотел бы попросить вас о помощи здесь.

Изменить: это моя переработанная новая функция:

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;
    }
}

person Oliver    schedule 20.03.2020    source источник


Ответы (1)


Экземпляр af::array имеет метод .get(), из которого можно получить экземпляр af_array.

af::array some_array = ...;
af_array c_array = some_array.get();

Вы также можете построить af::array из af_array, используя af::array(some_af_array).

af::array another_array = af::array(c_array);`
person Palle    schedule 28.05.2020
comment
Следует добавить следующее. Преобразование через конструктор работает, только если вы используете af_retain_array. В противном случае вы получите NullPointerException. - person Oliver; 04.06.2020