1 # Copyright (c) 2016 Cisco and/or its affiliates.
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at:
6 # http://www.apache.org/licenses/LICENSE-2.0
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
14 """CPU utilities library"""
16 from resources.libraries.python.ssh import SSH
18 __all__ = ["CpuUtils"]
20 class CpuUtils(object):
24 def __str2int(string):
25 """Conversion from string to integer, 0 in case of empty string.
27 :param string: Input string.
29 :return: Integer converted from string, 0 in case of ValueError.
38 def get_cpu_layout_from_all_nodes(nodes):
39 """Retrieve cpu layout from all nodes, assuming all nodes
42 :param nodes: DICT__nodes from Topology.DICT__nodes.
46 for node in nodes.values():
49 ret, stdout, stderr = ssh.exec_command(cmd)
50 # parsing of "lscpu -p" output:
51 # # CPU,Core,Socket,Node,,L1d,L1i,L2,L3
56 "Failed to execute ssh command, ret: {} err: {}".format(
58 node['cpuinfo'] = list()
59 for line in stdout.split("\n"):
60 if len(line) > 0 and line[0] != "#":
61 node['cpuinfo'].append([CpuUtils.__str2int(x) for x in
65 def cpu_node_count(node):
66 """Return count of numa nodes.
68 :param node: Targeted node.
70 :return: Count of numa nodes.
73 cpuinfo = node.get("cpuinfo")
74 if cpuinfo is not None:
75 return node["cpuinfo"][-1][3] + 1
77 raise RuntimeError("Node cpuinfo not available.")
80 def cpu_list_per_node(node, cpu_node):
81 """Return node related list of CPU numbers.
83 :param node: Node dictionary with cpuinfo.
84 :param cpu_node: Numa node number.
87 :return: List of cpu numbers related to numa from argument.
90 cpu_node = int(cpu_node)
91 cpuinfo = node.get("cpuinfo")
93 if cpuinfo is not None:
95 if cpu[3] == cpu_node:
96 cpulist.append(cpu[0])
98 raise RuntimeError("Node cpuinfo not available.")
103 def cpu_list_per_node_str(node, cpu_node, skip_cnt=0,
105 """Return string of node related list of CPU numbers.
107 :param node: Node dictionary with cpuinfo.
108 :param cpu_node: Numa node number.
109 :param skip_cnt: Skip first "skip_cnt" CPUs.
110 :param cpu_cnt: Count of cpus to return, if 0 then return all.
111 :param sep: Separator, default: 1,2,3,4,....
117 :return: Cpu numbers related to numa from argument.
121 cpu_list = CpuUtils.cpu_list_per_node(node, cpu_node)
122 cpu_list_len = len(cpu_list)
125 cpu_cnt = cpu_list_len - skip_cnt
127 if cpu_cnt + skip_cnt > cpu_list_len:
128 raise RuntimeError("cpu_cnt + skip_cnt > length(cpu list).")
130 cpu_flist = sep.join(str(a) for a in
131 cpu_list[skip_cnt:skip_cnt+cpu_cnt])