ADCT Python
Python client API implementation for publishing ADCT data
Loading...
Searching...
No Matches
Classes | Functions | Variables
adctk.builder Namespace Reference

Classes

class  APISequenceError
 Exception raised when functions in an api are called out of sequence. More...
 
class  Builder
 ADC Toolkit message and subsection construction class. More...
 
class  Header
 A class to build the header section with the application name given by user and default details. More...
 
class  Host
 Section for host OS, with optional hardware details. More...
 
class  Memory
 Section for memory stats. More...
 

Functions

 get_modules (submodules=False)
 
 get_libs ()
 Returns a list of name for shared libs open input example to match: 7ffff7dcd000-7ffff7dfc000 r-xp 00000000 00:17 134223798 /usr/lib64/ld-2.28.so.
 
 get_lscpu ()
 
 get_gpu_data ()
 
 get_numa_hardware ()
 
 get_meminfo (n, update=False)
 get fields that would appear in the procps 'free' utility.
 

Variables

dict _gpu_json = None
 
dict _numa_json = None
 
dict _midata = {}
 

Function Documentation

◆ get_gpu_data()

adctk.builder.get_gpu_data ( )
get structure about gpus that can be jsonified
83def get_gpu_data():
84 """get structure about gpus that can be jsonified"""
85 global _gpu_json # pylint: disable=W0603
86 if not _gpu_json is None:
87 return _gpu_json
88 _gpu_json = {}
89 try:
90 r = subprocess.run("lspci -vmm |grep -B1 -A 6 -i '3d controller'",
91 shell=True,
92 capture_output=True,
93 text=True,
94 check=True
95 )
96 except subprocess.CalledProcessError:
97 # expected to fail if lspci not installed or gpu records not found
98 return _gpu_json
99 gpu_count = 0
100 vendor: list[str] = []
101 device: list[str] = []
102 rev: list[str] = []
103 numa_node: list[int] = [] # int32
104 for line in r.stdout.splitlines():
105 if line[0] == '-':
106 continue
107 cp = line.split(":", 1)
108 name = cp[0]
109 if name == "Class":
110 cname = cp[1].strip()
111 if cname == "3D controller":
112 gpu_count += 1
113 continue
114 if name == "Vendor":
115 vendor.append(cp[1].strip())
116 continue
117 if name == "Device":
118 device.append(cp[1].strip())
119 continue
120 if name == "Rev":
121 rev.append(cp[1].strip())
122 continue
123 if name == "NUMANode":
124 numa_node.append(int(cp[1].strip()))
125 continue
126 sz = gpu_count
127 if sz != len(vendor) or sz != len(device) or sz != len(rev) or sz != len(numa_node):
128 log.logger.error("add_host_section:get_gpu_data: size mismatch")
129 return _gpu_json
130 _gpu_json["gpu_count"] = gpu_count
131 gpu_list = []
132 for i in range(0,gpu_count):
133 gpu_block = {"gpu_number": i,
134 "numa_node": numa_node[i],
135 "vendor": vendor[i],
136 "device": device[i],
137 "rev": rev[i]
138 }
139 gpu_list.append(gpu_block)
140 _gpu_json["gpulist"] = gpu_list
141 return _gpu_json
142

◆ get_libs()

adctk.builder.get_libs ( )

Returns a list of name for shared libs open input example to match: 7ffff7dcd000-7ffff7dfc000 r-xp 00000000 00:17 134223798 /usr/lib64/ld-2.28.so.

55def get_libs():
56 """! Returns a list of name for shared libs open
57 input example to match:
58 7ffff7dcd000-7ffff7dfc000 r-xp 00000000 00:17 134223798 /usr/lib64/ld-2.28.so.*
59 """
60 pid = os.getpid()
61 path = f"/proc/{pid}/maps"
62 with open(path, "r", encoding='utf-8') as maps:
63 lines = maps.readlines()
64 libs = set()
65 for e in lines:
66 if " r-xp " in e and ".so" in e:
67 libs.add(e.split()[-1])
68 return list(sorted(libs))
69

◆ get_lscpu()

adctk.builder.get_lscpu ( )
get stringified json from lscpu. The result is not cached (offline core changes)
70def get_lscpu():
71 """get stringified json from lscpu. The result is not cached (offline core changes)"""
72 try:
73 r = subprocess.run(["lscpu", "-J"],
74 capture_output=True,
75 text=True,
76 check=True
77 )
78 return r.stdout
79 except subprocess.CalledProcessError:
80 return "{}"
81

◆ get_meminfo()

adctk.builder.get_meminfo (   n,
  update = False 
)

get fields that would appear in the procps 'free' utility.


194def get_meminfo(n, update=False):
195 """! get fields that would appear in the procps 'free' utility. """
196 if update or len(_midata) == 0:
197 with open("/proc/meminfo","r", encoding='utf-8') as meminfo:
198 lines = meminfo.readlines()
199 for i in lines:
200 name,val = i.split(":")
201 _midata[name.strip()] = int(val.split()[0].strip())
202 _midata["MemUsed"] = _midata["MemTotal"] - _midata["MemFree"]
203 _midata["SwapUsed"] = _midata["SwapTotal"] - _midata["SwapFree"]
204 _midata["CachedAll"] = _midata["Cached"] + _midata["SReclaimable"]
205 if _midata["MemAvailable"] > _midata["MemTotal"]:
206 _midata["MemAvailable"] = _midata["MemFree"]
207 # work around container misreporting.
208 # documented in procps utility 'free'
209 if n in _midata:
210 return _midata[n]
211 return 0
212

◆ get_modules()

adctk.builder.get_modules (   submodules = False)

Returns a dictionary of name:path pairs.

Ignores builtin and binary modules.

34def get_modules(submodules=False):
35 """!## Returns a dictionary of name:path pairs.
36 Ignores builtin and binary modules.
37 """
38 mods = {}
39 basemods = sys.stdlib_module_names
40 for name, obj in sys.modules.items():
41 if hasattr(obj, '__file__') and obj.__file__ is not None:
42 path = os.path.abspath(obj.__file__)
43 if not name in basemods:
44 if submodules:
45 mods[name] = path
46 continue
47 parts = name.split(".")
48 for i in parts:
49 if i.startswith("_"):
50 break
51 else: # for-else
52 mods[name] = path
53 return mods
54

◆ get_numa_hardware()

adctk.builder.get_numa_hardware ( )
get object tree for numa_hardware. do data collection exactly once
144def get_numa_hardware():
145 """get object tree for numa_hardware. do data collection exactly once"""
146 global _numa_json # pylint: disable=W0603
147 if _numa_json:
148 return _numa_json
149 _numa_json = {}
150 try:
151 r = subprocess.run("numactl -H",
152 shell=True,
153 capture_output=True,
154 text=True,
155 check=True
156 )
157 except subprocess.CalledProcessError:
158 # expected to fail if lspci not installed or gpu records not found
159 return _numa_json
160 numa_node_count = 0
161 cpulist: list[str] = []
162 sizes: list[int] = [] # int64
163 for line in r.stdout.splitlines():
164 if line[0] == '-':
165 continue
166 cp = line.split(":", 1)
167 name = cp[0]
168 if name == "available":
169 numa_node_count = int(cp[1].split()[0])
170 continue
171 if name[-4:] == "cpus":
172 cpulist.append(cp[1].strip())
173 continue
174 if name[-4:] == "size":
175 i = cp[1].split()[0]
176 sizes.append(int(i))
177 continue
178 if name[-4:] == "nces":
179 # distances
180 break
181 sz = numa_node_count
182 if not sz or len(sizes) != sz or len(cpulist) != sz:
183 return _numa_json
184 node_list = []
185 for i in range(0,numa_node_count):
186 node_list.append({"node_number": i,
187 "node_megabytes": sizes[i],
188 "cpu_list": cpulist[i]
189 })
190 _numa_json["node_list"] = node_list
191 return _numa_json
192

Variable Documentation

◆ _gpu_json

dict adctk.builder._gpu_json = None
protected

◆ _midata

dict adctk.builder._midata = {}
protected

◆ _numa_json

dict adctk.builder._numa_json = None
protected