33#include < gtest/gtest.h>
44#include < rnexecutorch/Error.h>
55#include < rnexecutorch/host_objects/JSTensorViewIn.h>
6- #include < rnexecutorch/models/semantic_segmentation/Constants.h>
7- #include < rnexecutorch/models/semantic_segmentation/SemanticSegmentation.h>
6+ #include < rnexecutorch/models/semantic_segmentation/BaseSemanticSegmentation.h>
87#include < string>
98#include < vector>
109
@@ -19,6 +18,18 @@ constexpr auto kValidSemanticSegmentationModelPath =
1918constexpr auto kValidTestImagePath =
2019 " file:///data/local/tmp/rnexecutorch_tests/test_image.jpg" ;
2120
21+ // DeepLab V3 class labels (Pascal VOC)
22+ static const std::vector<std::string> kDeeplabV3Labels = {
23+ " BACKGROUND" , " AEROPLANE" , " BICYCLE" , " BIRD" , " BOAT" ,
24+ " BOTTLE" , " BUS" , " CAR" , " CAT" , " CHAIR" ,
25+ " COW" , " DININGTABLE" , " DOG" , " HORSE" , " MOTORBIKE" ,
26+ " PERSON" , " POTTEDPLANT" , " SHEEP" , " SOFA" , " TRAIN" ,
27+ " TVMONITOR" };
28+
29+ // ImageNet normalization constants
30+ static const std::vector<float > kImageNetMean = {0 .485f , 0 .456f , 0 .406f };
31+ static const std::vector<float > kImageNetStd = {0 .229f , 0 .224f , 0 .225f };
32+
2233static JSTensorViewIn makeRgbView (std::vector<uint8_t > &buf, int32_t h,
2334 int32_t w) {
2435 buf.assign (static_cast <size_t >(h * w * 3 ), 128 );
@@ -30,8 +41,9 @@ static JSTensorViewIn makeRgbView(std::vector<uint8_t> &buf, int32_t h,
3041class SemanticSegmentationForwardTest : public ::testing::Test {
3142protected:
3243 void SetUp () override {
33- model = std::make_unique<SemanticSegmentation>(
34- kValidSemanticSegmentationModelPath , nullptr );
44+ model = std::make_unique<BaseSemanticSegmentation>(
45+ kValidSemanticSegmentationModelPath , kImageNetMean , kImageNetStd ,
46+ kDeeplabV3Labels , nullptr );
3547 auto shapes = model->getAllInputShapes (" forward" );
3648 ASSERT_FALSE (shapes.empty ());
3749 shape = shapes[0 ];
@@ -47,21 +59,24 @@ class SemanticSegmentationForwardTest : public ::testing::Test {
4759 make_tensor_ptr (sizes, dummyData.data (), exec_aten::ScalarType::Float);
4860 }
4961
50- std::unique_ptr<SemanticSegmentation > model;
62+ std::unique_ptr<BaseSemanticSegmentation > model;
5163 std::vector<int32_t > shape;
5264 std::vector<float > dummyData;
5365 std::vector<int32_t > sizes;
5466 TensorPtr inputTensor;
5567};
5668
5769TEST (SemanticSegmentationCtorTests, InvalidPathThrows) {
58- EXPECT_THROW (SemanticSegmentation (" this_file_does_not_exist.pte" , nullptr ),
70+ EXPECT_THROW (BaseSemanticSegmentation (" this_file_does_not_exist.pte" ,
71+ kImageNetMean , kImageNetStd ,
72+ kDeeplabV3Labels , nullptr ),
5973 RnExecutorchError);
6074}
6175
6276TEST (SemanticSegmentationCtorTests, ValidPathDoesntThrow) {
63- EXPECT_NO_THROW (
64- SemanticSegmentation (kValidSemanticSegmentationModelPath , nullptr ));
77+ EXPECT_NO_THROW (BaseSemanticSegmentation (kValidSemanticSegmentationModelPath ,
78+ kImageNetMean , kImageNetStd ,
79+ kDeeplabV3Labels , nullptr ));
6580}
6681
6782TEST_F (SemanticSegmentationForwardTest, ForwardWithValidTensorSucceeds) {
@@ -108,40 +123,52 @@ TEST_F(SemanticSegmentationForwardTest, ForwardAfterUnloadThrows) {
108123// generateFromString tests
109124// ============================================================================
110125TEST (SemanticSegmentationGenerateTests, InvalidImagePathThrows) {
111- SemanticSegmentation model (kValidSemanticSegmentationModelPath , nullptr );
126+ BaseSemanticSegmentation model (kValidSemanticSegmentationModelPath ,
127+ kImageNetMean , kImageNetStd , kDeeplabV3Labels ,
128+ nullptr );
112129 EXPECT_THROW (
113130 (void )model.generateFromString (" nonexistent_image.jpg" , {}, true ),
114131 RnExecutorchError);
115132}
116133
117134TEST (SemanticSegmentationGenerateTests, EmptyImagePathThrows) {
118- SemanticSegmentation model (kValidSemanticSegmentationModelPath , nullptr );
135+ BaseSemanticSegmentation model (kValidSemanticSegmentationModelPath ,
136+ kImageNetMean , kImageNetStd , kDeeplabV3Labels ,
137+ nullptr );
119138 EXPECT_THROW ((void )model.generateFromString (" " , {}, true ), RnExecutorchError);
120139}
121140
122141TEST (SemanticSegmentationGenerateTests, MalformedURIThrows) {
123- SemanticSegmentation model (kValidSemanticSegmentationModelPath , nullptr );
142+ BaseSemanticSegmentation model (kValidSemanticSegmentationModelPath ,
143+ kImageNetMean , kImageNetStd , kDeeplabV3Labels ,
144+ nullptr );
124145 EXPECT_THROW (
125146 (void )model.generateFromString (" not_a_valid_uri://bad" , {}, true ),
126147 RnExecutorchError);
127148}
128149
129150TEST (SemanticSegmentationGenerateTests, ValidImageNoFilterReturnsResult) {
130- SemanticSegmentation model (kValidSemanticSegmentationModelPath , nullptr );
151+ BaseSemanticSegmentation model (kValidSemanticSegmentationModelPath ,
152+ kImageNetMean , kImageNetStd , kDeeplabV3Labels ,
153+ nullptr );
131154 auto result = model.generateFromString (kValidTestImagePath , {}, true );
132155 EXPECT_NE (result.argmax , nullptr );
133156 EXPECT_NE (result.classBuffers , nullptr );
134157}
135158
136159TEST (SemanticSegmentationGenerateTests, ValidImageReturnsAllClasses) {
137- SemanticSegmentation model (kValidSemanticSegmentationModelPath , nullptr );
160+ BaseSemanticSegmentation model (kValidSemanticSegmentationModelPath ,
161+ kImageNetMean , kImageNetStd , kDeeplabV3Labels ,
162+ nullptr );
138163 auto result = model.generateFromString (kValidTestImagePath , {}, true );
139164 ASSERT_NE (result.classBuffers , nullptr );
140165 EXPECT_EQ (result.classBuffers ->size (), 21u );
141166}
142167
143168TEST (SemanticSegmentationGenerateTests, ClassFilterLimitsClassBuffers) {
144- SemanticSegmentation model (kValidSemanticSegmentationModelPath , nullptr );
169+ BaseSemanticSegmentation model (kValidSemanticSegmentationModelPath ,
170+ kImageNetMean , kImageNetStd , kDeeplabV3Labels ,
171+ nullptr );
145172 std::set<std::string, std::less<>> filter = {" PERSON" , " CAT" };
146173 auto result = model.generateFromString (kValidTestImagePath , filter, true );
147174 ASSERT_NE (result.classBuffers , nullptr );
@@ -152,7 +179,9 @@ TEST(SemanticSegmentationGenerateTests, ClassFilterLimitsClassBuffers) {
152179}
153180
154181TEST (SemanticSegmentationGenerateTests, ResizeFalseReturnsResult) {
155- SemanticSegmentation model (kValidSemanticSegmentationModelPath , nullptr );
182+ BaseSemanticSegmentation model (kValidSemanticSegmentationModelPath ,
183+ kImageNetMean , kImageNetStd , kDeeplabV3Labels ,
184+ nullptr );
156185 auto result = model.generateFromString (kValidTestImagePath , {}, false );
157186 EXPECT_NE (result.argmax , nullptr );
158187}
@@ -161,7 +190,9 @@ TEST(SemanticSegmentationGenerateTests, ResizeFalseReturnsResult) {
161190// generateFromPixels tests
162191// ============================================================================
163192TEST (SemanticSegmentationPixelTests, ValidPixelsNoFilterReturnsResult) {
164- SemanticSegmentation model (kValidSemanticSegmentationModelPath , nullptr );
193+ BaseSemanticSegmentation model (kValidSemanticSegmentationModelPath ,
194+ kImageNetMean , kImageNetStd , kDeeplabV3Labels ,
195+ nullptr );
165196 std::vector<uint8_t > buf;
166197 auto view = makeRgbView (buf, 64 , 64 );
167198 auto result = model.generateFromPixels (view, {}, true );
@@ -170,7 +201,9 @@ TEST(SemanticSegmentationPixelTests, ValidPixelsNoFilterReturnsResult) {
170201}
171202
172203TEST (SemanticSegmentationPixelTests, ValidPixelsReturnsAllClasses) {
173- SemanticSegmentation model (kValidSemanticSegmentationModelPath , nullptr );
204+ BaseSemanticSegmentation model (kValidSemanticSegmentationModelPath ,
205+ kImageNetMean , kImageNetStd , kDeeplabV3Labels ,
206+ nullptr );
174207 std::vector<uint8_t > buf;
175208 auto view = makeRgbView (buf, 64 , 64 );
176209 auto result = model.generateFromPixels (view, {}, true );
@@ -179,7 +212,9 @@ TEST(SemanticSegmentationPixelTests, ValidPixelsReturnsAllClasses) {
179212}
180213
181214TEST (SemanticSegmentationPixelTests, ClassFilterLimitsClassBuffers) {
182- SemanticSegmentation model (kValidSemanticSegmentationModelPath , nullptr );
215+ BaseSemanticSegmentation model (kValidSemanticSegmentationModelPath ,
216+ kImageNetMean , kImageNetStd , kDeeplabV3Labels ,
217+ nullptr );
183218 std::vector<uint8_t > buf;
184219 auto view = makeRgbView (buf, 64 , 64 );
185220 std::set<std::string, std::less<>> filter = {" PERSON" };
@@ -194,32 +229,42 @@ TEST(SemanticSegmentationPixelTests, ClassFilterLimitsClassBuffers) {
194229// Inherited BaseModel tests
195230// ============================================================================
196231TEST (SemanticSegmentationInheritedTests, GetInputShapeWorks) {
197- SemanticSegmentation model (kValidSemanticSegmentationModelPath , nullptr );
232+ BaseSemanticSegmentation model (kValidSemanticSegmentationModelPath ,
233+ kImageNetMean , kImageNetStd , kDeeplabV3Labels ,
234+ nullptr );
198235 auto shape = model.getInputShape (" forward" , 0 );
199236 EXPECT_EQ (shape.size (), 4 );
200237 EXPECT_EQ (shape[0 ], 1 ); // Batch size
201238 EXPECT_EQ (shape[1 ], 3 ); // RGB channels
202239}
203240
204241TEST (SemanticSegmentationInheritedTests, GetAllInputShapesWorks) {
205- SemanticSegmentation model (kValidSemanticSegmentationModelPath , nullptr );
242+ BaseSemanticSegmentation model (kValidSemanticSegmentationModelPath ,
243+ kImageNetMean , kImageNetStd , kDeeplabV3Labels ,
244+ nullptr );
206245 auto shapes = model.getAllInputShapes (" forward" );
207246 EXPECT_FALSE (shapes.empty ());
208247}
209248
210249TEST (SemanticSegmentationInheritedTests, GetMethodMetaWorks) {
211- SemanticSegmentation model (kValidSemanticSegmentationModelPath , nullptr );
250+ BaseSemanticSegmentation model (kValidSemanticSegmentationModelPath ,
251+ kImageNetMean , kImageNetStd , kDeeplabV3Labels ,
252+ nullptr );
212253 auto result = model.getMethodMeta (" forward" );
213254 EXPECT_TRUE (result.ok ());
214255}
215256
216257TEST (SemanticSegmentationInheritedTests, GetMemoryLowerBoundReturnsPositive) {
217- SemanticSegmentation model (kValidSemanticSegmentationModelPath , nullptr );
258+ BaseSemanticSegmentation model (kValidSemanticSegmentationModelPath ,
259+ kImageNetMean , kImageNetStd , kDeeplabV3Labels ,
260+ nullptr );
218261 EXPECT_GT (model.getMemoryLowerBound (), 0u );
219262}
220263
221264TEST (SemanticSegmentationInheritedTests, InputShapeIsSquare) {
222- SemanticSegmentation model (kValidSemanticSegmentationModelPath , nullptr );
265+ BaseSemanticSegmentation model (kValidSemanticSegmentationModelPath ,
266+ kImageNetMean , kImageNetStd , kDeeplabV3Labels ,
267+ nullptr );
223268 auto shape = model.getInputShape (" forward" , 0 );
224269 EXPECT_EQ (shape[2 ], shape[3 ]); // Height == Width for DeepLabV3
225270}
@@ -228,11 +273,11 @@ TEST(SemanticSegmentationInheritedTests, InputShapeIsSquare) {
228273// Constants tests
229274// ============================================================================
230275TEST (SemanticSegmentationConstantsTests, ClassLabelsHas21Entries) {
231- EXPECT_EQ (constants:: kDeeplabV3Resnet50Labels .size (), 21u );
276+ EXPECT_EQ (kDeeplabV3Labels .size (), 21u );
232277}
233278
234279TEST (SemanticSegmentationConstantsTests, ClassLabelsContainExpectedClasses) {
235- auto &labels = constants:: kDeeplabV3Resnet50Labels ;
280+ auto &labels = kDeeplabV3Labels ;
236281 bool hasBackground = false ;
237282 bool hasPerson = false ;
238283 bool hasCat = false ;
0 commit comments