| 132 | } |
| 133 | |
| 134 | af_err af_assign_seq(af_array* out, const af_array lhs, const unsigned ndims, |
| 135 | const af_seq* index, const af_array rhs) { |
| 136 | try { |
| 137 | ARG_ASSERT(2, (ndims > 0 && ndims <= AF_MAX_DIMS)); |
| 138 | ARG_ASSERT(1, (lhs != 0)); |
| 139 | ARG_ASSERT(4, (rhs != 0)); |
| 140 | |
| 141 | const ArrayInfo& lInfo = getInfo(lhs); |
| 142 | |
| 143 | if (ndims == 1 && ndims != lInfo.ndims()) { |
| 144 | af_array tmp_in; |
| 145 | af_array tmp_out; |
| 146 | AF_CHECK(af_flat(&tmp_in, lhs)); |
| 147 | AF_CHECK(af_assign_seq(&tmp_out, tmp_in, ndims, index, rhs)); |
| 148 | AF_CHECK( |
| 149 | af_moddims(out, tmp_out, lInfo.ndims(), lInfo.dims().get())); |
| 150 | AF_CHECK(af_release_array(tmp_in)); |
| 151 | // This can run into a double free issue if tmp_in == tmp_out |
| 152 | // The condition ensures release only if both are different |
| 153 | // Issue found on Tegra X1 |
| 154 | if (tmp_in != tmp_out) { AF_CHECK(af_release_array(tmp_out)); } |
| 155 | return AF_SUCCESS; |
| 156 | } |
| 157 | |
| 158 | af_array res = 0; |
| 159 | |
| 160 | if (*out != lhs) { |
| 161 | int count = 0; |
| 162 | AF_CHECK(af_get_data_ref_count(&count, lhs)); |
| 163 | if (count > 1) { |
| 164 | AF_CHECK(af_copy_array(&res, lhs)); |
| 165 | } else { |
| 166 | res = retain(lhs); |
| 167 | } |
| 168 | } else { |
| 169 | res = lhs; |
| 170 | } |
| 171 | |
| 172 | try { |
| 173 | if (lhs != rhs) { |
| 174 | const dim4& outDims = getInfo(res).dims(); |
| 175 | const dim4& inDims = getInfo(rhs).dims(); |
| 176 | |
| 177 | vector<af_seq> inSeqs(ndims, af_span); |
| 178 | for (unsigned i = 0; i < ndims; ++i) { |
| 179 | inSeqs[i] = convert2Canonical(index[i], outDims[i]); |
| 180 | ARG_ASSERT(3, |
| 181 | (inSeqs[i].begin >= 0. || inSeqs[i].end >= 0.)); |
| 182 | if (signbit(inSeqs[i].step)) { |
| 183 | ARG_ASSERT(3, inSeqs[i].begin >= inSeqs[i].end); |
| 184 | } else { |
| 185 | ARG_ASSERT(3, inSeqs[i].begin <= inSeqs[i].end); |
| 186 | } |
| 187 | } |
| 188 | DIM_ASSERT(0, (outDims.ndims() >= inDims.ndims())); |
| 189 | DIM_ASSERT(0, (outDims.ndims() >= (dim_t)ndims)); |
| 190 | |
| 191 | const ArrayInfo& oInfo = getInfo(res); |