ReUseX
0.0.5
3D Point Cloud Processing for Building Reuse
Toggle main menu visibility
Loading...
Searching...
No Matches
BackendFactory.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/core/logging.hpp"
7
#include "reusex/vision/IMLBackend.hpp"
8
9
#ifdef REUSEX_USE_LIBTORCH
10
#include "reusex/vision/libtorch/Backend.hpp"
11
#endif
12
13
#ifdef REUSEX_USE_TENSORRT
14
#include "reusex/vision/tensor_rt/Backend.hpp"
15
#endif
16
17
#ifdef REUSEX_USE_ONNX
18
#include "reusex/vision/onnx/Backend.hpp"
19
#endif
20
21
#ifdef REUSEX_USE_OPENVINO
22
#include "reusex/vision/openvino/Backend.hpp"
23
#endif
24
25
#include <fmt/std.h>
26
27
#include <algorithm>
28
#include <cctype>
29
#include <filesystem>
30
31
namespace
reusex::vision
{
32
enum class
Backend
{
33
opencv
,
34
tensor_rt
,
35
libtorch
,
36
dnn
,
37
onnx_runtime
,
38
openvino
,
39
unknown
,
40
};
41
42
class
BackendFactory
{
43
public
:
44
/* Detects the model type from the model path.
45
*
46
* Inspects the path stem and, for directories, contained file names.
47
* Detection is case-insensitive:
48
* - name containing "sam3.1"/"sam3p1" -> Model::sam3p1
49
* - "sam3" or "sam2" in the name -> Model::sam3
50
* - directory with vision-encoder + tracker engines -> Model::sam3p1
51
* - directory containing "vision-encoder.*" -> Model::sam3
52
* - otherwise -> Model::yolo
53
*
54
* @param model_path: The file or directory path of the model.
55
* @return The detected model type.
56
*/
57
static
Model
detect_model
(
const
std::filesystem::path &model_path) {
58
auto
to_lower = [](std::string s) {
59
std::transform(s.begin(), s.end(), s.begin(),
60
[](
unsigned
char
c) { return std::tolower(c); });
61
return
s;
62
};
63
64
// Check directory/file name itself. A "sam3.1"/"sam3p1" name shortcut
65
// selects the video tracker; check it BEFORE the plain sam3/sam2 shortcut.
66
// Use filename() not stem(): a directory named "sam3.1-video" has stem()
67
// == "sam3" (".1-video" parsed as an extension), which would mis-route it
68
// to the plain sam3 path and skip the tracker.
69
auto
name = to_lower(model_path.filename().string());
70
if
(name.find(
"sam3.1"
) != std::string::npos ||
71
name.find(
"sam3p1"
) != std::string::npos) {
72
reusex::info
(
"Detected SAM3.1 model from path name: {}"
, model_path);
73
return
Model::sam3p1
;
74
}
75
if
(name.find(
"sam3"
) != std::string::npos ||
76
name.find(
"sam2"
) != std::string::npos) {
77
reusex::info
(
"Detected SAM3 model from path name: {}"
, model_path);
78
return
Model::sam3
;
79
}
80
81
// For directories, inspect contained filenames. SAM 3.1 additionally ships
82
// the tracker engines; require vision-encoder + memory-encoder +
83
// memory-attention and return sam3p1 BEFORE the plain-sam3 return.
84
if
(std::filesystem::is_directory(model_path)) {
85
bool
has_vision =
false
, has_mem_encoder =
false
,
86
has_mem_attention =
false
;
87
for
(
const
auto
&entry :
88
std::filesystem::directory_iterator(model_path)) {
89
auto
stem = to_lower(entry.path().stem().string());
90
if
(stem.find(
"vision-encoder"
) != std::string::npos)
91
has_vision =
true
;
92
if
(stem.find(
"tracker-memory-encoder"
) != std::string::npos)
93
has_mem_encoder =
true
;
94
if
(stem.find(
"tracker-memory-attention"
) != std::string::npos)
95
has_mem_attention =
true
;
96
}
97
if
(has_vision && has_mem_encoder && has_mem_attention) {
98
reusex::info
(
99
"Detected SAM3.1 video model (tracker engines present): {}"
,
100
model_path);
101
return
Model::sam3p1
;
102
}
103
if
(has_vision) {
104
reusex::info
(
"Detected SAM3 model from sub-model files: {}"
,
105
model_path);
106
return
Model::sam3
;
107
}
108
}
109
110
reusex::info
(
"Defaulting to YOLO model type for path: {}"
, model_path);
111
return
Model::yolo
;
112
}
113
114
/* Detects the appropriate backend based on the model path.
115
* @param model_path: The file or directory path of the model.
116
* @return The detected backend type.
117
*/
118
static
Backend
detect_backend
(
const
std::filesystem::path &model_path) {
119
using namespace
std::filesystem;
120
121
if
(is_regular_file(model_path))
122
return
detect_backend_from_file(model_path);
123
124
if
(is_directory(model_path))
125
for
(
const
auto
&entry : directory_iterator(model_path))
126
if
(entry.is_regular_file())
127
if
(
auto
backend = detect_backend_from_file(entry.path());
128
backend !=
Backend::unknown
)
129
return
backend;
130
131
return
Backend::unknown
;
132
}
133
134
/* Creates an instance of the specified backend type.
135
* @param type: The backend type to create.
136
* @return A unique pointer to the created backend instance.
137
* @throws std::runtime_error if the backend type is not implemented or
138
* unsupported.
139
*/
140
static
std::unique_ptr<IMLBackend>
create
(
Backend
type) {
141
switch
(type) {
142
case
Backend::opencv
:
143
reusex::error
(
"OpenCV backend is not implemented yet."
);
144
throw
std::runtime_error(
"OpenCV backend not implemented"
);
145
146
case
Backend::tensor_rt
:
147
#ifdef REUSEX_USE_TENSORRT
148
return
std::make_unique<reusex::vision::tensor_rt::TensorRTBackend>();
149
#else
150
reusex::error
(
"TensorRT backend not compiled in this build. "
151
"Rebuild with -DML_BACKENDS=TensorRT or AUTO."
);
152
throw
std::runtime_error(
"TensorRT backend not available"
);
153
#endif
154
155
case
Backend::libtorch
:
156
#ifdef REUSEX_USE_LIBTORCH
157
return
std::make_unique<reusex::vision::libtorch::LibTorchBackend>();
158
#else
159
reusex::error
(
"LibTorch backend not compiled in this build. "
160
"Rebuild with -DML_BACKENDS=LibTorch or AUTO."
);
161
throw
std::runtime_error(
"LibTorch backend not available"
);
162
#endif
163
164
case
Backend::dnn
:
165
reusex::error
(
"DNN backend is not implemented yet."
);
166
throw
std::runtime_error(
"DNN backend not implemented"
);
167
168
case
Backend::onnx_runtime
:
169
#ifdef REUSEX_USE_ONNX
170
return
std::make_unique<reusex::vision::onnx::ONNXBackend>();
171
#else
172
reusex::error
(
"ONNX Runtime backend is not implemented yet."
);
173
throw
std::runtime_error(
"ONNX Runtime backend not implemented"
);
174
#endif
175
176
case
Backend::openvino
:
177
#ifdef REUSEX_USE_OPENVINO
178
return
std::make_unique<reusex::vision::openvino::OpenVINOBackend>();
179
#else
180
reusex::error
(
"OpenVINO backend is not implemented yet."
);
181
throw
std::runtime_error(
"OpenVINO backend not implemented"
);
182
#endif
183
184
default
:
185
reusex::error
(
"Unsupported backend type: {}"
,
static_cast<
int
>
(type));
186
throw
std::runtime_error(
"Unsupported backend"
);
187
}
188
}
189
190
private
:
191
/* Helper function to detect backend type from a single file based on its
192
* extension.
193
* @param file_path: The path of the file to analyze.
194
* @return The detected backend type or unknown if the extension is not
195
* recognized.
196
*/
197
static
Backend
198
detect_backend_from_file(
const
std::filesystem::path &file_path) {
199
auto
ext = file_path.extension();
200
201
if
(ext.empty()) {
202
reusex::warn
(
"File {} has no extension. Unable to detect backend."
,
203
file_path);
204
return
Backend::unknown
;
205
}
206
207
else
if
(ext ==
".engine"
) {
208
reusex::info
(
"Detected TensorRT engine file: {}"
, file_path);
209
#ifndef REUSEX_USE_TENSORRT
210
reusex::warn
(
"TensorRT detected but not compiled in this build. Backend "
211
"unavailable."
);
212
#endif
213
return
Backend::tensor_rt
;
214
}
else
if
(ext ==
".pt"
|| ext ==
".pth"
|| ext ==
".torchscript"
) {
215
reusex::info
(
"Detected PyTorch model file: {}"
, file_path);
216
#ifndef REUSEX_USE_LIBTORCH
217
reusex::warn
(
"LibTorch detected but not compiled in this build. Backend "
218
"unavailable."
);
219
#endif
220
return
Backend::libtorch
;
221
}
else
if
(ext ==
".onnx"
) {
222
reusex::info
(
"Detected ONNX model file: {}"
, file_path);
223
#ifndef REUSEX_USE_ONNX
224
reusex::warn
(
"ONNX Runtime detected but not compiled in this build. "
225
"Backend unavailable."
);
226
#endif
227
return
Backend::onnx_runtime
;
228
}
else
if
(ext ==
".xml"
|| ext ==
".bin"
) {
229
reusex::info
(
"Detected OpenVINO model files: {}"
, file_path);
230
#ifndef REUSEX_USE_OPENVINO
231
reusex::warn
(
"OpenVINO detected but not compiled in this build. Backend "
232
"unavailable."
);
233
#endif
234
return
Backend::openvino
;
235
}
236
237
reusex::warn
(
"Unknown model file extension: {}. Unable to detect backend; "
238
"returning Backend::unknown."
,
239
ext);
240
return
Backend::unknown
;
241
}
242
};
243
}
// namespace reusex::vision
reusex::vision::BackendFactory
Definition
BackendFactory.hpp:42
reusex::vision::BackendFactory::detect_model
static Model detect_model(const std::filesystem::path &model_path)
Definition
BackendFactory.hpp:57
reusex::vision::BackendFactory::detect_backend
static Backend detect_backend(const std::filesystem::path &model_path)
Definition
BackendFactory.hpp:118
reusex::vision::BackendFactory::create
static std::unique_ptr< IMLBackend > create(Backend type)
Definition
BackendFactory.hpp:140
reusex::vision::libtorch
Definition
Backend.hpp:10
reusex::vision::tensor_rt
Definition
Backend.hpp:11
reusex::vision
Definition
annotate.hpp:12
reusex::vision::Backend
Backend
Definition
BackendFactory.hpp:32
reusex::vision::Backend::dnn
@ dnn
Definition
BackendFactory.hpp:36
reusex::vision::Backend::openvino
@ openvino
Definition
BackendFactory.hpp:38
reusex::vision::Backend::tensor_rt
@ tensor_rt
Definition
BackendFactory.hpp:34
reusex::vision::Backend::onnx_runtime
@ onnx_runtime
Definition
BackendFactory.hpp:37
reusex::vision::Backend::opencv
@ opencv
Definition
BackendFactory.hpp:33
reusex::vision::Backend::unknown
@ unknown
Definition
BackendFactory.hpp:39
reusex::vision::Backend::libtorch
@ libtorch
Definition
BackendFactory.hpp:35
reusex::vision::Model
Model
Definition
IMLBackend.hpp:15
reusex::vision::Model::sam3p1
@ sam3p1
Definition
IMLBackend.hpp:15
reusex::vision::Model::yolo
@ yolo
Definition
IMLBackend.hpp:15
reusex::vision::Model::sam3
@ sam3
Definition
IMLBackend.hpp:15
reusex::warn
void warn(fmt::format_string< Args... > format, Args &&...args)
Definition
logging.hpp:93
reusex::error
void error(fmt::format_string< Args... > format, Args &&...args)
Definition
logging.hpp:100
reusex::info
void info(fmt::format_string< Args... > format, Args &&...args)
Definition
logging.hpp:86
libs
reusex
include
vision
BackendFactory.hpp
Generated by
1.17.0