|
10 | 10 | # governing permissions and limitations under the License. |
11 | 11 | # |
12 | 12 | function(lagrange_limit_parallelism) |
13 | | - # Query system information |
14 | 13 | cmake_host_system_information(RESULT NUMBER_OF_PHYSICAL_CORES QUERY NUMBER_OF_PHYSICAL_CORES) |
15 | | - cmake_host_system_information(RESULT AVAILABLE_PHYSICAL_MEMORY QUERY AVAILABLE_PHYSICAL_MEMORY) |
16 | | - cmake_host_system_information(RESULT AVAILABLE_VIRTUAL_MEMORY QUERY AVAILABLE_VIRTUAL_MEMORY) |
17 | | - cmake_host_system_information(RESULT TOTAL_VIRTUAL_MEMORY QUERY TOTAL_VIRTUAL_MEMORY) |
18 | 14 | cmake_host_system_information(RESULT TOTAL_PHYSICAL_MEMORY QUERY TOTAL_PHYSICAL_MEMORY) |
19 | 15 |
|
20 | | - # Peak memory computed "manually" for each platform (in MB) |
21 | | - # Use a hard coded limit of 2 parallel linking jobs |
22 | | - set(max_rss_linux_debug 3000) |
23 | | - set(max_rss_linux_release 6000) # Force -j3 on a 16G memory machine. |
24 | | - set(max_rss_darwin_debug 729) |
25 | | - set(max_rss_darwin_release 395) |
26 | | - set(max_rss_windows_debug 2100) |
27 | | - set(max_rss_windows_release 1300) |
28 | | - |
29 | | - # Use "release" limit only for matching single-config mode |
30 | | - if(GENERATOR_IS_MULTI_CONFIG OR NOT DEFINED CMAKE_BUILD_TYPE) |
31 | | - message(STATUS "Defaulting to debug") |
32 | | - set(_postfix "debug") |
| 16 | + # Determine build type for memory estimation |
| 17 | + get_property(_is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) |
| 18 | + if(_is_multi_config OR NOT DEFINED CMAKE_BUILD_TYPE) |
| 19 | + set(_build_type "debug") |
33 | 20 | else() |
34 | | - string(TOLOWER ${CMAKE_BUILD_TYPE} _type) |
35 | | - if(_type STREQUAL release) |
36 | | - set(_postfix "release") |
37 | | - else() |
38 | | - set(_postfix "debug") |
39 | | - endif() |
| 21 | + string(TOLOWER "${CMAKE_BUILD_TYPE}" _build_type) |
40 | 22 | endif() |
41 | 23 |
|
42 | | - string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} _system) |
| 24 | + # Estimated peak RSS per link job (in MB), by build type. |
| 25 | + # Measure with: /usr/bin/time -v cmake --build --preset <preset> -j1 --target lagrange_python |
| 26 | + set(_default_link_memory_release 16000) # 16GB |
| 27 | + set(_default_link_memory_relwithdebinfo 32000) # 32GB |
| 28 | + set(_default_link_memory_debug 32000) # 32GB |
43 | 29 |
|
44 | | - # Use a 3/2 factor safety margin compared to observed memory usage |
45 | | - math(EXPR num_cpu_memory "${AVAILABLE_PHYSICAL_MEMORY} * 3 / 2 / ${max_rss_${_system}_${_postfix}}") |
| 30 | + # LTO links can require significantly more memory |
| 31 | + if(CMAKE_INTERPROCEDURAL_OPTIMIZATION) |
| 32 | + set(_default_link_memory_release 64000) # 64GB |
| 33 | + set(_default_link_memory_relwithdebinfo 64000) # 64GB |
| 34 | + endif() |
46 | 35 |
|
47 | | - # Compute limits for link/compile steps |
48 | | - set(num_cpu_link 2) |
49 | | - set(num_cpu_compile ${NUMBER_OF_PHYSICAL_CORES}) |
50 | | - if(num_cpu_link GREATER num_cpu_memory) |
51 | | - set(num_cpu_link ${num_cpu_memory}) |
| 36 | + if(DEFINED _default_link_memory_${_build_type}) |
| 37 | + set(_link_memory ${_default_link_memory_${_build_type}}) |
| 38 | + else() |
| 39 | + set(_link_memory ${_default_link_memory_debug}) |
52 | 40 | endif() |
53 | | - if(num_cpu_compile GREATER num_cpu_memory) |
54 | | - set(num_cpu_compile ${num_cpu_memory}) |
| 41 | + |
| 42 | + math(EXPR num_link_jobs "${TOTAL_PHYSICAL_MEMORY} / ${_link_memory}") |
| 43 | + if(num_link_jobs LESS 1) |
| 44 | + set(num_link_jobs 1) |
55 | 45 | endif() |
56 | 46 |
|
57 | 47 | if(CMAKE_SCRIPT_MODE_FILE) |
58 | | - # The message() command, without any mode, will print to stderr. But jenkins only allows us |
59 | | - # to capture stdout. To print a clean message without hyphens, we use cmake's echo command. |
60 | | - execute_process(COMMAND ${CMAKE_COMMAND} -E echo "${num_cpu_compile}") |
| 48 | + # Script mode: echo the number of physical cores for use as the -j flag in Jenkins. |
| 49 | + # Link parallelism is handled separately via Ninja job pools at configure time. |
| 50 | + execute_process(COMMAND ${CMAKE_COMMAND} -E echo "${NUMBER_OF_PHYSICAL_CORES}") |
61 | 51 | else() |
62 | | - message(STATUS "Parallelism: Available physical memory: ${AVAILABLE_PHYSICAL_MEMORY} / ${TOTAL_PHYSICAL_MEMORY}") |
63 | | - message(STATUS "Parallelism: Available virtual memory: ${AVAILABLE_VIRTUAL_MEMORY} / ${TOTAL_VIRTUAL_MEMORY}") |
64 | | - message(STATUS "Parallelism: Number of physical cores: ${NUMBER_OF_PHYSICAL_CORES}") |
65 | | - message(STATUS "Parallelism: Limiting link pool to ${num_cpu_link}") |
66 | | - message(STATUS "Parallelism: Limiting compile pool to ${num_cpu_compile}") |
67 | | - endif() |
| 52 | + message(STATUS "Parallelism: Total physical memory: ${TOTAL_PHYSICAL_MEMORY} MB") |
| 53 | + message(STATUS "Parallelism: Link job memory budget: ${_link_memory} MB (${_build_type})") |
| 54 | + message(STATUS "Parallelism: Limiting link pool to ${num_link_jobs}") |
68 | 55 |
|
69 | | - # Limit parallelism based on number of physical cores + available memory. |
70 | | - set_property(GLOBAL PROPERTY JOB_POOLS |
71 | | - pool-link=${num_cpu_link} |
72 | | - pool-compile=${num_cpu_compile} |
73 | | - pool-precompile-header=${num_cpu_compile} |
74 | | - ) |
75 | | - set(CMAKE_JOB_POOL_LINK "pool-link" CACHE STRING "Job pool for linking" FORCE) |
76 | | - set(CMAKE_JOB_POOL_COMPILE "pool-compile" CACHE STRING "Job pool for compiling" FORCE) |
77 | | - set(CMAKE_JOB_POOL_PRECOMPILE_HEADER "pool-precompile-header" CACHE STRING "Job pool for generating pre-compiled headers" FORCE) |
78 | | - |
79 | | - # Note: We cannot set directly CMAKE_BUILD_PARALLEL_LEVEL or CTEST_PARALLEL_LEVEL from this CMake file, |
80 | | - # since those are environment variables [1]: they are not cached and do not affect subsequent CMake calls. |
81 | | - # In practice, the parallelism for Ninja should be limited by our job pools, so the only thing we need is |
82 | | - # to run ctest in parallel. |
83 | | - # [1]: https://cmake.org/cmake/help/latest/manual/cmake-language.7.html#cmake-language-environment-variables |
| 56 | + set_property(GLOBAL PROPERTY JOB_POOLS pool-link=${num_link_jobs}) |
| 57 | + set(CMAKE_JOB_POOL_LINK "pool-link" CACHE STRING "Job pool for linking" FORCE) |
| 58 | + endif() |
84 | 59 | endfunction() |
85 | 60 |
|
86 | | -# If this file is run in script mode, calling this function will simply echo the total number of |
87 | | -# cores that we desire to build/test with. |
| 61 | +# If this file is run in script mode, it echoes the number of physical cores for use as |
| 62 | +# the -j flag for cmake --build and ctest. Link parallelism is not relevant here — it is |
| 63 | +# enforced by Ninja job pools set during the configure step. |
88 | 64 | if(CMAKE_SCRIPT_MODE_FILE) |
89 | 65 | if(DEFINED CMAKE_ARGV3) |
90 | 66 | # We need to extract build type from preset |
|
0 commit comments