1use bon::Builder;
2
3use crate::to_command::ToCommand;
4
5#[derive(Default, Builder)]
6pub struct NUMANodeMem {
7 mem_size: Option<usize>,
8 cpu_first: Option<usize>,
9 cpu_last: Option<usize>,
10 node_id: Option<usize>,
11 initiator: Option<usize>,
12}
13
14#[derive(Default, Builder)]
15pub struct NUMANodeMemDev {
16 mem_id: Option<usize>,
17 cpu_first: Option<usize>,
18 cpu_last: Option<usize>,
19 node_id: Option<usize>,
20 initiator: Option<usize>,
21}
22#[derive(Default, Builder)]
23pub struct NUMADist {
24 src: usize,
25 dst: usize,
26 val: usize,
27}
28
29#[derive(Default, Builder)]
30pub struct NUMACPU {
31 node_id: usize,
32 socket_id: Option<usize>,
33 core_id: Option<usize>,
34 thread_id: Option<usize>,
35}
36
37pub enum NUMAHierarchy {
38 Memory,
39 FirstLevel,
40 SecondLevel,
41 ThirdLevel,
42}
43pub enum NUMADataType {
44 AccessLatency,
45 ReadLatency,
46 WriteLatency,
47}
48
49#[derive(Builder)]
50pub struct NUMAHMATLb {
51 initiator: usize,
52 target: usize,
53 hierarchy: NUMAHierarchy,
54 data_type: NUMADataType,
55 latency: Option<usize>, bandwidth: Option<usize>, }
58
59pub enum HMATCacheAssociativity {
60 None,
61 Direct,
62 Complex,
63}
64pub enum HMATCachePolicy {
65 None,
66 WriteBack,
67 WriteThrough,
68}
69
70#[derive(Builder)]
71pub struct NUMAHMATCache {
72 node_id: usize,
73 size: usize,
74 level: usize,
75 associativity: Option<HMATCacheAssociativity>,
76 policy: Option<HMATCachePolicy>,
77 line: Option<usize>,
78}
79
80pub enum NUMA {
81 NodeMem(NUMANodeMem),
82 NodeMemDev(NUMANodeMemDev),
83 Dist(NUMADist),
84 Cpu(NUMACPU),
85 HMATLB(NUMAHMATLb),
86 HMATCache(NUMAHMATCache),
87}
88
89impl ToCommand for NUMA {
90 fn to_command(&self) -> Vec<String> {
91 let mut cmd = vec!["-numa".to_string()];
92
93 match self {
94 NUMA::NodeMem(node_mem) => {
95 let mut node_mem_args = "node".to_string();
96 if let Some(mem) = &node_mem.mem_size {
97 node_mem_args.push_str(format!(",mem={}", mem).as_str());
98 }
99 if let Some(cpu) = &node_mem.cpu_first {
100 node_mem_args.push_str(format!(",cpu={}", cpu).as_str());
101 }
102 if let Some(cpu) = &node_mem.cpu_last {
103 node_mem_args.push_str(format!("-{}", cpu).as_str());
104 }
105 if let Some(node_id) = &node_mem.node_id {
106 node_mem_args.push_str(format!(",nodeid={}", node_id).as_str());
107 }
108 if let Some(initiator) = &node_mem.initiator {
109 node_mem_args.push_str(format!(",initiator={}", initiator).as_str());
110 }
111 cmd.push(node_mem_args.to_string());
112 }
113 NUMA::NodeMemDev(node_memdev) => {
114 let mut node_memdev_args = "node".to_string();
115 if let Some(memdev) = &node_memdev.mem_id {
116 node_memdev_args.push_str(format!(",memdev={}", memdev).as_str());
117 }
118 if let Some(cpu) = &node_memdev.cpu_first {
119 node_memdev_args.push_str(format!(",cpu={}", cpu).as_str());
120 }
121 if let Some(cpu) = &node_memdev.cpu_last {
122 node_memdev_args.push_str(format!("-{}", cpu).as_str());
123 }
124 if let Some(node_id) = &node_memdev.node_id {
125 node_memdev_args.push_str(format!(",nodeid={}", node_id).as_str());
126 }
127 if let Some(initiator) = &node_memdev.initiator {
128 node_memdev_args.push_str(format!(",initiator={}", initiator).as_str());
129 }
130 cmd.push(node_memdev_args.to_string());
131 }
132 NUMA::Dist(dist) => {
133 cmd.push(format!(
134 "dist,src={},dst={},val={}",
135 dist.src, dist.dst, dist.val
136 ));
137 }
138 NUMA::Cpu(cpu) => {
139 let mut cpu_args = "cpu".to_string();
140
141 cpu_args.push_str(format!(",node-id={}", cpu.node_id).as_str());
142 if let Some(socket_id) = &cpu.socket_id {
143 cpu_args.push_str(format!(",socket-id={}", socket_id).as_str());
144 }
145 if let Some(core_id) = &cpu.core_id {
146 cpu_args.push_str(format!(",core-id={}", core_id).as_str());
147 }
148 if let Some(thread_id) = &cpu.thread_id {
149 cpu_args.push_str(format!(",thread-id={}", thread_id).as_str());
150 }
151 cmd.push(cpu_args.to_string());
152 }
153 NUMA::HMATLB(hmat_lb) => {
154 let mut hmat_lb_args = "hmat-lb".to_string();
155 hmat_lb_args.push_str(
156 format!(
157 ",initiator={},target={},hierarchy=",
158 hmat_lb.initiator, hmat_lb.target
159 )
160 .as_str(),
161 );
162 match hmat_lb.hierarchy {
163 NUMAHierarchy::Memory => hmat_lb_args.push_str("memory"),
164 NUMAHierarchy::FirstLevel => hmat_lb_args.push_str("first-level"),
165 NUMAHierarchy::SecondLevel => hmat_lb_args.push_str("second-level"),
166 NUMAHierarchy::ThirdLevel => hmat_lb_args.push_str("third-level"),
167 }
168 hmat_lb_args.push_str("data-type=");
169 match hmat_lb.data_type {
170 NUMADataType::AccessLatency => hmat_lb_args.push_str("access-latency"),
171 NUMADataType::ReadLatency => hmat_lb_args.push_str("read-latency"),
172 NUMADataType::WriteLatency => hmat_lb_args.push_str("write-latency"),
173 }
174 if let Some(lat) = &hmat_lb.latency {
175 hmat_lb_args.push_str(format!(",latency={}", lat).as_str());
176 }
177 if let Some(bw) = &hmat_lb.bandwidth {
178 hmat_lb_args.push_str(format!(",bandwidth={}", bw).as_str());
179 }
180 cmd.push(hmat_lb_args);
181 }
182 NUMA::HMATCache(hmat_cache) => {
183 let mut hmat_cache_args = "hmat-cache".to_string();
184 hmat_cache_args.push_str(
185 format!(
186 ",node-id={},size={},level={}",
187 hmat_cache.node_id, hmat_cache.size, hmat_cache.level
188 )
189 .as_str(),
190 );
191 if let Some(assoc) = &hmat_cache.associativity {
192 hmat_cache_args.push_str(",associativity=");
193 match assoc {
194 HMATCacheAssociativity::None => hmat_cache_args.push_str("none"),
195 HMATCacheAssociativity::Direct => hmat_cache_args.push_str("direct"),
196 HMATCacheAssociativity::Complex => hmat_cache_args.push_str("complex"),
197 }
198 }
199 if let Some(policy) = &hmat_cache.policy {
200 hmat_cache_args.push_str(",policy=");
201 match policy {
202 HMATCachePolicy::None => hmat_cache_args.push_str("none"),
203 HMATCachePolicy::WriteBack => hmat_cache_args.push_str("write-back"),
204 HMATCachePolicy::WriteThrough => hmat_cache_args.push_str("write-through"),
205 }
206 }
207 if let Some(line) = &hmat_cache.line {
208 hmat_cache_args.push_str(format!(",line={}", line).as_str());
209 }
210 }
211 }
212 cmd
213 }
214}