Source code for arrayfire.interop

######################################################## Copyright (c) 2015, ArrayFire# All rights reserved.## This file is distributed under 3-clause BSD license.# The complete license agreement can be obtained at:# http://arrayfire.com/licenses/BSD-3-Clause########################################################"""Interop with other python packages.This module provides helper functions to copy data to arrayfire from the following modules:     1. numpy - numpy.ndarray     2. pycuda - pycuda.gpuarray     3. pyopencl - pyopencl.array     4. numba - numba.cuda.cudadrv.devicearray.DeviceNDArray"""from.arrayimport*from.deviceimport*def_fc_to_af_array(in_ptr,in_shape,in_dtype,is_device=False,copy=True):"""    Fortran Contiguous to af array    """res=Array(in_ptr,in_shape,in_dtype,is_device=is_device)ifnotis_device:returnreslock_array(res)returnres.copy()ifcopyelseresdef_cc_to_af_array(in_ptr,ndim,in_shape,in_dtype,is_device=False,copy=True):"""    C Contiguous to af array    """ifndim==1:return_fc_to_af_array(in_ptr,in_shape,in_dtype,is_device,copy)else:shape=tuple(reversed(in_shape))res=Array(in_ptr,shape,in_dtype,is_device=is_device)ifis_device:lock_array(res)returnres._reorder()_nptype_to_aftype={'b1':Dtype.b8,'u1':Dtype.u8,'u2':Dtype.u16,'i2':Dtype.s16,'s4':Dtype.u32,'i4':Dtype.s32,'f4':Dtype.f32,'c8':Dtype.c32,'s8':Dtype.u64,'i8':Dtype.s64,'f8':Dtype.f64,'c16':Dtype.c64}try:importnumpyasnpexceptImportError:AF_NUMPY_FOUND=Falseelse:fromnumpyimportndarrayasNumpyArrayfrom.dataimportreorderAF_NUMPY_FOUND=True
[docs]defnp_to_af_array(np_arr,copy=True):""" Convert numpy.ndarray to arrayfire.Array. Parameters ---------- np_arr : numpy.ndarray() copy : Bool specifying if array is to be copied. Default is true. Can only be False if array is fortran contiguous. Returns --------- af_arr : arrayfire.Array() """in_shape=np_arr.shapein_ptr=np_arr.ctypes.data_as(c_void_ptr_t)in_dtype=_nptype_to_aftype[np_arr.dtype.str[1:]]ifnotcopy:raiseRuntimeError("Copy can not be False for numpy arrays")if(np_arr.flags['F_CONTIGUOUS']):return_fc_to_af_array(in_ptr,in_shape,in_dtype)elif(np_arr.flags['C_CONTIGUOUS']):return_cc_to_af_array(in_ptr,np_arr.ndim,in_shape,in_dtype)else:returnnp_to_af_array(np_arr.copy())
from_ndarray=np_to_af_arraytry:importpycuda.gpuarrayexceptImportError:AF_PYCUDA_FOUND=Falseelse:frompycuda.gpuarrayimportGPUArrayasCudaArrayAF_PYCUDA_FOUND=Truedefpycuda_to_af_array(pycu_arr,copy=True):""" Convert pycuda.gpuarray to arrayfire.Array Parameters ----------- pycu_arr : pycuda.GPUArray() copy : Bool specifying if array is to be copied. Default is true. Can only be False if array is fortran contiguous. Returns ---------- af_arr : arrayfire.Array() Note ---------- The input array is copied to af.Array """in_ptr=pycu_arr.ptrin_shape=pycu_arr.shapein_dtype=pycu_arr.dtype.charifnotcopyandnotpycu_arr.flags.f_contiguous:raiseRuntimeError("Copy can only be False when arr.flags.f_contiguous is True")if(pycu_arr.flags.f_contiguous):return_fc_to_af_array(in_ptr,in_shape,in_dtype,True,copy)elif(pycu_arr.flags.c_contiguous):return_cc_to_af_array(in_ptr,pycu_arr.ndim,in_shape,in_dtype,True,copy)else:returnpycuda_to_af_array(pycu_arr.copy())try:frompyopencl.arrayimportArrayasOpenclArrayexceptImportError:AF_PYOPENCL_FOUND=Falseelse:from.openclimportadd_device_contextas_add_device_contextfrom.openclimportset_device_contextas_set_device_contextfrom.openclimportget_device_idas_get_device_idfrom.openclimportget_contextas_get_contextAF_PYOPENCL_FOUND=Truedefpyopencl_to_af_array(pycl_arr,copy=True):""" Convert pyopencl.gpuarray to arrayfire.Array Parameters ----------- pycl_arr : pyopencl.Array() copy : Bool specifying if array is to be copied. Default is true. Can only be False if array is fortran contiguous. Returns ---------- af_arr : arrayfire.Array() Note ---------- The input array is copied to af.Array """ctx=pycl_arr.context.int_ptrque=pycl_arr.queue.int_ptrdev=pycl_arr.queue.device.int_ptrdev_idx=Nonectx_idx=Noneforninrange(get_device_count()):set_device(n)dev_idx=_get_device_id()ctx_idx=_get_context()if(dev_idx==devandctx_idx==ctx):breakif(dev_idx==Noneorctx_idx==Noneordev_idx!=devorctx_idx!=ctx):print("Adding context and queue")_add_device_context(dev,ctx,que)_set_device_context(dev,ctx)info()in_ptr=pycl_arr.base_data.int_ptrin_shape=pycl_arr.shapein_dtype=pycl_arr.dtype.charifnotcopyandnotpycl_arr.flags.f_contiguous:raiseRuntimeError("Copy can only be False when arr.flags.f_contiguous is True")print("Copying array")print(pycl_arr.base_data.int_ptr)if(pycl_arr.flags.f_contiguous):return_fc_to_af_array(in_ptr,in_shape,in_dtype,True,copy)elif(pycl_arr.flags.c_contiguous):return_cc_to_af_array(in_ptr,pycl_arr.ndim,in_shape,in_dtype,True,copy)else:returnpyopencl_to_af_array(pycl_arr.copy())try:importnumbaexceptImportError:AF_NUMBA_FOUND=Falseelse:fromnumbaimportcudaNumbaCudaArray=cuda.cudadrv.devicearray.DeviceNDArrayAF_NUMBA_FOUND=Truedefnumba_to_af_array(nb_arr,copy=True):""" Convert numba.gpuarray to arrayfire.Array Parameters ----------- nb_arr : numba.cuda.cudadrv.devicearray.DeviceNDArray() copy : Bool specifying if array is to be copied. Default is true. Can only be False if array is fortran contiguous. Returns ---------- af_arr : arrayfire.Array() Note ---------- The input array is copied to af.Array """in_ptr=nb_arr.device_ctypes_pointer.valuein_shape=nb_arr.shapein_dtype=_nptype_to_aftype[nb_arr.dtype.str[1:]]ifnotcopyandnotnb_arr.flags.f_contiguous:raiseRuntimeError("Copy can only be False when arr.flags.f_contiguous is True")if(nb_arr.is_f_contiguous()):return_fc_to_af_array(in_ptr,in_shape,in_dtype,True,copy)elif(nb_arr.is_c_contiguous()):return_cc_to_af_array(in_ptr,nb_arr.ndim,in_shape,in_dtype,True,copy)else:returnnumba_to_af_array(nb_arr.copy())
[docs]defto_array(in_array,copy=True):""" Helper function to convert input from a different module to af.Array Parameters ------------- in_array : array like object Can be one of the following: - numpy.ndarray - pycuda.GPUArray - pyopencl.Array - numba.cuda.cudadrv.devicearray.DeviceNDArray - array.array - list copy : Bool specifying if array is to be copied. Default is true. Can only be False if array is fortran contiguous. Returns -------------- af.Array of same dimensions as input after copying the data from the input """ifAF_NUMPY_FOUNDandisinstance(in_array,NumpyArray):returnnp_to_af_array(in_array,copy)ifAF_PYCUDA_FOUNDandisinstance(in_array,CudaArray):returnpycuda_to_af_array(in_array,copy)ifAF_PYOPENCL_FOUNDandisinstance(in_array,OpenclArray):returnpyopencl_to_af_array(in_array,copy)ifAF_NUMBA_FOUNDandisinstance(in_array,NumbaCudaArray):returnnumba_to_af_array(in_array,copy)returnArray(src=in_array)