| 6514 | } |
| 6515 | |
| 6516 | bool sam3_test_run_patch_mulmat_host_ref(const sam3_model & model, |
| 6517 | const float * input_data, |
| 6518 | const int64_t input_ne[4], |
| 6519 | bool use_double_accum, |
| 6520 | std::vector<float> & output_data, |
| 6521 | int64_t output_ne[4]) { |
| 6522 | if (!input_data) { |
| 6523 | return false; |
| 6524 | } |
| 6525 | |
| 6526 | int64_t ne[4]; |
| 6527 | sam3_normalize_ne4(input_ne, ne); |
| 6528 | |
| 6529 | const int64_t patch_k = model.vit.patch_embed_w->ne[0] * model.vit.patch_embed_w->ne[1] * model.vit.patch_embed_w->ne[2]; |
| 6530 | const int64_t n_img = model.hparams.n_img_embd(); |
| 6531 | |
| 6532 | if (ne[0] != patch_k || ne[1] != n_img || ne[2] != n_img) { |
| 6533 | fprintf(stderr, "%s: patch_mulmat input shape mismatch [%lld,%lld,%lld,%lld]\n", |
| 6534 | __func__, |
| 6535 | (long long) ne[0], (long long) ne[1], (long long) ne[2], (long long) ne[3]); |
| 6536 | return false; |
| 6537 | } |
| 6538 | |
| 6539 | const int64_t n_patch = ne[1] * ne[2] * ne[3]; |
| 6540 | const int64_t n_out = model.vit.patch_embed_w->ne[3]; |
| 6541 | |
| 6542 | std::vector<ggml_fp16_t> input_f16((size_t) (patch_k * n_patch)); |
| 6543 | ggml_fp32_to_fp16_row(input_data, input_f16.data(), patch_k * n_patch); |
| 6544 | |
| 6545 | std::vector<ggml_fp16_t> weight_f16((size_t) (patch_k * n_out)); |
| 6546 | ggml_backend_tensor_get(model.vit.patch_embed_w, weight_f16.data(), 0, weight_f16.size() * sizeof(ggml_fp16_t)); |
| 6547 | |
| 6548 | output_data.resize((size_t) (n_patch * n_out)); |
| 6549 | output_ne[0] = n_patch; |
| 6550 | output_ne[1] = n_out; |
| 6551 | output_ne[2] = 1; |
| 6552 | output_ne[3] = 1; |
| 6553 | |
| 6554 | for (int64_t oc = 0; oc < n_out; ++oc) { |
| 6555 | const ggml_fp16_t * w_row = weight_f16.data() + oc * patch_k; |
| 6556 | float * dst_row = output_data.data() + oc * n_patch; |
| 6557 | |
| 6558 | for (int64_t p = 0; p < n_patch; ++p) { |
| 6559 | const ggml_fp16_t * x_row = input_f16.data() + p * patch_k; |
| 6560 | |
| 6561 | if (use_double_accum) { |
| 6562 | double acc = 0.0; |
| 6563 | for (int64_t k = 0; k < patch_k; ++k) { |
| 6564 | acc += (double) ggml_fp16_to_fp32(x_row[k]) * (double) ggml_fp16_to_fp32(w_row[k]); |
| 6565 | } |
| 6566 | dst_row[p] = (float) acc; |
| 6567 | } else { |
| 6568 | float acc = 0.0f; |
| 6569 | for (int64_t k = 0; k < patch_k; ++k) { |
| 6570 | acc += ggml_fp16_to_fp32(x_row[k]) * ggml_fp16_to_fp32(w_row[k]); |
| 6571 | } |
| 6572 | dst_row[p] = acc; |
| 6573 | } |