Overhaul rack system with split FLOPS, VRAM, cooling, interconnect, and multi-vendor SKUs
CI / build-and-push (push) Successful in 29s
CI / build-and-push (push) Successful in 29s
Expand from 10 to 18 rack SKUs across NVIDIA, AMD, and custom ASIC vendors, each with distinct training vs inference FLOPS, VRAM capacity, cooling requirements, and interconnect technology. Adds cooling hierarchy (air/liquid/immersion) that gates rack deployment, VRAM requirements that gate model training by generation, interconnect multipliers for distributed training scaling, and PUE-based energy cost reduction for advanced cooling. Includes save migration from v4 to v5, 6 new research nodes, and UI updates showing split compute stats. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,7 @@ import type {
|
||||
GameState, InfrastructureState, Cluster, Campus, DataCenter,
|
||||
DeploymentCohort, PipelineStage, RackSkuId, NetworkSwitch,
|
||||
SwitchTier, DCNetworkSummary, CampusNetworkSummary, ClusterNetworkSummary,
|
||||
CampusRetrofitQueue, DCTier,
|
||||
CampusRetrofitQueue, DCTier, IntraNodeInterconnect, NetworkFabric, RackSkuConfig,
|
||||
} from '@ai-tycoon/shared';
|
||||
import {
|
||||
LOCATION_CONFIGS,
|
||||
@@ -19,6 +19,8 @@ import {
|
||||
T3_COUNT_PER_DC_TIER,
|
||||
SWITCH_REPAIR_COST_FRACTION,
|
||||
NETWORK_DEGRADATION,
|
||||
COOLING_TYPE_CONFIGS,
|
||||
NETWORK_FABRIC_CONFIGS,
|
||||
estimateNetworkSlots,
|
||||
} from '@ai-tycoon/shared';
|
||||
import type { TickNotification } from '../tick';
|
||||
@@ -435,6 +437,30 @@ function processNetworkTick(
|
||||
return { switchRepairCosts, notifications, dirty };
|
||||
}
|
||||
|
||||
// --- Interconnect Training Multiplier ---
|
||||
|
||||
const INTRA_NODE_BONUS: Record<IntraNodeInterconnect, number> = {
|
||||
'pcie-gen4': 0.0,
|
||||
'pcie-gen5': 0.05,
|
||||
'nvlink-3': 0.15,
|
||||
'nvlink-4': 0.25,
|
||||
'nvlink-5': 0.35,
|
||||
'nvlink-domain': 0.50,
|
||||
'infinity-fabric': 0.10,
|
||||
'custom-mesh': 0.40,
|
||||
};
|
||||
|
||||
function computeInterconnectMultiplier(
|
||||
sku: RackSkuConfig,
|
||||
rackCount: number,
|
||||
fabric: NetworkFabric,
|
||||
): number {
|
||||
if (rackCount <= 1) return 1.0;
|
||||
const intra = INTRA_NODE_BONUS[sku.intraNodeInterconnect] ?? 0;
|
||||
const fabricBonus = NETWORK_FABRIC_CONFIGS[fabric].trainingScalingBonus;
|
||||
return Math.min(1.0, 0.6 + intra + fabricBonus);
|
||||
}
|
||||
|
||||
// --- Main Infrastructure Tick ---
|
||||
|
||||
export function processInfrastructure(state: GameState): InfraTickResult {
|
||||
@@ -463,6 +489,9 @@ export function processInfrastructure(state: GameState): InfraTickResult {
|
||||
notifications.push(...netResult.notifications);
|
||||
|
||||
let totalFlops = 0;
|
||||
let totalTrainingFlops = 0;
|
||||
let totalInferenceFlops = 0;
|
||||
let totalVramGB = 0;
|
||||
let totalUptime = 0;
|
||||
let totalRackCount = 0;
|
||||
let totalComputeRackCount = 0;
|
||||
@@ -684,14 +713,23 @@ export function processInfrastructure(state: GameState): InfraTickResult {
|
||||
|
||||
let usedPowerKW = 0;
|
||||
let dcFlops = 0;
|
||||
let dcTrainingFlops = 0;
|
||||
let dcInferenceFlops = 0;
|
||||
let dcTotalVramGB = 0;
|
||||
if (dc.rackSkuId && computeRacksOnline > 0) {
|
||||
const sku = RACK_SKU_CONFIGS[dc.rackSkuId];
|
||||
usedPowerKW = computeRacksOnline * sku.powerDrawKW;
|
||||
dcFlops = effectiveComputeRacks * sku.flopsPerRack * networkSummary.effectiveFlopsFraction;
|
||||
const bwFraction = networkSummary.effectiveFlopsFraction;
|
||||
const interconnectMult = computeInterconnectMultiplier(sku, effectiveComputeRacks, dc.networkFabric);
|
||||
dcTrainingFlops = effectiveComputeRacks * sku.trainingFlops * bwFraction * interconnectMult;
|
||||
dcInferenceFlops = effectiveComputeRacks * sku.inferenceFlops * bwFraction;
|
||||
dcTotalVramGB = computeRacksOnline * sku.totalVramGB;
|
||||
dcFlops = dcTrainingFlops + dcInferenceFlops;
|
||||
}
|
||||
|
||||
const pue = COOLING_TYPE_CONFIGS[dc.coolingType].pueMultiplier;
|
||||
const energyCostPerTick = (tierConfig.baseEnergyCostPerTick + usedPowerKW * BASE_ENERGY_COST_PER_FLOP)
|
||||
* location.energyCostMultiplier;
|
||||
* location.energyCostMultiplier * pue;
|
||||
const maintenanceCostPerTick = totalRacksInDc * BASE_MAINTENANCE_PER_RACK;
|
||||
const currentUptime = totalRacksInDc > 0 ? effectiveComputeRacks / totalRacksInDc : 1;
|
||||
|
||||
@@ -703,6 +741,9 @@ export function processInfrastructure(state: GameState): InfraTickResult {
|
||||
}
|
||||
|
||||
totalFlops += dcFlops;
|
||||
totalTrainingFlops += dcTrainingFlops;
|
||||
totalInferenceFlops += dcInferenceFlops;
|
||||
totalVramGB += dcTotalVramGB;
|
||||
totalRackCount += totalRacksInDc + netSlots;
|
||||
totalComputeRackCount += totalRacksInDc;
|
||||
totalDataCenterCount++;
|
||||
@@ -714,6 +755,7 @@ export function processInfrastructure(state: GameState): InfraTickResult {
|
||||
deploymentCohorts: updatedCohorts,
|
||||
networkSummary, effectiveComputeRacks,
|
||||
usedSlots, usedPowerKW, energyCostPerTick, maintenanceCostPerTick, currentUptime,
|
||||
dcTrainingFlops, dcInferenceFlops, dcTotalVramGB,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -788,6 +830,9 @@ export function processInfrastructure(state: GameState): InfraTickResult {
|
||||
clusters,
|
||||
switchRegistry: registry,
|
||||
totalFlops,
|
||||
totalTrainingFlops,
|
||||
totalInferenceFlops,
|
||||
totalVramGB,
|
||||
totalUptime: dcWithRacks > 0 ? totalUptime / dcWithRacks : 1,
|
||||
totalRackCount,
|
||||
totalComputeRackCount,
|
||||
|
||||
Reference in New Issue
Block a user