Skip to content

Commit 068bd07

Browse files
yutingyemeta-codesync[bot]
authored andcommitted
Make character tests deterministic with seeded RNG (#1558)
Summary: Pull Request resolved: #1558 Make character tests draw random inputs from fixed, test-owned `Random<>` engines instead of the shared singleton helpers. Thread `Random<>` through blend-shape test helpers and character test helpers so random data generation is deterministic and local to each test/helper call. Reviewed By: cstollmeta Differential Revision: D110375520 fbshipit-source-id: a52ecd80be20e47fc9eb096785252e0e50341d56
1 parent 1e92d56 commit 068bd07

3 files changed

Lines changed: 68 additions & 59 deletions

File tree

momentum/test/character/blend_shape_test.cpp

Lines changed: 41 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -18,32 +18,32 @@ using Types = testing::Types<float, double>;
1818
template <typename T>
1919
struct BlendShapeTest : testing::Test {
2020
using Type = T;
21+
Random<> rng{12345};
2122
};
2223

2324
TYPED_TEST_SUITE(BlendShapeTest, Types);
2425

2526
// Helper function to create random vertices
2627
template <typename T>
27-
std::vector<Eigen::Vector3<T>> createRandomVertices(size_t count) {
28+
std::vector<Eigen::Vector3<T>> createRandomVertices(Random<>& rng, size_t count) {
2829
std::vector<Eigen::Vector3<T>> vertices;
2930
vertices.reserve(count);
3031
for (size_t i = 0; i < count; ++i) {
31-
vertices.push_back(uniform<Eigen::Vector3<T>>(T(-1), T(1)));
32+
vertices.push_back(rng.template uniform<Eigen::Vector3<T>>(T(-1), T(1)));
3233
}
3334
return vertices;
3435
}
3536

3637
// Helper function to create random blend weights
3738
template <typename T>
38-
BlendWeightsT<T> createRandomBlendWeights(size_t count) {
39+
BlendWeightsT<T> createRandomBlendWeights(Random<>& rng, size_t count) {
3940
BlendWeightsT<T> weights;
40-
weights.v = uniform<VectorX<T>>(count, T(-1), T(1));
41+
weights.v = rng.template uniform<VectorX<T>>(count, T(-1), T(1));
4142
return weights;
4243
}
4344

4445
// Tests for BlendShapeBase
4546
TEST(BlendShapeTest, BlendShapeBaseConstruction) {
46-
Random<>::GetSingleton().setSeed(12345);
4747
const size_t modelSize = 10;
4848
const size_t numShapes = 5;
4949

@@ -56,14 +56,14 @@ TEST(BlendShapeTest, BlendShapeBaseConstruction) {
5656
}
5757

5858
TEST(BlendShapeTest, BlendShapeBaseSetShapeVector) {
59-
Random<>::GetSingleton().setSeed(12345);
59+
Random<> rng{12345};
6060
const size_t modelSize = 10;
6161
const size_t numShapes = 5;
6262

6363
BlendShapeBase blendShapeBase(modelSize, numShapes);
6464

6565
// Create a random shape vector
66-
std::vector<Vector3f> shapeVector = createRandomVertices<float>(modelSize);
66+
std::vector<Vector3f> shapeVector = createRandomVertices<float>(rng, modelSize);
6767

6868
// Set the shape vector at index 2
6969
blendShapeBase.setShapeVector(2, shapeVector);
@@ -78,7 +78,6 @@ TEST(BlendShapeTest, BlendShapeBaseSetShapeVector) {
7878
}
7979

8080
TYPED_TEST(BlendShapeTest, BlendShapeBaseComputeDeltas) {
81-
Random<>::GetSingleton().setSeed(12345);
8281
using T = typename TestFixture::Type;
8382

8483
const size_t modelSize = 10;
@@ -89,13 +88,13 @@ TYPED_TEST(BlendShapeTest, BlendShapeBaseComputeDeltas) {
8988
// Create and set random shape vectors
9089
std::vector<std::vector<Vector3f>> shapeVectors;
9190
for (size_t i = 0; i < numShapes; ++i) {
92-
std::vector<Vector3f> shapeVector = createRandomVertices<float>(modelSize);
91+
std::vector<Vector3f> shapeVector = createRandomVertices<float>(this->rng, modelSize);
9392
shapeVectors.push_back(shapeVector);
9493
blendShapeBase.setShapeVector(i, shapeVector);
9594
}
9695

9796
// Create random blend weights
98-
BlendWeightsT<T> blendWeights = createRandomBlendWeights<T>(numShapes);
97+
BlendWeightsT<T> blendWeights = createRandomBlendWeights<T>(this->rng, numShapes);
9998

10099
// Compute deltas
101100
VectorX<T> deltas = blendShapeBase.computeDeltas(blendWeights);
@@ -120,7 +119,6 @@ TYPED_TEST(BlendShapeTest, BlendShapeBaseComputeDeltas) {
120119
}
121120

122121
TYPED_TEST(BlendShapeTest, BlendShapeBaseApplyDeltas) {
123-
Random<>::GetSingleton().setSeed(12345);
124122
using T = typename TestFixture::Type;
125123

126124
const size_t modelSize = 10;
@@ -131,16 +129,16 @@ TYPED_TEST(BlendShapeTest, BlendShapeBaseApplyDeltas) {
131129
// Create and set random shape vectors
132130
std::vector<std::vector<Vector3f>> shapeVectors;
133131
for (size_t i = 0; i < numShapes; ++i) {
134-
std::vector<Vector3f> shapeVector = createRandomVertices<float>(modelSize);
132+
std::vector<Vector3f> shapeVector = createRandomVertices<float>(this->rng, modelSize);
135133
shapeVectors.push_back(shapeVector);
136134
blendShapeBase.setShapeVector(i, shapeVector);
137135
}
138136

139137
// Create random blend weights
140-
BlendWeightsT<T> blendWeights = createRandomBlendWeights<T>(numShapes);
138+
BlendWeightsT<T> blendWeights = createRandomBlendWeights<T>(this->rng, numShapes);
141139

142140
// Create base shape
143-
std::vector<Eigen::Vector3<T>> baseShape = createRandomVertices<T>(modelSize);
141+
std::vector<Eigen::Vector3<T>> baseShape = createRandomVertices<T>(this->rng, modelSize);
144142
std::vector<Eigen::Vector3<T>> result = baseShape;
145143

146144
// Apply deltas
@@ -165,12 +163,12 @@ TYPED_TEST(BlendShapeTest, BlendShapeBaseApplyDeltas) {
165163

166164
// Tests for BlendShape
167165
TEST(BlendShapeTest, BlendShapeConstruction) {
168-
Random<>::GetSingleton().setSeed(12345);
166+
Random<> rng{12345};
169167
const size_t modelSize = 10;
170168
const size_t numShapes = 5;
171169

172170
// Create a random base shape
173-
std::vector<Vector3f> baseShape = createRandomVertices<float>(modelSize);
171+
std::vector<Vector3f> baseShape = createRandomVertices<float>(rng, modelSize);
174172

175173
BlendShape blendShape(baseShape, numShapes);
176174

@@ -190,17 +188,17 @@ TEST(BlendShapeTest, BlendShapeConstruction) {
190188
}
191189

192190
TEST(BlendShapeTest, BlendShapeSetBaseShape) {
193-
Random<>::GetSingleton().setSeed(12345);
191+
Random<> rng{12345};
194192
const size_t modelSize = 10;
195193
const size_t numShapes = 5;
196194

197195
// Create a random base shape
198-
std::vector<Vector3f> baseShape1 = createRandomVertices<float>(modelSize);
196+
std::vector<Vector3f> baseShape1 = createRandomVertices<float>(rng, modelSize);
199197

200198
BlendShape blendShape(baseShape1, numShapes);
201199

202200
// Create a new random base shape
203-
std::vector<Vector3f> baseShape2 = createRandomVertices<float>(modelSize);
201+
std::vector<Vector3f> baseShape2 = createRandomVertices<float>(rng, modelSize);
204202

205203
// Set the new base shape
206204
blendShape.setBaseShape(baseShape2);
@@ -214,27 +212,26 @@ TEST(BlendShapeTest, BlendShapeSetBaseShape) {
214212
}
215213

216214
TYPED_TEST(BlendShapeTest, BlendShapeComputeShape) {
217-
Random<>::GetSingleton().setSeed(12345);
218215
using T = typename TestFixture::Type;
219216

220217
const size_t modelSize = 10;
221218
const size_t numShapes = 5;
222219

223220
// Create a random base shape
224-
std::vector<Vector3f> baseShape = createRandomVertices<float>(modelSize);
221+
std::vector<Vector3f> baseShape = createRandomVertices<float>(this->rng, modelSize);
225222

226223
BlendShape blendShape(baseShape, numShapes);
227224

228225
// Create and set random shape vectors
229226
std::vector<std::vector<Vector3f>> shapeVectors;
230227
for (size_t i = 0; i < numShapes; ++i) {
231-
std::vector<Vector3f> shapeVector = createRandomVertices<float>(modelSize);
228+
std::vector<Vector3f> shapeVector = createRandomVertices<float>(this->rng, modelSize);
232229
shapeVectors.push_back(shapeVector);
233230
blendShape.setShapeVector(i, shapeVector);
234231
}
235232

236233
// Create random blend weights
237-
BlendWeightsT<T> blendWeights = createRandomBlendWeights<T>(numShapes);
234+
BlendWeightsT<T> blendWeights = createRandomBlendWeights<T>(this->rng, numShapes);
238235

239236
// Compute shape
240237
std::vector<Eigen::Vector3<T>> shape = blendShape.computeShape(blendWeights);
@@ -274,25 +271,25 @@ TYPED_TEST(BlendShapeTest, BlendShapeComputeShape) {
274271
}
275272

276273
TEST(BlendShapeTest, BlendShapeEstimateCoefficients) {
277-
Random<>::GetSingleton().setSeed(12345);
274+
Random<> rng{12345};
278275
const size_t modelSize = 10;
279276
const size_t numShapes = 5;
280277

281278
// Create a random base shape
282-
std::vector<Vector3f> baseShape = createRandomVertices<float>(modelSize);
279+
std::vector<Vector3f> baseShape = createRandomVertices<float>(rng, modelSize);
283280

284281
BlendShape blendShape(baseShape, numShapes);
285282

286283
// Create and set random shape vectors
287284
std::vector<std::vector<Vector3f>> shapeVectors;
288285
for (size_t i = 0; i < numShapes; ++i) {
289-
std::vector<Vector3f> shapeVector = createRandomVertices<float>(modelSize);
286+
std::vector<Vector3f> shapeVector = createRandomVertices<float>(rng, modelSize);
290287
shapeVectors.push_back(shapeVector);
291288
blendShape.setShapeVector(i, shapeVector);
292289
}
293290

294291
// Create known blend weights
295-
auto knownCoefficients = uniform<VectorXf>(numShapes, -1.f, 1.f);
292+
auto knownCoefficients = rng.uniform<VectorXf>(numShapes, -1.f, 1.f);
296293
BlendWeightsT<float> blendWeights;
297294
blendWeights.v = knownCoefficients;
298295

@@ -325,17 +322,17 @@ TEST(BlendShapeTest, BlendShapeEstimateCoefficients) {
325322
}
326323

327324
TEST(BlendShapeTest, BlendShapeSetShapeVector) {
328-
Random<>::GetSingleton().setSeed(12345);
325+
Random<> rng{12345};
329326
const size_t modelSize = 10;
330327
const size_t numShapes = 5;
331328

332329
// Create a random base shape
333-
std::vector<Vector3f> baseShape = createRandomVertices<float>(modelSize);
330+
std::vector<Vector3f> baseShape = createRandomVertices<float>(rng, modelSize);
334331

335332
BlendShape blendShape(baseShape, numShapes);
336333

337334
// Create a random shape vector
338-
std::vector<Vector3f> shapeVector = createRandomVertices<float>(modelSize);
335+
std::vector<Vector3f> shapeVector = createRandomVertices<float>(rng, modelSize);
339336

340337
// Set the shape vector at index 2
341338
blendShape.setShapeVector(2, shapeVector);
@@ -352,7 +349,7 @@ TEST(BlendShapeTest, BlendShapeSetShapeVector) {
352349
EXPECT_FALSE(blendShape.getFactorizationValid());
353350

354351
// Force factorization to be computed
355-
std::vector<Vector3f> targetShape = createRandomVertices<float>(modelSize);
352+
std::vector<Vector3f> targetShape = createRandomVertices<float>(rng, modelSize);
356353
(void)blendShape.estimateCoefficients(targetShape);
357354

358355
// Check that factorization is now valid
@@ -366,19 +363,19 @@ TEST(BlendShapeTest, BlendShapeSetShapeVector) {
366363
}
367364

368365
TEST(BlendShapeTest, BlendShapeIsApprox) {
369-
Random<>::GetSingleton().setSeed(12345);
366+
Random<> rng{12345};
370367
const size_t modelSize = 10;
371368
const size_t numShapes = 5;
372369

373370
// Create a random base shape
374-
std::vector<Vector3f> baseShape = createRandomVertices<float>(modelSize);
371+
std::vector<Vector3f> baseShape = createRandomVertices<float>(rng, modelSize);
375372

376373
BlendShape blendShape1(baseShape, numShapes);
377374

378375
// Create and set random shape vectors
379376
std::vector<std::vector<Vector3f>> shapeVectors;
380377
for (size_t i = 0; i < numShapes; ++i) {
381-
std::vector<Vector3f> shapeVector = createRandomVertices<float>(modelSize);
378+
std::vector<Vector3f> shapeVector = createRandomVertices<float>(rng, modelSize);
382379
shapeVectors.push_back(shapeVector);
383380
blendShape1.setShapeVector(i, shapeVector);
384381
}
@@ -393,15 +390,15 @@ TEST(BlendShapeTest, BlendShapeIsApprox) {
393390
EXPECT_TRUE(blendShape1.isApprox(blendShape2));
394391

395392
// Modify the second blend shape
396-
std::vector<Vector3f> differentBaseShape = createRandomVertices<float>(modelSize);
393+
std::vector<Vector3f> differentBaseShape = createRandomVertices<float>(rng, modelSize);
397394
blendShape2.setBaseShape(differentBaseShape);
398395

399396
// Check that the blend shapes are no longer approximately equal
400397
EXPECT_FALSE(blendShape1.isApprox(blendShape2));
401398

402399
// Reset the base shape but modify a shape vector
403400
blendShape2.setBaseShape(baseShape);
404-
std::vector<Vector3f> differentShapeVector = createRandomVertices<float>(modelSize);
401+
std::vector<Vector3f> differentShapeVector = createRandomVertices<float>(rng, modelSize);
405402
blendShape2.setShapeVector(0, differentShapeVector);
406403

407404
// Check that the blend shapes are no longer approximately equal
@@ -410,7 +407,6 @@ TEST(BlendShapeTest, BlendShapeIsApprox) {
410407

411408
// Test edge cases
412409
TEST(BlendShapeTest, EdgeCases) {
413-
Random<>::GetSingleton().setSeed(12345);
414410
// Test with empty base shape and no shape vectors
415411
BlendShape emptyBlendShape;
416412
EXPECT_EQ(emptyBlendShape.modelSize(), 0);
@@ -444,43 +440,43 @@ TEST(BlendShapeTest, EdgeCases) {
444440

445441
// Test error cases
446442
TEST(BlendShapeTest, ErrorCases) {
447-
Random<>::GetSingleton().setSeed(12345);
443+
Random<> rng{12345};
448444
const size_t modelSize = 10;
449445
const size_t numShapes = 5;
450446

451447
// Create a random base shape
452-
std::vector<Vector3f> baseShape = createRandomVertices<float>(modelSize);
448+
std::vector<Vector3f> baseShape = createRandomVertices<float>(rng, modelSize);
453449

454450
BlendShape blendShape(baseShape, numShapes);
455451

456452
// Test setting a shape vector with wrong size
457-
std::vector<Vector3f> wrongSizeShapeVector = createRandomVertices<float>(modelSize + 1);
453+
std::vector<Vector3f> wrongSizeShapeVector = createRandomVertices<float>(rng, modelSize + 1);
458454

459455
// This should trigger an assertion failure, but we can't test that directly in gtest
460456
// Just documenting that this would be an error case
461457

462458
// Test estimating coefficients with wrong size vertices
463-
std::vector<Vector3f> wrongSizeVertices = createRandomVertices<float>(modelSize + 1);
459+
std::vector<Vector3f> wrongSizeVertices = createRandomVertices<float>(rng, modelSize + 1);
464460

465461
// This should trigger an assertion failure, but we can't test that directly in gtest
466462
// Just documenting that this would be an error case
467463

468464
// Test with blend weights that have more coefficients than shape vectors
469465
BlendWeightsT<float> tooManyWeights;
470-
tooManyWeights.v = uniform<VectorXf>(numShapes + 1, -1.f, 1.f);
466+
tooManyWeights.v = rng.uniform<VectorXf>(numShapes + 1, -1.f, 1.f);
471467

472468
// This should trigger an assertion failure, but we can't test that directly in gtest
473469
// Just documenting that this would be an error case
474470
}
475471

476472
// Test with different sizes
477473
TEST(BlendShapeTest, DifferentSizes) {
478-
Random<>::GetSingleton().setSeed(12345);
474+
Random<> rng{12345};
479475
// Test with a larger model
480476
const size_t largeModelSize = 1000;
481477
const size_t numShapes = 10;
482478

483-
std::vector<Vector3f> baseShape = createRandomVertices<float>(largeModelSize);
479+
std::vector<Vector3f> baseShape = createRandomVertices<float>(rng, largeModelSize);
484480
BlendShape largeBlendShape(baseShape, numShapes);
485481

486482
EXPECT_EQ(largeBlendShape.modelSize(), largeModelSize);
@@ -490,15 +486,14 @@ TEST(BlendShapeTest, DifferentSizes) {
490486
const size_t modelSize = 10;
491487
const size_t manyShapes = 100;
492488

493-
baseShape = createRandomVertices<float>(modelSize);
489+
baseShape = createRandomVertices<float>(rng, modelSize);
494490
BlendShape manyShapesBlendShape(baseShape, manyShapes);
495491

496492
EXPECT_EQ(manyShapesBlendShape.modelSize(), modelSize);
497493
EXPECT_EQ(manyShapesBlendShape.shapeSize(), manyShapes);
498494
}
499495

500496
TEST(BlendShapeTest, BlendShapeNames) {
501-
Random<>::GetSingleton().setSeed(12345);
502497
const size_t modelSize = 10;
503498
const size_t numShapes = 5;
504499

0 commit comments

Comments
 (0)