|
20 | 20 |
|
21 | 21 | import copy |
22 | 22 | import logging |
23 | | -import pathlib |
24 | 23 | import re |
25 | 24 | from typing import TYPE_CHECKING |
26 | 25 |
|
27 | 26 | if TYPE_CHECKING: |
28 | 27 | from typing import ( |
29 | 28 | Any, |
30 | 29 | Final, |
31 | | - List, |
32 | 30 | Mapping, |
33 | 31 | MutableMapping, |
34 | | - MutableSequence, |
35 | | - Sequence, |
36 | | - Set, |
37 | 32 | Tuple, |
38 | | - Union, |
39 | 33 | ) |
40 | 34 |
|
41 | 35 | from typing_extensions import ( |
|
44 | 38 |
|
45 | 39 | CPUInfo: TypeAlias = MutableMapping[str, Any] |
46 | 40 |
|
47 | | -import pandas as pd |
48 | | - |
49 | | -from .tdp_sources import ( |
50 | | - CRAWLERS_TDP_COLUMN, |
51 | | - HONORED_KEY_COLUMNS_CRAWLERS, |
52 | | -) |
53 | | - |
54 | 41 | CPU_DETAILS_FILENAME: "Final[str]" = "cpu_details.json" |
55 | 42 | CORE_AFFINITY_FILENAME: "Final[str]" = "core_affinity.json" |
56 | 43 | REFERENCE_PID_FILENAME: "Final[str]" = "reference_pid.txt" |
|
62 | 49 | COMMAND_TXT_FILENAME_TEMPLATE: "Final[str]" = "command-{0}_{1}.txt" |
63 | 50 | COMMAND_JSON_FILENAME_TEMPLATE: "Final[str]" = "command-{0}_{1}.json" |
64 | 51 |
|
65 | | -HONORED_KEY_COLUMNS_CPU_SPEC_DATASET: "Final[Sequence[str]]" = ( |
66 | | - "ProcessorNumber", |
67 | | - "Processor Number", |
68 | | - "Name", |
69 | | - "CpuName", |
70 | | -) |
71 | | - |
72 | | -HONORED_KEY_COLUMNS: "Final[Sequence[str]]" = ( |
73 | | - *HONORED_KEY_COLUMNS_CPU_SPEC_DATASET, |
74 | | - *HONORED_KEY_COLUMNS_CRAWLERS, |
75 | | -) |
76 | | - |
77 | 52 | logger = logging.getLogger(__name__) |
78 | 53 |
|
79 | 54 |
|
@@ -126,154 +101,3 @@ def parse_cpuinfo( |
126 | 101 | processor2corecpu[processor] = (physical_id, core_id) |
127 | 102 |
|
128 | 103 | return cpu_hash, processor2corecpu |
129 | | - |
130 | | - |
131 | | -def _tdp_finder_from_model_name( |
132 | | - model_name: "str", |
133 | | - key_column: "str", |
134 | | - cpus_df: "pd.DataFrame", |
135 | | - processors_file: "pathlib.Path", |
136 | | -) -> "Tuple[str, str, float, pathlib.Path]": |
137 | | - if key_column not in cpus_df: |
138 | | - errmsg = f"Unable to find a valid processor identification column in file {processors_file.as_posix()}" |
139 | | - logger.error(errmsg) |
140 | | - raise KeyError(errmsg) |
141 | | - elif ( |
142 | | - key_column in HONORED_KEY_COLUMNS_CRAWLERS |
143 | | - and CRAWLERS_TDP_COLUMN not in cpus_df |
144 | | - ): |
145 | | - errmsg = f"Unable to find a valid processor TDP column in file {processors_file.as_posix()}" |
146 | | - logger.error(errmsg) |
147 | | - raise KeyError(errmsg) |
148 | | - |
149 | | - filtered_cpus = cpus_df[cpus_df[key_column].apply(lambda pn: str(pn) in model_name)] |
150 | | - |
151 | | - if len(filtered_cpus) == 0: |
152 | | - errmsg = f"Unable to match a valid processor row for {model_name} in file {processors_file.as_posix()}" |
153 | | - logger.warning(errmsg) |
154 | | - raise LookupError(errmsg) |
155 | | - |
156 | | - matches: "List[Tuple[str, Union[str, float, int]]]" = [] |
157 | | - tried_match = False |
158 | | - if key_column in HONORED_KEY_COLUMNS_CRAWLERS: |
159 | | - column = filtered_cpus[CRAWLERS_TDP_COLUMN] |
160 | | - if not column.hasnans: |
161 | | - putative_tdp_val = column.values[0] |
162 | | - if isinstance(putative_tdp_val, (str, float, int)): |
163 | | - tried_match = True |
164 | | - matches.append((CRAWLERS_TDP_COLUMN, putative_tdp_val)) |
165 | | - else: |
166 | | - for column_name, column in filtered_cpus.items(): |
167 | | - if not column.hasnans: |
168 | | - putative_tdp_str = column.values[0] |
169 | | - if isinstance(putative_tdp_str, str): |
170 | | - tried_match = True |
171 | | - matched = re.search( |
172 | | - r"^(?:[0-9]+(?:\.[0-9]+])?-)?([0-9]+(?:\.[0-9]+])?) W", |
173 | | - putative_tdp_str, |
174 | | - ) |
175 | | - if matched: |
176 | | - matches.append((str(column_name), matched.group(1))) |
177 | | - |
178 | | - if len(matches) == 0: |
179 | | - if tried_match: |
180 | | - submsg = "found model description but not the consumption" |
181 | | - else: |
182 | | - submsg = "no match on model description" |
183 | | - errmsg = f"Unable to find processor package consumption values for {model_name} in file {processors_file.as_posix()} ({submsg})" |
184 | | - logger.warning(errmsg) |
185 | | - raise ValueError(errmsg) |
186 | | - elif len(matches) > 1: |
187 | | - # Now, sort by consumption |
188 | | - matches.sort(key=lambda t: t[1], reverse=True) |
189 | | - |
190 | | - return (model_name, matches[0][0], float(matches[0][1]), processors_file) |
191 | | - |
192 | | - |
193 | | -def tdp_finder_from_model_name( |
194 | | - model_name: "str", processors_files: "Sequence[pathlib.Path]" |
195 | | -) -> "Tuple[str, str, float, pathlib.Path]": |
196 | | - errors = [] |
197 | | - notfound = [] |
198 | | - for processors_file in processors_files: |
199 | | - # low_memory is needed to avoid a warning in some CSV files with mixed data |
200 | | - cpus = pd.read_csv(processors_file, low_memory=False) |
201 | | - |
202 | | - for key_column in HONORED_KEY_COLUMNS: |
203 | | - if key_column in cpus: |
204 | | - break |
205 | | - else: |
206 | | - errors.append( |
207 | | - f"Unable to find a valid processor identification column in file {processors_file.as_posix()}" |
208 | | - ) |
209 | | - continue |
210 | | - |
211 | | - try: |
212 | | - return _tdp_finder_from_model_name( |
213 | | - model_name, key_column, cpus, processors_file |
214 | | - ) |
215 | | - except LookupError: |
216 | | - # We are recovering for this case, where |
217 | | - errmsg = f"Nothing found for {model_name} under {key_column} in {processors_file.as_posix()}" |
218 | | - logger.debug(errmsg) |
219 | | - notfound.append(errmsg) |
220 | | - |
221 | | - if len(errors) > 0 or len(notfound) > 0: |
222 | | - for error in (*errors, *notfound): |
223 | | - logger.error(error) |
224 | | - |
225 | | - raise Exception() |
226 | | - |
227 | | - |
228 | | -def tdp_finder_from_cpuinfo( |
229 | | - cpu_details: "Sequence[CPUInfo]", processors_files: "Sequence[pathlib.Path]" |
230 | | -) -> "Sequence[Tuple[str, str, float, pathlib.Path]]": |
231 | | - # First, account for the number of different model names |
232 | | - unique_model_names: "Set[str]" = set() |
233 | | - for cpu_details_cpu in cpu_details: |
234 | | - model_name = cpu_details_cpu["model name"] |
235 | | - unique_model_names.add(model_name) |
236 | | - |
237 | | - errors = [] |
238 | | - found_tdp: "MutableSequence[Tuple[str, str, float, pathlib.Path]]" = [] |
239 | | - seen_model_names: "Set[str]" = set() |
240 | | - for processors_file in processors_files: |
241 | | - # low_memory is needed to avoid a warning in some CSV files with mixed data |
242 | | - cpus = pd.read_csv(processors_file, low_memory=False) |
243 | | - # print(f"COLUMNS {processors_file.as_posix()} {list(cpus.columns)}") |
244 | | - |
245 | | - for key_column in HONORED_KEY_COLUMNS: |
246 | | - if key_column in cpus: |
247 | | - break |
248 | | - else: |
249 | | - errors.append( |
250 | | - f"Unable to find a valid processor identification column in file {processors_file.as_posix()}" |
251 | | - ) |
252 | | - continue |
253 | | - |
254 | | - for model_name in unique_model_names: |
255 | | - if model_name not in seen_model_names: |
256 | | - try: |
257 | | - found_tdp.append( |
258 | | - _tdp_finder_from_model_name( |
259 | | - model_name, key_column, cpus, processors_file |
260 | | - ) |
261 | | - ) |
262 | | - seen_model_names.add(model_name) |
263 | | - except LookupError: |
264 | | - # We are recovering for this case, where |
265 | | - logger.debug( |
266 | | - f"Nothing found for {model_name} under {key_column} in {processors_file.as_posix()}" |
267 | | - ) |
268 | | - |
269 | | - # Once all matches are found, answer |
270 | | - if len(found_tdp) == len(unique_model_names): |
271 | | - break |
272 | | - |
273 | | - if len(found_tdp) == 0 and len(errors) > 0: |
274 | | - for error in errors: |
275 | | - logger.error(error) |
276 | | - |
277 | | - raise Exception() |
278 | | - |
279 | | - return found_tdp |
0 commit comments