Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interoperability with numpy #6

Closed
cmey opened this issue Jul 29, 2015 · 11 comments
Closed

Interoperability with numpy #6

cmey opened this issue Jul 29, 2015 · 11 comments
Milestone

Comments

@cmey
Copy link

cmey commented Jul 29, 2015

Would it be possible to support interoperability with numpy?

import numpy as np
import arrayfire as af

A = np.zeros((2,3), dtype=np.complex64)
Ad = af.array(A) # <-- load data from a numpy array
af.display(Ad)
print(Ad.elements(), Ad.type(), Ad.dims(), Ad.numdims())

Currently:

Using opencl backend
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-3-c8c7947108da> in <module>()
      3 
      4 A = np.zeros((2,3), dtype=np.complex64)
----> 5 Ad = af.array(A) # <-- load data from a numpy array
      6 af.display(Ad)
      7 print(Ad.elements(), Ad.type(), Ad.dims(), Ad.numdims())

/Users/cmey/Code/GitHub/arrayfire-python/arrayfire/array.pyc in __init__(self, src, dims)
    133                 type_char = tmp.typecode
    134             else:
--> 135                 raise TypeError("src is an object of unsupported class")
    136 
    137             elements = 1

TypeError: src is an object of unsupported class
@pavanky
Copy link
Member

pavanky commented Jul 29, 2015

We are trying to ensure ArrayFire works out of the box on a python distribution. Numpy may not always be installed on the machine. That said, I pushed out 14d5bc6 that should add the ability to interop with numpy in the following manner:

import numpy as np
import arrayfire as af

def af_array(src, transpose=False):
    res = af.array(src.ctypes.data, src.shape, src.dtype.char)
    return res if not transpose else af.transpose(res)

a = np.random.random((5,5))
b = af_array(a)

print(a)
af.display(b)

@pavanky pavanky closed this as completed Jul 29, 2015
@pavanky
Copy link
Member

pavanky commented Jul 29, 2015

The transpose flag may be necessary because numpy is row major by default and ArrayFire is column major.

@cmey
Copy link
Author

cmey commented Jul 30, 2015

Works great, thanks!

@mklf
Copy link

mklf commented Aug 6, 2015

This only work for square matrix with contigous data , for example:

import numpy as np
import arrayfire as af

def af_array(src, transpose=False):
    res = af.array(src.ctypes.data, src.shape, src.dtype.char)
    return res if not transpose else af.transpose(res)

a = np.random.random((5000,5000))[100:103,200:203]
b = af_array(a,transpose=True)

print(a)
af.display(b)

will print:

Using cuda backend
[[ 0.00902216  0.72194459  0.93649477]
 [ 0.74371952  0.94558585  0.49367796]
 [ 0.01659066  0.38938187  0.44101624]]
b
[3 3 1 1]
    0.0090     0.7219     0.9365 
    0.0837     0.7593     0.4400 
    0.1749     0.0054     0.7595 

the data of the two array are different.
a solution to this is convert the numpy.ndarray to fortran order and ensure it contigous:

import numpy as np
import arrayfire as af

def af_array(src):
    src_ = src if np.isfortran(src) else np.asfortranarray(src)
    res = af.array(src_.ctypes.data, src_.shape, src_.dtype.char)
    return res

@pavanky pavanky reopened this Aug 6, 2015
@pavanky
Copy link
Member

pavanky commented Aug 31, 2015

@FilipeMaia Can you comment here on how you are achieving this in afnumpy ?

@pavanky
Copy link
Member

pavanky commented Aug 31, 2015

This is actually present in master as a constructor thanks to @FilipeMaia

The lay out changes are going to be difficult to implicitly handle inside arrayfire. I think it should be left to the user to change it to proper format before calling arrayfire functions.

@pavanky pavanky closed this as completed Aug 31, 2015
@FilipeMaia
Copy link
Contributor

The only way to ensure a conversion where the dimensions of the arrayfire array match dimensions of the numpy is like @mklf did in the last code snippet (N.B. this often means the data will have to be transposed as numpy uses C order by default).

In afnumpy I'm currently assuming the numpy arrays are always in C order and have the shape of the arrayfire array be the inverse of the numpy array, e.g.:

# Assuming src is in contiguous C order
A = af.array(src.ctypes.data, src.shape[::-1], src.dtype.char)

@pavanky pavanky reopened this Oct 2, 2015
@pavanky pavanky added this to the 3.1 milestone Oct 2, 2015
@pavanky
Copy link
Member

pavanky commented Oct 2, 2015

I closed the issue hastily. arrayfire --> numpy is supported but the opposite is not.

@pavanky
Copy link
Member

pavanky commented Nov 11, 2015

This is fixed in master. All you need to do now is call the following function:

af_arr = af.np_to_af_array(np_arr)

This will take care of all cases @mklf mentions.

@pavanky pavanky closed this as completed Nov 11, 2015
@cmey
Copy link
Author

cmey commented Nov 11, 2015

Thank you!

@pavanky
Copy link
Member

pavanky commented Nov 11, 2015

@cmey I have uploaded the latest version to be available via pip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants