| 125 | |
| 126 | template <typename T, typename Context> |
| 127 | void ContiguousKernel(const Context& dev_ctx, |
| 128 | const DenseTensor& input, |
| 129 | DenseTensor* out) { |
| 130 | DenseTensorMeta meta = input.meta(); |
| 131 | meta.strides = meta.calc_strides(meta.dims); |
| 132 | meta.offset = 0; |
| 133 | out->set_meta(meta); |
| 134 | |
| 135 | const T* input_data = input.data<T>(); |
| 136 | T* output_data = dev_ctx.template Alloc<T>(out); |
| 137 | auto numel = input.numel(); |
| 138 | |
| 139 | if (numel == 0) { |
| 140 | return; |
| 141 | } |
| 142 | |
| 143 | if (IsComplexType(input.dtype())) { |
| 144 | FallbackContiguous<T>( |
| 145 | input.dims(), input.strides(), numel, input_data, output_data); |
| 146 | return; |
| 147 | } |
| 148 | |
| 149 | #if defined(_WIN32) |
| 150 | FallbackContiguous<T>( |
| 151 | input.dims(), input.strides(), numel, input_data, output_data); |
| 152 | return; |
| 153 | #else |
| 154 | if (FastTransposeCopyValid(*out, input)) { |
| 155 | constexpr int64_t TRANS_NUMEL = 60; |
| 156 | void* trans_buffer = |
| 157 | malloc(SizeOf(input.dtype()) * TRANS_NUMEL * TRANS_NUMEL); |
| 158 | |
| 159 | const T* tmp_src_ptr = input_data; |
| 160 | T* tmp_out_ptr = output_data; |
| 161 | T* tmp_buf_ptr = reinterpret_cast<T*>(trans_buffer); |
| 162 | |
| 163 | int64_t dim0 = out->dims()[0]; |
| 164 | int64_t dim1 = out->dims()[1]; |
| 165 | |
| 166 | for (int64_t d0 = 0; d0 < dim0; d0 += TRANS_NUMEL) { |
| 167 | for (int64_t d1 = 0; d1 < dim1; d1 += TRANS_NUMEL) { |
| 168 | const T* src_ptr_inter = tmp_src_ptr + d0 + d1 * dim0; |
| 169 | T* out_ptr_inter = tmp_out_ptr + d1 + d0 * dim1; |
| 170 | |
| 171 | int nr = std::min(dim0 - d0, TRANS_NUMEL); |
| 172 | int nc = std::min(dim1 - d1, TRANS_NUMEL); |
| 173 | |
| 174 | for (int c = 0; c < nc; c++) { |
| 175 | memcpy(tmp_buf_ptr + c * TRANS_NUMEL, |
| 176 | src_ptr_inter + c * dim0, |
| 177 | nr * sizeof(T)); |
| 178 | } |
| 179 | |
| 180 | int rc_max = std::max(nr, nc); |
| 181 | int rc_min = std::min(nr, nc); |
| 182 | for (int r = 0; r < rc_max; r++) { |
| 183 | int end = std::min(r, rc_min); |
| 184 | for (int c = 0; c < end; c++) { |
nothing calls this directly
no test coverage detected