| 896 | } // namespace |
| 897 | |
| 898 | class HeartCodecFlowEstimatorGraph { |
| 899 | public: |
| 900 | HeartCodecFlowEstimatorGraph( |
| 901 | const HeartCodecWeightsRuntime & runtime, |
| 902 | int64_t batch_size, |
| 903 | int64_t frames) |
| 904 | : runtime_(&runtime), |
| 905 | batch_size_(batch_size), |
| 906 | frames_(frames) { |
| 907 | if (batch_size_ <= 0 || frames_ <= 0) { |
| 908 | throw std::runtime_error("HeartCodec flow estimator graph shape is invalid"); |
| 909 | } |
| 910 | const auto & config = runtime_->assets().codec_config; |
| 911 | ggml_init_params params{runtime_->flow_estimator_graph_arena_bytes(), nullptr, true}; |
| 912 | ctx_.reset(ggml_init(params)); |
| 913 | if (ctx_ == nullptr) { |
| 914 | throw std::runtime_error("failed to initialize HeartCodec flow estimator graph context"); |
| 915 | } |
| 916 | core::ModuleBuildContext ctx{ctx_.get(), "heartcodec.flow_estimator", runtime_->backend_type()}; |
| 917 | auto input = core::make_tensor( |
| 918 | ctx, |
| 919 | GGML_TYPE_F32, |
| 920 | core::TensorShape::from_dims({batch_size_, frames_, config.in_channels})); |
| 921 | input_ = input.tensor; |
| 922 | auto timesteps = core::make_tensor(ctx, GGML_TYPE_F32, core::TensorShape::from_dims({batch_size_})); |
| 923 | timesteps_ = timesteps.tensor; |
| 924 | freqs_ = ggml_new_tensor_2d(ctx_.get(), GGML_TYPE_F32, 256, 1); |
| 925 | auto freqs = core::wrap_tensor(freqs_, core::TensorShape::from_dims({1, 256}), GGML_TYPE_F32); |
| 926 | positions_ = ggml_new_tensor_1d(ctx_.get(), GGML_TYPE_I32, frames_); |
| 927 | auto positions = core::wrap_tensor(positions_, core::TensorShape::from_dims({frames_}), GGML_TYPE_I32); |
| 928 | auto out = flow_estimator( |
| 929 | ctx, |
| 930 | input, |
| 931 | timesteps, |
| 932 | freqs, |
| 933 | positions, |
no test coverage detected