Skip to content

Commit 9a5298f

Browse files
committed
Add stress tests for shared container with 8 and 12 segments
Two new SegmentationTest cases that exercise the shared IrContainer under higher concurrent load than existing tests (max 3 segments): - SharedContainerStress8Segments: linear chain with 7 segment_set boundaries, 8 segments compiling in parallel - SharedContainerStress12ParallelBranches: 4 inputs x 3 independent reductions each, at least 6 segments compiling in parallel Both pass with correct results, validating the shared_ptr + mutex infrastructure under real multi-thread contention.
1 parent ea7db55 commit 9a5298f

1 file changed

Lines changed: 84 additions & 0 deletions

File tree

tests/cpp/test_segmentation.cpp

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,4 +1034,88 @@ TEST_F(SegmentationTest, ReshapeWithCrossSegmentExtent) {
10341034
executor_cache.fusion(), outputs, {t_a, t_b}, __LINE__, __FILE__);
10351035
}
10361036

1037+
// Stress test: 8 segments sharing one IrContainer via segmenter container
1038+
// sharing. Exercises parallel compilation with 8 concurrent threads all
1039+
// registering vals/exprs into the same shared container.
1040+
TEST_F(SegmentationTest, SharedContainerStress8Segments) {
1041+
auto fusion = std::make_unique<Fusion>();
1042+
FusionGuard fg(fusion.get());
1043+
1044+
// Build a linear chain with 7 segment_set boundaries → 8 segments.
1045+
// Each segment does a different pointwise op to keep them distinct.
1046+
auto tv0 = makeContigConcreteTensor({1024, 256}, DataType::Float);
1047+
fusion->addInput(tv0);
1048+
1049+
auto tv = relu(tv0);
1050+
tv = segment_set(tv);
1051+
tv = neg(tv);
1052+
tv = segment_set(tv);
1053+
tv = sin(tv);
1054+
tv = segment_set(tv);
1055+
tv = relu(tv);
1056+
tv = segment_set(tv);
1057+
tv = neg(tv);
1058+
tv = segment_set(tv);
1059+
tv = sin(tv);
1060+
tv = segment_set(tv);
1061+
tv = relu(tv);
1062+
tv = segment_set(tv);
1063+
tv = neg(tv);
1064+
fusion->addOutput(tv);
1065+
1066+
auto options = at::TensorOptions().dtype(at::kFloat).device(at::kCUDA, 0);
1067+
at::Tensor t0 = at::randn({1024, 256}, options);
1068+
1069+
FusionExecutorCache executor_cache(std::move(fusion));
1070+
auto outputs = executor_cache.runFusionWithInputs({t0});
1071+
1072+
FusionKernelRuntime* runtime = executor_cache.getMostRecentKernelRuntime();
1073+
EXPECT_THAT(runtime->fusionSegments()->groups(), SizeIs(8));
1074+
1075+
testValidate(executor_cache.fusion(), outputs, {t0}, __LINE__, __FILE__);
1076+
}
1077+
1078+
// Stress test: 12 parallel branches each producing a segment via independent
1079+
// reductions. Unlike the linear chain above, this creates 12 segments that
1080+
// can all compile simultaneously, maximizing concurrent lock contention on the
1081+
// shared IrContainer.
1082+
TEST_F(SegmentationTest, SharedContainerStress12ParallelBranches) {
1083+
auto fusion = std::make_unique<Fusion>();
1084+
FusionGuard fg(fusion.get());
1085+
1086+
// 4 inputs, each feeds 3 independent reductions on different axes.
1087+
// Reductions on different axes cannot be merged → separate segments.
1088+
std::vector<TensorView*> inputs;
1089+
for (int i = 0; i < 4; i++) {
1090+
auto tv = makeContigConcreteTensor({64, 128, 32}, DataType::Float);
1091+
fusion->addInput(tv);
1092+
inputs.push_back(tv);
1093+
}
1094+
1095+
for (int i = 0; i < 4; i++) {
1096+
// Each input → 3 reductions on axes 0, 1, 2
1097+
for (int axis = 0; axis < 3; axis++) {
1098+
auto r = sum(inputs[i], {axis});
1099+
fusion->addOutput(r);
1100+
}
1101+
}
1102+
1103+
auto options = at::TensorOptions().dtype(at::kFloat).device(at::kCUDA, 0);
1104+
std::vector<c10::IValue> aten_inputs;
1105+
for (int i = 0; i < 4; i++) {
1106+
aten_inputs.push_back(at::randn({64, 128, 32}, options));
1107+
}
1108+
1109+
FusionExecutorCache executor_cache(std::move(fusion));
1110+
auto outputs = executor_cache.runFusionWithInputs(aten_inputs);
1111+
1112+
FusionKernelRuntime* runtime = executor_cache.getMostRecentKernelRuntime();
1113+
// Expect at least 6 segments (the segmenter may merge some compatible
1114+
// reductions, but incompatible reduction axes force separate segments)
1115+
EXPECT_GE(runtime->fusionSegments()->groups().size(), 6);
1116+
1117+
testValidate(
1118+
executor_cache.fusion(), outputs, aten_inputs, __LINE__, __FILE__);
1119+
}
1120+
10371121
} // namespace nvfuser

0 commit comments

Comments
 (0)