NumSharp icon indicating copy to clipboard operation
NumSharp copied to clipboard

is there any way to convert NumSharp.NDArray to Numpy.NDarray?

Open lelelemonade opened this issue 4 years ago • 5 comments

lelelemonade avatar Jan 06 '20 10:01 lelelemonade

Me and @henon have collaborated just two days ago on a solution for that, The trick is to create a python scope, load a script that takes in a pointer-length and returns an np.ndarray Remember! you have to keep reference to the original NDArray, otherwise the NDArray will be disposed and will release the memory. (@henon is there a tag field we can use in NDarray?)

Note: the code below is psuedo, the rest of the code can be found here: ConsoleApp9.zip

numpy_interop.py as embedded resource

import numpy as np
import ctypes

def to_numpy(ptr, bytes, dtype, shape):
    return np.frombuffer((ctypes.c_uint8*(bytes)).from_address(ptr), dtype).reshape(shape)

PythonExtensions.cs

public static class PythonExtensions {

    ...
    private static PyScope NumpyInteropScope;
    private static PyObject NumpyConverter;

    public static unsafe NDarray ToNumpyNET(this NDArray nd) {
        using (Py.GIL()) {
            if (NumpyInteropScope == null) {
                NumpyInteropScope = Py.CreateScope();
                NumpyInteropScope.ExecResource("numpy_interop.py");
                NumpyConverter = NumpyInteropScope.GetFunction("to_numpy");
            }

            return new NDarray(NumpyConverter.Invoke(new PyLong((long) nd.Unsafe.Address),
                new PyLong(nd.size * nd.dtypesize),
                new PyString(nd.dtype.Name.ToLowerInvariant()),
                new PyTuple(nd.shape.Select(dim => (PyObject) new PyLong(dim)).ToArray())));
        }
    }
}

main.cs

using numsharp_np = NumSharp.np;
using numpy_np = Numpy.np;
static void Main(string[] args) {
    var numsharp_nd = numsharp_np.arange(10);
    var numpy_nd = numsharp_nd.ToNumpyNET();
    numpy_nd[1] = (NDarray) 5;
    Debug.Assert(numsharp_nd[1].array_equal(5));
    Console.WriteLine("numsharp_nd[1].array_equal(5) is indeed true!");
}

Nucs avatar Jan 06 '20 11:01 Nucs

Added some changes that will make sure the NDarray will hold reference to the NDArray as long as the PyObject doesnt change internally.

ConsoleApp9.zip

Nucs avatar Jan 06 '20 11:01 Nucs

Remember! you have to keep reference to the original NDArray, otherwise the NDArray will be disposed and will release the memory. (@henon is there a tag field we can use in NDarray?)

Not yet, but I will add one in Numpy.NET and support this.

henon avatar Jan 06 '20 15:01 henon

Hi, could you provide instruction on how to use the ConsoleApp9.zip? And does it able to convert Numpy array back to NumSharp array?

davidvct avatar Feb 24 '23 04:02 davidvct

@davidvct, if I remember correctly I have added support for copying data to and from Numpy.NET like @Nucs did in this solution. Read this to see how: https://github.com/SciSharp/Numpy.NET#create-a-numpy-array-from-a-c-array-and-vice-versa

henon avatar Feb 24 '23 10:02 henon