10
10
"""
11
11
Interop with other python packages.
12
12
13
- This module provides interoperability with the following python packages.
13
+ This module provides helper functions to copy data to arrayfire from the following modules:
14
+
15
+ 1. numpy - numpy.ndarray
16
+ 2. pycuda - pycuda.gpuarray
17
+ 3. pyopencl - pyopencl.array
14
18
15
- 1. numpy
16
- 2. pycuda
17
- 3. pyopencl
18
19
"""
19
20
20
21
from .array import *
21
22
from .device import *
22
23
24
+
25
+ def _fc_to_af_array (in_ptr , in_shape , in_dtype , is_device = False , copy = True ):
26
+ """
27
+ Fortran Contiguous to af array
28
+ """
29
+ res = Array (in_ptr , in_shape , in_dtype , is_device = is_device )
30
+
31
+ if is_device :
32
+ lock_array (res )
33
+ pass
34
+
35
+ return res .copy () if copy else res
36
+
37
+ def _cc_to_af_array (in_ptr , ndim , in_shape , in_dtype , is_device = False , copy = True ):
38
+ """
39
+ C Contiguous to af array
40
+ """
41
+ if ndim == 1 :
42
+ return _fc_to_af_array (in_ptr , in_shape , in_dtype , is_device , copy )
43
+ elif ndim == 2 :
44
+ shape = (in_shape [1 ], in_shape [0 ])
45
+ res = Array (in_ptr , shape , in_dtype , is_device = is_device )
46
+ if is_device : lock_array (res )
47
+ return reorder (res , 1 , 0 )
48
+ elif ndim == 3 :
49
+ shape = (in_shape [2 ], in_shape [1 ], in_shape [0 ])
50
+ res = Array (in_ptr , shape , in_dtype , is_device = is_device )
51
+ if is_device : lock_array (res )
52
+ return reorder (res , 2 , 1 , 0 )
53
+ elif ndim == 4 :
54
+ shape = (in_shape [3 ], in_shape [2 ], in_shape [1 ], in_shape [0 ])
55
+ res = Array (in_ptr , shape , in_dtype , is_device = is_device )
56
+ if is_device : lock_array (res )
57
+ return reorder (res , 3 , 2 , 1 , 0 )
58
+ else :
59
+ raise RuntimeError ("Unsupported ndim" )
60
+
23
61
try :
24
62
import numpy as np
25
63
from numpy import ndarray as NumpyArray
40
78
'f8' : Dtype .f64 ,
41
79
'c16' : Dtype .c64 }
42
80
43
- def np_to_af_array (np_arr ):
81
+ def np_to_af_array (np_arr , copy = True ):
44
82
"""
45
83
Convert numpy.ndarray to arrayfire.Array.
46
84
47
85
Parameters
48
86
----------
49
87
np_arr : numpy.ndarray()
50
88
89
+ copy : Bool specifying if array is to be copied.
90
+ Default is true.
91
+ Can only be False if array is fortran contiguous.
92
+
51
93
Returns
52
94
---------
53
95
af_arr : arrayfire.Array()
@@ -57,27 +99,15 @@ def np_to_af_array(np_arr):
57
99
in_ptr = np_arr .ctypes .data_as (c_void_ptr_t )
58
100
in_dtype = _nptype_to_aftype [np_arr .dtype .str [1 :]]
59
101
102
+ if not copy :
103
+ raise RuntimeError ("Copy can not be False for numpy arrays" )
104
+
60
105
if (np_arr .flags ['F_CONTIGUOUS' ]):
61
- return Array (in_ptr , in_shape , in_dtype )
106
+ return _fc_to_af_array (in_ptr , in_shape , in_dtype )
62
107
elif (np_arr .flags ['C_CONTIGUOUS' ]):
63
- if np_arr .ndim == 1 :
64
- return Array (in_ptr , in_shape , in_dtype )
65
- elif np_arr .ndim == 2 :
66
- shape = (in_shape [1 ], in_shape [0 ])
67
- res = Array (in_ptr , shape , in_dtype )
68
- return reorder (res , 1 , 0 )
69
- elif np_arr .ndim == 3 :
70
- shape = (in_shape [2 ], in_shape [1 ], in_shape [0 ])
71
- res = Array (in_ptr , shape , in_dtype )
72
- return reorder (res , 2 , 1 , 0 )
73
- elif np_arr .ndim == 4 :
74
- shape = (in_shape [3 ], in_shape [2 ], in_shape [1 ], in_shape [0 ])
75
- res = Array (in_ptr , shape , in_dtype )
76
- return reorder (res , 3 , 2 , 1 , 0 )
77
- else :
78
- raise RuntimeError ("Unsupported ndim" )
108
+ return _cc_to_af_array (in_ptr , np_arr .ndim , in_shape , in_dtype )
79
109
else :
80
- return np_to_af_array (np . asfortranarray ( np_arr ))
110
+ return np_to_af_array (np_arr . copy ( ))
81
111
82
112
from_ndarray = np_to_af_array
83
113
except :
@@ -88,14 +118,18 @@ def np_to_af_array(np_arr):
88
118
from pycuda .gpuarray import GPUArray as CudaArray
89
119
AF_PYCUDA_FOUND = True
90
120
91
- def pycuda_to_af_array (pycu_arr ):
121
+ def pycuda_to_af_array (pycu_arr , copy = True ):
92
122
"""
93
123
Convert pycuda.gpuarray to arrayfire.Array
94
124
95
125
Parameters
96
126
-----------
97
127
pycu_arr : pycuda.GPUArray()
98
128
129
+ copy : Bool specifying if array is to be copied.
130
+ Default is true.
131
+ Can only be False if array is fortran contiguous.
132
+
99
133
Returns
100
134
----------
101
135
af_arr : arrayfire.Array()
@@ -109,31 +143,13 @@ def pycuda_to_af_array(pycu_arr):
109
143
in_shape = pycu_arr .shape
110
144
in_dtype = pycu_arr .dtype .char
111
145
146
+ if not copy and not pycu_arr .flags .f_contiguous :
147
+ raise RuntimeError ("Copy can only be False when arr.flags.f_contiguous is True" )
148
+
112
149
if (pycu_arr .flags .f_contiguous ):
113
- res = Array (in_ptr , in_shape , in_dtype , is_device = True )
114
- lock_array (res )
115
- res = res .copy ()
116
- return res
150
+ return _fc_to_af_array (in_ptr , in_shape , in_dtype , True , copy )
117
151
elif (pycu_arr .flags .c_contiguous ):
118
- if pycu_arr .ndim == 1 :
119
- return Array (in_ptr , in_shape , in_dtype , is_device = True )
120
- elif pycu_arr .ndim == 2 :
121
- shape = (in_shape [1 ], in_shape [0 ])
122
- res = Array (in_ptr , shape , in_dtype , is_device = True )
123
- lock_array (res )
124
- return reorder (res , 1 , 0 )
125
- elif pycu_arr .ndim == 3 :
126
- shape = (in_shape [2 ], in_shape [1 ], in_shape [0 ])
127
- res = Array (in_ptr , shape , in_dtype , is_device = True )
128
- lock_array (res )
129
- return reorder (res , 2 , 1 , 0 )
130
- elif pycu_arr .ndim == 4 :
131
- shape = (in_shape [3 ], in_shape [2 ], in_shape [1 ], in_shape [0 ])
132
- res = Array (in_ptr , shape , in_dtype , is_device = True )
133
- lock_array (res )
134
- return reorder (res , 3 , 2 , 1 , 0 )
135
- else :
136
- raise RuntimeError ("Unsupported ndim" )
152
+ return _cc_to_af_array (in_ptr , pycu_arr .ndim , in_shape , in_dtype , True , copy )
137
153
else :
138
154
return pycuda_to_af_array (pycu_arr .copy ())
139
155
except :
@@ -147,14 +163,18 @@ def pycuda_to_af_array(pycu_arr):
147
163
from .opencl import get_context as _get_context
148
164
AF_PYOPENCL_FOUND = True
149
165
150
- def pyopencl_to_af_array (pycl_arr ):
166
+ def pyopencl_to_af_array (pycl_arr , copy = True ):
151
167
"""
152
168
Convert pyopencl.gpuarray to arrayfire.Array
153
169
154
170
Parameters
155
171
-----------
156
172
pycl_arr : pyopencl.Array()
157
173
174
+ copy : Bool specifying if array is to be copied.
175
+ Default is true.
176
+ Can only be False if array is fortran contiguous.
177
+
158
178
Returns
159
179
----------
160
180
af_arr : arrayfire.Array()
@@ -179,44 +199,31 @@ def pyopencl_to_af_array(pycl_arr):
179
199
180
200
if (dev_idx == None or ctx_idx == None or
181
201
dev_idx != dev or ctx_idx != ctx ):
202
+ print ("Adding context and queue" )
182
203
_add_device_context (dev , ctx , que )
183
204
_set_device_context (dev , ctx )
184
205
206
+ info ()
185
207
in_ptr = pycl_arr .base_data .int_ptr
186
208
in_shape = pycl_arr .shape
187
209
in_dtype = pycl_arr .dtype .char
188
210
211
+ if not copy and not pycl_arr .flags .f_contiguous :
212
+ raise RuntimeError ("Copy can only be False when arr.flags.f_contiguous is True" )
213
+
214
+ print ("Copying array" )
215
+ print (pycl_arr .base_data .int_ptr )
189
216
if (pycl_arr .flags .f_contiguous ):
190
- res = Array (in_ptr , in_shape , in_dtype , is_device = True )
191
- lock_array (res )
192
- return res
217
+ return _fc_to_af_array (in_ptr , in_shape , in_dtype , True , copy )
193
218
elif (pycl_arr .flags .c_contiguous ):
194
- if pycl_arr .ndim == 1 :
195
- return Array (in_ptr , in_shape , in_dtype , is_device = True )
196
- elif pycl_arr .ndim == 2 :
197
- shape = (in_shape [1 ], in_shape [0 ])
198
- res = Array (in_ptr , shape , in_dtype , is_device = True )
199
- lock_array (res )
200
- return reorder (res , 1 , 0 )
201
- elif pycl_arr .ndim == 3 :
202
- shape = (in_shape [2 ], in_shape [1 ], in_shape [0 ])
203
- res = Array (in_ptr , shape , in_dtype , is_device = True )
204
- lock_array (res )
205
- return reorder (res , 2 , 1 , 0 )
206
- elif pycl_arr .ndim == 4 :
207
- shape = (in_shape [3 ], in_shape [2 ], in_shape [1 ], in_shape [0 ])
208
- res = Array (in_ptr , shape , in_dtype , is_device = True )
209
- lock_array (res )
210
- return reorder (res , 3 , 2 , 1 , 0 )
211
- else :
212
- raise RuntimeError ("Unsupported ndim" )
219
+ return _cc_to_af_array (in_ptr , pycl_arr .ndim , in_shape , in_dtype , True , copy )
213
220
else :
214
221
return pyopencl_to_af_array (pycl_arr .copy ())
215
222
except :
216
223
AF_PYOPENCL_FOUND = False
217
224
218
225
219
- def to_array (in_array ):
226
+ def to_array (in_array , copy = True ):
220
227
"""
221
228
Helper function to convert input from a different module to af.Array
222
229
@@ -226,16 +233,19 @@ def to_array(in_array):
226
233
in_array : array like object
227
234
Can be one of numpy.ndarray, pycuda.GPUArray, pyopencl.Array, array.array, list
228
235
236
+ copy : Bool specifying if array is to be copied.
237
+ Default is true.
238
+ Can only be False if array is fortran contiguous.
239
+
229
240
Returns
230
241
--------------
231
242
af.Array of same dimensions as input after copying the data from the input
232
243
233
-
234
244
"""
235
245
if AF_NUMPY_FOUND and isinstance (in_array , NumpyArray ):
236
- return np_to_af_array (in_array )
246
+ return np_to_af_array (in_array , copy )
237
247
if AF_PYCUDA_FOUND and isinstance (in_array , CudaArray ):
238
- return pycuda_to_af_array (in_array )
248
+ return pycuda_to_af_array (in_array , copy )
239
249
if AF_PYOPENCL_FOUND and isinstance (in_array , OpenclArray ):
240
- return pyopencl_to_af_array (in_array )
250
+ return pyopencl_to_af_array (in_array , copy )
241
251
return Array (src = in_array )
0 commit comments