afnumpy
afnumpy copied to clipboard
Feature request
Hi,
Could you overload the ndarray constructor, so that one can a pass raw pointer on device to create an instance, along with shape, dtype etc?
--dinesh
You can pass raw arrayfire arrays, and take advantage of them to achieve what you want:
import arrayfire
import numpy
import afnumpy
import ctypes
# I'm assuming device_ptr is the raw pointer, pointing to a float array of size [1024,1024]
s = arrayfire.Array()
ndims = 2
dims = numpy.zeros(ndims,dtype=numpy.int64)
dims[0] = 1024
dims[1] = 1024
arrayfire.backend.get().af_device_array(ctypes.pointer(s.arr),
ctypes.c_void_p(device_ptr),
ndims, ctypes.c_void_p(dims.ctypes.data),
arrayfire.Dtype.f32.value)
arrayfire.backend.get().af_retain_array(ctypes.pointer(s.arr),s.arr)
A = afnumpy.multiarray.ndarray(dims, dtype=dtype, af_array=s)
# Now it's safe to delete s
But I agree that a simpler way would be desirable. I'll try to add one that fits well with the rest of the interface.
I am trying to create a afnumpy array from C as a return object. I have to create arrayfire array before I can do this. I would be nicer, if a method could take a buffer on device (plus other meta data) and create an afnumpy object.
I've made it possible to call afnumpy.array()
on an arrayfire array.
I'll probably try to add a cuda_buffer
argument to ndarray
to pass raw device memory.
Thanks a lot.
Commit 59ae6b2 adds a buffer_type
argument to the ndarray
constructor making it possible to pass raw pointers directly. buffer_type
defaults to python
in which case buffer
is a normal python buffer, but it can also be cpu
, opencl
or cuda
, in which case buffer should be a pointer to memory of the corresponding type. In case of raw pointers the buffer_type
must match the active arrayfire backend or an exception is raised.
Example usage:
import arrayfire as af
import afnumpy as afnp
a = af.randu(3,2)
shape = a.dims()[::-1]
c = afnp.ndarray(shape, dtype='f', buffer=a.raw_ptr(), buffer_type=af.get_active_backend())
print a
# The next line also modifies a, as they share the same memory
c[0,0] = -1
print a
Hi Filipe,
Thanks a lot. I like that you put the "buffer_type" as the last argument.
regards --dinesh
On Sat, Apr 2, 2016 at 1:32 PM, Filipe Maia [email protected] wrote:
Commit 59ae6b2 https://github.com/FilipeMaia/afnumpy/commit/59ae6b2f8e096fe373bd9ffb0a57fd03b4cb3f30 adds a buffer_type argument to the ndarray constructor making it possible to pass raw pointers directly. buffer_type defaults to python in which case buffer is a normal python buffer, but it can also be cpu, opencl or cuda, in which case buffer should be a pointer to memory of the corresponding type. In case of raw pointers the buffer_type must match the active arrayfire backend or an exception is raised.
Example usage:
import arrayfire as afimport afnumpy as afnp a = af.randu(3,2) shape = a.dims()[::-1] c = afnp.ndarray(shape, dtype='f', buffer=a.raw_ptr(), buffer_type=af.get_active_backend())print a# The next line also modifies a, as they share the same memory c[0,0] = -1print a
— You are receiving this because you modified the open/close state. Reply to this email directly or view it on GitHub https://github.com/FilipeMaia/afnumpy/issues/20#issuecomment-204802086
Hi Filipe,
I am working on C-API for Afnumpy. I am returning afnumpy array constructed using the
afnumpy.ndarray(shape, buffer=ptr buffer_type='cuda')
arguments, with buffer being allocated inside the C-code. When the returned array goes out of scope, it seems the memory is not being released.
Does that sound normal to you?
PyObject * args = PyTuple_New(1);
PyTuple_SetItem(args, 0, shape);
PyObject * kwargs = PyDict_New();
PyObject * key = Py_BuildValue("s", "buffer");
PyObject * val = PyLong_FromVoidPtr(buffer);
PyDict_SetItem(kwargs, key, val);
key = Py_BuildValue("s", "buffer_type");
val = Py_BuildValue("s", "cuda");
PyDict_SetItem(kwargs, key, val);
key = Py_BuildValue("s", "dtype");
PyDict_SetItem(kwargs, key, af_type);
PyObject *out = PyObject_Call(ndarray, args, kwargs);`
Yes this is how it currently works as people often want to continue to do work on the memory after the array is deleted. This is the same behaviour as with numpy when buffers are passed.
I can understand the usefulness of increasing the reference count. Unfortunately, it is causing lots of problem for us. Since the af_array created the constructor has no external reference, there is no way to explicitly release it. Will it be possible to make either of the following modifications?
- Remove the af_retain_array in the constructor. It is unlikely that someone would want to create an Afnumpy array from a C pointer, within Python.
- Accept an optional boolean, which allows Afnumpy array steal the ownership or not. This will not be elegant since constructor already has so many arguments.
- Define a factory method, which will allow me to create an Afnumpy array from C.