ReUseX  0.0.5
3D Point Cloud Processing for Building Reuse
Loading...
Searching...
No Matches
Sam3.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2025 Povl Filip Sonne-Frederiksen
2//
3// SPDX-License-Identifier: GPL-3.0-or-later
4
5#pragma once
6#include "reusex/vision/IData.hpp"
7#include "reusex/vision/IModel.hpp"
8#include "reusex/vision/common/object.hpp"
9#include "reusex/vision/tensor_rt/Data.hpp"
10#include "reusex/vision/tensor_rt/Sam3Type.hpp"
11#include "reusex/vision/tensor_rt/common/memory.hpp"
12#include "reusex/vision/tensor_rt/common/norm.hpp"
13#include "reusex/vision/tensor_rt/common/tensorrt.hpp"
14
15#include <tokenizers_cpp.h>
16
17#include <unordered_map>
18#include <vector>
19
21
22/* TensorRTSam3 is an implementation of the SAM3 model using TensorRT for
23efficient inference. It supports batch processing of images and prompts, with
24careful memory management to optimize performance on GPU. The class handles the
25loading of TensorRT engines for the vision encoder, text encoder, geometry
26encoder, and decoder, and provides a forward method to process input data and
27produce segmentation results. The implementation includes preprocessing of
28images, gathering of features from the vision encoder, and post-processing of
29the decoder outputs to generate final masks and bounding boxes. The design
30allows for flexibility in handling different types of prompts (text and
31geometry) and is optimized for use in real-time applications where latency is a
32concern. */
33class TensorRTSam3 : public IModel {
34 private:
36 using InferResultArray =
37 std::vector<::reusex::vision::common::object::DetectionBoxArray>;
38
39 public:
40 /* Constructor for TensorRTSam3 without geometry encoder. Initializes the
41 * model with the specified paths for the vision encoder, text encoder, and
42 * decoder, and sets the GPU ID for inference.
43 * @param vision_encoder_path: Path to the TensorRT engine file for the vision
44 * encoder.
45 * @param text_encoder_path: Path to the TensorRT engine file for the text
46 * encoder.
47 * @param decoder_path: Path to the TensorRT engine file for the decoder.
48 * @param gpu_id: ID of the GPU to use for inference.
49 */
50 TensorRTSam3(const std::string &vision_encoder_path,
51 const std::string &text_encoder_path,
52 const std::string &geometry_encoder_path,
53 const std::string &decoder_path,
54 const std::string &tokenizer_path, int gpu_id);
55
56 /* Destructor for TensorRTSam3. Cleans up any resources used by the model.
57 * @param model_path: Path to the model files (not used in this
58 * implementation).
59 * @return A unique pointer to an instance of TensorRTSam3.
60 */
61 static std::unique_ptr<TensorRTSam3>
62 create(const std::filesystem::path &model_path);
63
64 /* Forward method for TensorRTSam3. Takes a span of input pairs and processes
65 * them through the model to produce output pairs. This method handles the
66 * entire inference pipeline, including preprocessing, feature extraction,
67 * decoding, and post-processing to generate the final segmentation results.
68 * @param input: A span of input pairs containing the data to be processed.
69 * @return A vector of output pairs containing the results of the inference.
70 */
71 std::vector<IDataset::Pair>
72 forward(const std::span<IDataset::Pair> &input) override;
73
74 protected:
75 // virtual ~TensorRTSam3() = default;
76
77 /* Loads the TensorRT engines for the vision encoder, text encoder, geometry
78 * encoder, and decoder. This method is responsible for initializing the
79 * engines based on the provided model paths and ensuring that they are ready
80 * for inference. It returns true if all engines are loaded successfully, and
81 * false otherwise.
82 * @return A boolean indicating whether the engines were loaded successfully.
83 */
85
86 static std::string load_bytes_from_file(const std::string &file_path);
87
89 const cv::Mat &image, const std::string &label,
90 const std::vector<std::pair<std::string, std::array<float, 4>>> &boxes);
91
92 /*
93 // Core implementation
94 virtual InferResultArray forwards(const std::vector<Sam3Input> &inputs,
95 bool return_mask = false,
96 void *stream = nullptr) override;
97 virtual InferResultArray forwards(const std::vector<Sam3Input> &inputs,
98 const std::string &geom_label,
99 bool return_mask = false,
100 void *stream = nullptr) override;
101 */
102
103 private:
104 // Define internal structure for flattening Prompt
105 struct PromptMeta {
106 int image_idx; // Which image this Prompt belongs to
107 int original_idx; // The index of this Prompt in the original image vector
108 const Sam3PromptUnit *ptr; // Pointer to the original Prompt data
109 };
110
111 // Internal processing function
112 void preprocess(const TensorRTData &input, int ibatch, void *stream);
113
114 bool encode_image(int batch_size, void *stream);
115
116 // Modification: Gather features, collect data from Vision features according
117 // to the image index corresponding to the current Prompt Batch
118 void gather_vision_features(const std::vector<PromptMeta> &batch_prompts,
119 int batch_size, void *stream);
120
121 // Modified encoding function, based on the current batch size
122 bool encode_text(const std::vector<PromptMeta> &batch_prompts, int batch_size,
123 void *stream);
124 bool encode_boxes(const std::vector<PromptMeta> &batch_prompts,
125 int batch_size, int max_boxes, void *stream);
126 bool decode(int batch_size, int prompt_len, void *stream);
127
128 // Post-processing
129 void postprocess(InferResult &image_result, int batch_idx, int image_idx,
130 const std::string &label, const int label_id,
131 float confidence_threshold, bool return_mask, void *stream);
132
133 /* Allocates memory for all the necessary buffers used during inference. This
134 * method is designed to be called only once during the initialization phase
135 * of the model, and it sets up the memory structures based on the maximum
136 * batch sizes and input dimensions defined in the class. It ensures that all
137 * buffers are properly allocated and ready for use during the forward pass,
138 * optimizing memory usage and performance on the GPU.
139 */
140 void allocate_memory_once();
141
142 void set_binding_dim(std::shared_ptr<TensorRT::Engine> &engine,
143 int binding_index, const std::vector<int> &dims);
144
145 private:
146 // Configuration
147 bool isdynamic_model_ = true;
148 int input_image_width_ = 1008;
149 int input_image_height_ = 1008;
150 int gpu_id_ = 0;
151
152 // --- Batch processing limit configuration ---
153 // Can be adjusted according to VRAM size
154 const int max_image_batch_ =
155 2; // This Vision Encoder is relatively large, limit the number of images
156 // processed simultaneously
157 const int max_prompt_batch_ =
158 4; // Decoder is smaller, but VRAM is limited, limit the number of Prompts
159 // decoded each time
160 const int max_boxes_per_prompt_ =
161 20; // Preset maximum number of supported Boxes
162
163 // State variables
164 std::vector<std::pair<int, int>>
165 original_image_sizes_; // Size: max_image_batch_
166 int num_queries_ = 200;
167 int mask_height_ = 288;
168 int mask_width_ = 288;
169
170 // Model path
171 std::string vision_encoder_path_;
172 std::string text_encoder_path_;
173 std::string geometry_encoder_path_;
174 std::string decoder_path_;
175
176 // TRT engine
177 std::shared_ptr<TensorRT::Engine> vision_encoder_trt_;
178 std::shared_ptr<TensorRT::Engine> text_encoder_trt_;
179 std::shared_ptr<TensorRT::Engine> decoder_trt_;
180 std::shared_ptr<TensorRT::Engine> geometry_encoder_trt_;
181
182 // std::unordered_map<
183 // std::string, std::pair<std::array<int64_t, 32>, std::array<int64_t,
184 // 32>>> text_input_map_;
185 // INFO:
186 // The first array is for input_ids, the second is for attention_mask. The
187 // last int is the prompt ID
188 std::unordered_map<std::string, std::tuple<std::array<int64_t, 32>,
189 std::array<int64_t, 32>, int>>
190 text_input_map_;
191
192 // --- Memory management ---
194 1.0f / 127.5f, -1.0f, norm_image::ChannelType::SwapRB);
195
196 std::vector<int> vision_input_shape_;
197 std::vector<int> fpn_feat_0_shape_;
198 std::vector<int> text_ids_shape_;
199 std::vector<int> geom_box_shape_;
200
201 // Image Batch buffers (Size: max_image_batch_)
202 tensor::Memory<float> preprocessed_images_;
203 std::vector<std::shared_ptr<tensor::Memory<uint8_t>>> original_images_buf_;
204 tensor::Memory<float> affine_matrix_;
205 // Mask post-processing requires the corresponding matrix of the original
206 // image (Size: max_image_batch_)
207 tensor::Memory<float> mask_affine_matrix_;
208
209 // Vision Encoder Outputs (Size: max_image_batch_)
210 tensor::Memory<float> fpn_feat_0_;
211 tensor::Memory<float> fpn_feat_1_;
212 tensor::Memory<float> fpn_feat_2_;
213 tensor::Memory<float> fpn_pos_2_;
214
215 // Decoder Input Buffers (Size: max_prompt_batch_)
216 // These are gathered from Vision Output
217 tensor::Memory<float> fpn_feat_0_gather_;
218 tensor::Memory<float> fpn_feat_1_gather_;
219 tensor::Memory<float> fpn_feat_2_gather_;
220 tensor::Memory<float> fpn_pos_2_gather_;
221
222 // Prompt Inputs (Size: max_prompt_batch_)
223 tensor::Memory<int64_t> text_input_ids_;
224 tensor::Memory<int64_t> text_attention_mask_;
225
226 tensor::Memory<float> geom_boxes_;
227 tensor::Memory<int64_t> geom_labels_;
228
229 tensor::Memory<float> text_features_;
230 tensor::Memory<bool> text_mask_;
231
232 tensor::Memory<float> geom_features_;
233 tensor::Memory<bool> geom_mask_;
234
235 // Used to store the results of pre-set geometry models
236 std::unordered_map<std::string, std::shared_ptr<tensor::Memory<float>>>
237 geom_features_cache_;
238 std::unordered_map<std::string, std::shared_ptr<tensor::Memory<bool>>>
239 geom_mask_cache_;
240
241 tensor::Memory<float> prompt_features_;
242 tensor::Memory<bool> prompt_mask_;
243
244 // Decoder Output (Size: max_prompt_batch_)
245 tensor::Memory<float> pred_masks_;
246 tensor::Memory<float> pred_boxes_;
247 tensor::Memory<float> pred_logits_;
248 tensor::Memory<float> presence_logits_;
249
250 // Postprocess (Size: max_prompt_batch_)
251 tensor::Memory<float> filter_boxes_;
252 tensor::Memory<float> filter_scores_;
253 tensor::Memory<int> filter_indices_;
254 tensor::Memory<int> box_count_;
255 tensor::Memory<uint8_t> mask_buffer_;
257 box_affine_matrices_; // Matrix for each Box during Mask recovery
258
259 // Tokenizer
260 std::unique_ptr<tokenizers::Tokenizer> tokenizer_;
261};
262} // namespace reusex::vision::tensor_rt
static std::unique_ptr< TensorRTSam3 > create(const std::filesystem::path &model_path)
TensorRTSam3(const std::string &vision_encoder_path, const std::string &text_encoder_path, const std::string &geometry_encoder_path, const std::string &decoder_path, const std::string &tokenizer_path, int gpu_id)
std::vector< IDataset::Pair > forward(const std::span< IDataset::Pair > &input) override
bool setup_geometry_input(const cv::Mat &image, const std::string &label, const std::vector< std::pair< std::string, std::array< float, 4 > > > &boxes)
static std::string load_bytes_from_file(const std::string &file_path)
std::vector< DetectionBox > DetectionBoxArray
Convenience alias for a collection of DetectionBox results.
Definition object.hpp:216
static Norm alpha_beta(float alpha, float beta=0, ChannelType channel_type=ChannelType::None)