From 204701fe1e1ce697b6af0a34799702345a38ca73 Mon Sep 17 00:00:00 2001 From: Alice Boucher Date: Wed, 3 Sep 2025 13:04:07 +0000 Subject: [PATCH 1/3] Print version / machine info before solving --- .../linear_programming/cuopt/run_mip.cpp | 192 ++++++++++++++++++ cpp/CMakeLists.txt | 16 ++ cpp/cuopt_cli.cpp | 191 +++++++++++++++++ 3 files changed, 399 insertions(+) diff --git a/benchmarks/linear_programming/cuopt/run_mip.cpp b/benchmarks/linear_programming/cuopt/run_mip.cpp index 713d55f16b..6f5387dd1e 100644 --- a/benchmarks/linear_programming/cuopt/run_mip.cpp +++ b/benchmarks/linear_programming/cuopt/run_mip.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -290,6 +291,148 @@ void return_gpu_to_the_queue(std::unordered_map& pid_gpu_map, pid_file_map.erase(pid); } +static int get_physical_cores() +{ + std::ifstream cpuinfo("/proc/cpuinfo"); + if (!cpuinfo.is_open()) return 0; + + std::string line; + int physical_id = -1, core_id = -1; + std::set> cores; + + while (std::getline(cpuinfo, line)) { + if (line.find("physical id") != std::string::npos) { + physical_id = std::stoi(line.substr(line.find(":") + 1)); + } else if (line.find("core id") != std::string::npos) { + core_id = std::stoi(line.substr(line.find(":") + 1)); + } + + if (physical_id != -1 && core_id != -1) { + cores.insert({physical_id, core_id}); + physical_id = -1; + core_id = -1; + } + } + + if (cores.empty()) { + cpuinfo.clear(); + cpuinfo.seekg(0); + while (std::getline(cpuinfo, line)) { + if (line.find("cpu cores") != std::string::npos) { + return std::stoi(line.substr(line.find(":") + 1)); + } + } + return 1; + } + return cores.size(); +} + +static std::string get_cpu_model_from_proc() +{ + std::ifstream cpuinfo("/proc/cpuinfo"); + if (!cpuinfo.is_open()) return ""; + + std::string line; + while (std::getline(cpuinfo, line)) { + std::size_t pos = line.find("model name"); + if (pos == std::string::npos) pos = line.find("Processor"); + if (pos != std::string::npos) { + std::size_t colon = line.find(':', pos); + if (colon != std::string::npos) return line.substr(colon + 2); // Skip ": " + } + } + return ""; +} + +// From https://gcc.gnu.org/onlinedocs/gcc/x86-Built-in-Functions.html +// Also supported by clang +static std::string get_cpu_model_builtin() +{ +#if defined(__GNUC__) || defined(__clang__) + __builtin_cpu_init(); + return __builtin_cpu_is("amd") ? "AMD CPU" + : __builtin_cpu_is("intel") ? "Intel CPU" + : __builtin_cpu_is("atom") ? "Intel Atom CPU" + : __builtin_cpu_is("slm") ? "Intel Silvermont CPU" + : __builtin_cpu_is("core2") ? "Intel Core 2 CPU" + : __builtin_cpu_is("corei7") ? "Intel Core i7 CPU" + : __builtin_cpu_is("nehalem") ? "Intel Core i7 Nehalem CPU" + : __builtin_cpu_is("westmere") ? "Intel Core i7 Westmere CPU" + : __builtin_cpu_is("sandybridge") ? "Intel Core i7 Sandy Bridge CPU" + : __builtin_cpu_is("ivybridge") ? "Intel Core i7 Ivy Bridge CPU" + : __builtin_cpu_is("haswell") ? "Intel Core i7 Haswell CPU" + : __builtin_cpu_is("broadwell") ? "Intel Core i7 Broadwell CPU" + : __builtin_cpu_is("skylake") ? "Intel Core i7 Skylake CPU" + : __builtin_cpu_is("skylake-avx512") ? "Intel Core i7 Skylake AVX512 CPU" + : __builtin_cpu_is("cannonlake") ? "Intel Core i7 Cannon Lake CPU" + : __builtin_cpu_is("icelake-client") ? "Intel Core i7 Ice Lake Client CPU" + : __builtin_cpu_is("icelake-server") ? "Intel Core i7 Ice Lake Server CPU" + : __builtin_cpu_is("cascadelake") ? "Intel Core i7 Cascadelake CPU" + : __builtin_cpu_is("tigerlake") ? "Intel Core i7 Tigerlake CPU" + : __builtin_cpu_is("cooperlake") ? "Intel Core i7 Cooperlake CPU" + : __builtin_cpu_is("sapphirerapids") ? "Intel Core i7 sapphirerapids CPU" + : __builtin_cpu_is("alderlake") ? "Intel Core i7 Alderlake CPU" + : __builtin_cpu_is("rocketlake") ? "Intel Core i7 Rocketlake CPU" + : __builtin_cpu_is("graniterapids") ? "Intel Core i7 graniterapids CPU" + : __builtin_cpu_is("graniterapids-d") ? "Intel Core i7 graniterapids D CPU" + : __builtin_cpu_is("bonnell") ? "Intel Atom Bonnell CPU" + : __builtin_cpu_is("silvermont") ? "Intel Atom Silvermont CPU" + : __builtin_cpu_is("goldmont") ? "Intel Atom Goldmont CPU" + : __builtin_cpu_is("goldmont-plus") ? "Intel Atom Goldmont Plus CPU" + : __builtin_cpu_is("tremont") ? "Intel Atom Tremont CPU" + : __builtin_cpu_is("sierraforest") ? "Intel Atom Sierra Forest CPU" + : __builtin_cpu_is("grandridge") ? "Intel Atom Grand Ridge CPU" + : __builtin_cpu_is("amdfam10h") ? "AMD Family 10h CPU" + : __builtin_cpu_is("barcelona") ? "AMD Family 10h Barcelona CPU" + : __builtin_cpu_is("shanghai") ? "AMD Family 10h Shanghai CPU" + : __builtin_cpu_is("istanbul") ? "AMD Family 10h Istanbul CPU" + : __builtin_cpu_is("btver1") ? "AMD Family 14h CPU" + : __builtin_cpu_is("amdfam15h") ? "AMD Family 15h CPU" + : __builtin_cpu_is("bdver1") ? "AMD Family 15h Bulldozer version 1" + : __builtin_cpu_is("bdver2") ? "AMD Family 15h Bulldozer version 2" + : __builtin_cpu_is("bdver3") ? "AMD Family 15h Bulldozer version 3" + : __builtin_cpu_is("bdver4") ? "AMD Family 15h Bulldozer version 4" + : __builtin_cpu_is("btver2") ? "AMD Family 16h CPU" + : __builtin_cpu_is("amdfam17h") ? "AMD Family 17h CPU" + : __builtin_cpu_is("znver1") ? "AMD Family 17h Zen version 1" + : __builtin_cpu_is("znver2") ? "AMD Family 17h Zen version 2" + : __builtin_cpu_is("amdfam19h") ? "AMD Family 19h CPU" + : "Unknown"; +#else + return "Unknown"; +#endif +} + +static std::string get_cpu_model() +{ + if (auto model_from_proc = get_cpu_model_from_proc(); !model_from_proc.empty()) { + return model_from_proc; + } else if (auto model_from_builtin = get_cpu_model_builtin(); !model_from_builtin.empty()) { + return model_from_builtin; + } + return "Unknown"; +} + +static double get_available_memory_gb() +{ + std::ifstream meminfo("/proc/meminfo"); + if (!meminfo.is_open()) return 0.0; + + std::string line; + long kb = 0; + while (std::getline(meminfo, line)) { + if (line.find("MemAvailable:") == 0 || line.find("MemFree:") == 0) { + std::size_t pos = line.find_first_of("0123456789"); + if (pos != std::string::npos) { + kb = std::stol(line.substr(pos)); + break; + } + } + } + + return kb / (1024.0 * 1024.0); // Convert KB to GB +} + int main(int argc, char* argv[]) { argparse::ArgumentParser program("solve_mps_file"); @@ -383,6 +526,55 @@ int main(int argc, char* argv[]) initial_solution_file = program.get("--initial-solution-path"); } + int device_id = 0; + cudaGetDevice(&device_id); + cudaDeviceProp device_prop; + cudaGetDeviceProperties(&device_prop, device_id); + cudaUUID_t uuid = device_prop.uuid; + char uuid_str[37] = {0}; + snprintf(uuid_str, + sizeof(uuid_str), + "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + uuid.bytes[0], + uuid.bytes[1], + uuid.bytes[2], + uuid.bytes[3], + uuid.bytes[4], + uuid.bytes[5], + uuid.bytes[6], + uuid.bytes[7], + uuid.bytes[8], + uuid.bytes[9], + uuid.bytes[10], + uuid.bytes[11], + uuid.bytes[12], + uuid.bytes[13], + uuid.bytes[14], + uuid.bytes[15]); + int version = 0; + cudaRuntimeGetVersion(&version); + int major = version / 1000; + int minor = (version % 1000) / 10; + printf("cuOpt version: %d.%d.%d, git hash: %s, host arch: %s, device archs: %s\n", + CUOPT_VERSION_MAJOR, + CUOPT_VERSION_MINOR, + CUOPT_VERSION_PATCH, + CUOPT_GIT_COMMIT_HASH, + CUOPT_CPU_ARCHITECTURE, + CUOPT_CUDA_ARCHITECTURES); + printf("CPU: %s, threads (physical/logical): %d/%d, RAM: %.2f GiB\n", + get_cpu_model().c_str(), + get_physical_cores(), + std::thread::hardware_concurrency(), + get_available_memory_gb()); + printf("CUDA %d.%d, device: %s (ID %d), VRAM: %.2f GiB\n", + major, + minor, + device_prop.name, + device_id, + (double)device_prop.totalGlobalMem / (1024.0 * 1024.0 * 1024.0)); + printf("CUDA device UUID: %s\n\n", uuid_str); + if (run_dir) { std::queue task_queue; std::queue gpu_queue; diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 76c856e0e5..4e6fce2c1c 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -367,6 +367,18 @@ target_compile_options(cuopt_cli "$<$:${CUOPT_CUDA_FLAGS}>" ) +execute_process( + COMMAND git rev-parse --short HEAD + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE GIT_COMMIT_HASH + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +target_compile_definitions(cuopt_cli PUBLIC + "CUOPT_GIT_COMMIT_HASH=\"${GIT_COMMIT_HASH}\"" + "CUOPT_CUDA_ARCHITECTURES=\"${CMAKE_CUDA_ARCHITECTURES}\"" + "CUOPT_CPU_ARCHITECTURE=\"${CMAKE_SYSTEM_PROCESSOR}\"") + target_include_directories(cuopt_cli PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src" @@ -398,6 +410,10 @@ if(BUILD_BENCHMARKS) PRIVATE "$<$:${CUOPT_CXX_FLAGS}>" "$<$:${CUOPT_CUDA_FLAGS}>" ) + target_compile_definitions(solve_MPS_file PUBLIC + "CUOPT_GIT_COMMIT_HASH=\"${GIT_COMMIT_HASH}\"" + "CUOPT_CUDA_ARCHITECTURES=\"${CMAKE_CUDA_ARCHITECTURES}\"" + "CUOPT_CPU_ARCHITECTURE=\"${CMAKE_SYSTEM_PROCESSOR}\"") target_link_libraries(solve_MPS_file PUBLIC cuopt diff --git a/cpp/cuopt_cli.cpp b/cpp/cuopt_cli.cpp index ac22cf9fe2..a5299c56b0 100644 --- a/cpp/cuopt_cli.cpp +++ b/cpp/cuopt_cli.cpp @@ -67,6 +67,148 @@ * parameters, and write the solution to a .sol file in the output directory. */ +static int get_physical_cores() +{ + std::ifstream cpuinfo("/proc/cpuinfo"); + if (!cpuinfo.is_open()) return 0; + + std::string line; + int physical_id = -1, core_id = -1; + std::set> cores; + + while (std::getline(cpuinfo, line)) { + if (line.find("physical id") != std::string::npos) { + physical_id = std::stoi(line.substr(line.find(":") + 1)); + } else if (line.find("core id") != std::string::npos) { + core_id = std::stoi(line.substr(line.find(":") + 1)); + } + + if (physical_id != -1 && core_id != -1) { + cores.insert({physical_id, core_id}); + physical_id = -1; + core_id = -1; + } + } + + if (cores.empty()) { + cpuinfo.clear(); + cpuinfo.seekg(0); + while (std::getline(cpuinfo, line)) { + if (line.find("cpu cores") != std::string::npos) { + return std::stoi(line.substr(line.find(":") + 1)); + } + } + return 1; + } + return cores.size(); +} + +static std::string get_cpu_model_from_proc() +{ + std::ifstream cpuinfo("/proc/cpuinfo"); + if (!cpuinfo.is_open()) return ""; + + std::string line; + while (std::getline(cpuinfo, line)) { + std::size_t pos = line.find("model name"); + if (pos == std::string::npos) pos = line.find("Processor"); + if (pos != std::string::npos) { + std::size_t colon = line.find(':', pos); + if (colon != std::string::npos) return line.substr(colon + 2); // Skip ": " + } + } + return ""; +} + +// From https://gcc.gnu.org/onlinedocs/gcc/x86-Built-in-Functions.html +// Also supported by clang +static std::string get_cpu_model_builtin() +{ +#if defined(__GNUC__) || defined(__clang__) + __builtin_cpu_init(); + return __builtin_cpu_is("amd") ? "AMD CPU" + : __builtin_cpu_is("intel") ? "Intel CPU" + : __builtin_cpu_is("atom") ? "Intel Atom CPU" + : __builtin_cpu_is("slm") ? "Intel Silvermont CPU" + : __builtin_cpu_is("core2") ? "Intel Core 2 CPU" + : __builtin_cpu_is("corei7") ? "Intel Core i7 CPU" + : __builtin_cpu_is("nehalem") ? "Intel Core i7 Nehalem CPU" + : __builtin_cpu_is("westmere") ? "Intel Core i7 Westmere CPU" + : __builtin_cpu_is("sandybridge") ? "Intel Core i7 Sandy Bridge CPU" + : __builtin_cpu_is("ivybridge") ? "Intel Core i7 Ivy Bridge CPU" + : __builtin_cpu_is("haswell") ? "Intel Core i7 Haswell CPU" + : __builtin_cpu_is("broadwell") ? "Intel Core i7 Broadwell CPU" + : __builtin_cpu_is("skylake") ? "Intel Core i7 Skylake CPU" + : __builtin_cpu_is("skylake-avx512") ? "Intel Core i7 Skylake AVX512 CPU" + : __builtin_cpu_is("cannonlake") ? "Intel Core i7 Cannon Lake CPU" + : __builtin_cpu_is("icelake-client") ? "Intel Core i7 Ice Lake Client CPU" + : __builtin_cpu_is("icelake-server") ? "Intel Core i7 Ice Lake Server CPU" + : __builtin_cpu_is("cascadelake") ? "Intel Core i7 Cascadelake CPU" + : __builtin_cpu_is("tigerlake") ? "Intel Core i7 Tigerlake CPU" + : __builtin_cpu_is("cooperlake") ? "Intel Core i7 Cooperlake CPU" + : __builtin_cpu_is("sapphirerapids") ? "Intel Core i7 sapphirerapids CPU" + : __builtin_cpu_is("alderlake") ? "Intel Core i7 Alderlake CPU" + : __builtin_cpu_is("rocketlake") ? "Intel Core i7 Rocketlake CPU" + : __builtin_cpu_is("graniterapids") ? "Intel Core i7 graniterapids CPU" + : __builtin_cpu_is("graniterapids-d") ? "Intel Core i7 graniterapids D CPU" + : __builtin_cpu_is("bonnell") ? "Intel Atom Bonnell CPU" + : __builtin_cpu_is("silvermont") ? "Intel Atom Silvermont CPU" + : __builtin_cpu_is("goldmont") ? "Intel Atom Goldmont CPU" + : __builtin_cpu_is("goldmont-plus") ? "Intel Atom Goldmont Plus CPU" + : __builtin_cpu_is("tremont") ? "Intel Atom Tremont CPU" + : __builtin_cpu_is("sierraforest") ? "Intel Atom Sierra Forest CPU" + : __builtin_cpu_is("grandridge") ? "Intel Atom Grand Ridge CPU" + : __builtin_cpu_is("amdfam10h") ? "AMD Family 10h CPU" + : __builtin_cpu_is("barcelona") ? "AMD Family 10h Barcelona CPU" + : __builtin_cpu_is("shanghai") ? "AMD Family 10h Shanghai CPU" + : __builtin_cpu_is("istanbul") ? "AMD Family 10h Istanbul CPU" + : __builtin_cpu_is("btver1") ? "AMD Family 14h CPU" + : __builtin_cpu_is("amdfam15h") ? "AMD Family 15h CPU" + : __builtin_cpu_is("bdver1") ? "AMD Family 15h Bulldozer version 1" + : __builtin_cpu_is("bdver2") ? "AMD Family 15h Bulldozer version 2" + : __builtin_cpu_is("bdver3") ? "AMD Family 15h Bulldozer version 3" + : __builtin_cpu_is("bdver4") ? "AMD Family 15h Bulldozer version 4" + : __builtin_cpu_is("btver2") ? "AMD Family 16h CPU" + : __builtin_cpu_is("amdfam17h") ? "AMD Family 17h CPU" + : __builtin_cpu_is("znver1") ? "AMD Family 17h Zen version 1" + : __builtin_cpu_is("znver2") ? "AMD Family 17h Zen version 2" + : __builtin_cpu_is("amdfam19h") ? "AMD Family 19h CPU" + : "Unknown"; +#else + return "Unknown"; +#endif +} + +static std::string get_cpu_model() +{ + if (auto model_from_proc = get_cpu_model_from_proc(); !model_from_proc.empty()) { + return model_from_proc; + } else if (auto model_from_builtin = get_cpu_model_builtin(); !model_from_builtin.empty()) { + return model_from_builtin; + } + return "Unknown"; +} + +static double get_available_memory_gb() +{ + std::ifstream meminfo("/proc/meminfo"); + if (!meminfo.is_open()) return 0.0; + + std::string line; + long kb = 0; + while (std::getline(meminfo, line)) { + if (line.find("MemAvailable:") == 0 || line.find("MemFree:") == 0) { + std::size_t pos = line.find_first_of("0123456789"); + if (pos != std::string::npos) { + kb = std::stol(line.substr(pos)); + break; + } + } + } + + return kb / (1024.0 * 1024.0); // Convert KB to GB +} + /** * @brief Make an async memory resource for RMM * @return std::shared_ptr @@ -96,6 +238,55 @@ int run_single_file(const std::string& file_path, return -1; } + int device_id = 0; + cudaGetDevice(&device_id); + cudaDeviceProp device_prop; + cudaGetDeviceProperties(&device_prop, device_id); + cudaUUID_t uuid = device_prop.uuid; + char uuid_str[37] = {0}; + snprintf(uuid_str, + sizeof(uuid_str), + "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + uuid.bytes[0], + uuid.bytes[1], + uuid.bytes[2], + uuid.bytes[3], + uuid.bytes[4], + uuid.bytes[5], + uuid.bytes[6], + uuid.bytes[7], + uuid.bytes[8], + uuid.bytes[9], + uuid.bytes[10], + uuid.bytes[11], + uuid.bytes[12], + uuid.bytes[13], + uuid.bytes[14], + uuid.bytes[15]); + int version = 0; + cudaRuntimeGetVersion(&version); + int major = version / 1000; + int minor = (version % 1000) / 10; + CUOPT_LOG_INFO("cuOpt version: %d.%d.%d, git hash: %s, host arch: %s, device archs: %s", + CUOPT_VERSION_MAJOR, + CUOPT_VERSION_MINOR, + CUOPT_VERSION_PATCH, + CUOPT_GIT_COMMIT_HASH, + CUOPT_CPU_ARCHITECTURE, + CUOPT_CUDA_ARCHITECTURES); + CUOPT_LOG_INFO("CPU: %s, threads (physical/logical): %d/%d, RAM: %.2f GiB", + get_cpu_model().c_str(), + get_physical_cores(), + std::thread::hardware_concurrency(), + get_available_memory_gb()); + CUOPT_LOG_INFO("CUDA %d.%d, device: %s (ID %d), VRAM: %.2f GiB", + major, + minor, + device_prop.name, + device_id, + (double)device_prop.totalGlobalMem / (1024.0 * 1024.0 * 1024.0)); + CUOPT_LOG_INFO("CUDA device UUID: %s\n", uuid_str); + std::string base_filename = file_path.substr(file_path.find_last_of("/\\") + 1); constexpr bool input_mps_strict = false; From b5c4ba01def62058eb5dd074606bac94ead68ad5 Mon Sep 17 00:00:00 2001 From: Alice Boucher Date: Wed, 3 Sep 2025 15:49:16 +0000 Subject: [PATCH 2/3] fix Cmake compile definitions --- cpp/CMakeLists.txt | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 4e6fce2c1c..101efebe98 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -100,7 +100,8 @@ message(VERBOSE "CUOPT: LIBCUOPT_LOGGING_LEVEL = '${LIBCUOPT_LOGGING_LEVEL}'.") message("-- Building with logging level = ${LIBCUOPT_LOGGING_LEVEL}") -message("-- Building for GPU_ARCHS = ${CMAKE_CUDA_ARCHITECTURES}") +message("-- Building for GPU_ARCHS = '${CMAKE_CUDA_ARCHITECTURES}'") +message("-- Host target architecture = '${CMAKE_SYSTEM_PROCESSOR}'") # make the flags global in order to propagate flags to test cmake files set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} --expt-relaxed-constexpr --expt-extended-lambda") @@ -373,11 +374,13 @@ execute_process( OUTPUT_VARIABLE GIT_COMMIT_HASH OUTPUT_STRIP_TRAILING_WHITESPACE ) +message("-- Building with GIT_COMMIT_HASH = '${GIT_COMMIT_HASH}'") +list(JOIN CMAKE_CUDA_ARCHITECTURES "," JOINED_CUDA_ARCHITECTURES) # ';' breaks compile_definitions, replace it target_compile_definitions(cuopt_cli PUBLIC - "CUOPT_GIT_COMMIT_HASH=\"${GIT_COMMIT_HASH}\"" - "CUOPT_CUDA_ARCHITECTURES=\"${CMAKE_CUDA_ARCHITECTURES}\"" - "CUOPT_CPU_ARCHITECTURE=\"${CMAKE_SYSTEM_PROCESSOR}\"") + CUOPT_GIT_COMMIT_HASH="${GIT_COMMIT_HASH}" + CUOPT_CUDA_ARCHITECTURES="${JOINED_CUDA_ARCHITECTURES}" + CUOPT_CPU_ARCHITECTURE="${CMAKE_SYSTEM_PROCESSOR}") target_include_directories(cuopt_cli PRIVATE @@ -412,7 +415,7 @@ if(BUILD_BENCHMARKS) ) target_compile_definitions(solve_MPS_file PUBLIC "CUOPT_GIT_COMMIT_HASH=\"${GIT_COMMIT_HASH}\"" - "CUOPT_CUDA_ARCHITECTURES=\"${CMAKE_CUDA_ARCHITECTURES}\"" + "CUOPT_CUDA_ARCHITECTURES=\"${JOINED_CUDA_ARCHITECTURES}\"" "CUOPT_CPU_ARCHITECTURE=\"${CMAKE_SYSTEM_PROCESSOR}\"") target_link_libraries(solve_MPS_file PUBLIC From 0d69dfe1e97f74c6e63e9b1d39cbce55ae910c2f Mon Sep 17 00:00:00 2001 From: Alice Boucher Date: Fri, 5 Sep 2025 13:42:03 +0000 Subject: [PATCH 3/3] address review comments --- .../linear_programming/cuopt/run_mip.cpp | 192 --------------- cpp/CMakeLists.txt | 37 ++- cpp/cuopt_cli.cpp | 191 --------------- cpp/src/CMakeLists.txt | 3 +- cpp/src/linear_programming/solve.cu | 3 + cpp/src/mip/solve.cu | 3 + cpp/src/utilities/version_info.cpp | 227 ++++++++++++++++++ cpp/src/utilities/version_info.hpp | 21 ++ 8 files changed, 271 insertions(+), 406 deletions(-) create mode 100644 cpp/src/utilities/version_info.cpp create mode 100644 cpp/src/utilities/version_info.hpp diff --git a/benchmarks/linear_programming/cuopt/run_mip.cpp b/benchmarks/linear_programming/cuopt/run_mip.cpp index 0d15578f91..e3e8641b4f 100644 --- a/benchmarks/linear_programming/cuopt/run_mip.cpp +++ b/benchmarks/linear_programming/cuopt/run_mip.cpp @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -291,148 +290,6 @@ void return_gpu_to_the_queue(std::unordered_map& pid_gpu_map, pid_file_map.erase(pid); } -static int get_physical_cores() -{ - std::ifstream cpuinfo("/proc/cpuinfo"); - if (!cpuinfo.is_open()) return 0; - - std::string line; - int physical_id = -1, core_id = -1; - std::set> cores; - - while (std::getline(cpuinfo, line)) { - if (line.find("physical id") != std::string::npos) { - physical_id = std::stoi(line.substr(line.find(":") + 1)); - } else if (line.find("core id") != std::string::npos) { - core_id = std::stoi(line.substr(line.find(":") + 1)); - } - - if (physical_id != -1 && core_id != -1) { - cores.insert({physical_id, core_id}); - physical_id = -1; - core_id = -1; - } - } - - if (cores.empty()) { - cpuinfo.clear(); - cpuinfo.seekg(0); - while (std::getline(cpuinfo, line)) { - if (line.find("cpu cores") != std::string::npos) { - return std::stoi(line.substr(line.find(":") + 1)); - } - } - return 1; - } - return cores.size(); -} - -static std::string get_cpu_model_from_proc() -{ - std::ifstream cpuinfo("/proc/cpuinfo"); - if (!cpuinfo.is_open()) return ""; - - std::string line; - while (std::getline(cpuinfo, line)) { - std::size_t pos = line.find("model name"); - if (pos == std::string::npos) pos = line.find("Processor"); - if (pos != std::string::npos) { - std::size_t colon = line.find(':', pos); - if (colon != std::string::npos) return line.substr(colon + 2); // Skip ": " - } - } - return ""; -} - -// From https://gcc.gnu.org/onlinedocs/gcc/x86-Built-in-Functions.html -// Also supported by clang -static std::string get_cpu_model_builtin() -{ -#if defined(__GNUC__) || defined(__clang__) - __builtin_cpu_init(); - return __builtin_cpu_is("amd") ? "AMD CPU" - : __builtin_cpu_is("intel") ? "Intel CPU" - : __builtin_cpu_is("atom") ? "Intel Atom CPU" - : __builtin_cpu_is("slm") ? "Intel Silvermont CPU" - : __builtin_cpu_is("core2") ? "Intel Core 2 CPU" - : __builtin_cpu_is("corei7") ? "Intel Core i7 CPU" - : __builtin_cpu_is("nehalem") ? "Intel Core i7 Nehalem CPU" - : __builtin_cpu_is("westmere") ? "Intel Core i7 Westmere CPU" - : __builtin_cpu_is("sandybridge") ? "Intel Core i7 Sandy Bridge CPU" - : __builtin_cpu_is("ivybridge") ? "Intel Core i7 Ivy Bridge CPU" - : __builtin_cpu_is("haswell") ? "Intel Core i7 Haswell CPU" - : __builtin_cpu_is("broadwell") ? "Intel Core i7 Broadwell CPU" - : __builtin_cpu_is("skylake") ? "Intel Core i7 Skylake CPU" - : __builtin_cpu_is("skylake-avx512") ? "Intel Core i7 Skylake AVX512 CPU" - : __builtin_cpu_is("cannonlake") ? "Intel Core i7 Cannon Lake CPU" - : __builtin_cpu_is("icelake-client") ? "Intel Core i7 Ice Lake Client CPU" - : __builtin_cpu_is("icelake-server") ? "Intel Core i7 Ice Lake Server CPU" - : __builtin_cpu_is("cascadelake") ? "Intel Core i7 Cascadelake CPU" - : __builtin_cpu_is("tigerlake") ? "Intel Core i7 Tigerlake CPU" - : __builtin_cpu_is("cooperlake") ? "Intel Core i7 Cooperlake CPU" - : __builtin_cpu_is("sapphirerapids") ? "Intel Core i7 sapphirerapids CPU" - : __builtin_cpu_is("alderlake") ? "Intel Core i7 Alderlake CPU" - : __builtin_cpu_is("rocketlake") ? "Intel Core i7 Rocketlake CPU" - : __builtin_cpu_is("graniterapids") ? "Intel Core i7 graniterapids CPU" - : __builtin_cpu_is("graniterapids-d") ? "Intel Core i7 graniterapids D CPU" - : __builtin_cpu_is("bonnell") ? "Intel Atom Bonnell CPU" - : __builtin_cpu_is("silvermont") ? "Intel Atom Silvermont CPU" - : __builtin_cpu_is("goldmont") ? "Intel Atom Goldmont CPU" - : __builtin_cpu_is("goldmont-plus") ? "Intel Atom Goldmont Plus CPU" - : __builtin_cpu_is("tremont") ? "Intel Atom Tremont CPU" - : __builtin_cpu_is("sierraforest") ? "Intel Atom Sierra Forest CPU" - : __builtin_cpu_is("grandridge") ? "Intel Atom Grand Ridge CPU" - : __builtin_cpu_is("amdfam10h") ? "AMD Family 10h CPU" - : __builtin_cpu_is("barcelona") ? "AMD Family 10h Barcelona CPU" - : __builtin_cpu_is("shanghai") ? "AMD Family 10h Shanghai CPU" - : __builtin_cpu_is("istanbul") ? "AMD Family 10h Istanbul CPU" - : __builtin_cpu_is("btver1") ? "AMD Family 14h CPU" - : __builtin_cpu_is("amdfam15h") ? "AMD Family 15h CPU" - : __builtin_cpu_is("bdver1") ? "AMD Family 15h Bulldozer version 1" - : __builtin_cpu_is("bdver2") ? "AMD Family 15h Bulldozer version 2" - : __builtin_cpu_is("bdver3") ? "AMD Family 15h Bulldozer version 3" - : __builtin_cpu_is("bdver4") ? "AMD Family 15h Bulldozer version 4" - : __builtin_cpu_is("btver2") ? "AMD Family 16h CPU" - : __builtin_cpu_is("amdfam17h") ? "AMD Family 17h CPU" - : __builtin_cpu_is("znver1") ? "AMD Family 17h Zen version 1" - : __builtin_cpu_is("znver2") ? "AMD Family 17h Zen version 2" - : __builtin_cpu_is("amdfam19h") ? "AMD Family 19h CPU" - : "Unknown"; -#else - return "Unknown"; -#endif -} - -static std::string get_cpu_model() -{ - if (auto model_from_proc = get_cpu_model_from_proc(); !model_from_proc.empty()) { - return model_from_proc; - } else if (auto model_from_builtin = get_cpu_model_builtin(); !model_from_builtin.empty()) { - return model_from_builtin; - } - return "Unknown"; -} - -static double get_available_memory_gb() -{ - std::ifstream meminfo("/proc/meminfo"); - if (!meminfo.is_open()) return 0.0; - - std::string line; - long kb = 0; - while (std::getline(meminfo, line)) { - if (line.find("MemAvailable:") == 0 || line.find("MemFree:") == 0) { - std::size_t pos = line.find_first_of("0123456789"); - if (pos != std::string::npos) { - kb = std::stol(line.substr(pos)); - break; - } - } - } - - return kb / (1024.0 * 1024.0); // Convert KB to GB -} - int main(int argc, char* argv[]) { argparse::ArgumentParser program("solve_MIP"); @@ -526,55 +383,6 @@ int main(int argc, char* argv[]) initial_solution_file = program.get("--initial-solution-path"); } - int device_id = 0; - cudaGetDevice(&device_id); - cudaDeviceProp device_prop; - cudaGetDeviceProperties(&device_prop, device_id); - cudaUUID_t uuid = device_prop.uuid; - char uuid_str[37] = {0}; - snprintf(uuid_str, - sizeof(uuid_str), - "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", - uuid.bytes[0], - uuid.bytes[1], - uuid.bytes[2], - uuid.bytes[3], - uuid.bytes[4], - uuid.bytes[5], - uuid.bytes[6], - uuid.bytes[7], - uuid.bytes[8], - uuid.bytes[9], - uuid.bytes[10], - uuid.bytes[11], - uuid.bytes[12], - uuid.bytes[13], - uuid.bytes[14], - uuid.bytes[15]); - int version = 0; - cudaRuntimeGetVersion(&version); - int major = version / 1000; - int minor = (version % 1000) / 10; - printf("cuOpt version: %d.%d.%d, git hash: %s, host arch: %s, device archs: %s\n", - CUOPT_VERSION_MAJOR, - CUOPT_VERSION_MINOR, - CUOPT_VERSION_PATCH, - CUOPT_GIT_COMMIT_HASH, - CUOPT_CPU_ARCHITECTURE, - CUOPT_CUDA_ARCHITECTURES); - printf("CPU: %s, threads (physical/logical): %d/%d, RAM: %.2f GiB\n", - get_cpu_model().c_str(), - get_physical_cores(), - std::thread::hardware_concurrency(), - get_available_memory_gb()); - printf("CUDA %d.%d, device: %s (ID %d), VRAM: %.2f GiB\n", - major, - minor, - device_prop.name, - device_id, - (double)device_prop.totalGlobalMem / (1024.0 * 1024.0 * 1024.0)); - printf("CUDA device UUID: %s\n\n", uuid_str); - if (run_dir) { std::queue task_queue; std::queue gpu_queue; diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index df67584abd..76e5b16a03 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -262,6 +262,21 @@ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/libmps_parser) set(CMAKE_LIBRARY_PATH ${CMAKE_CURRENT_BINARY_DIR}/libmps_parser/) +execute_process( + COMMAND git rev-parse --short HEAD + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE GIT_COMMIT_HASH + OUTPUT_STRIP_TRAILING_WHITESPACE +) +message("-- Building with GIT_COMMIT_HASH = '${GIT_COMMIT_HASH}'") + + +list(JOIN CMAKE_CUDA_ARCHITECTURES "," JOINED_CUDA_ARCHITECTURES) # ';' breaks compile_definitions, replace it +target_compile_definitions(cuopt PUBLIC + CUOPT_GIT_COMMIT_HASH="${GIT_COMMIT_HASH}" + CUOPT_CUDA_ARCHITECTURES="${JOINED_CUDA_ARCHITECTURES}" + CUOPT_CPU_ARCHITECTURE="${CMAKE_SYSTEM_PROCESSOR}") + target_link_libraries(cuopt PUBLIC CUDA::cublas @@ -379,20 +394,6 @@ if(NOT BUILD_LP_ONLY) "$<$:${CUOPT_CUDA_FLAGS}>" ) -execute_process( - COMMAND git rev-parse --short HEAD - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - OUTPUT_VARIABLE GIT_COMMIT_HASH - OUTPUT_STRIP_TRAILING_WHITESPACE -) -message("-- Building with GIT_COMMIT_HASH = '${GIT_COMMIT_HASH}'") - -list(JOIN CMAKE_CUDA_ARCHITECTURES "," JOINED_CUDA_ARCHITECTURES) # ';' breaks compile_definitions, replace it -target_compile_definitions(cuopt_cli PUBLIC - CUOPT_GIT_COMMIT_HASH="${GIT_COMMIT_HASH}" - CUOPT_CUDA_ARCHITECTURES="${JOINED_CUDA_ARCHITECTURES}" - CUOPT_CPU_ARCHITECTURE="${CMAKE_SYSTEM_PROCESSOR}") - target_include_directories(cuopt_cli PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src" @@ -426,10 +427,6 @@ if(BUILD_MIP_BENCHMARKS AND NOT BUILD_LP_ONLY) PRIVATE "$<$:${CUOPT_CXX_FLAGS}>" "$<$:${CUOPT_CUDA_FLAGS}>" ) - target_compile_definitions(solve_MIP PUBLIC - "CUOPT_GIT_COMMIT_HASH=\"${GIT_COMMIT_HASH}\"" - "CUOPT_CUDA_ARCHITECTURES=\"${JOINED_CUDA_ARCHITECTURES}\"" - "CUOPT_CPU_ARCHITECTURE=\"${CMAKE_SYSTEM_PROCESSOR}\"") target_link_libraries(solve_MIP PUBLIC cuopt @@ -446,10 +443,6 @@ if(BUILD_LP_BENCHMARKS) PRIVATE "$<$:${CUOPT_CXX_FLAGS}>" "$<$:${CUOPT_CUDA_FLAGS}>" ) - target_compile_definitions(solve_LP PUBLIC - "CUOPT_GIT_COMMIT_HASH=\"${GIT_COMMIT_HASH}\"" - "CUOPT_CUDA_ARCHITECTURES=\"${JOINED_CUDA_ARCHITECTURES}\"" - "CUOPT_CPU_ARCHITECTURE=\"${CMAKE_SYSTEM_PROCESSOR}\"") target_link_libraries(solve_LP PUBLIC cuopt diff --git a/cpp/cuopt_cli.cpp b/cpp/cuopt_cli.cpp index a5299c56b0..ac22cf9fe2 100644 --- a/cpp/cuopt_cli.cpp +++ b/cpp/cuopt_cli.cpp @@ -67,148 +67,6 @@ * parameters, and write the solution to a .sol file in the output directory. */ -static int get_physical_cores() -{ - std::ifstream cpuinfo("/proc/cpuinfo"); - if (!cpuinfo.is_open()) return 0; - - std::string line; - int physical_id = -1, core_id = -1; - std::set> cores; - - while (std::getline(cpuinfo, line)) { - if (line.find("physical id") != std::string::npos) { - physical_id = std::stoi(line.substr(line.find(":") + 1)); - } else if (line.find("core id") != std::string::npos) { - core_id = std::stoi(line.substr(line.find(":") + 1)); - } - - if (physical_id != -1 && core_id != -1) { - cores.insert({physical_id, core_id}); - physical_id = -1; - core_id = -1; - } - } - - if (cores.empty()) { - cpuinfo.clear(); - cpuinfo.seekg(0); - while (std::getline(cpuinfo, line)) { - if (line.find("cpu cores") != std::string::npos) { - return std::stoi(line.substr(line.find(":") + 1)); - } - } - return 1; - } - return cores.size(); -} - -static std::string get_cpu_model_from_proc() -{ - std::ifstream cpuinfo("/proc/cpuinfo"); - if (!cpuinfo.is_open()) return ""; - - std::string line; - while (std::getline(cpuinfo, line)) { - std::size_t pos = line.find("model name"); - if (pos == std::string::npos) pos = line.find("Processor"); - if (pos != std::string::npos) { - std::size_t colon = line.find(':', pos); - if (colon != std::string::npos) return line.substr(colon + 2); // Skip ": " - } - } - return ""; -} - -// From https://gcc.gnu.org/onlinedocs/gcc/x86-Built-in-Functions.html -// Also supported by clang -static std::string get_cpu_model_builtin() -{ -#if defined(__GNUC__) || defined(__clang__) - __builtin_cpu_init(); - return __builtin_cpu_is("amd") ? "AMD CPU" - : __builtin_cpu_is("intel") ? "Intel CPU" - : __builtin_cpu_is("atom") ? "Intel Atom CPU" - : __builtin_cpu_is("slm") ? "Intel Silvermont CPU" - : __builtin_cpu_is("core2") ? "Intel Core 2 CPU" - : __builtin_cpu_is("corei7") ? "Intel Core i7 CPU" - : __builtin_cpu_is("nehalem") ? "Intel Core i7 Nehalem CPU" - : __builtin_cpu_is("westmere") ? "Intel Core i7 Westmere CPU" - : __builtin_cpu_is("sandybridge") ? "Intel Core i7 Sandy Bridge CPU" - : __builtin_cpu_is("ivybridge") ? "Intel Core i7 Ivy Bridge CPU" - : __builtin_cpu_is("haswell") ? "Intel Core i7 Haswell CPU" - : __builtin_cpu_is("broadwell") ? "Intel Core i7 Broadwell CPU" - : __builtin_cpu_is("skylake") ? "Intel Core i7 Skylake CPU" - : __builtin_cpu_is("skylake-avx512") ? "Intel Core i7 Skylake AVX512 CPU" - : __builtin_cpu_is("cannonlake") ? "Intel Core i7 Cannon Lake CPU" - : __builtin_cpu_is("icelake-client") ? "Intel Core i7 Ice Lake Client CPU" - : __builtin_cpu_is("icelake-server") ? "Intel Core i7 Ice Lake Server CPU" - : __builtin_cpu_is("cascadelake") ? "Intel Core i7 Cascadelake CPU" - : __builtin_cpu_is("tigerlake") ? "Intel Core i7 Tigerlake CPU" - : __builtin_cpu_is("cooperlake") ? "Intel Core i7 Cooperlake CPU" - : __builtin_cpu_is("sapphirerapids") ? "Intel Core i7 sapphirerapids CPU" - : __builtin_cpu_is("alderlake") ? "Intel Core i7 Alderlake CPU" - : __builtin_cpu_is("rocketlake") ? "Intel Core i7 Rocketlake CPU" - : __builtin_cpu_is("graniterapids") ? "Intel Core i7 graniterapids CPU" - : __builtin_cpu_is("graniterapids-d") ? "Intel Core i7 graniterapids D CPU" - : __builtin_cpu_is("bonnell") ? "Intel Atom Bonnell CPU" - : __builtin_cpu_is("silvermont") ? "Intel Atom Silvermont CPU" - : __builtin_cpu_is("goldmont") ? "Intel Atom Goldmont CPU" - : __builtin_cpu_is("goldmont-plus") ? "Intel Atom Goldmont Plus CPU" - : __builtin_cpu_is("tremont") ? "Intel Atom Tremont CPU" - : __builtin_cpu_is("sierraforest") ? "Intel Atom Sierra Forest CPU" - : __builtin_cpu_is("grandridge") ? "Intel Atom Grand Ridge CPU" - : __builtin_cpu_is("amdfam10h") ? "AMD Family 10h CPU" - : __builtin_cpu_is("barcelona") ? "AMD Family 10h Barcelona CPU" - : __builtin_cpu_is("shanghai") ? "AMD Family 10h Shanghai CPU" - : __builtin_cpu_is("istanbul") ? "AMD Family 10h Istanbul CPU" - : __builtin_cpu_is("btver1") ? "AMD Family 14h CPU" - : __builtin_cpu_is("amdfam15h") ? "AMD Family 15h CPU" - : __builtin_cpu_is("bdver1") ? "AMD Family 15h Bulldozer version 1" - : __builtin_cpu_is("bdver2") ? "AMD Family 15h Bulldozer version 2" - : __builtin_cpu_is("bdver3") ? "AMD Family 15h Bulldozer version 3" - : __builtin_cpu_is("bdver4") ? "AMD Family 15h Bulldozer version 4" - : __builtin_cpu_is("btver2") ? "AMD Family 16h CPU" - : __builtin_cpu_is("amdfam17h") ? "AMD Family 17h CPU" - : __builtin_cpu_is("znver1") ? "AMD Family 17h Zen version 1" - : __builtin_cpu_is("znver2") ? "AMD Family 17h Zen version 2" - : __builtin_cpu_is("amdfam19h") ? "AMD Family 19h CPU" - : "Unknown"; -#else - return "Unknown"; -#endif -} - -static std::string get_cpu_model() -{ - if (auto model_from_proc = get_cpu_model_from_proc(); !model_from_proc.empty()) { - return model_from_proc; - } else if (auto model_from_builtin = get_cpu_model_builtin(); !model_from_builtin.empty()) { - return model_from_builtin; - } - return "Unknown"; -} - -static double get_available_memory_gb() -{ - std::ifstream meminfo("/proc/meminfo"); - if (!meminfo.is_open()) return 0.0; - - std::string line; - long kb = 0; - while (std::getline(meminfo, line)) { - if (line.find("MemAvailable:") == 0 || line.find("MemFree:") == 0) { - std::size_t pos = line.find_first_of("0123456789"); - if (pos != std::string::npos) { - kb = std::stol(line.substr(pos)); - break; - } - } - } - - return kb / (1024.0 * 1024.0); // Convert KB to GB -} - /** * @brief Make an async memory resource for RMM * @return std::shared_ptr @@ -238,55 +96,6 @@ int run_single_file(const std::string& file_path, return -1; } - int device_id = 0; - cudaGetDevice(&device_id); - cudaDeviceProp device_prop; - cudaGetDeviceProperties(&device_prop, device_id); - cudaUUID_t uuid = device_prop.uuid; - char uuid_str[37] = {0}; - snprintf(uuid_str, - sizeof(uuid_str), - "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", - uuid.bytes[0], - uuid.bytes[1], - uuid.bytes[2], - uuid.bytes[3], - uuid.bytes[4], - uuid.bytes[5], - uuid.bytes[6], - uuid.bytes[7], - uuid.bytes[8], - uuid.bytes[9], - uuid.bytes[10], - uuid.bytes[11], - uuid.bytes[12], - uuid.bytes[13], - uuid.bytes[14], - uuid.bytes[15]); - int version = 0; - cudaRuntimeGetVersion(&version); - int major = version / 1000; - int minor = (version % 1000) / 10; - CUOPT_LOG_INFO("cuOpt version: %d.%d.%d, git hash: %s, host arch: %s, device archs: %s", - CUOPT_VERSION_MAJOR, - CUOPT_VERSION_MINOR, - CUOPT_VERSION_PATCH, - CUOPT_GIT_COMMIT_HASH, - CUOPT_CPU_ARCHITECTURE, - CUOPT_CUDA_ARCHITECTURES); - CUOPT_LOG_INFO("CPU: %s, threads (physical/logical): %d/%d, RAM: %.2f GiB", - get_cpu_model().c_str(), - get_physical_cores(), - std::thread::hardware_concurrency(), - get_available_memory_gb()); - CUOPT_LOG_INFO("CUDA %d.%d, device: %s (ID %d), VRAM: %.2f GiB", - major, - minor, - device_prop.name, - device_id, - (double)device_prop.totalGlobalMem / (1024.0 * 1024.0 * 1024.0)); - CUOPT_LOG_INFO("CUDA device UUID: %s\n", uuid_str); - std::string base_filename = file_path.substr(file_path.find_last_of("/\\") + 1); constexpr bool input_mps_strict = false; diff --git a/cpp/src/CMakeLists.txt b/cpp/src/CMakeLists.txt index 1ffa94fc0d..76a7426178 100644 --- a/cpp/src/CMakeLists.txt +++ b/cpp/src/CMakeLists.txt @@ -14,7 +14,8 @@ # limitations under the License. set(UTIL_SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/utilities/seed_generator.cu - ${CMAKE_CURRENT_SOURCE_DIR}/utilities/logger_helper.cpp) + ${CMAKE_CURRENT_SOURCE_DIR}/utilities/logger_helper.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/utilities/version_info.cpp) add_subdirectory(linear_programming) add_subdirectory(math_optimization) diff --git a/cpp/src/linear_programming/solve.cu b/cpp/src/linear_programming/solve.cu index 8dc1909c87..e90312067b 100644 --- a/cpp/src/linear_programming/solve.cu +++ b/cpp/src/linear_programming/solve.cu @@ -35,6 +35,7 @@ #include #include +#include #include #include @@ -571,6 +572,8 @@ optimization_problem_solution_t solve_lp(optimization_problem_t #include #include +#include #include #include @@ -170,6 +171,8 @@ mip_solution_t solve_mip(optimization_problem_t& op_problem, // This needs to be called before pdlp is initialized init_handler(op_problem.get_handle_ptr()); + print_version_info(); + raft::common::nvtx::range fun_scope("Running solver"); // This is required as user might forget to set some fields diff --git a/cpp/src/utilities/version_info.cpp b/cpp/src/utilities/version_info.cpp new file mode 100644 index 0000000000..902495a48c --- /dev/null +++ b/cpp/src/utilities/version_info.cpp @@ -0,0 +1,227 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights + * reserved. SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "version_info.hpp" + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace cuopt { + +static int get_physical_cores() +{ + std::ifstream cpuinfo("/proc/cpuinfo"); + if (!cpuinfo.is_open()) return 0; + + std::string line; + int physical_id = -1, core_id = -1; + std::set> cores; + + while (std::getline(cpuinfo, line)) { + if (line.find("physical id") != std::string::npos) { + physical_id = std::stoi(line.substr(line.find(":") + 1)); + } else if (line.find("core id") != std::string::npos) { + core_id = std::stoi(line.substr(line.find(":") + 1)); + } + + if (physical_id != -1 && core_id != -1) { + cores.insert({physical_id, core_id}); + physical_id = -1; + core_id = -1; + } + } + + if (cores.empty()) { + cpuinfo.clear(); + cpuinfo.seekg(0); + while (std::getline(cpuinfo, line)) { + if (line.find("cpu cores") != std::string::npos) { + return std::stoi(line.substr(line.find(":") + 1)); + } + } + return 1; + } + return cores.size(); +} + +static std::string get_cpu_model_from_proc() +{ + std::ifstream cpuinfo("/proc/cpuinfo"); + if (!cpuinfo.is_open()) return ""; + + std::string line; + while (std::getline(cpuinfo, line)) { + std::size_t pos = line.find("model name"); + if (pos == std::string::npos) pos = line.find("Processor"); + if (pos != std::string::npos) { + std::size_t colon = line.find(':', pos); + if (colon != std::string::npos) return line.substr(colon + 2); // Skip ": " + } + } + return ""; +} + +// From https://gcc.gnu.org/onlinedocs/gcc/x86-Built-in-Functions.html +// Also supported by clang +static std::string get_cpu_model_builtin() +{ +#if (defined(__x86_64__) || defined(__i386__)) && (defined(__GNUC__) || defined(__clang__)) + __builtin_cpu_init(); + return __builtin_cpu_is("amd") ? "AMD CPU" + : __builtin_cpu_is("intel") ? "Intel CPU" + : __builtin_cpu_is("atom") ? "Intel Atom CPU" + : __builtin_cpu_is("slm") ? "Intel Silvermont CPU" + : __builtin_cpu_is("core2") ? "Intel Core 2 CPU" + : __builtin_cpu_is("corei7") ? "Intel Core i7 CPU" + : __builtin_cpu_is("nehalem") ? "Intel Core i7 Nehalem CPU" + : __builtin_cpu_is("westmere") ? "Intel Core i7 Westmere CPU" + : __builtin_cpu_is("sandybridge") ? "Intel Core i7 Sandy Bridge CPU" + : __builtin_cpu_is("ivybridge") ? "Intel Core i7 Ivy Bridge CPU" + : __builtin_cpu_is("haswell") ? "Intel Core i7 Haswell CPU" + : __builtin_cpu_is("broadwell") ? "Intel Core i7 Broadwell CPU" + : __builtin_cpu_is("skylake") ? "Intel Core i7 Skylake CPU" + : __builtin_cpu_is("skylake-avx512") ? "Intel Core i7 Skylake AVX512 CPU" + : __builtin_cpu_is("cannonlake") ? "Intel Core i7 Cannon Lake CPU" + : __builtin_cpu_is("icelake-client") ? "Intel Core i7 Ice Lake Client CPU" + : __builtin_cpu_is("icelake-server") ? "Intel Core i7 Ice Lake Server CPU" + : __builtin_cpu_is("cascadelake") ? "Intel Core i7 Cascadelake CPU" + : __builtin_cpu_is("tigerlake") ? "Intel Core i7 Tigerlake CPU" + : __builtin_cpu_is("cooperlake") ? "Intel Core i7 Cooperlake CPU" + : __builtin_cpu_is("sapphirerapids") ? "Intel Core i7 sapphirerapids CPU" + : __builtin_cpu_is("alderlake") ? "Intel Core i7 Alderlake CPU" + : __builtin_cpu_is("rocketlake") ? "Intel Core i7 Rocketlake CPU" + : __builtin_cpu_is("graniterapids") ? "Intel Core i7 graniterapids CPU" + : __builtin_cpu_is("graniterapids-d") ? "Intel Core i7 graniterapids D CPU" + : __builtin_cpu_is("bonnell") ? "Intel Atom Bonnell CPU" + : __builtin_cpu_is("silvermont") ? "Intel Atom Silvermont CPU" + : __builtin_cpu_is("goldmont") ? "Intel Atom Goldmont CPU" + : __builtin_cpu_is("goldmont-plus") ? "Intel Atom Goldmont Plus CPU" + : __builtin_cpu_is("tremont") ? "Intel Atom Tremont CPU" + : __builtin_cpu_is("sierraforest") ? "Intel Atom Sierra Forest CPU" + : __builtin_cpu_is("grandridge") ? "Intel Atom Grand Ridge CPU" + : __builtin_cpu_is("amdfam10h") ? "AMD Family 10h CPU" + : __builtin_cpu_is("barcelona") ? "AMD Family 10h Barcelona CPU" + : __builtin_cpu_is("shanghai") ? "AMD Family 10h Shanghai CPU" + : __builtin_cpu_is("istanbul") ? "AMD Family 10h Istanbul CPU" + : __builtin_cpu_is("btver1") ? "AMD Family 14h CPU" + : __builtin_cpu_is("amdfam15h") ? "AMD Family 15h CPU" + : __builtin_cpu_is("bdver1") ? "AMD Family 15h Bulldozer version 1" + : __builtin_cpu_is("bdver2") ? "AMD Family 15h Bulldozer version 2" + : __builtin_cpu_is("bdver3") ? "AMD Family 15h Bulldozer version 3" + : __builtin_cpu_is("bdver4") ? "AMD Family 15h Bulldozer version 4" + : __builtin_cpu_is("btver2") ? "AMD Family 16h CPU" + : __builtin_cpu_is("amdfam17h") ? "AMD Family 17h CPU" + : __builtin_cpu_is("znver1") ? "AMD Family 17h Zen version 1" + : __builtin_cpu_is("znver2") ? "AMD Family 17h Zen version 2" + : __builtin_cpu_is("amdfam19h") ? "AMD Family 19h CPU" + : "Unknown"; +#else + return "Unknown"; +#endif +} + +static std::string get_cpu_model() +{ + if (auto model_from_proc = get_cpu_model_from_proc(); !model_from_proc.empty()) { + return model_from_proc; + } else if (auto model_from_builtin = get_cpu_model_builtin(); !model_from_builtin.empty()) { + return model_from_builtin; + } + return "Unknown"; +} + +static double get_available_memory_gb() +{ + std::ifstream meminfo("/proc/meminfo"); + if (!meminfo.is_open()) return 0.0; + + std::string line; + long kb = 0; + while (std::getline(meminfo, line)) { + if (line.find("MemAvailable:") == 0 || line.find("MemFree:") == 0) { + std::size_t pos = line.find_first_of("0123456789"); + if (pos != std::string::npos) { + kb = std::stol(line.substr(pos)); + break; + } + } + } + + return kb / (1024.0 * 1024.0); // Convert KB to GB +} + +void print_version_info() +{ + int device_id = 0; + cudaGetDevice(&device_id); + cudaDeviceProp device_prop; + cudaGetDeviceProperties(&device_prop, device_id); + cudaUUID_t uuid = device_prop.uuid; + char uuid_str[37] = {0}; + snprintf(uuid_str, + sizeof(uuid_str), + "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + uuid.bytes[0], + uuid.bytes[1], + uuid.bytes[2], + uuid.bytes[3], + uuid.bytes[4], + uuid.bytes[5], + uuid.bytes[6], + uuid.bytes[7], + uuid.bytes[8], + uuid.bytes[9], + uuid.bytes[10], + uuid.bytes[11], + uuid.bytes[12], + uuid.bytes[13], + uuid.bytes[14], + uuid.bytes[15]); + int version = 0; + cudaRuntimeGetVersion(&version); + int major = version / 1000; + int minor = (version % 1000) / 10; + CUOPT_LOG_INFO("cuOpt version: %d.%d.%d, git hash: %s, host arch: %s, device archs: %s", + CUOPT_VERSION_MAJOR, + CUOPT_VERSION_MINOR, + CUOPT_VERSION_PATCH, + CUOPT_GIT_COMMIT_HASH, + CUOPT_CPU_ARCHITECTURE, + CUOPT_CUDA_ARCHITECTURES); + CUOPT_LOG_INFO("CPU: %s, threads (physical/logical): %d/%d, RAM: %.2f GiB", + get_cpu_model().c_str(), + get_physical_cores(), + std::thread::hardware_concurrency(), + get_available_memory_gb()); + CUOPT_LOG_INFO("CUDA %d.%d, device: %s (ID %d), VRAM: %.2f GiB", + major, + minor, + device_prop.name, + device_id, + (double)device_prop.totalGlobalMem / (1024.0 * 1024.0 * 1024.0)); + CUOPT_LOG_INFO("CUDA device UUID: %s\n", uuid_str); +} + +} // namespace cuopt diff --git a/cpp/src/utilities/version_info.hpp b/cpp/src/utilities/version_info.hpp new file mode 100644 index 0000000000..7549fcdccd --- /dev/null +++ b/cpp/src/utilities/version_info.hpp @@ -0,0 +1,21 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights + * reserved. SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +namespace cuopt { +void print_version_info(); +}