intel-extension-for-pytorch
517 строк · 14.6 Кб
1# Referenced from https://github.com/pytorch/pytorch/blob/master/torch/utils/collect_env.py
2# Run it with `python collect_env.py`.
3import locale
4import re
5import subprocess
6import sys
7import os
8from collections import namedtuple
9
10try:
11import torch
12
13TORCH_AVAILABLE = True
14except (ImportError, NameError, AttributeError, OSError):
15TORCH_AVAILABLE = False
16
17try:
18import intel_extension_for_pytorch as ipex
19
20IPEX_AVAILABLE = True
21except (ImportError, NameError, AttributeError, OSError):
22IPEX_AVAILABLE = False
23
24
25# System Environment Information
26SystemEnv = namedtuple(
27"SystemEnv",
28[
29"torch_version",
30"torch_cxx11_abi",
31"ipex_version",
32"ipex_gitrev",
33"build_type",
34"gcc_version",
35"clang_version",
36"icx_version",
37"cmake_version",
38"os",
39"libc_version",
40"python_version",
41"python_platform",
42"is_xpu_available",
43"dpcpp_runtime_version",
44"mkl_version",
45"gpu_models",
46"intel_opencl_version",
47"level_zero_version",
48"pip_version", # 'pip' or 'pip3'
49"pip_packages",
50"conda_packages",
51"cpu_info",
52],
53)
54
55
56def run(command):
57"""Returns (return-code, stdout, stderr)"""
58my_env = os.environ.copy()
59my_env["LC_ALL"] = "C"
60p = subprocess.Popen(
61command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=my_env, shell=True
62)
63raw_output, raw_err = p.communicate()
64rc = p.returncode
65if get_platform() == "win32":
66enc = "oem"
67else:
68enc = locale.getpreferredencoding()
69output = raw_output.decode(enc)
70err = raw_err.decode(enc)
71return rc, output.strip(), err.strip()
72
73
74def run_and_read_all(run_lambda, command):
75"""Runs command using run_lambda; reads and returns entire output if rc is 0"""
76rc, out, _ = run_lambda(command)
77if rc != 0:
78return None
79return out
80
81
82def run_and_parse_first_match(run_lambda, command, regex):
83"""Runs command using run_lambda, returns the first regex match if it exists"""
84rc, out, _ = run_lambda(command)
85if rc != 0:
86return None
87match = re.search(regex, out)
88if match is None:
89return None
90return match.group(1)
91
92
93def run_and_return_first_line(run_lambda, command):
94"""Runs command using run_lambda and returns first line if output is not empty"""
95rc, out, _ = run_lambda(command)
96if rc != 0:
97return None
98return out.split("\n")[0]
99
100
101def get_conda_packages(run_lambda):
102conda = os.environ.get("CONDA_EXE", "conda")
103out = run_and_read_all(run_lambda, "{} list".format(conda))
104if out is None:
105return out
106
107return "\n".join(
108line
109for line in out.splitlines()
110if not line.startswith("#")
111and any(
112name in line
113for name in {
114"torch",
115"numpy",
116"mkl",
117}
118)
119)
120
121
122def get_gcc_version(run_lambda):
123return run_and_parse_first_match(run_lambda, "gcc --version", r"gcc (.*)")
124
125
126def get_clang_version(run_lambda):
127return run_and_parse_first_match(
128run_lambda, "clang --version", r"clang version (.*)"
129)
130
131
132def get_icx_version(run_lambda):
133return run_and_parse_first_match(
134run_lambda, "icx --version", r"Intel\(R\) oneAPI DPC\+\+\/C\+\+ Compiler (.*)"
135)
136
137
138def get_cmake_version(run_lambda):
139return run_and_parse_first_match(run_lambda, "cmake --version", r"cmake (.*)")
140
141
142def get_pkg_version(run_lambda, pkg):
143txt = ""
144index = -1
145if get_platform() == "linux":
146mgr_name = ""
147if mgr_name == "":
148rc, _, _ = run("which dpkg")
149if rc == 0:
150mgr_name = "dpkg"
151if mgr_name == "":
152rc, _, _ = run("which yum")
153if rc == 0:
154mgr_name = "yum"
155if mgr_name == "":
156rc, _, _ = run("which dnf")
157if rc == 0:
158mgr_name = "dnf"
159if mgr_name != "":
160cmd = ""
161if mgr_name == "yum" or mgr_name == "dnf":
162index = 1
163pkg_name = ""
164if pkg == "intel_opencl":
165pkg_name = "intel-opencl"
166if pkg == "level_zero":
167pkg_name = "intel-level-zero-gpu"
168if pkg_name != "":
169cmd = f"{mgr_name} list | grep {pkg_name}"
170if mgr_name == "dpkg":
171index = 2
172pkg_name = ""
173if pkg == "intel_opencl":
174pkg_name = "intel-opencl-icd"
175if pkg == "level_zero":
176pkg_name = "intel-level-zero-gpu"
177if pkg_name != "":
178cmd = f"{mgr_name} -l | grep {pkg_name}"
179if cmd != "":
180txt = run_and_read_all(run_lambda, cmd)
181lst_txt = []
182if txt:
183lst_txt = re.sub(" +", " ", txt).split(" ")
184if len(lst_txt) > index and index != -1:
185txt = lst_txt[index]
186else:
187txt = "N/A"
188return txt
189
190
191def get_gpu_info(run_lambda):
192if TORCH_AVAILABLE and IPEX_AVAILABLE:
193devices = [
194f"[{i}] {torch.xpu.get_device_properties(i)}"
195for i in range(torch.xpu.device_count())
196]
197return "\n".join(devices)
198else:
199return "N/A"
200
201
202def get_running_dpcpp_version(run_lambda):
203return run_and_read_all(
204run_lambda, 'env | grep CMPLR_ROOT | rev | cut -d "/" -f 1 | rev'
205)
206
207
208def get_mkl_version(run_lambda):
209return run_and_read_all(
210run_lambda, 'env | grep MKLROOT | rev | cut -d "/" -f 1 | rev'
211)
212
213
214def get_cpu_info(run_lambda):
215rc, out, err = 0, "", ""
216if get_platform() == "linux":
217rc, out, err = run_lambda("lscpu")
218elif get_platform() == "win32":
219rc, out, err = run_lambda(
220"wmic cpu get Name,Manufacturer,Family,Architecture,ProcessorType,DeviceID,\
221CurrentClockSpeed,MaxClockSpeed,L2CacheSize,L2CacheSpeed,Revision /VALUE"
222)
223elif get_platform() == "darwin":
224rc, out, err = run_lambda("sysctl -n machdep.cpu.brand_string")
225cpu_info = "N/A"
226if rc == 0:
227cpu_info = out
228else:
229cpu_info = err
230return cpu_info
231
232
233def get_platform():
234if sys.platform.startswith("linux"):
235return "linux"
236elif sys.platform.startswith("win32"):
237return "win32"
238elif sys.platform.startswith("cygwin"):
239return "cygwin"
240elif sys.platform.startswith("darwin"):
241return "darwin"
242else:
243return sys.platform
244
245
246def get_mac_version(run_lambda):
247return run_and_parse_first_match(run_lambda, "sw_vers -productVersion", r"(.*)")
248
249
250def get_windows_version(run_lambda):
251system_root = os.environ.get("SYSTEMROOT", "C:\\Windows")
252wmic_cmd = os.path.join(system_root, "System32", "Wbem", "wmic")
253findstr_cmd = os.path.join(system_root, "System32", "findstr")
254return run_and_read_all(
255run_lambda, "{} os get Caption | {} /v Caption".format(wmic_cmd, findstr_cmd)
256)
257
258
259def get_lsb_version(run_lambda):
260return run_and_parse_first_match(
261run_lambda, "lsb_release -a", r"Description:\t(.*)"
262)
263
264
265def check_release_file(run_lambda):
266return run_and_parse_first_match(
267run_lambda, "cat /etc/*-release", r'PRETTY_NAME="(.*)"'
268)
269
270
271def get_os(run_lambda):
272from platform import machine
273
274platform = get_platform()
275
276if platform == "win32" or platform == "cygwin":
277return get_windows_version(run_lambda)
278
279if platform == "darwin":
280version = get_mac_version(run_lambda)
281if version is None:
282return None
283return "macOS {} ({})".format(version, machine())
284
285if platform == "linux":
286# Ubuntu/Debian based
287desc = get_lsb_version(run_lambda)
288if desc is not None:
289return "{} ({})".format(desc, machine())
290
291# Try reading /etc/*-release
292desc = check_release_file(run_lambda)
293if desc is not None:
294return "{} ({})".format(desc, machine())
295
296return "{} ({})".format(platform, machine())
297
298# Unknown platform
299return platform
300
301
302def get_python_platform():
303import platform
304
305return platform.platform()
306
307
308def get_libc_version():
309import platform
310
311if get_platform() != "linux":
312return "N/A"
313return "-".join(platform.libc_ver())
314
315
316def get_pip_packages(run_lambda):
317"""Returns `pip list` output. Note: will also find conda-installed pytorch
318and numpy packages."""
319
320# People generally have `pip` as `pip` or `pip3`
321# But here it is incoved as `python -mpip`
322def run_with_pip(pip):
323out = run_and_read_all(run_lambda, "{} list --format=freeze".format(pip))
324return "\n".join(
325line
326for line in out.splitlines()
327if any(
328name in line
329for name in {
330"torch",
331"numpy",
332"mypy",
333}
334)
335)
336
337pip_version = "pip3" if sys.version[0] == "3" else "pip"
338out = run_with_pip(sys.executable + " -mpip")
339
340return pip_version, out
341
342
343def get_env_info():
344run_lambda = run
345pip_version, pip_list_output = get_pip_packages(run_lambda)
346
347if TORCH_AVAILABLE:
348torch_version_str = torch.__version__
349torch_cxx11_abi_str = torch._C._GLIBCXX_USE_CXX11_ABI
350else:
351torch_version_str = torch_cxx11_abi_str = "N/A"
352
353if IPEX_AVAILABLE:
354ipex_version_str = ipex.__version__
355try:
356import intel_extension_for_pytorch._version as ver
357except ImportError:
358import intel_extension_for_pytorch.version as ver
359try:
360ipex_gitrev_str = ver.__ipex_gitrev__
361except AttributeError:
362ipex_gitrev_str = ver.__gitrev__
363try:
364build_type_str = str(ver.__build_type__)
365except AttributeError:
366build_type_str = str(ver.__mode__)
367try:
368xpu_available_str = str(torch.xpu.is_available())
369except AttributeError:
370xpu_available_str = False
371else:
372ipex_version_str = ipex_gitrev_str = "N/A"
373build_type_str = xpu_available_str = "N/A"
374
375sys_version = sys.version.replace("\n", " ")
376
377return SystemEnv(
378torch_version=torch_version_str,
379torch_cxx11_abi=torch_cxx11_abi_str,
380ipex_version=ipex_version_str,
381ipex_gitrev=ipex_gitrev_str,
382build_type=build_type_str,
383python_version="{} ({}-bit runtime)".format(
384sys_version, sys.maxsize.bit_length() + 1
385),
386python_platform=get_python_platform(),
387is_xpu_available=xpu_available_str,
388dpcpp_runtime_version=get_running_dpcpp_version(run_lambda),
389mkl_version=get_mkl_version(run_lambda),
390gpu_models=f"\n{get_gpu_info(run_lambda)}",
391intel_opencl_version=get_pkg_version(run_lambda, "intel_opencl"),
392level_zero_version=get_pkg_version(run_lambda, "level_zero"),
393pip_version=pip_version,
394pip_packages=pip_list_output,
395conda_packages=get_conda_packages(run_lambda),
396os=get_os(run_lambda),
397libc_version=get_libc_version(),
398gcc_version=get_gcc_version(run_lambda),
399clang_version=get_clang_version(run_lambda),
400icx_version=get_icx_version(run_lambda),
401cmake_version=get_cmake_version(run_lambda),
402cpu_info=get_cpu_info(run_lambda),
403)
404
405
406env_info_fmt = """
407PyTorch version: {torch_version}
408PyTorch CXX11 ABI: {torch_cxx11_abi}
409IPEX version: {ipex_version}
410IPEX commit: {ipex_gitrev}
411Build type: {build_type}
412
413OS: {os}
414GCC version: {gcc_version}
415Clang version: {clang_version}
416IGC version: {icx_version}
417CMake version: {cmake_version}
418Libc version: {libc_version}
419
420Python version: {python_version}
421Python platform: {python_platform}
422Is XPU available: {is_xpu_available}
423DPCPP runtime version: {dpcpp_runtime_version}
424MKL version: {mkl_version}
425GPU models and configuration: {gpu_models}
426Intel OpenCL ICD version: {intel_opencl_version}
427Level Zero version: {level_zero_version}
428
429CPU:
430{cpu_info}
431
432Versions of relevant libraries:
433{pip_packages}
434{conda_packages}
435""".strip()
436
437
438def pretty_str(envinfo):
439def replace_nones(dct, replacement="Could not collect"):
440for key in dct.keys():
441if dct[key] is not None:
442continue
443dct[key] = replacement
444return dct
445
446def replace_empties(dct, replacement="Could not collect"):
447for key in dct.keys():
448if dct[key] is not None and len(dct[key]) > 0:
449continue
450dct[key] = replacement
451return dct
452
453def replace_bools(dct, true="Yes", false="No"):
454for key in dct.keys():
455if dct[key] is True:
456dct[key] = true
457elif dct[key] is False:
458dct[key] = false
459return dct
460
461def prepend(text, tag="[prepend]"):
462lines = text.split("\n")
463updated_lines = [tag + line for line in lines]
464return "\n".join(updated_lines)
465
466def replace_if_empty(text, replacement="No relevant packages"):
467if text is not None and len(text) == 0:
468return replacement
469return text
470
471def maybe_start_on_next_line(string):
472# If `string` is multiline, prepend a \n to it.
473if string is not None and len(string.split("\n")) > 1:
474return "\n{}\n".format(string)
475return string
476
477mutable_dict = envinfo._asdict()
478
479# Replace True with Yes, False with No
480mutable_dict = replace_bools(mutable_dict)
481
482# Replace all None objects with 'N/A'
483mutable_dict = replace_nones(mutable_dict, replacement="N/A")
484
485# Replace all empty objects with 'N/A'
486mutable_dict = replace_empties(mutable_dict, replacement="N/A")
487
488# If either of these are '', replace with 'No relevant packages'
489mutable_dict["pip_packages"] = replace_if_empty(mutable_dict["pip_packages"])
490mutable_dict["conda_packages"] = replace_if_empty(mutable_dict["conda_packages"])
491
492# Tag conda and pip packages with a prefix
493# If they were previously None, they'll show up as ie '[conda] Could not collect'
494if mutable_dict["pip_packages"]:
495mutable_dict["pip_packages"] = prepend(
496mutable_dict["pip_packages"], "[{}] ".format(envinfo.pip_version)
497)
498if mutable_dict["conda_packages"]:
499mutable_dict["conda_packages"] = prepend(
500mutable_dict["conda_packages"], "[conda] "
501)
502mutable_dict["cpu_info"] = envinfo.cpu_info
503return env_info_fmt.format(**mutable_dict)
504
505
506def get_pretty_env_info():
507return pretty_str(get_env_info())
508
509
510def main():
511print("Collecting environment information...")
512output = get_pretty_env_info()
513print(output)
514
515
516if __name__ == "__main__":
517main()
518