forked from ROCm/rocprofiler-compute
-
Notifications
You must be signed in to change notification settings - Fork 0
/
CMakeLists.txt
476 lines (416 loc) · 15.9 KB
/
CMakeLists.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
cmake_minimum_required(VERSION 3.19 FATAL_ERROR)
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR AND CMAKE_CURRENT_SOURCE_DIR STREQUAL
CMAKE_SOURCE_DIR)
set(MSG "")
message(STATUS "Warning! Building from the source directory is not recommended")
message(STATUS "If unintended, please remove 'CMakeCache.txt' and 'CMakeFiles'")
message(STATUS "and build from a separate directory")
message(FATAL_ERROR "In-source build")
endif()
# System info
cmake_host_system_information(RESULT LOCALHOST QUERY FQDN)
message(STATUS "Hostname: ${LOCALHOST}")
# Versioning info derived from file
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/VERSION" FULL_VERSION_STRING LIMIT_COUNT 1)
string(REGEX REPLACE "(\n|\r)" "" FULL_VERSION_STRING "${FULL_VERSION_STRING}")
set(OMNIPERF_FULL_VERSION "${FULL_VERSION_STRING}")
string(REGEX REPLACE "([0-9]+)\.([0-9]+)\.([0-9]+)(.*)" "\\1.\\2.\\3" OMNIPERF_VERSION
"${FULL_VERSION_STRING}")
# string(REGEX REPLACE "(${OMNIPERF_VERSION})(.*)" "\\2" OMNIPERF_VERSION_TWEAK
# "${FULL_VERSION_STRING}")
# string(REGEX REPLACE "^\\." "" OMNIPERF_VERSION_TWEAK "${OMNIPERF_VERSION_TWEAK}")
project(
omniperf
VERSION ${OMNIPERF_VERSION}
LANGUAGES C
DESCRIPTION "OmniPerf"
HOMEPAGE_URL "https://github.com/ROCm/omniperf")
include(ExternalProject)
include(GNUInstallDirs)
# version control info
find_package(Git)
if(Git_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
execute_process(
COMMAND git log --pretty=format:%h -n 1
OUTPUT_VARIABLE OMNIPERF_GIT_REV
OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "Git revision: ${OMNIPERF_GIT_REV}")
set(GIT_CLONE TRUE)
else()
set(GIT_CLONE FALSER)
endif()
set(CMAKE_BUILD_TYPE "Release")
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX
"/opt/rocm"
CACHE PATH "default install path" FORCE)
endif()
message(STATUS "Installation path: ${CMAKE_INSTALL_PREFIX}")
option(CHECK_PYTHON_DEPS "Verify necessary python dependencies" ON)
if(CHECK_PYTHON_DEPS)
# Python 3 is required
message(STATUS "Detecting Python interpreter...")
find_package(
Python3 3.8
COMPONENTS Interpreter
REQUIRED)
# Allow user-provided python search path
if(DEFINED PYTHON_DEPS)
set(ENV{PYTHONPATH} "${PYTHON_DEPS}")
message(STATUS "Optional PYTHON_DEPS provided:")
list(APPEND CMAKE_MESSAGE_INDENT " ")
message(STATUS "including ${PYTHON_DEPS} in search path")
list(POP_BACK CMAKE_MESSAGE_INDENT)
endif()
# Check required Python packages
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/requirements.txt" pythonDeps)
message(STATUS "Checking for required Python package dependencies...")
set_property(GLOBAL PROPERTY pythonDepsFlag "groovy")
function(checkPythonPackage [package])
# mapping for non-default package names
set(PACKAGE ${ARGV0})
if(${ARGV0} STREQUAL "pyyaml")
set(PACKAGE "yaml")
endif()
execute_process(
COMMAND ${Python3_EXECUTABLE} -c "import ${PACKAGE}"
OUTPUT_QUIET ERROR_QUIET
RESULT_VARIABLE EXIT_CODE)
if(${EXIT_CODE} EQUAL 0)
message(STATUS "${ARGV0} = yes")
else()
message(STATUS "${ARGV0} = missing")
set_property(GLOBAL PROPERTY pythonDepsFlag "missing")
endif()
endfunction()
list(APPEND CMAKE_MESSAGE_INDENT " ")
foreach(package IN LISTS pythonDeps)
# Filter out any version requirements from requirements.txt
string(REGEX REPLACE "[><=].*" "" package "${package}")
string(REPLACE "-" "_" package "${package}")
checkpythonpackage(${package})
endforeach()
list(POP_BACK CMAKE_MESSAGE_INDENT)
get_property(pythonDepsInstalled GLOBAL PROPERTY pythonDepsFlag)
if(${pythonDepsInstalled} STREQUAL "groovy")
message(STATUS "OK: Python dependencies available in current environment.")
else()
message(
FATAL_ERROR
"\nNecessary Python package dependencies not found. Please install required dependencies "
"above using your favorite package manager. If using pip, consider running:\n"
"python3 -m pip install -r requirements.txt\n"
"at the top-level of this repository. If preparing a shared installation for "
"multiple users, consider adding the -t <target-dir> option to install necessary dependencies "
"into a shared directory, e.g.\n"
"python3 -m pip install -t <shared-install-path> -r requirements.txt\n"
"Note that the -DPYTHON_DEPS=<shared-install-path> can be used to provide an "
"additional search path to cmake for python packages.")
endif()
endif()
# ----------------------
# modulefile creation
# ----------------------
set(MOD_INSTALL_PATH
"${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}/modulefiles/${PROJECT_NAME}"
CACHE STRING "Install path for modulefile")
message(STATUS "Modulefile install path: ${MOD_INSTALL_PATH}")
set(moduleFileTemplate "omniperf.lua.in")
configure_file(
${PROJECT_SOURCE_DIR}/cmake/${moduleFileTemplate}
${PROJECT_BINARY_DIR}/${MOD_INSTALL_PATH}/${OMNIPERF_FULL_VERSION}.lua @ONLY)
# Thera mods
if(LOCALHOST MATCHES "TheraS01|.*\.thera\.amd\.com|thera-hn")
list(APPEND CMAKE_MESSAGE_INDENT " ")
message(STATUS "Using thera-specific modulefile modification")
file(READ ${PROJECT_SOURCE_DIR}/cmake/modfile.thera.mod mod_additions)
file(APPEND ${PROJECT_BINARY_DIR}/${MOD_INSTALL_PATH}/${OMNIPERF_FULL_VERSION}.lua
${mod_additions})
list(POP_BACK CMAKE_MESSAGE_INDENT)
endif()
# git versioning file
if(${GIT_CLONE})
configure_file(${PROJECT_SOURCE_DIR}/cmake/VERSION.sha.in
${PROJECT_SOURCE_DIR}/VERSION.sha @ONLY)
endif()
# Setup testing collateral
option(ENABLE_TESTS "Enable compilation of testing collateral" OFF)
set(CMAKE_HIP_FLAGS_RELEASE "-O2")
if(${ENABLE_TESTS})
enable_language("C" "HIP")
add_subdirectory(tests)
endif()
message(STATUS "Enable tests compilation: ${ENABLE_TESTS}")
enable_testing()
option(ENABLE_COVERAGE "Enable code coverage" OFF)
set(COV_OPTION "")
if(${ENABLE_COVERAGE})
set(COV_OPTION "--cov=src" "--cov-append" "--cov-report=term-missing"
"--cov-report=lcov:tests/coverage.info")
# "--cov-report=term-missing" "--cov-report=xml:tests/coverage.xml")
endif()
message(STATUS "Code coverage: ${ENABLE_COVERAGE}")
# CPU threads available for testing
set(PYTEST_NUMPROCS
"1"
CACHE STRING "Number of parallel threads to use with CPU-oriented tests")
message(STATUS "Pytest CPU threadcount: ${PYTEST_NUMPROCS}")
# ---------------------------
# profile mode tests
# ---------------------------
add_test(
NAME test_profile_kernel_execution
COMMAND pytest -m kernel_execution --junitxml=tests/test_profile_kernel_execution.xml
${COV_OPTION} ${PROJECT_SOURCE_DIR}/tests/test_profile_general.py
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(
NAME test_profile_ipblocks
COMMAND pytest -m block --junitxml=tests/test_profile_blocks.xml ${COV_OPTION}
${PROJECT_SOURCE_DIR}/tests/test_profile_general.py
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
set_property(TEST test_profile_ipblocks PROPERTY COST 11)
add_test(
NAME test_profile_dispatch
COMMAND pytest -m dispatch --junitxml=tests/test_profile_dispatch.xml ${COV_OPTION}
${PROJECT_SOURCE_DIR}/tests/test_profile_general.py
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
set_property(TEST test_profile_ipblocks PROPERTY COST 5)
add_test(
NAME test_profile_mem
COMMAND pytest -m mem --junitxml=tests/test_profile_mem.xml ${COV_OPTION}
${PROJECT_SOURCE_DIR}/tests/test_profile_general.py
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(
NAME test_profile_join
COMMAND pytest -m join --junitxml=tests/test_profile_join.xml ${COV_OPTION}
${PROJECT_SOURCE_DIR}/tests/test_profile_general.py
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(
NAME test_profile_sort
COMMAND pytest -m sort --junitxml=tests/test_profile_sort.xml ${COV_OPTION}
${PROJECT_SOURCE_DIR}/tests/test_profile_general.py
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test(
NAME test_profile_misc
COMMAND pytest -m misc --junitxml=tests/test_profile_misc.xml ${COV_OPTION}
${PROJECT_SOURCE_DIR}/tests/test_profile_general.py
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
set_tests_properties(
test_profile_kernel_execution
test_profile_ipblocks
test_profile_dispatch
test_profile_mem
test_profile_join
test_profile_sort
test_profile_misc
PROPERTIES LABELS "profile" RESOURCE_GROUPS gpus:1)
# ---------------------------
# analysis command tests
# ---------------------------
add_test(
NAME test_analyze_commands
COMMAND pytest -n ${PYTEST_NUMPROCS} --junitxml=tests/test_analyze_commands.xml
${COV_OPTION} ${PROJECT_SOURCE_DIR}/tests/test_analyze_commands.py
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
# ---------------------------
# analyze workloads tests
# ---------------------------
add_test(
NAME test_analyze_workloads
COMMAND pytest -n ${PYTEST_NUMPROCS} --junitxml=tests/test_analyze_workloads.xml
${COV_OPTION} ${PROJECT_SOURCE_DIR}/tests/test_analyze_workloads.py
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
# ---------
# Install
# ---------
# top-level omniperf utility
install(
PROGRAMS src/omniperf
DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/${PROJECT_NAME}
COMPONENT main)
# python dependency requirements
install(
FILES requirements.txt
DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/${PROJECT_NAME}
COMPONENT main)
# support files and version info
install(
FILES src/argparser.py src/config.py src/omniperf_base.py src/roofline.py VERSION
VERSION.sha
DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/${PROJECT_NAME}
COMPONENT main)
# src/omniperf_analyze
install(
DIRECTORY src/omniperf_analyze
DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/${PROJECT_NAME}
COMPONENT main
PATTERN src/omniperf_analyze/tests EXCLUDE
PATTERN "__pycache__" EXCLUDE)
# src/utils
install(
DIRECTORY src/utils
DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/${PROJECT_NAME}
COMPONENT main
PATTERN "rooflines*" EXCLUDE
PATTERN "__pycache__" EXCLUDE)
# src/utils/rooflines
file(GLOB rooflinebins src/utils/rooflines/roofline-*)
install(
PROGRAMS ${rooflinebins}
DESTINATION ${CMAKE_INSTALL_BINDIR}
COMPONENT main)
# src/omniperf_soc
install(
DIRECTORY src/omniperf_soc
DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/${PROJECT_NAME}
COMPONENT main
PATTERN "__pycache__" EXCLUDE)
# src/omniperf_profile
install(
DIRECTORY src/omniperf_profile
DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/${PROJECT_NAME}
COMPONENT main
PATTERN "__pycache__" EXCLUDE)
# grafana assets
install(
DIRECTORY grafana
DESTINATION ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}
COMPONENT main)
# samples
install(
DIRECTORY sample
DESTINATION ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}
COMPONENT main
FILES_MATCHING
PATTERN "*.hip"
PATTERN "*.h"
PATTERN "*.cpp"
PATTERN "workloads" EXCLUDE)
# modulefile
install(
FILES ${PROJECT_BINARY_DIR}/${MOD_INSTALL_PATH}/${OMNIPERF_FULL_VERSION}.lua
DESTINATION ${MOD_INSTALL_PATH}
COMPONENT main)
# top-level symlink for bin/omniperf
install(
CODE "execute_process(
COMMAND bash -c \"set -e
cd \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}
ln -sf ../${CMAKE_INSTALL_LIBEXECDIR}/${PROJECT_NAME}/omniperf ${CMAKE_INSTALL_BINDIR}/omniperf
\")"
COMPONENT main)
# License header update(s)
add_custom_target(
license
COMMAND
${PROJECT_SOURCE_DIR}/utils/update_license.py --source ${PROJECT_SOURCE_DIR}/src
--license ${PROJECT_SOURCE_DIR}/LICENSE --extension '.py'
COMMAND
${PROJECT_SOURCE_DIR}/utils/update_license.py --source ${PROJECT_SOURCE_DIR}
--license ${PROJECT_SOURCE_DIR}/LICENSE --file
"src/omniperf,cmake/Dockerfile,cmake/rocm_install.sh,docker/docker-entrypoint.sh,src/omniperf_analyze/convertor/mongodb/convert"
)
# TEST collateral
option(INSTALL_TESTS "Build test suite" OFF)
if(INSTALL_TESTS)
install(
DIRECTORY tests
DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/${PROJECT_NAME}
COMPONENT tests
FILES_MATCHING
PATTERN "*.py"
PATTERN "__pycache__" EXCLUDE)
install(
FILES requirements-test.txt
DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/${PROJECT_NAME}
COMPONENT tests)
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/CTestTestfile.cmake
COMPONENT tests
DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/${PROJECT_NAME})
endif()
message(STATUS "Install tests: ${INSTALL_TESTS}")
# ----------
# Packaging
# ----------
message(STATUS "Packaging config...")
set(CPACK_GENERATOR
"DEB" "RPM"
CACHE STRING "")
set(CPACK_PACKAGE_NAME
"${PROJECT_NAME}"
CACHE STRING "")
set(CPACK_PACKAGE_CONTACT "https://github.com/ROCm/omniperf")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Omniperf: tool for GPU performance profiling")
set(CPACK_RPM_PACKAGE_DESCRIPTION "Omniperf is a performance analysis tool for profiling
machine learning/HPC workloads running on AMD GPUs.")
set(CPACK_PACKAGE_VENDOR "Advanced Micro Devices, Inc.")
# Package versioning
set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})
set(CPACK_PACKAGE_VERSION
"${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}"
)
# RPM package specific variables
set(CPACK_RPM_PACKAGE_LICENSE "MIT")
set(CPACK_RPM_PACKAGE_PROVIDES "${CPACK_PACKAGE_NAME}")
set(CPACK_RPM_COMPONENT_INSTALL ON)
set(CPACK_RPM_PACKAGE_RELEASE_DIST ON)
set(CPACK_RPM_FILE_NAME "RPM-DEFAULT")
if(DEFINED CPACK_PACKAGING_INSTALL_PREFIX)
set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "${CPACK_PACKAGING_INSTALL_PREFIX}")
endif()
# Debian package specific variables
set(CPACK_DEBIAN_PACKAGE_LICENSE "MIT")
set(CPACK_DEB_COMPONENT_INSTALL ON)
set(CPACK_DEBIAN_FILE_NAME "DEB-DEFAULT")
# Dependencies
set(PACKAGE_REQUIRES
"rocprofiler"
CACHE STRING "Package dependencies")
set(CPACK_RPM_PACKAGE_REQUIRES ${PACKAGE_REQUIRES})
set(CPACK_DEBIAN_PACKAGE_DEPENDS ${PACKAGE_REQUIRES})
# Disable automatic dependency generation
set(CPACK_RPM_PACKAGE_AUTOREQPROV OFF)
set(CPACK_RPM_PACKAGE_AUTOREQ OFF)
set(CPACK_RPM_PACKAGE_AUTOPROV OFF)
if(INSTALL_TESTS)
set(CPACK_RPM_TESTS_PACKAGE_REQUIRES ${CPACK_PACKAGE_NAME})
set(CPACK_DEBIAN_TESTS_PACKAGE_DEPENDS ${CPACK_PACKAGE_NAME})
endif()
# ----- Check for packaging override -----
if(DEFINED ENV{ROCM_LIBPATCH_VERSION})
set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION}.$ENV{ROCM_LIBPATCH_VERSION}")
endif()
if(DEFINED ENV{CPACK_RPM_PACKAGE_RELEASE})
set(CPACK_RPM_PACKAGE_RELEASE $ENV{CPACK_RPM_PACKAGE_RELEASE})
else()
set(CPACK_RPM_PACKAGE_RELEASE "local")
endif()
if(DEFINED ENV{CPACK_DEBIAN_PACKAGE_RELEASE})
set(CPACK_DEBIAN_PACKAGE_RELEASE $ENV{CPACK_DEBIAN_PACKAGE_RELEASE})
else()
set(CPACK_DEBIAN_PACKAGE_RELEASE "local")
endif()
# Log package info
message(STATUS " Package Name: ${CPACK_PACKAGE_NAME}")
message(STATUS " Package Version: ${CPACK_PACKAGE_VERSION}")
message(STATUS " RPM Package Release: ${CPACK_RPM_PACKAGE_RELEASE}")
message(STATUS " Debian Package Release: ${CPACK_DEBIAN_PACKAGE_RELEASE}")
message(STATUS " Packaging Install Prefix: ${CPACK_PACKAGING_INSTALL_PREFIX}")
message(STATUS " Install Tests: ${INSTALL_TESTS}")
message(STATUS " Package Dependencies: ${PACKAGE_REQUIRES}")
message(STATUS " CPack Generator: ${CPACK_GENERATOR}")
# Source tarball
set(CPACK_SOURCE_GENERATOR "TGZ")
set(CPACK_SOURCE_PACKAGE_FILE_NAME ${CMAKE_PROJECT_NAME}-${FULL_VERSION_STRING})
set(CPACK_SOURCE_IGNORE_FILES
".*~$"
\.git/
\.github
\.gitmodules
\.gitignore
/tests
/build)
include(CPack)