Skip to content

Commit 0abf350

Browse files
author
George Bisbas
committed
misc: Update advisor notebook
1 parent 2c0a1a9 commit 0abf350

7 files changed

Lines changed: 74 additions & 94 deletions

File tree

benchmarks/user/advisor/roofline.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,8 @@ def roofline(name, project, scale, precision, mode, th):
171171
label_x = row.self_ai + (row.self_ai + ai_max - 2 * ai_min) * (2**0.005 - 1)
172172
label_y = row.self_gflops
173173
ax.text(label_x, label_y,
174-
'Time: %.2fs\n'
175-
'Peak pct: %.0f%%' % (row.self_time, row.percent_weight),
174+
f'Time: {row.self_time:.2f}s\n'
175+
f'Incidence: {row.percent_weight:.0f}%',
176176
bbox={'boxstyle': 'round', 'facecolor': 'white'}, fontsize=8)
177177
top_loops_data = [{'ai': row.self_ai,
178178
'gflops': row.self_gflops,
@@ -213,5 +213,6 @@ def roofline(name, project, scale, precision, mode, th):
213213
log('\nJSON file saved as %s.json.' % name)
214214
log('Done!')
215215

216+
216217
if __name__ == '__main__':
217218
roofline()

benchmarks/user/advisor/run_advisor.py

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28,37 +28,40 @@
2828
'in --exec-args (if any).')
2929
def run_with_advisor(path, output, name, exec_args):
3030
path = Path(path)
31-
check(path.is_file(), '%s not found' % path)
32-
check(path.suffix == '.py', '%s not a Python file' % path)
31+
check(path.is_file(), f'{path} not found')
32+
check(path.suffix == '.py', f'{path} not a Python file')
3333

3434
# Create a directory to store the profiling report
3535
if name is None:
3636
name = path.stem
3737
if exec_args:
38-
name = "%s_%s" % (name, ''.join(exec_args.split()))
38+
name = f"{name}_{''.join(exec_args.split())}"
3939
if output is None:
4040
output = Path(gettempdir()).joinpath('devito-profilings')
4141
output.mkdir(parents=True, exist_ok=True)
4242
else:
4343
output = Path(output)
4444
if name is None:
45-
output = Path(mkdtemp(dir=str(output), prefix="%s-" % name))
45+
output = Path(mkdtemp(dir=str(output), prefix=f"{name}-"))
4646
else:
4747
output = Path(output).joinpath(name)
4848
output.mkdir(parents=True, exist_ok=True)
4949

50-
# Intel Advisor and Intel compilers must be available through either
51-
# Intel oneAPI (tested with Intel oneAPI 2025.1)
50+
# advixe-cl and icx should be available through Intel oneAPI
51+
# (tested with Intel oneAPI 2025.1)
5252
try:
5353
ret = check_output(['advixe-cl', '--version']).decode("utf-8")
54+
log(f"Found advixe-cl version: {ret.strip()}\n")
5455
except FileNotFoundError:
55-
check(False, "Error: Couldn't detect `advixe-cl` to run Intel Advisor.")
56+
check(False, "Error: Couldn't detect `advixe-cl` to run Intel Advisor."
57+
" Please source the Advisor environment.")
5658

5759
try:
5860
ret = check_output(['icx', '--version']).decode("utf-8")
59-
log("Found icx version: %s" % ret.strip())
61+
log(f"Found icx version: {ret.strip()}\n")
6062
except FileNotFoundError:
61-
check(False, "Error: Couldn't detect Intel Compiler (icx).")
63+
check(False, "Error: Couldn't detect Intel Compiler (icx)."
64+
" Please source the Intel oneAPI compilers.")
6265

6366
# All good, Intel compiler and advisor are available
6467
os.environ['DEVITO_ARCH'] = 'icx'
@@ -82,7 +85,6 @@ def run_with_advisor(path, output, name, exec_args):
8285
ret = check_output(['numactl', '--show']).decode("utf-8")
8386
ret = dict(i.split(':') for i in ret.split('\n') if i)
8487
n_sockets = len(ret['cpubind'].split())
85-
n_cores = len(ret['physcpubind'].split()) # noqa
8688
except FileNotFoundError:
8789
check(False, "Couldn't detect `numactl`, necessary for thread pinning.")
8890

@@ -145,9 +147,9 @@ def run_with_advisor(path, output, name, exec_args):
145147
advixe_handler.setFormatter(advixe_formatter)
146148
advixe_logger.addHandler(advixe_handler)
147149

148-
log("Project folder: %s" % str(output))
149-
log("Logging progress in: `%s`" % str(advixe_handler))
150-
150+
log(f"Project folder: {output}")
151+
log(f"Logging progress in: `{advixe_handler.baseFilename}`")
152+
151153
with progress('Performing `cache warm-up` run'):
152154
try:
153155
p_warm_up = Popen(py_cmd, stdout=PIPE, stderr=PIPE)
@@ -171,13 +173,13 @@ def run_with_advisor(path, output, name, exec_args):
171173
except OSError:
172174
check(False, 'Failed!')
173175

174-
log('Storing `survey` and `tripcounts` data in `%s`' % str(output))
176+
log(f'Storing `survey` and `tripcounts` data in `{output}`')
175177
log('To plot a roofline type: ')
176-
log('python3 roofline.py --name %s --project %s --scale %f'
177-
% (name, str(output), n_sockets))
178+
log(f'python3 roofline.py --name {name} --project {output} --scale {n_sockets}')
178179

179180
log('\nTo open the roofline using advixe-gui: ')
180-
log('advixe-gui %s' % str(output))
181+
log(f'advixe-gui {output}')
182+
181183

182184
if __name__ == '__main__':
183185
run_with_advisor()

devito/arch/archinfo.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from functools import cached_property
44
from subprocess import PIPE, Popen, DEVNULL, run
5+
from pathlib import Path
56
import ctypes
67
import re
78
import os
@@ -17,8 +18,8 @@
1718

1819
__all__ = ['platform_registry', 'get_cpu_info', 'get_gpu_info', 'get_nvidia_cc',
1920
'get_cuda_path', 'get_hip_path', 'check_cuda_runtime', 'get_m1_llvm_path',
20-
'Platform', 'Cpu64', 'Intel64', 'IntelSkylake', 'Amd', 'Arm', 'Power',
21-
'Device', 'NvidiaDevice', 'AmdDevice', 'IntelDevice',
21+
'get_advisor_path', 'Platform', 'Cpu64', 'Intel64', 'IntelSkylake', 'Amd',
22+
'Arm', 'Power', 'Device', 'NvidiaDevice', 'AmdDevice', 'IntelDevice',
2223
# Brand-agnostic
2324
'ANYCPU', 'ANYGPU',
2425
# Intel CPUs
@@ -464,6 +465,27 @@ def get_cuda_path():
464465
return None
465466

466467

468+
def get_advisor_path():
469+
"""
470+
Detect if Intel Advisor is installed on the machine and return
471+
its location if it is.
472+
"""
473+
path = None
474+
475+
env_path = os.environ["PATH"]
476+
env_path_dirs = env_path.split(":")
477+
478+
for env_path_dir in env_path_dirs:
479+
# intel/oneapi/advisor is the directory for Intel oneAPI
480+
if "intel/advisor" in env_path_dir or "intel/oneapi/advisor" in env_path_dir:
481+
path = Path(env_path_dir)
482+
if path.name.startswith('bin'):
483+
path = path.parent
484+
return path
485+
486+
return path
487+
488+
467489
@memoized_func
468490
def get_hip_path():
469491
# *** First try: via commonly used environment variables

devito/arch/compiler.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
call_capture_output as _call_capture_output)
1515

1616
from devito.arch import (AMDGPUX, Cpu64, AppleArm, NvidiaDevice, POWER8, POWER9,
17-
Graviton, Cortex, IntelDevice, get_nvidia_cc, NvidiaArm,
18-
check_cuda_runtime, get_m1_llvm_path)
17+
Graviton, Cortex, IntelDevice, get_nvidia_cc,
18+
check_cuda_runtime, get_m1_llvm_path, get_advisor_path)
1919
from devito.exceptions import CompilationError
2020
from devito.logger import debug, warning
2121
from devito.parameters import configuration
@@ -771,17 +771,15 @@ def __init_finalize__(self, **kwargs):
771771

772772
if configuration['profiling'] == 'advisor':
773773
# Locate the Intel Advisor installation and
774-
# add the necessary flags to the compiler
775-
from devito.operator.profiling import locate_intel_advisor
776-
path = locate_intel_advisor()
774+
# add the necessary paths and flags to the compiler
775+
path = get_advisor_path()
777776
self.add_include_dirs(path.joinpath('include').as_posix())
778777

779778
_default_libs = ['ittnotify']
780779
self.add_libraries(_default_libs)
781780

782781
libdir = path.joinpath('lib64').as_posix()
783-
self.add_library_dirs(libdir)
784-
self.add_ldflags('-Wl,-rpath,%s' % libdir)
782+
self.add_library_dirs(libdir, rpath=True)
785783

786784
def __init_intel_mpi__(self, **kwargs):
787785
# Make sure the MPI compiler uses an Intel compiler underneath,

devito/operator/profiling.py

Lines changed: 2 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@
22
from contextlib import contextmanager
33
from functools import reduce
44
from operator import mul
5-
from pathlib import Path
6-
from subprocess import DEVNULL, PIPE, run
75
from time import time as seq_time
8-
import os
96

107
import cgen as c
118
import numpy as np
@@ -14,7 +11,7 @@
1411
from devito.ir.iet import (ExpressionBundle, List, TimedList, Section,
1512
Iteration, FindNodes, Transformer)
1613
from devito.ir.support import IntervalGroup
17-
from devito.logger import warning, error
14+
from devito.logger import warning
1815
from devito.mpi import MPI
1916
from devito.parameters import configuration
2017
from devito.symbolics import subs_op_args
@@ -367,12 +364,7 @@ class AdvisorProfiler(AdvancedProfiler):
367364
_ext_calls = [_api_resume, _api_pause]
368365

369366
def __init__(self, name):
370-
path = locate_intel_advisor()
371-
if path is None:
372-
self.initialized = False
373-
else:
374-
super(AdvisorProfiler, self).__init__(name)
375-
367+
super(AdvisorProfiler, self).__init__(name)
376368
return
377369

378370
def analyze(self, iet):
@@ -525,55 +517,3 @@ def create_profile(name):
525517
'advisor': AdvisorProfiler
526518
}
527519
"""Profiling levels."""
528-
529-
530-
def locate_intel_advisor():
531-
"""
532-
Detect if Intel Advisor is installed on the machine and return
533-
its location if it is.
534-
535-
"""
536-
path = None
537-
538-
try:
539-
# Check if the directory to Intel Advisor is specified
540-
path = Path(os.environ['DEVITO_ADVISOR_DIR'])
541-
except KeyError:
542-
# Otherwise, 'sniff' the location of Advisor's directory
543-
error_msg = 'Intel Advisor cannot be found on your system, consider if you'\
544-
' have sourced its environment variables correctly. Information can'\
545-
' be found at https://software.intel.com/content/www/us/en/develop/'\
546-
'documentation/advisor-user-guide/top/launch-the-intel-advisor/'\
547-
'intel-advisor-cli/setting-and-using-intel-advisor-environment'\
548-
'-variables.html'
549-
try:
550-
res = run(["advixe-cl", "--version"], stdout=PIPE, stderr=DEVNULL)
551-
ver = res.stdout.decode("utf-8")
552-
if not ver:
553-
error(error_msg)
554-
return None
555-
except (UnicodeDecodeError, FileNotFoundError):
556-
error(error_msg)
557-
return None
558-
559-
env_path = os.environ["PATH"]
560-
env_path_dirs = env_path.split(":")
561-
562-
for env_path_dir in env_path_dirs:
563-
# intel/advisor is the advisor directory for Intel Parallel Studio,
564-
# intel/oneapi/advisor is the directory for Intel oneAPI
565-
if "intel/advisor" in env_path_dir or "intel/oneapi/advisor" in env_path_dir:
566-
path = Path(env_path_dir)
567-
if path.name.startswith('bin'):
568-
path = path.parent
569-
570-
if not path:
571-
error(error_msg)
572-
return None
573-
574-
if path.joinpath('bin64').joinpath('advixe-cl').is_file():
575-
return path
576-
else:
577-
warning("Requested `advisor` profiler, but couldn't locate executable"
578-
"in advisor directory")
579-
return None

examples/performance/02_advisor_roofline.ipynb

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,21 +81,25 @@
8181
"name": "stdout",
8282
"output_type": "stream",
8383
"text": [
84+
"\u001b[1;37;32mFound advixe-cl version: Intel(R) Advisor 2025.0.0 (build 615865) Command Line Tool\n",
85+
"Copyright (C) 2009-2025 Intel Corporation. All rights reserved.\n",
86+
"\u001b[0m\n",
8487
"\u001b[1;37;32mFound icx version: Intel(R) oneAPI DPC++/C++ Compiler 2025.0.4 (2025.0.4.20241205)\n",
8588
"Target: x86_64-unknown-linux-gnu\n",
8689
"Thread model: posix\n",
8790
"InstalledDir: /opt/intel/oneapi/compiler/2025.0/bin/compiler\n",
88-
"Configuration file: /opt/intel/oneapi/compiler/2025.0/bin/compiler/../icx.cfg\u001b[0m\n",
91+
"Configuration file: /opt/intel/oneapi/compiler/2025.0/bin/compiler/../icx.cfg\n",
92+
"\u001b[0m\n",
8993
"\u001b[1;37;32mSetting up multi-threading environment with OpenMP ... \u001b[0m\u001b[1;37;32mDone!\u001b[0m\n",
9094
"\u001b[1;37;32mStarting Intel Advisor's `roofline` analysis for `JupyterProfiling`\u001b[0m\n",
9195
"\u001b[1;37;32mProject folder: /home/gb4018/workspace/devitocodes/devito/examples/performance/profilings/JupyterProfiling\u001b[0m\n",
92-
"\u001b[1;37;32mLogging progress in: `<FileHandler /home/gb4018/workspace/devitocodes/devito/examples/performance/profilings/JupyterProfiling/JupyterProfiling_2025.2.10.20.10.45.log (NOTSET)>`\u001b[0m\n",
96+
"\u001b[1;37;32mLogging progress in: `/home/gb4018/workspace/devitocodes/devito/examples/performance/profilings/JupyterProfiling/JupyterProfiling_2025.2.11.17.2.29.log`\u001b[0m\n",
9397
"\u001b[1;37;32mPerforming `cache warm-up` run ... \u001b[0m\u001b[1;37;32mDone!\u001b[0m\n",
9498
"\u001b[1;37;32mPerforming `survey` analysis ... \u001b[0m\u001b[1;37;32mDone!\u001b[0m\n",
9599
"\u001b[1;37;32mPerforming `tripcounts` analysis ... \u001b[0m\u001b[1;37;32mDone!\u001b[0m\n",
96100
"\u001b[1;37;32mStoring `survey` and `tripcounts` data in `/home/gb4018/workspace/devitocodes/devito/examples/performance/profilings/JupyterProfiling`\u001b[0m\n",
97101
"\u001b[1;37;32mTo plot a roofline type: \u001b[0m\n",
98-
"\u001b[1;37;32mpython3 roofline.py --name JupyterProfiling --project /home/gb4018/workspace/devitocodes/devito/examples/performance/profilings/JupyterProfiling --scale 1.000000\u001b[0m\n",
102+
"\u001b[1;37;32mpython3 roofline.py --name JupyterProfiling --project /home/gb4018/workspace/devitocodes/devito/examples/performance/profilings/JupyterProfiling --scale 1\u001b[0m\n",
99103
"\u001b[1;37;32m\n",
100104
"To open the roofline using advixe-gui: \u001b[0m\n",
101105
"\u001b[1;37;32madvixe-gui /home/gb4018/workspace/devitocodes/devito/examples/performance/profilings/JupyterProfiling\u001b[0m\n"

tests/test_benchmark.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import sys
44

55
from benchmarks.user.benchmark import run
6-
from devito import configuration, switchconfig
6+
from devito import configuration, switchconfig, Grid, TimeFunction, Eq, Operator
77
from conftest import skipif
88
from subprocess import check_call
99

@@ -87,3 +87,16 @@ def test_run_mpi(mode):
8787
'dump_norms': 'norms.txt'
8888
}
8989
run('acoustic', **kwargs)
90+
91+
92+
@switchconfig(profiling='advisor')
93+
def test_advisor_profiling():
94+
grid = Grid(shape=(10, 10, 10))
95+
96+
f = TimeFunction(name='f', grid=grid, space_order=2)
97+
98+
eq0 = [Eq(f.forward, f.dx + 1.)]
99+
100+
# Only check codegen, do not run
101+
op = Operator(eq0)
102+
assert 'ittnotify.h' in op._includes

0 commit comments

Comments
 (0)