|
12 | 12 |
|
13 | 13 | #include <af/array.h> |
14 | 14 | #include <af/index.h> |
| 15 | +#include <af/arith.h> |
15 | 16 | #include <ArrayInfo.hpp> |
16 | 17 | #include <err_common.hpp> |
17 | 18 | #include <handle.hpp> |
18 | 19 | #include <backend.hpp> |
19 | 20 | #include <Array.hpp> |
20 | 21 | #include <lookup.hpp> |
| 22 | +#include <index.hpp> |
21 | 23 |
|
22 | 24 | using namespace detail; |
23 | 25 | using std::vector; |
@@ -116,3 +118,91 @@ af_make_seq(double begin, double end, double step) { |
116 | 118 | af_seq seq = {begin, end, step}; |
117 | 119 | return seq; |
118 | 120 | } |
| 121 | + |
| 122 | +// idxrs parameter to the below static function |
| 123 | +// expects 4 values which is handled appropriately |
| 124 | +// by the C-API af_index_gen |
| 125 | +template<typename T> |
| 126 | +static inline |
| 127 | +af_array genIndex(const af_array& in, const af_index_t idxrs[]) |
| 128 | +{ |
| 129 | + return getHandle<T>(index<T>(getArray<T>(in), idxrs)); |
| 130 | +} |
| 131 | + |
| 132 | +af_err af_index_gen(af_array *out, const af_array in, const dim_type ndims, const af_index_t* indexers) |
| 133 | +{ |
| 134 | + af_array output = 0; |
| 135 | + // spanner is sequence indexer used for indexing along the |
| 136 | + // dimensions after ndims |
| 137 | + af_index_t spanner; |
| 138 | + spanner.mIndexer.seq = af_span; |
| 139 | + spanner.mIsSeq = true; |
| 140 | + |
| 141 | + try { |
| 142 | + ARG_ASSERT(2, (ndims>0)); |
| 143 | + ARG_ASSERT(3, (indexers!=NULL)); |
| 144 | + |
| 145 | + int track = 0; |
| 146 | + af_seq seqs[] = {af_span, af_span, af_span, af_span}; |
| 147 | + for (dim_type i = 0; i < ndims; i++) { |
| 148 | + if (indexers[i].mIsSeq) { |
| 149 | + track++; |
| 150 | + seqs[i] = indexers[i].mIndexer.seq; |
| 151 | + } |
| 152 | + } |
| 153 | + |
| 154 | + if (track==ndims) { |
| 155 | + // all indexers are sequences, redirecting to af_index |
| 156 | + return af_index(out, in, ndims, seqs); |
| 157 | + } |
| 158 | + |
| 159 | + af_index_t idxrs[4]; |
| 160 | + // set all dimensions above ndims to spanner indexer |
| 161 | + for (dim_type i=ndims; i<4; ++i) idxrs[i] = spanner; |
| 162 | + |
| 163 | + for (dim_type i=0; i<ndims; ++i) { |
| 164 | + if (!indexers[i].mIsSeq) { |
| 165 | + // check if all af_arrays have atleast one value |
| 166 | + // to enable indexing along that dimension |
| 167 | + ArrayInfo idxInfo = getInfo(indexers[i].mIndexer.arr); |
| 168 | + af_dtype idxType = idxInfo.getType(); |
| 169 | + |
| 170 | + ARG_ASSERT(3, (idxType!=c32)); |
| 171 | + ARG_ASSERT(3, (idxType!=c64)); |
| 172 | + ARG_ASSERT(3, (idxType!=b8 )); |
| 173 | + |
| 174 | + idxrs[i].mIndexer.arr = indexers[i].mIndexer.arr; |
| 175 | + idxrs[i].mIsSeq = indexers[i].mIsSeq; |
| 176 | + } else { |
| 177 | + // af_seq is being used for this dimension |
| 178 | + // just copy the indexer to local variable |
| 179 | + idxrs[i] = indexers[i]; |
| 180 | + } |
| 181 | + } |
| 182 | + |
| 183 | + ArrayInfo iInfo = getInfo(in); |
| 184 | + dim4 iDims = iInfo.dims(); |
| 185 | + |
| 186 | + ARG_ASSERT(1, (iDims.ndims()>0)); |
| 187 | + |
| 188 | + af_dtype inType = getInfo(in).getType(); |
| 189 | + switch(inType) { |
| 190 | + case c64: output = genIndex<cdouble>(in, idxrs); break; |
| 191 | + case f64: output = genIndex<double >(in, idxrs); break; |
| 192 | + case c32: output = genIndex<cfloat >(in, idxrs); break; |
| 193 | + case f32: output = genIndex<float >(in, idxrs); break; |
| 194 | + case u64: output = genIndex<uintl >(in, idxrs); break; |
| 195 | + case u32: output = genIndex<uint >(in, idxrs); break; |
| 196 | + case s64: output = genIndex<intl >(in, idxrs); break; |
| 197 | + case s32: output = genIndex<int >(in, idxrs); break; |
| 198 | + case u8: output = genIndex<uchar >(in, idxrs); break; |
| 199 | + case b8: output = genIndex<char >(in, idxrs); break; |
| 200 | + default: TYPE_ERROR(1, inType); |
| 201 | + } |
| 202 | + } |
| 203 | + CATCHALL; |
| 204 | + |
| 205 | + std::swap(*out, output); |
| 206 | + |
| 207 | + return AF_SUCCESS; |
| 208 | +} |
0 commit comments