Return cluster topology as JSON.
(
state: web::Data<Arc<RwLock<Master<M>>>>,
req: HttpRequest,
)
| 83 | |
| 84 | /// Return cluster topology as JSON. |
| 85 | pub async fn topology<M: Model>( |
| 86 | state: web::Data<Arc<RwLock<Master<M>>>>, |
| 87 | req: HttpRequest, |
| 88 | ) -> HttpResponse { |
| 89 | if !check_ui_auth(&state, &req).await { |
| 90 | return HttpResponse::Unauthorized() |
| 91 | .insert_header(("WWW-Authenticate", "Basic realm=\"cake\"")) |
| 92 | .body("Unauthorized"); |
| 93 | } |
| 94 | |
| 95 | let master = state.read().await; |
| 96 | let ctx = &master.ctx; |
| 97 | |
| 98 | let num_layers = ctx |
| 99 | .config |
| 100 | .as_ref() |
| 101 | .map(|c| c.num_hidden_layers) |
| 102 | .unwrap_or(0); |
| 103 | |
| 104 | // Estimate per-layer size from safetensors index |
| 105 | let layer_size_bytes = estimate_layer_size(&ctx.data_path, num_layers); |
| 106 | |
| 107 | // Collect worker layers from topology |
| 108 | let mut worker_layer_set = HashSet::new(); |
| 109 | let mut workers = Vec::new(); |
| 110 | |
| 111 | for (name, node) in ctx.topology.iter() { |
| 112 | for layer in &node.layers { |
| 113 | worker_layer_set.insert(layer.clone()); |
| 114 | } |
| 115 | workers.push(WorkerTopologyInfo { |
| 116 | name: name.clone(), |
| 117 | host: node.host.clone(), |
| 118 | description: node.description.clone(), |
| 119 | layers: node.layers.clone(), |
| 120 | vram_bytes: node.vram_bytes, |
| 121 | tflops: node.tflops, |
| 122 | backend: node.backend.clone(), |
| 123 | hostname: node.hostname.clone(), |
| 124 | os: node.os.clone(), |
| 125 | }); |
| 126 | } |
| 127 | |
| 128 | // Derive layer prefix from config |
| 129 | let layer_prefix = ctx |
| 130 | .config |
| 131 | .as_ref() |
| 132 | .map(|c| format!("{}.layers", c.model_prefix)) |
| 133 | .unwrap_or_else(|| "model.layers".to_string()); |
| 134 | |
| 135 | // Master layers = all layers not assigned to workers |
| 136 | let master_layers: Vec<String> = (0..num_layers) |
| 137 | .map(|i| format!("{layer_prefix}.{i}")) |
| 138 | .filter(|l| !worker_layer_set.contains(l)) |
| 139 | .collect(); |
| 140 | |
| 141 | let device = if ctx.device.is_cuda() { |
| 142 | "cuda" |
nothing calls this directly
no test coverage detected