| 53 | } |
| 54 | |
| 55 | core::TensorValue FastPackedProjection4Module::build( |
| 56 | core::ModuleBuildContext & ctx, |
| 57 | const core::TensorValue & input, |
| 58 | const LinearWeights & weights) const { |
| 59 | if (ctx.ggml == nullptr) { |
| 60 | throw std::runtime_error("ModuleBuildContext.ggml is null"); |
| 61 | } |
| 62 | if (ctx.backend_type != core::BackendType::Cuda) { |
| 63 | throw std::runtime_error("FastPackedProjection4Module is CUDA-only"); |
| 64 | } |
| 65 | |
| 66 | core::validate_rank_between(input, 1, core::kMaxTensorRank, "input"); |
| 67 | core::validate_last_dim(input, config_.in_features, "input"); |
| 68 | core::validate_shape( |
| 69 | weights.weight, |
| 70 | core::TensorShape::from_dims({config_.out_features, config_.in_features}), |
| 71 | "weight"); |
| 72 | if (weights.bias.has_value()) { |
| 73 | throw std::runtime_error("FastPackedProjection4Module does not support bias"); |
| 74 | } |
| 75 | |
| 76 | const auto contiguous_input = core::ensure_backend_addressable_layout(ctx, input); |
| 77 | const auto matrix_input_shape = flatten_to_matrix_shape(contiguous_input.shape); |
| 78 | const auto matrix_input = core::reshape_tensor(ctx, contiguous_input, matrix_input_shape); |
| 79 | |
| 80 | ggml_tensor * projected_raw = |
| 81 | ggml_mul_mat_pack4(ctx.ggml, weights.weight.tensor, matrix_input.tensor); |
| 82 | if (config_.precision != GGML_PREC_DEFAULT) { |
| 83 | ggml_mul_mat_set_prec(projected_raw, config_.precision); |
| 84 | } |
| 85 | |
| 86 | auto projected = core::wrap_tensor( |
| 87 | projected_raw, |
| 88 | core::TensorShape::from_dims({matrix_input_shape.at(0), config_.out_features}), |
| 89 | GGML_TYPE_F32); |
| 90 | return core::reshape_tensor(ctx, projected, input.shape.with_last_dim(config_.out_features)); |
| 91 | } |
| 92 | |
| 93 | const core::ModuleSchema & FastPackedProjection4Module::static_schema() noexcept { |
| 94 | return kFastPackedProjection4Schema; |
nothing calls this directly
no test coverage detected