1use serde::{Deserialize, Serialize};
8use std::collections::BTreeMap;
9
10#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
12pub struct TensorShard {
13 pub dim: usize,
15 pub ranks: Vec<u32>,
17}
18
19#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
21pub struct ExpertPlacement {
22 pub rank: u32,
24 #[serde(default, skip_serializing_if = "Vec::is_empty")]
26 pub replicas: Vec<u32>,
27}
28
29#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
31pub struct Placement {
32 #[serde(default, skip_serializing_if = "Vec::is_empty")]
34 pub parallelism: Vec<String>,
35 #[serde(default, skip_serializing_if = "Option::is_none")]
36 pub world_size: Option<u32>,
37 #[serde(default, skip_serializing_if = "Option::is_none")]
38 pub topology: Option<String>,
39 #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
41 pub tensors: BTreeMap<String, TensorShard>,
42 #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
44 pub experts: BTreeMap<String, ExpertPlacement>,
45}
46
47impl Placement {
48 pub fn ranks_for(&self, tensor: &str) -> Option<&[u32]> {
50 self.tensors.get(tensor).map(|s| s.ranks.as_slice())
51 }
52
53 pub fn has_tensor_map(&self) -> bool {
55 !self.tensors.is_empty() || !self.experts.is_empty()
56 }
57}