Skip to content
This repository was archived by the owner on Jan 18, 2023. It is now read-only.

Commit 0588698

Browse files
pbrownlow7lmdaly
authored andcommitted
Add support for SST-CP features (#260)
* Add support for SST-CP features
1 parent e3df769 commit 0588698

File tree

3 files changed

+170
-2
lines changed

3 files changed

+170
-2
lines changed

intel/init.py

Lines changed: 114 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
from . import config, topology, discover, sst_bf as sst
15+
from . import config, topology, discover, sst_bf as sst, sst_cp as cp
1616
import logging
1717
import sys
1818

@@ -39,14 +39,88 @@ def init(conf_dir, num_exclusive_cores, num_shared_cores,
3939
logging.info("Could not read SST-BF label from the node metadata: {}"
4040
.format(err))
4141

42+
sst_cp = False
43+
try:
44+
sst_cp = discover.get_node_label(cp.NFD_LABEL) in ["true", "True"]
45+
except Exception as err:
46+
logging.info("Could not read SST-CP label from the node metadata: {}"
47+
.format(err))
48+
49+
if sst_bf and sst_cp:
50+
logging.error("SST-BF and SST-CP are mutually exclusive features in "
51+
"CMK, please disable one or both.")
52+
sys.exit(1)
53+
4254
platform = topology.discover(sst_bf)
4355

4456
# List of intel.topology.Core objects.
4557
cores = platform.get_cores()
4658

4759
check_isolated_cores(platform, num_exclusive_cores, num_shared_cores)
4860

49-
if sst_bf and platform.has_isolated_sst_bf_cores():
61+
if sst_cp and platform.has_isolated_cores():
62+
epp_order = cp.get_epp_order(platform)
63+
64+
if len(epp_order) > 3:
65+
logging.error("There must not be more than 3 EPP values "
66+
"among the cores. EPP values present: {}"
67+
.format(", ".join(epp_order)))
68+
sys.exit(1)
69+
70+
check_sst_cp_isolated_cores(platform, num_exclusive_cores,
71+
num_shared_cores, epp_order)
72+
logging.info("EPP order: {}".format(", ".join(epp_order)))
73+
74+
if len(epp_order) == 3:
75+
sst_cp_exclusive_cores = platform.get_epp_cores(
76+
epp_order[0], num_exclusive_cores)
77+
sst_cp_shared_cores = platform.get_epp_cores(
78+
epp_order[1], num_shared_cores)
79+
sst_cp_infra_cores = platform.get_epp_cores_no_limit(
80+
epp_order[2])
81+
82+
logging.info("Isolated SST-CP exclusive cores (EPP value:"
83+
" {}): {}".format(epp_order[0], ",".join(
84+
[str(c.core_id) for c in sst_cp_exclusive_cores])))
85+
logging.info("Isolated SST-CP shared cores (EPP value: {}"
86+
"): {}".format(epp_order[1], ",".join(
87+
[str(c.core_id) for c in sst_cp_shared_cores])))
88+
logging.info("SST-CP infra cores (EPP value: {}): {}"
89+
.format(epp_order[2], ",".join([str(c.core_id)
90+
for c in sst_cp_infra_cores])))
91+
elif len(epp_order) == 2:
92+
logging.info("Only two EPP values set; exclusive and "
93+
"shared pools will take all of the cores "
94+
"of the highest EPP value")
95+
sst_cp_exclusive_cores = platform.get_epp_cores(
96+
epp_order[0], num_exclusive_cores)
97+
sst_cp_shared_cores = platform.get_epp_cores(
98+
epp_order[0], num_shared_cores, sst_cp_exclusive_cores)
99+
sst_cp_infra_cores = platform.get_epp_cores_no_limit(
100+
epp_order[1])
101+
102+
logging.info("Isolated SST-CP exclusive cores (EPP value: {}): {}"
103+
.format(epp_order[0], ",".join([str(c.core_id)
104+
for c in sst_cp_exclusive_cores])))
105+
logging.info("Isolated SST-CP shared cores (EPP value: {}): {}"
106+
.format(epp_order[0], ",".join([str(c.core_id)
107+
for c in sst_cp_shared_cores])))
108+
logging.info("SST-CP infra cores (EPP value {}): {}"
109+
.format(epp_order[1], ",".join([str(c.core_id)
110+
for c in sst_cp_infra_cores])))
111+
else:
112+
logging.error("There must be either 2 or 3 EPP values set among "
113+
"the cores. EPP values present: {}".format(
114+
", ".join(epp_order)))
115+
sys.exit(1)
116+
117+
assign(sst_cp_exclusive_cores, "exclusive",
118+
count=num_exclusive_cores)
119+
assign(sst_cp_shared_cores, "shared",
120+
count=num_shared_cores)
121+
assign(sst_cp_infra_cores, "infra")
122+
123+
elif sst_bf and platform.has_isolated_sst_bf_cores():
50124
sst_bf_cores = [str(c.core_id) for c
51125
in platform.get_isolated_sst_bf_cores()]
52126
logging.info("Isolated SST-BF physical cores: {}".format(
@@ -172,6 +246,44 @@ def check_isolated_cores(platform, num_exclusive_cores, num_shared_cores):
172246
(num_isolated_cores, required_isolated_cores))
173247

174248

249+
def check_sst_cp_isolated_cores(platform, num_exclusive_cores,
250+
num_shared_cores, epp_order):
251+
error_occured = False
252+
253+
if len(epp_order) == 3:
254+
exclusive_cores = platform.get_epp_cores_no_limit(epp_order[0])
255+
shared_cores = platform.get_epp_cores_no_limit(epp_order[1])
256+
257+
if num_exclusive_cores != len(exclusive_cores):
258+
logging.error("Number of requested exclusive cores must"
259+
" match the number of cores with EPP value"
260+
" %s. Exclusive cores %d compared to requested %d"
261+
% (epp_order[0], len(exclusive_cores),
262+
num_exclusive_cores))
263+
error_occured = True
264+
265+
if num_shared_cores != len(shared_cores):
266+
logging.error("Number of requested shared cores must"
267+
" match the number of cores with EPP value"
268+
" %s. Shared cores %d compared to requested %d"
269+
% (epp_order[1], len(shared_cores),
270+
num_shared_cores))
271+
error_occured = True
272+
elif len(epp_order) == 2:
273+
requested_cores = num_exclusive_cores + num_shared_cores
274+
cores = platform.get_epp_cores_no_limit(epp_order[0])
275+
276+
if len(cores) != requested_cores:
277+
logging.error("Requested number of isolated cores "
278+
"should match number of cores with EPP "
279+
"value %s. %d cores requested. %d cores available",
280+
epp_order[0], requested_cores, len(cores))
281+
error_occured = True
282+
283+
if error_occured:
284+
sys.exit(1)
285+
286+
175287
def assign(cores, pool, count=None):
176288
free_cores = [c for c in cores if c.pool is None]
177289

intel/sst_cp.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
CPU_EPP_PATH = "/sys/devices/system/cpu/cpu{}/cpufreq\
2+
/energy_performance_preference"
3+
4+
NFD_LABEL = "feature.node.kubernetes.io/cpu-power.sst_cp.enabled"
5+
6+
7+
def get_epp_order(platform):
8+
epp_order = ["performance", "balance_performance",
9+
"balance_power", "power"]
10+
epp_values_present = []
11+
current_epp_conf = []
12+
13+
for c in platform.get_cores():
14+
with open(CPU_EPP_PATH.format(c.core_id)) as f:
15+
core_epp_value = f.read().split("\n")[0]
16+
if core_epp_value not in epp_values_present:
17+
epp_values_present.append(core_epp_value)
18+
19+
for epp_value in epp_order:
20+
if epp_value in epp_values_present:
21+
current_epp_conf.append(epp_value)
22+
23+
return current_epp_conf
24+
25+
26+
def get_epp_cores(platform, epp_value, num_required, unavailable_cores):
27+
cores = []
28+
unavailable_core_ids = [c.core_id for c in unavailable_cores]
29+
for socket in platform.sockets.values():
30+
for core_id in socket.cores.keys():
31+
if core_id not in unavailable_core_ids:
32+
with open(CPU_EPP_PATH.format(core_id)) as f:
33+
if f.readline().rstrip() == epp_value:
34+
cores.append(socket.cores[core_id])
35+
if len(cores) == num_required:
36+
return cores
37+
38+
39+
def get_epp_cores_no_limit(platform, epp_value):
40+
cores = []
41+
for socket in platform.sockets.values():
42+
for core_id in socket.cores.keys():
43+
with open(CPU_EPP_PATH.format(core_id)) as f:
44+
if f.readline().rstrip() == epp_value:
45+
cores.append(socket.cores[core_id])
46+
47+
return cores

intel/topology.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import os
2020
import subprocess
2121
from . import sst_bf
22+
from . import sst_cp
2223

2324
ENV_LSCPU_SYSFS = "CMK_DEV_LSCPU_SYSFS"
2425

@@ -138,6 +139,14 @@ def get_cores_from_pool(self, pool):
138139
cores += socket.get_cores_from_pool(pool)
139140
return cores
140141

142+
def get_epp_cores(self, epp_value, num_required,
143+
unavailable_cores=[]):
144+
return sst_cp.get_epp_cores(self, epp_value, num_required,
145+
unavailable_cores)
146+
147+
def get_epp_cores_no_limit(self, epp_value):
148+
return sst_cp.get_epp_cores_no_limit(self, epp_value)
149+
141150

142151
class Socket:
143152
def __init__(self, socket_id, cores=None):

0 commit comments

Comments
 (0)