| 8381 | } |
| 8382 | |
| 8383 | static void ggml_compute_forward_repeat_f16( |
| 8384 | const struct ggml_compute_params * params, |
| 8385 | const struct ggml_tensor * src0, |
| 8386 | struct ggml_tensor * dst) { |
| 8387 | GGML_ASSERT(params->ith == 0); |
| 8388 | GGML_ASSERT(ggml_can_repeat(src0, dst)); |
| 8389 | |
| 8390 | if (params->type == GGML_TASK_INIT || params->type == GGML_TASK_FINALIZE) { |
| 8391 | return; |
| 8392 | } |
| 8393 | |
| 8394 | GGML_TENSOR_UNARY_OP_LOCALS; |
| 8395 | |
| 8396 | // guaranteed to be an integer due to the check in ggml_can_repeat |
| 8397 | const int nr0 = (int)(ne0/ne00); |
| 8398 | const int nr1 = (int)(ne1/ne01); |
| 8399 | const int nr2 = (int)(ne2/ne02); |
| 8400 | const int nr3 = (int)(ne3/ne03); |
| 8401 | |
| 8402 | // TODO: support for transposed / permuted tensors |
| 8403 | GGML_ASSERT(nb0 == sizeof(ggml_fp16_t)); |
| 8404 | GGML_ASSERT(nb00 == sizeof(ggml_fp16_t)); |
| 8405 | |
| 8406 | // TODO: maybe this is not optimal? |
| 8407 | for (int i3 = 0; i3 < nr3; i3++) { |
| 8408 | for (int k3 = 0; k3 < ne03; k3++) { |
| 8409 | for (int i2 = 0; i2 < nr2; i2++) { |
| 8410 | for (int k2 = 0; k2 < ne02; k2++) { |
| 8411 | for (int i1 = 0; i1 < nr1; i1++) { |
| 8412 | for (int k1 = 0; k1 < ne01; k1++) { |
| 8413 | for (int i0 = 0; i0 < nr0; i0++) { |
| 8414 | ggml_fp16_t * y = (ggml_fp16_t *) ((char *) dst->data + (i3*ne03 + k3)*nb3 + (i2*ne02 + k2)*nb2 + (i1*ne01 + k1)*nb1 + (i0*ne00)*nb0); |
| 8415 | ggml_fp16_t * x = (ggml_fp16_t *) ((char *) src0->data + ( k3)*nb03 + ( k2)*nb02 + ( k1)*nb01); |
| 8416 | // ggml_vec_cpy_f16(ne00, y, x) |
| 8417 | for (int i = 0; i < ne00; ++i) { |
| 8418 | y[i] = x[i]; |
| 8419 | } |
| 8420 | } |
| 8421 | } |
| 8422 | } |
| 8423 | } |
| 8424 | } |
| 8425 | } |
| 8426 | } |
| 8427 | } |
| 8428 | |
| 8429 | static void ggml_compute_forward_repeat( |
| 8430 | const struct ggml_compute_params * params, |
no test coverage detected