Array<T> createSubArray(const Array<T> &parent, const vector<af_seq> &index, bool copy) { parent.eval(); dim4 dDims = parent.getDataDims(); dim4 dStrides = calcStrides(dDims); dim4 parent_strides = parent.strides(); if (dStrides != parent_strides) { const Array<T> parentCopy = copyArray(parent); return createSubArray(parentCopy, index, copy); } dim4 pDims = parent.dims(); dim4 dims = toDims(index, pDims); dim4 strides = toStride(index, dDims); // Find total offsets after indexing dim4 offsets = toOffset(index, pDims); dim_t offset = parent.getOffset(); for (int i = 0; i < 4; i++) offset += offsets[i] * parent_strides[i]; Array<T> out = Array<T>(parent, dims, offset, strides); if (!copy) return out; if (strides[0] != 1 || strides[1] < 0 || strides[2] < 0 || strides[3] < 0) { out = copyArray(out); } return out; }
Array<T>::Array(dim4 dims, const T * const in_data): ArrayInfo(getActiveDeviceId(), dims, dim4(0,0,0,0), calcStrides(dims), (af_dtype)dtype_traits<T>::af_type), data(memAlloc<T>(dims.elements()), memFree<T>), data_dims(dims), node(), ready(true), offset(0), owner(true) { std::copy(in_data, in_data + dims.elements(), data.get()); }
Array<T>::Array(const af::dim4 &dims, Node_ptr n) : info(getActiveDeviceId(), dims, 0, calcStrides(dims), (af_dtype)dtype_traits<T>::af_type) , data() , data_dims(dims) , node(n) , ready(false) , owner(true) {}
Array<T>::Array(dim4 dims) : info(getActiveDeviceId(), dims, 0, calcStrides(dims), (af_dtype)dtype_traits<T>::af_type) , data(memAlloc<T>(dims.elements()).release(), memFree<T>) , data_dims(dims) , node(bufferNodePtr<T>()) , ready(true) , owner(true) {}
void copyData(T *to, const Array<T> &from) { if(from.isOwner()) { // FIXME: Check for errors / exceptions memcpy(to, from.get(), from.elements()*sizeof(T)); } else { dim4 ostrides = calcStrides(from.dims()); stridedCopy<T>(to, ostrides, from.get(), from.dims(), from.strides(), from.ndims() - 1); } }
Array<T>::Array(dim4 dims, const T * const in_data, bool is_device, bool copy_device): info(getActiveDeviceId(), dims, 0, calcStrides(dims), (af_dtype)dtype_traits<T>::af_type), data((is_device & !copy_device) ? (T*)in_data : memAlloc<T>(dims.elements()).release(), memFree<T>), data_dims(dims), node(bufferNodePtr<T>()), ready(true), owner(true) { static_assert(is_standard_layout<Array<T>>::value, "Array<T> must be a standard layout type"); static_assert(offsetof(Array<T>, info) == 0, "Array<T>::info must be the first member variable of Array<T>"); if (!is_device || copy_device) { // Ensure the memory being written to isnt used anywhere else. getQueue().sync(); copy(in_data, in_data + dims.elements(), data.get()); } }
Array<T>::Array(af::dim4 dims, TNJ::Node_ptr n) : ArrayInfo(-1, dims, af::dim4(0,0,0,0), calcStrides(dims), (af_dtype)dtype_traits<T>::af_type), data(), data_dims(dims), node(n), ready(false), offset(0), owner(true) { }
void resetInfo(const af::dim4& dims) { dim_size = dims; dim_strides = calcStrides(dims); dim_offsets = af::dim4(0,0,0,0); }