From abbaa123aa0bc7c1d712a7cde018dfbdcccf0c43 Mon Sep 17 00:00:00 2001 From: Michael Wild Date: Fri, 8 Oct 2010 09:16:04 +0200 Subject: [PATCH 1/9] Add module ProcessorCount.cmake (#11302) Credit goes to David Cole ( http://www.kitware.com/blog/home/post/63 ). Also add a script-based test of the new module. Signed-off-by: Michael Wild --- Modules/ProcessorCount.cmake | 60 ++++++++++++++++++++ Tests/CMakeTests/CMakeLists.txt | 1 + Tests/CMakeTests/ProcessorCountTest.cmake.in | 9 +++ 3 files changed, 70 insertions(+) create mode 100644 Modules/ProcessorCount.cmake create mode 100644 Tests/CMakeTests/ProcessorCountTest.cmake.in diff --git a/Modules/ProcessorCount.cmake b/Modules/ProcessorCount.cmake new file mode 100644 index 000000000..e4aea1969 --- /dev/null +++ b/Modules/ProcessorCount.cmake @@ -0,0 +1,60 @@ +# - ProcessorCount(var) +# Determine the number of processors/cores and save value in ${var} +# +# Sets the variable named ${var} to the number of physical cores available on +# the machine if the information can be determined. Otherwise it is set to 0. +# Currently this functionality is only implemented for Windows, Mac OS X and +# Unix systems providing getconf or the /proc/cpuinfo interface (e.g. Linux). + +# A more reliable way might be to compile a small C program that uses the CPUID +# instruction, but that again requires compiler support or compiling assembler +# code. + +#============================================================================= +# Copyright 2002-2009 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distributed this file outside of CMake, substitute the full +# License text for the above reference.) + +function(ProcessorCount var) + # Unknown: + set(count 0) + + if(WIN32) + # Windows: + set(count "$ENV{NUMBER_OF_PROCESSORS}") + elseif(APPLE) + # Mac: + find_program(ProcessorCount_cmd_sysctl sysctl + PATHS /usr/sbin) + if(ProcessorCount_cmd_sysctl) + execute_process(COMMAND ${ProcessorCount_cmd_sysctl} -n hw.ncpu + OUTPUT_STRIP_TRAILING_WHITESPACE + OUTPUT_VARIABLE count) + endif() + else() + find_program(ProcessorCount_cmd_getconf getconf) + if(ProcessorCount_cmd_getconf) + # Linux and other systems with getconf: + execute_process(COMMAND ${ProcessorCount_cmd_getconf} _NPROCESSORS_ONLN + OUTPUT_STRIP_TRAILING_WHITESPACE + OUTPUT_VARIABLE count) + else() + # Linux and other systems with /proc/cpuinfo: + set(cpuinfo_file /proc/cpuinfo) + if(EXISTS "${cpuinfo_file}") + file(STRINGS "${cpuinfo_file}" procs REGEX "^processor.: [0-9]+$") + list(LENGTH procs count) + endif() + endif() + endif() + + set(${var} ${count} PARENT_SCOPE) +endfunction() diff --git a/Tests/CMakeTests/CMakeLists.txt b/Tests/CMakeTests/CMakeLists.txt index cceef3bcf..5cb50c93a 100644 --- a/Tests/CMakeTests/CMakeLists.txt +++ b/Tests/CMakeTests/CMakeLists.txt @@ -27,6 +27,7 @@ AddCMakeTest(String "") AddCMakeTest(Math "") AddCMakeTest(CMakeMinimumRequired "") AddCMakeTest(CompilerIdVendor "") +AddCMakeTest(ProcessorCount "") AddCMakeTest(FileDownload "") set_property(TEST CMake.FileDownload PROPERTY diff --git a/Tests/CMakeTests/ProcessorCountTest.cmake.in b/Tests/CMakeTests/ProcessorCountTest.cmake.in new file mode 100644 index 000000000..0815fd847 --- /dev/null +++ b/Tests/CMakeTests/ProcessorCountTest.cmake.in @@ -0,0 +1,9 @@ +include(ProcessorCount) + +ProcessorCount(processor_count) +message("processor_count='${processor_count}'") + +if(processor_count EQUAL 0) + message(FATAL_ERROR "could not determine number of processors +- Additional code needed in ProcessorCount.cmake?") +endif() From 9cc8ad99c9ace52283e293ca3542b3303ce361ee Mon Sep 17 00:00:00 2001 From: David Cole Date: Fri, 5 Nov 2010 09:21:51 -0400 Subject: [PATCH 2/9] Add correct module notice header. Fixes failing ModuleNotices test. --- Modules/ProcessorCount.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/ProcessorCount.cmake b/Modules/ProcessorCount.cmake index e4aea1969..b46a0122f 100644 --- a/Modules/ProcessorCount.cmake +++ b/Modules/ProcessorCount.cmake @@ -11,7 +11,7 @@ # code. #============================================================================= -# Copyright 2002-2009 Kitware, Inc. +# Copyright 2010 Kitware, Inc. # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. @@ -20,7 +20,7 @@ # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the License for more information. #============================================================================= -# (To distributed this file outside of CMake, substitute the full +# (To distribute this file outside of CMake, substitute the full # License text for the above reference.) function(ProcessorCount var) From 4d6418f68353f888e08b42b86ea9eb7e2e2781e3 Mon Sep 17 00:00:00 2001 From: David Cole Date: Fri, 5 Nov 2010 15:57:21 -0400 Subject: [PATCH 3/9] If getconf returns empty output, try cpuinfo. (#11302) Also, add message output (temporarily) for gathering data on all the dashboard machines. After the test runs on the overnight dashboards tonight, I'll comment out the message output and commit/push again. --- Modules/ProcessorCount.cmake | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/Modules/ProcessorCount.cmake b/Modules/ProcessorCount.cmake index b46a0122f..5ccfbffed 100644 --- a/Modules/ProcessorCount.cmake +++ b/Modules/ProcessorCount.cmake @@ -30,6 +30,7 @@ function(ProcessorCount var) if(WIN32) # Windows: set(count "$ENV{NUMBER_OF_PROCESSORS}") + message("ProcessorCount: using environment variable") elseif(APPLE) # Mac: find_program(ProcessorCount_cmd_sysctl sysctl @@ -38,21 +39,29 @@ function(ProcessorCount var) execute_process(COMMAND ${ProcessorCount_cmd_sysctl} -n hw.ncpu OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE count) + message("ProcessorCount: using sysctl '${ProcessorCount_cmd_sysctl}'") endif() else() + # Linux (and other systems with getconf): find_program(ProcessorCount_cmd_getconf getconf) if(ProcessorCount_cmd_getconf) - # Linux and other systems with getconf: execute_process(COMMAND ${ProcessorCount_cmd_getconf} _NPROCESSORS_ONLN OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE count) - else() - # Linux and other systems with /proc/cpuinfo: - set(cpuinfo_file /proc/cpuinfo) - if(EXISTS "${cpuinfo_file}") - file(STRINGS "${cpuinfo_file}" procs REGEX "^processor.: [0-9]+$") - list(LENGTH procs count) - endif() + message("ProcessorCount: using getconf '${ProcessorCount_cmd_getconf}'") + endif() + endif() + + # Execute this code when there is no 'sysctl' or 'getconf' or + # when previously executed methods return empty output: + # + if(NOT count) + # Systems with /proc/cpuinfo: + set(cpuinfo_file /proc/cpuinfo) + if(EXISTS "${cpuinfo_file}") + file(STRINGS "${cpuinfo_file}" procs REGEX "^processor.: [0-9]+$") + list(LENGTH procs count) + message("ProcessorCount: using cpuinfo '${cpuinfo_file}'") endif() endif() From 3430955d5f207232ed0ada83d3e6519ae5c908eb Mon Sep 17 00:00:00 2001 From: David Cole Date: Mon, 8 Nov 2010 09:37:04 -0500 Subject: [PATCH 4/9] Add ProcessorCount support for QNX via pidin. (#11302) Thanks to Rolf Eike Beer for the code snippet parsing the pidin output. --- Modules/ProcessorCount.cmake | 24 ++++++++++++++++++-- Tests/CMakeTests/ProcessorCountTest.cmake.in | 6 ++++- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/Modules/ProcessorCount.cmake b/Modules/ProcessorCount.cmake index 5ccfbffed..5c382679f 100644 --- a/Modules/ProcessorCount.cmake +++ b/Modules/ProcessorCount.cmake @@ -42,7 +42,7 @@ function(ProcessorCount var) message("ProcessorCount: using sysctl '${ProcessorCount_cmd_sysctl}'") endif() else() - # Linux (and other systems with getconf): + # Linux (systems with getconf): find_program(ProcessorCount_cmd_getconf getconf) if(ProcessorCount_cmd_getconf) execute_process(COMMAND ${ProcessorCount_cmd_getconf} _NPROCESSORS_ONLN @@ -50,9 +50,22 @@ function(ProcessorCount var) OUTPUT_VARIABLE count) message("ProcessorCount: using getconf '${ProcessorCount_cmd_getconf}'") endif() + + if(NOT count) + # QNX (systems with pidin): + find_program(ProcessorCount_cmd_pidin pidin) + if(ProcessorCount_cmd_pidin) + execute_process(COMMAND ${ProcessorCount_cmd_pidin} info + OUTPUT_STRIP_TRAILING_WHITESPACE + OUTPUT_VARIABLE pidin_output) + string(REGEX MATCHALL "Processor[0-9]+: " procs "${pidin_output}") + list(LENGTH procs count) + message("ProcessorCount: using pidin '${ProcessorCount_cmd_pidin}'") + endif() + endif() endif() - # Execute this code when there is no 'sysctl' or 'getconf' or + # Execute this code when there is no 'sysctl' or 'getconf' or 'pidin' or # when previously executed methods return empty output: # if(NOT count) @@ -65,5 +78,12 @@ function(ProcessorCount var) endif() endif() + # Ensure an integer return (avoid inadvertently returning an empty string + # or an error string)... If it's not a decimal integer, return 0: + # + if(NOT count MATCHES "^[0-9]+$") + set(count 0) + endif() + set(${var} ${count} PARENT_SCOPE) endfunction() diff --git a/Tests/CMakeTests/ProcessorCountTest.cmake.in b/Tests/CMakeTests/ProcessorCountTest.cmake.in index 0815fd847..ac7a1da95 100644 --- a/Tests/CMakeTests/ProcessorCountTest.cmake.in +++ b/Tests/CMakeTests/ProcessorCountTest.cmake.in @@ -3,7 +3,11 @@ include(ProcessorCount) ProcessorCount(processor_count) message("processor_count='${processor_count}'") +if(NOT processor_count MATCHES "^[0-9]+$") + message(FATAL_ERROR "ProcessorCount function returned a non-integer") +endif() + if(processor_count EQUAL 0) message(FATAL_ERROR "could not determine number of processors -- Additional code needed in ProcessorCount.cmake?") +- Additional code for this platform needed in ProcessorCount.cmake?") endif() From 6259bc4222d7eb391a76ab5fd5e0460be238241e Mon Sep 17 00:00:00 2001 From: David Cole Date: Tue, 9 Nov 2010 14:29:52 -0500 Subject: [PATCH 5/9] Compare ProcessorCount to SystemInformation count. (#11302) Maximize output to gather data on the dashboards. Only FATAL_ERROR out once at the bottom if an error occurred earlier. --- Tests/CMakeTests/ProcessorCountTest.cmake.in | 40 ++++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/Tests/CMakeTests/ProcessorCountTest.cmake.in b/Tests/CMakeTests/ProcessorCountTest.cmake.in index ac7a1da95..6550973a8 100644 --- a/Tests/CMakeTests/ProcessorCountTest.cmake.in +++ b/Tests/CMakeTests/ProcessorCountTest.cmake.in @@ -3,11 +3,45 @@ include(ProcessorCount) ProcessorCount(processor_count) message("processor_count='${processor_count}'") -if(NOT processor_count MATCHES "^[0-9]+$") - message(FATAL_ERROR "ProcessorCount function returned a non-integer") +execute_process( + COMMAND "@CMAKE_BINARY_DIR@/Source/kwsys/$ENV{CMAKE_CONFIG_TYPE}/cmsysTestsCxx" + testSystemInformation + OUTPUT_VARIABLE out) +string(REGEX REPLACE "(.*)GetNumberOfPhysicalCPU:.([0-9]*)(.*)" "\\2" + system_info_processor_count "${out}") +message("system_info_processor_count='${system_info_processor_count}'") + +if(system_info_processor_count EQUAL processor_count) + message("processor count matches system information") endif() +# Evaluate possible error conditions: +# +set(err 0) + if(processor_count EQUAL 0) - message(FATAL_ERROR "could not determine number of processors + set(err 1) + message("could not determine number of processors - Additional code for this platform needed in ProcessorCount.cmake?") endif() + +if(NOT system_info_processor_count EQUAL processor_count) + set(err 2) + message("SystemInformation and ProcessorCount.cmake disagree:\n" + "processor_count='${processor_count}'\n" + "SystemInformation processor_count='${system_info_processor_count}'") +endif() + +if(NOT processor_count MATCHES "^[0-9]+$") + set(err 3) + message("ProcessorCount function returned a non-integer") +endif() + +if(NOT system_info_processor_count MATCHES "^[0-9]+$") + set(err 4) + message("SystemInformation ProcessorCount function returned a non-integer") +endif() + +if(err) + message(FATAL_ERROR "err='${err}'") +endif() From c15983690f23ee9e39aced14cf74b55595d7d391 Mon Sep 17 00:00:00 2001 From: David Cole Date: Wed, 10 Nov 2010 10:23:50 -0500 Subject: [PATCH 6/9] ProcessorCount test: more output, do not fail. (#11302) More dev work remains to be done here. Removing test failure condition until that dev work is complete, so it does not mask or hide other, more important failures, on the dashboard. --- Tests/CMakeTests/ProcessorCountTest.cmake.in | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/Tests/CMakeTests/ProcessorCountTest.cmake.in b/Tests/CMakeTests/ProcessorCountTest.cmake.in index 6550973a8..c653628e7 100644 --- a/Tests/CMakeTests/ProcessorCountTest.cmake.in +++ b/Tests/CMakeTests/ProcessorCountTest.cmake.in @@ -9,39 +9,56 @@ execute_process( OUTPUT_VARIABLE out) string(REGEX REPLACE "(.*)GetNumberOfPhysicalCPU:.([0-9]*)(.*)" "\\2" system_info_processor_count "${out}") + message("system_info_processor_count='${system_info_processor_count}'") if(system_info_processor_count EQUAL processor_count) message("processor count matches system information") endif() +message("") +message("CTEST_FULL_OUTPUT (Avoid ctest truncation of output)") +message("") +message("out='${out}'") +message("") + # Evaluate possible error conditions: # set(err 0) if(processor_count EQUAL 0) set(err 1) + message("err 1") message("could not determine number of processors - Additional code for this platform needed in ProcessorCount.cmake?") + message("") endif() if(NOT system_info_processor_count EQUAL processor_count) set(err 2) + message("err 2") message("SystemInformation and ProcessorCount.cmake disagree:\n" "processor_count='${processor_count}'\n" "SystemInformation processor_count='${system_info_processor_count}'") + message("") endif() if(NOT processor_count MATCHES "^[0-9]+$") set(err 3) + message("err 3") message("ProcessorCount function returned a non-integer") + message("") endif() if(NOT system_info_processor_count MATCHES "^[0-9]+$") set(err 4) + message("err 4") message("SystemInformation ProcessorCount function returned a non-integer") + message("") endif() +# TODO: Make this test fail again, once all the dev work is done... +# if(err) - message(FATAL_ERROR "err='${err}'") +# message(FATAL_ERROR "err='${err}'") endif() From 6dd74d5a593e422dcc588ad8bc37382e06e8b256 Mon Sep 17 00:00:00 2001 From: David Cole Date: Wed, 9 Mar 2011 14:06:58 -0500 Subject: [PATCH 7/9] ProcessorCount: Add support for remaining platforms (#11302) Including AIX, cygwin, FreeBSD, HPUX, IRIX, OpenBSD and Sun. --- Modules/ProcessorCount.cmake | 131 ++++++++++++++++++++++++++++------- 1 file changed, 105 insertions(+), 26 deletions(-) diff --git a/Modules/ProcessorCount.cmake b/Modules/ProcessorCount.cmake index 5c382679f..001f928cc 100644 --- a/Modules/ProcessorCount.cmake +++ b/Modules/ProcessorCount.cmake @@ -3,15 +3,27 @@ # # Sets the variable named ${var} to the number of physical cores available on # the machine if the information can be determined. Otherwise it is set to 0. -# Currently this functionality is only implemented for Windows, Mac OS X and -# Unix systems providing getconf or the /proc/cpuinfo interface (e.g. Linux). +# Currently this functionality is implemented for AIX, cygwin, FreeBSD, HPUX, +# IRIX, Linux, Mac OS X, QNX, Sun and Windows. +# +# This function is guaranteed to return a positive integer (>=1) if it +# succeeds. It returns 0 if there's a problem determining the processor count. +# +# Example use, in a ctest -S dashboard script: +# +# include(ProcessorCount) +# ProcessorCount(N) +# if(NOT N EQUAL 0) +# set(CTEST_BUILD_FLAGS -j${N}) +# set(ctest_test_args ${ctest_test_args} PARALLEL_LEVEL ${N}) +# endif() # A more reliable way might be to compile a small C program that uses the CPUID # instruction, but that again requires compiler support or compiling assembler # code. #============================================================================= -# Copyright 2010 Kitware, Inc. +# Copyright 2010-2011 Kitware, Inc. # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. @@ -30,43 +42,102 @@ function(ProcessorCount var) if(WIN32) # Windows: set(count "$ENV{NUMBER_OF_PROCESSORS}") - message("ProcessorCount: using environment variable") - elseif(APPLE) - # Mac: + message("ProcessorCount: WIN32, trying environment variable") + endif() + + if(NOT count) + # Mac, FreeBSD, OpenBSD (systems with sysctl): find_program(ProcessorCount_cmd_sysctl sysctl - PATHS /usr/sbin) + PATHS /usr/sbin /sbin) if(ProcessorCount_cmd_sysctl) execute_process(COMMAND ${ProcessorCount_cmd_sysctl} -n hw.ncpu OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE count) - message("ProcessorCount: using sysctl '${ProcessorCount_cmd_sysctl}'") + message("ProcessorCount: trying sysctl '${ProcessorCount_cmd_sysctl}'") endif() - else() + endif() + + if(NOT count) # Linux (systems with getconf): find_program(ProcessorCount_cmd_getconf getconf) if(ProcessorCount_cmd_getconf) execute_process(COMMAND ${ProcessorCount_cmd_getconf} _NPROCESSORS_ONLN OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE count) - message("ProcessorCount: using getconf '${ProcessorCount_cmd_getconf}'") - endif() - - if(NOT count) - # QNX (systems with pidin): - find_program(ProcessorCount_cmd_pidin pidin) - if(ProcessorCount_cmd_pidin) - execute_process(COMMAND ${ProcessorCount_cmd_pidin} info - OUTPUT_STRIP_TRAILING_WHITESPACE - OUTPUT_VARIABLE pidin_output) - string(REGEX MATCHALL "Processor[0-9]+: " procs "${pidin_output}") - list(LENGTH procs count) - message("ProcessorCount: using pidin '${ProcessorCount_cmd_pidin}'") - endif() + message("ProcessorCount: trying getconf '${ProcessorCount_cmd_getconf}'") endif() endif() - # Execute this code when there is no 'sysctl' or 'getconf' or 'pidin' or - # when previously executed methods return empty output: + if(NOT count) + # HPUX (systems with machinfo): + find_program(ProcessorCount_cmd_machinfo machinfo + PATHS /usr/contrib/bin) + if(ProcessorCount_cmd_machinfo) + execute_process(COMMAND ${ProcessorCount_cmd_machinfo} + OUTPUT_STRIP_TRAILING_WHITESPACE + OUTPUT_VARIABLE machinfo_output) + string(REGEX MATCHALL "Number of CPUs = ([0-9]+)" procs "${machinfo_output}") + set(count "${CMAKE_MATCH_1}") + message("ProcessorCount: trying machinfo '${ProcessorCount_cmd_machinfo}'") + endif() + endif() + + if(NOT count) + # IRIX (systems with hinv): + find_program(ProcessorCount_cmd_hinv hinv + PATHS /sbin) + if(ProcessorCount_cmd_hinv) + execute_process(COMMAND ${ProcessorCount_cmd_hinv} + OUTPUT_STRIP_TRAILING_WHITESPACE + OUTPUT_VARIABLE hinv_output) + string(REGEX MATCHALL "([0-9]+) .* Processors" procs "${hinv_output}") + set(count "${CMAKE_MATCH_1}") + message("ProcessorCount: trying hinv '${ProcessorCount_cmd_hinv}'") + endif() + endif() + + if(NOT count) + # AIX (systems with lsconf): + find_program(ProcessorCount_cmd_lsconf lsconf + PATHS /usr/sbin) + if(ProcessorCount_cmd_lsconf) + execute_process(COMMAND ${ProcessorCount_cmd_lsconf} + OUTPUT_STRIP_TRAILING_WHITESPACE + OUTPUT_VARIABLE lsconf_output) + string(REGEX MATCHALL "Number Of Processors: ([0-9]+)" procs "${lsconf_output}") + set(count "${CMAKE_MATCH_1}") + message("ProcessorCount: trying lsconf '${ProcessorCount_cmd_lsconf}'") + endif() + endif() + + if(NOT count) + # QNX (systems with pidin): + find_program(ProcessorCount_cmd_pidin pidin) + if(ProcessorCount_cmd_pidin) + execute_process(COMMAND ${ProcessorCount_cmd_pidin} info + OUTPUT_STRIP_TRAILING_WHITESPACE + OUTPUT_VARIABLE pidin_output) + string(REGEX MATCHALL "Processor[0-9]+: " procs "${pidin_output}") + list(LENGTH procs count) + message("ProcessorCount: trying pidin '${ProcessorCount_cmd_pidin}'") + endif() + endif() + + if(NOT count) + # Sun (systems where uname -X emits "NumCPU" in its output): + find_program(ProcessorCount_cmd_uname uname) + if(ProcessorCount_cmd_uname) + execute_process(COMMAND ${ProcessorCount_cmd_uname} -X + OUTPUT_STRIP_TRAILING_WHITESPACE + OUTPUT_VARIABLE uname_X_output) + string(REGEX MATCHALL "NumCPU = ([0-9]+)" procs "${uname_X_output}") + set(count "${CMAKE_MATCH_1}") + message("ProcessorCount: trying uname -X '${ProcessorCount_cmd_uname}'") + endif() + endif() + + # Execute this code when all previously attempted methods return empty + # output: # if(NOT count) # Systems with /proc/cpuinfo: @@ -74,10 +145,18 @@ function(ProcessorCount var) if(EXISTS "${cpuinfo_file}") file(STRINGS "${cpuinfo_file}" procs REGEX "^processor.: [0-9]+$") list(LENGTH procs count) - message("ProcessorCount: using cpuinfo '${cpuinfo_file}'") + message("ProcessorCount: trying cpuinfo '${cpuinfo_file}'") endif() endif() + # Since cygwin builds of CMake do not define WIN32 anymore, but they still + # run on Windows, and will still have this env var defined: + # + if(NOT count) + set(count "$ENV{NUMBER_OF_PROCESSORS}") + message("ProcessorCount: last fallback, trying environment variable") + endif() + # Ensure an integer return (avoid inadvertently returning an empty string # or an error string)... If it's not a decimal integer, return 0: # From 4dd2ec2cb9dec683eafd3b303e04418c694675a3 Mon Sep 17 00:00:00 2001 From: David Cole Date: Wed, 9 Mar 2011 16:21:10 -0500 Subject: [PATCH 8/9] ProcessorCount: Test fails if count is 0 (#11302) It also fails if count is not a decimal integer. --- Tests/CMakeTests/ProcessorCountTest.cmake.in | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Tests/CMakeTests/ProcessorCountTest.cmake.in b/Tests/CMakeTests/ProcessorCountTest.cmake.in index c653628e7..c5feb315c 100644 --- a/Tests/CMakeTests/ProcessorCountTest.cmake.in +++ b/Tests/CMakeTests/ProcessorCountTest.cmake.in @@ -25,9 +25,11 @@ message("") # Evaluate possible error conditions: # set(err 0) +set(fatal 0) if(processor_count EQUAL 0) set(err 1) + set(fatal 1) message("err 1") message("could not determine number of processors - Additional code for this platform needed in ProcessorCount.cmake?") @@ -45,6 +47,7 @@ endif() if(NOT processor_count MATCHES "^[0-9]+$") set(err 3) + set(fatal 1) message("err 3") message("ProcessorCount function returned a non-integer") message("") @@ -57,8 +60,6 @@ if(NOT system_info_processor_count MATCHES "^[0-9]+$") message("") endif() -# TODO: Make this test fail again, once all the dev work is done... -# -if(err) -# message(FATAL_ERROR "err='${err}'") +if(fatal) + message(FATAL_ERROR "processor_count='${processor_count}' - see previous test output for more details - it is likely more/different code is needed in ProcessorCount.cmake to fix this test failure - processor_count should be a non-zero positive integer (>=1) for all supported CMake platforms") endif() From e6c2701002a1c4620cbc58083698bd961e1ab999 Mon Sep 17 00:00:00 2001 From: David Cole Date: Fri, 18 Mar 2011 14:28:24 -0400 Subject: [PATCH 9/9] ProcessorCount: Use ERROR_QUIET with execute_process (#11302) Also, comment out all "debugging" calls to message() that helped us interpret the output on other platforms when running on the dashboard clients. Using ERROR_QUIET avoids unnecessary stderr output while calling external tools to determine the processor count. If there's an error parsing the output, we set the count to 0 anyhow. Also, the test will fail on a CMake dashboard run if the count comes back equal to 0. Now that the code is "done"-ish, remove the debugging output. Expect no output on stdout or stderr when calling the ProcessorCount function from now on. --- Modules/ProcessorCount.cmake | 35 ++++++++++++++------ Tests/CMakeTests/ProcessorCountTest.cmake.in | 13 ++++++-- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/Modules/ProcessorCount.cmake b/Modules/ProcessorCount.cmake index 001f928cc..eff4766b1 100644 --- a/Modules/ProcessorCount.cmake +++ b/Modules/ProcessorCount.cmake @@ -17,6 +17,14 @@ # set(CTEST_BUILD_FLAGS -j${N}) # set(ctest_test_args ${ctest_test_args} PARALLEL_LEVEL ${N}) # endif() +# +# This function is intended to offer an approximation of the value of the +# number of compute cores available on the current machine, such that you +# may use that value for parallel building and parallel testing. It is meant +# to help utilize as much of the machine as seems reasonable. Of course, +# knowledge of what else might be running on the machine simultaneously +# should be used when deciding whether to request a machine's full capacity +# all for yourself. # A more reliable way might be to compile a small C program that uses the CPUID # instruction, but that again requires compiler support or compiling assembler @@ -42,7 +50,7 @@ function(ProcessorCount var) if(WIN32) # Windows: set(count "$ENV{NUMBER_OF_PROCESSORS}") - message("ProcessorCount: WIN32, trying environment variable") + #message("ProcessorCount: WIN32, trying environment variable") endif() if(NOT count) @@ -51,9 +59,10 @@ function(ProcessorCount var) PATHS /usr/sbin /sbin) if(ProcessorCount_cmd_sysctl) execute_process(COMMAND ${ProcessorCount_cmd_sysctl} -n hw.ncpu + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE count) - message("ProcessorCount: trying sysctl '${ProcessorCount_cmd_sysctl}'") + #message("ProcessorCount: trying sysctl '${ProcessorCount_cmd_sysctl}'") endif() endif() @@ -62,9 +71,10 @@ function(ProcessorCount var) find_program(ProcessorCount_cmd_getconf getconf) if(ProcessorCount_cmd_getconf) execute_process(COMMAND ${ProcessorCount_cmd_getconf} _NPROCESSORS_ONLN + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE count) - message("ProcessorCount: trying getconf '${ProcessorCount_cmd_getconf}'") + #message("ProcessorCount: trying getconf '${ProcessorCount_cmd_getconf}'") endif() endif() @@ -74,11 +84,12 @@ function(ProcessorCount var) PATHS /usr/contrib/bin) if(ProcessorCount_cmd_machinfo) execute_process(COMMAND ${ProcessorCount_cmd_machinfo} + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE machinfo_output) string(REGEX MATCHALL "Number of CPUs = ([0-9]+)" procs "${machinfo_output}") set(count "${CMAKE_MATCH_1}") - message("ProcessorCount: trying machinfo '${ProcessorCount_cmd_machinfo}'") + #message("ProcessorCount: trying machinfo '${ProcessorCount_cmd_machinfo}'") endif() endif() @@ -88,11 +99,12 @@ function(ProcessorCount var) PATHS /sbin) if(ProcessorCount_cmd_hinv) execute_process(COMMAND ${ProcessorCount_cmd_hinv} + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE hinv_output) string(REGEX MATCHALL "([0-9]+) .* Processors" procs "${hinv_output}") set(count "${CMAKE_MATCH_1}") - message("ProcessorCount: trying hinv '${ProcessorCount_cmd_hinv}'") + #message("ProcessorCount: trying hinv '${ProcessorCount_cmd_hinv}'") endif() endif() @@ -102,11 +114,12 @@ function(ProcessorCount var) PATHS /usr/sbin) if(ProcessorCount_cmd_lsconf) execute_process(COMMAND ${ProcessorCount_cmd_lsconf} + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE lsconf_output) string(REGEX MATCHALL "Number Of Processors: ([0-9]+)" procs "${lsconf_output}") set(count "${CMAKE_MATCH_1}") - message("ProcessorCount: trying lsconf '${ProcessorCount_cmd_lsconf}'") + #message("ProcessorCount: trying lsconf '${ProcessorCount_cmd_lsconf}'") endif() endif() @@ -115,11 +128,12 @@ function(ProcessorCount var) find_program(ProcessorCount_cmd_pidin pidin) if(ProcessorCount_cmd_pidin) execute_process(COMMAND ${ProcessorCount_cmd_pidin} info + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE pidin_output) string(REGEX MATCHALL "Processor[0-9]+: " procs "${pidin_output}") list(LENGTH procs count) - message("ProcessorCount: trying pidin '${ProcessorCount_cmd_pidin}'") + #message("ProcessorCount: trying pidin '${ProcessorCount_cmd_pidin}'") endif() endif() @@ -128,11 +142,12 @@ function(ProcessorCount var) find_program(ProcessorCount_cmd_uname uname) if(ProcessorCount_cmd_uname) execute_process(COMMAND ${ProcessorCount_cmd_uname} -X + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE uname_X_output) string(REGEX MATCHALL "NumCPU = ([0-9]+)" procs "${uname_X_output}") set(count "${CMAKE_MATCH_1}") - message("ProcessorCount: trying uname -X '${ProcessorCount_cmd_uname}'") + #message("ProcessorCount: trying uname -X '${ProcessorCount_cmd_uname}'") endif() endif() @@ -145,7 +160,7 @@ function(ProcessorCount var) if(EXISTS "${cpuinfo_file}") file(STRINGS "${cpuinfo_file}" procs REGEX "^processor.: [0-9]+$") list(LENGTH procs count) - message("ProcessorCount: trying cpuinfo '${cpuinfo_file}'") + #message("ProcessorCount: trying cpuinfo '${cpuinfo_file}'") endif() endif() @@ -154,7 +169,7 @@ function(ProcessorCount var) # if(NOT count) set(count "$ENV{NUMBER_OF_PROCESSORS}") - message("ProcessorCount: last fallback, trying environment variable") + #message("ProcessorCount: last fallback, trying environment variable") endif() # Ensure an integer return (avoid inadvertently returning an empty string diff --git a/Tests/CMakeTests/ProcessorCountTest.cmake.in b/Tests/CMakeTests/ProcessorCountTest.cmake.in index c5feb315c..98f6ab16d 100644 --- a/Tests/CMakeTests/ProcessorCountTest.cmake.in +++ b/Tests/CMakeTests/ProcessorCountTest.cmake.in @@ -1,14 +1,20 @@ include(ProcessorCount) ProcessorCount(processor_count) + +message("### 1. This line should be the first line of text in the test output.") +message("### 2. If there was output from this test before line #1, then the") +message("### 3. ProcessorCount(...) function call is emitting output that it shouldn't...") + message("processor_count='${processor_count}'") execute_process( COMMAND "@CMAKE_BINARY_DIR@/Source/kwsys/$ENV{CMAKE_CONFIG_TYPE}/cmsysTestsCxx" testSystemInformation - OUTPUT_VARIABLE out) + OUTPUT_VARIABLE tsi_out + ERROR_VARIABLE tsi_err) string(REGEX REPLACE "(.*)GetNumberOfPhysicalCPU:.([0-9]*)(.*)" "\\2" - system_info_processor_count "${out}") + system_info_processor_count "${tsi_out}") message("system_info_processor_count='${system_info_processor_count}'") @@ -19,7 +25,8 @@ endif() message("") message("CTEST_FULL_OUTPUT (Avoid ctest truncation of output)") message("") -message("out='${out}'") +message("tsi_out='${tsi_out}'") +message("tsi_err='${tsi_err}'") message("") # Evaluate possible error conditions: