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> createSubArray(const Array<T>& parent, const std::vector<af_seq> &index, bool copy) { parent.eval(); dim4 dDims = parent.getDataDims(); dim4 pDims = parent.dims(); dim4 dims = toDims (index, pDims); dim4 offset = toOffset(index, dDims); dim4 stride = toStride (index, dDims); Array<T> out = Array<T>(parent, dims, offset, stride); if (!copy) return out; if (stride[0] != 1 || stride[1] < 0 || stride[2] < 0 || stride[3] < 0) { out = copyArray(out); } return out; }
Array<T> index(const Array<T>& in, const af_index_t idxrs[]) { kernel::IndexKernelParam_t p; std::vector<af_seq> seqs(4, af_span); // create seq vector to retrieve output // dimensions, offsets & offsets for (dim_t x=0; x<4; ++x) { if (idxrs[x].isSeq) { seqs[x] = idxrs[x].idx.seq; } } // retrieve dimensions, strides and offsets dim4 iDims = in.dims(); dim4 dDims = in.getDataDims(); dim4 oDims = toDims (seqs, iDims); dim4 iOffs = toOffset(seqs, dDims); dim4 iStrds= toStride(seqs, dDims); for (dim_t i=0; i<4; ++i) { p.isSeq[i] = idxrs[i].isSeq; p.offs[i] = iOffs[i]; p.strds[i] = iStrds[i]; } Buffer* bPtrs[4]; std::vector< Array<uint> > idxArrs(4, createEmptyArray<uint>(dim4())); // look through indexs to read af_array indexs for (dim_t x=0; x<4; ++x) { // set index pointers were applicable if (!p.isSeq[x]) { idxArrs[x] = castArray<uint>(idxrs[x].idx.arr); bPtrs[x] = idxArrs[x].get(); // set output array ith dimension value oDims[x] = idxArrs[x].elements(); } else { // alloc an 1-element buffer to avoid OpenCL from failing bPtrs[x] = bufferAlloc(sizeof(uint)); } } Array<T> out = createEmptyArray<T>(oDims); if(oDims.elements() == 0) { return out; } kernel::index<T>(out, in, p, bPtrs); for (dim_t x=0; x<4; ++x) { if (p.isSeq[x]) bufferFree(bPtrs[x]); } return out; }