| 72 | } |
| 73 | |
| 74 | af_err af_reorder(af_array *out, const af_array in, const af::dim4 &rdims) { |
| 75 | try { |
| 76 | const ArrayInfo &info = getInfo(in); |
| 77 | af_dtype type = info.getType(); |
| 78 | |
| 79 | if (info.elements() == 0) { return af_retain_array(out, in); } |
| 80 | |
| 81 | DIM_ASSERT(1, info.elements() > 0); |
| 82 | |
| 83 | // Check that dimensions are not repeated |
| 84 | // allDims is to check if all dimensions are there exactly once |
| 85 | // If all dimensions are present, the allDims will be -1, -1, -1, -1 |
| 86 | // after the loop |
| 87 | // Example: |
| 88 | // rdims = {2, 0, 3, 1} |
| 89 | // i = 0 => 2 found and cond is true so alldims[2] = -1 |
| 90 | // i = 1 => 0 found and cond is true so alldims[0] = -1 |
| 91 | // i = 2 => 3 found and cond is true so alldims[3] = -1 |
| 92 | // i = 3 => 1 found and cond is true so alldims[1] = -1 |
| 93 | // rdims = {2, 0, 3, 2} // Failure case |
| 94 | // i = 3 => 2 found so cond is false (since alldims[2] = -1 when i = 0) |
| 95 | // so failed. |
| 96 | dim_t allDims[] = {0, 1, 2, 3}; |
| 97 | for (int i = 0; i < 4; i++) { |
| 98 | DIM_ASSERT(i + 2, rdims[i] == allDims[rdims[i]]); |
| 99 | allDims[rdims[i]] = -1; |
| 100 | } |
| 101 | |
| 102 | af_array output; |
| 103 | |
| 104 | switch (type) { |
| 105 | case f32: output = reorder<float>(in, rdims); break; |
| 106 | case c32: output = reorder<cfloat>(in, rdims); break; |
| 107 | case f64: output = reorder<double>(in, rdims); break; |
| 108 | case c64: output = reorder<cdouble>(in, rdims); break; |
| 109 | case b8: output = reorder<char>(in, rdims); break; |
| 110 | case s32: output = reorder<int>(in, rdims); break; |
| 111 | case u32: output = reorder<uint>(in, rdims); break; |
| 112 | case s8: output = reorder<schar>(in, rdims); break; |
| 113 | case u8: output = reorder<uchar>(in, rdims); break; |
| 114 | case s64: output = reorder<intl>(in, rdims); break; |
| 115 | case u64: output = reorder<uintl>(in, rdims); break; |
| 116 | case s16: output = reorder<short>(in, rdims); break; |
| 117 | case u16: output = reorder<ushort>(in, rdims); break; |
| 118 | case f16: output = reorder<half>(in, rdims); break; |
| 119 | default: TYPE_ERROR(1, type); |
| 120 | } |
| 121 | swap(*out, output); |
| 122 | } |
| 123 | CATCHALL; |
| 124 | |
| 125 | return AF_SUCCESS; |
| 126 | } |
| 127 | |
| 128 | af_err af_reorder(af_array *out, const af_array in, const unsigned x, |
| 129 | const unsigned y, const unsigned z, const unsigned w) { |