|
| 1 | +#include "col2im-1d.hpp" |
| 2 | + |
| 3 | +template <typename T> |
| 4 | +static void col2im_1d_sycl( |
| 5 | + const T * col, |
| 6 | + T * dst, |
| 7 | + const int64_t T_in, |
| 8 | + const int64_t T_out, |
| 9 | + const int64_t OC, |
| 10 | + const int64_t K, |
| 11 | + const int64_t K_OC, |
| 12 | + const int32_t s0, |
| 13 | + const int32_t p0, |
| 14 | + dpct::queue_ptr stream) { |
| 15 | + |
| 16 | + const int64_t total = T_out * OC; |
| 17 | + const uint32_t block_size = 256; |
| 18 | + const uint32_t num_blocks = (uint32_t) ((total + block_size - 1) / block_size); |
| 19 | + |
| 20 | + stream->parallel_for( |
| 21 | + sycl::nd_range<3>( |
| 22 | + sycl::range<3>(1, 1, num_blocks * block_size), |
| 23 | + sycl::range<3>(1, 1, block_size)), |
| 24 | + [=](sycl::nd_item<3> item_ct1) { |
| 25 | + const int64_t idx = item_ct1.get_global_id(2); |
| 26 | + if (idx >= total) { |
| 27 | + return; |
| 28 | + } |
| 29 | + |
| 30 | + const int64_t oc = idx / T_out; |
| 31 | + const int64_t t_out = idx - oc * T_out; |
| 32 | + const int64_t t_abs = t_out + p0; |
| 33 | + |
| 34 | + int64_t t_in_min = (t_abs - K + s0) / s0; |
| 35 | + if (t_in_min < 0) { |
| 36 | + t_in_min = 0; |
| 37 | + } |
| 38 | + int64_t t_in_max = t_abs / s0; |
| 39 | + if (t_in_max >= T_in) { |
| 40 | + t_in_max = T_in - 1; |
| 41 | + } |
| 42 | + |
| 43 | + float sum = 0.0f; |
| 44 | + for (int64_t t_in = t_in_min; t_in <= t_in_max; ++t_in) { |
| 45 | + const int64_t k = t_abs - t_in * s0; |
| 46 | + sum += (float) col[(oc * K + k) + t_in * K_OC]; |
| 47 | + } |
| 48 | + |
| 49 | + dst[idx] = (T) sum; |
| 50 | + }); |
| 51 | +} |
| 52 | + |
| 53 | +void ggml_sycl_op_col2im_1d(ggml_backend_sycl_context & ctx, ggml_tensor * dst) { |
| 54 | + const ggml_tensor * src0 = dst->src[0]; |
| 55 | + |
| 56 | + GGML_ASSERT(src0 != nullptr); |
| 57 | + GGML_ASSERT(ggml_is_contiguous(src0)); |
| 58 | + GGML_ASSERT(src0->type == dst->type); |
| 59 | + |
| 60 | + const int32_t s0 = ((const int32_t *) dst->op_params)[0]; |
| 61 | + const int32_t OC = ((const int32_t *) dst->op_params)[1]; |
| 62 | + const int32_t p0 = ((const int32_t *) dst->op_params)[2]; |
| 63 | + |
| 64 | + const int64_t K_OC = src0->ne[0]; |
| 65 | + const int64_t T_in = src0->ne[1]; |
| 66 | + const int64_t K = K_OC / OC; |
| 67 | + const int64_t T_out = dst->ne[0]; |
| 68 | + |
| 69 | + GGML_ASSERT(OC > 0); |
| 70 | + GGML_ASSERT(K_OC % OC == 0); |
| 71 | + |
| 72 | + dpct::queue_ptr stream = ctx.stream(); |
| 73 | + |
| 74 | + switch (src0->type) { |
| 75 | + case GGML_TYPE_F32: |
| 76 | + col2im_1d_sycl<float>( |
| 77 | + (const float *) src0->data, |
| 78 | + (float *) dst->data, |
| 79 | + T_in, T_out, OC, K, K_OC, s0, p0, stream); |
| 80 | + break; |
| 81 | + case GGML_TYPE_F16: |
| 82 | + col2im_1d_sycl<sycl::half>( |
| 83 | + (const sycl::half *) src0->data, |
| 84 | + (sycl::half *) dst->data, |
| 85 | + T_in, T_out, OC, K, K_OC, s0, p0, stream); |
| 86 | + break; |
| 87 | +#ifdef GGML_SYCL_HAS_BF16 |
| 88 | + case GGML_TYPE_BF16: |
| 89 | + col2im_1d_sycl<sycl::ext::oneapi::bfloat16>( |
| 90 | + (const sycl::ext::oneapi::bfloat16 *) src0->data, |
| 91 | + (sycl::ext::oneapi::bfloat16 *) dst->data, |
| 92 | + T_in, T_out, OC, K, K_OC, s0, p0, stream); |
| 93 | + break; |
| 94 | +#endif |
| 95 | + default: |
| 96 | + GGML_ABORT("col2im_1d: unsupported type %d", src0->type); |
| 97 | + } |
| 98 | +} |
0 commit comments