Model validation: the rigid-body engines on every card in turn, even where this card has room for all
The engines past this card's first now go one card after the other, from the next card and this one last, each within half of its own budget, as MR's do. Before, this card took every extra engine it had room for and the other cards only the rest, so a small cell on four cards ran all its fits on one. Where this card has no room for a second engine (a large cell on 15.6 GB cards) the plan is unchanged: 1/3/3/3. This card's scale fits take the room its engines leave. Engines are interchangeable and deterministic, so only where fits run changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4
This commit is contained in:
1 parent
b004a846dd
commit
3fa17b9385
3 files changed
+36
-20
No files matched your search
@@ -1909,30 +1909,33 @@ ModelValidationGPUPlan PlanModelValidationGPU(const ModelValidationGPUNeed &need
|
||||
plan.null_structure_factors = take(need.null_structure_factors, plan.budget);
|
||||
plan.scale_fit_engines = need.scale_fit_engines > 0 && take(need.scale_fit, plan.budget) ? 1 : 0;
|
||||
|
||||
// More engines only within half of the budget (see the declaration).
|
||||
// More engines only within half of the budget (see the declaration). The rigid body's past this card's first go
|
||||
// one card after the other in turn, from the next card and this one last, so that the fits run on every card
|
||||
// even where this one alone has room for them all.
|
||||
const auto room = [&](size_t budget) { return std::min(budget / 2, budget > need.beside ? budget - need.beside : 0); };
|
||||
while (plan.rigid_body_engines > 0 && plan.rigid_body_engines < need.rigid_body_engines
|
||||
&& take(need.rigid_body, room(plan.budget)))
|
||||
plan.rigid_body_engines++;
|
||||
while (plan.scale_fit_engines > 0 && plan.scale_fit_engines < need.scale_fit_engines
|
||||
&& take(need.scale_fit, room(plan.budget)))
|
||||
plan.scale_fit_engines++;
|
||||
|
||||
// The rigid-body engines this card has no room for, on the other cards in turn.
|
||||
plan.rigid_body_per_card.assign(1 + need.other_cards.size(), 0);
|
||||
plan.rigid_body_per_card[0] = plan.rigid_body_engines;
|
||||
std::vector<size_t> held(plan.rigid_body_per_card.size(), 0);
|
||||
held[0] = plan.bytes;
|
||||
for (bool added = plan.rigid_body_engines > 0; added;) {
|
||||
added = false;
|
||||
for (size_t k = 1; k < held.size() && plan.rigid_body_engines < need.rigid_body_engines; k++)
|
||||
if (held[k] + need.rigid_body <= room(ModelGPUBudget(need.other_cards[k - 1], need.resident))) {
|
||||
for (size_t i = 1; i <= held.size() && plan.rigid_body_engines < need.rigid_body_engines; i++) {
|
||||
const size_t k = i % held.size(); // this card last in each turn
|
||||
const bool fits = k == 0 ? take(need.rigid_body, room(plan.budget))
|
||||
: held[k] + need.rigid_body
|
||||
<= room(ModelGPUBudget(need.other_cards[k - 1], need.resident));
|
||||
if (!fits)
|
||||
continue;
|
||||
if (k > 0)
|
||||
held[k] += need.rigid_body;
|
||||
plan.rigid_body_per_card[k]++;
|
||||
plan.rigid_body_engines++;
|
||||
added = true;
|
||||
}
|
||||
plan.rigid_body_per_card[k]++;
|
||||
plan.rigid_body_engines++;
|
||||
added = true;
|
||||
}
|
||||
}
|
||||
while (plan.scale_fit_engines > 0 && plan.scale_fit_engines < need.scale_fit_engines
|
||||
&& take(need.scale_fit, room(plan.budget)))
|
||||
plan.scale_fit_engines++;
|
||||
held[0] = plan.bytes;
|
||||
plan.most_on_a_card = *std::max_element(held.begin(), held.end());
|
||||
|
||||
const size_t cards = held.size();
|
||||
|
||||
@@ -329,10 +329,11 @@ size_t ModelGPUBudget(size_t card, size_t resident);
|
||||
// only within half of the budget, less what a validation beside holds: they change only how many fits
|
||||
// run at once, and buy little - on a large cell a fit already fills the card (measured on a 16 GB card:
|
||||
// 13.6 s with one rigid-body engine, 13.1 s with two, 12.6 s with five) - so the card keeps headroom
|
||||
// rather than filling with them. Where this card has no room for all the rigid-body engines the
|
||||
// validation can use, the rest go on the other cards, one card after the other in turn, each by the same
|
||||
// rule against its own budget (80% of its total, less what is resident): this card's parts are decided as
|
||||
// on a machine with this card alone, and how many cards there are changes only where fits run. A second
|
||||
// rather than filling with them. The rigid-body engines past this card's first go one card after the other
|
||||
// in turn, from the next card and this one last, each by the same rule against its own budget (80% of its
|
||||
// total, less what is resident), so that the fits run on every card even where this one has room for them
|
||||
// all; this card's other parts are decided as on a machine with this card alone (its scale fits in the room
|
||||
// its engines leave), and how many cards there are changes only where fits run. A second
|
||||
// validation may run beside where twice the whole of this one's GPU parts, at every engine it can use, fits
|
||||
// the budgets of the cards together, and twice what this one holds on any card fits every card's budget.
|
||||
ModelValidationGPUPlan PlanModelValidationGPU(const ModelValidationGPUNeed &need);
|
||||
|
||||
@@ -197,6 +197,18 @@ TEST_CASE("ModelValidation_GPUPlanEnginesOnOtherCards", "[ModelValidation]") {
|
||||
// One card alone: the plan as it was.
|
||||
CHECK(alone.rigid_body_per_card == std::vector<size_t>{1});
|
||||
CHECK(alone.most_on_a_card == alone.bytes);
|
||||
|
||||
// Engines this card alone has room for still go on every card in turn: ten of 0.1 GB on four cards, from the
|
||||
// next card and this one last.
|
||||
need = LargeCellNeed(card);
|
||||
need.other_cards = {card, card, card};
|
||||
need.rigid_body = 100000000;
|
||||
const ModelValidationGPUPlan small = PlanModelValidationGPU(need);
|
||||
CHECK(small.rigid_body_per_card == std::vector<size_t>{3, 3, 2, 2});
|
||||
CHECK(small.rigid_body_engines == 10);
|
||||
CHECK(small.scale_fit_engines == 4);
|
||||
need.other_cards.clear();
|
||||
CHECK(PlanModelValidationGPU(need).rigid_body_per_card == std::vector<size_t>{10});
|
||||
}
|
||||
|
||||
TEST_CASE("ModelValidation_GPUPlanPartThatDoesNotFitGoesToTheCPU", "[ModelValidation]") {
|
||||
|
||||
Reference in new issue
Block a user