Compare commits

...
Sign in to create a new pull request.

51 commits
master ... evo

Author SHA1 Message Date
XMRig
5e13d78315
Merge remote-tracking branch 'remotes/origin/dev' into evo 2022-09-25 09:49:01 +07:00
XMRig
b8191cef2b
Merge remote-tracking branch 'remotes/origin/dev' into evo 2022-09-21 06:17:57 +07:00
XMRig
6f0291bfde
Fixed build. 2022-09-19 05:45:16 +07:00
XMRig
6f3187049a
Merge remote-tracking branch 'remotes/origin/dev' into evo 2022-09-19 05:14:21 +07:00
XMRig
4fec1b0aed
Taskbar class cleanup. 2022-08-16 17:54:33 +07:00
XMRig
d862ba853f
Revert Taskbar class. 2022-08-16 17:31:39 +07:00
XMRig
9a4558561f
Fixed MSVC build. 2022-08-07 22:19:54 +07:00
XMRig
f99554858b
Fixed GhostRider build. 2022-08-07 21:21:36 +07:00
XMRig
571bc798f4
Fixed typo. 2022-08-07 17:31:13 +07:00
XMRig
8d043dadec
Fixed build (GhostRider temporarily disabled) 2022-08-07 17:25:32 +07:00
XMRig
1438672fe5
Fixed kawpow build. 2022-08-06 15:25:40 +07:00
XMRig
f6dbe32c86
Merge remote-tracking branch 'remotes/origin/sync-base' into evo 2022-08-06 10:22:49 +07:00
XMRig
4948a8c354
Add base submodule. 2022-08-05 11:20:22 +07:00
XMRig
637c023d06
Remove base. 2022-08-05 11:04:18 +07:00
XMRig
ce0b879542
Update base. 2022-08-05 11:00:18 +07:00
XMRig
f006ec0b68
Change 3rdparty code location. 2022-08-05 10:27:21 +07:00
XMRig
04e5ff0349
Move legacy code to v6 folder. 2022-08-04 17:44:37 +07:00
XMRig
9ad1c02430
Update IConfig. 2022-07-30 04:24:28 +07:00
XMRig
61c263af6e
Removed IConfigListener. 2022-07-29 01:59:02 +07:00
XMRig
fe0ed9eaae
Fixed build with -DWITH_DEBUG_LOG=ON 2022-07-23 02:18:20 +07:00
XMRig
d8f39ebef3
Update DNS subsystem. 2022-07-13 17:45:18 +07:00
XMRig
07d53fb77e
Merge branch 'dev' into sync-base 2022-07-10 06:53:04 +07:00
XMRig
3ded8e6734
Merge branch 'dev' into sync-base 2022-06-14 05:19:28 +07:00
XMRig
774f630e14
Update Log class. 2022-06-10 02:15:10 +07:00
XMRig
d6a1c98314
Update Signals class. 2022-05-17 18:05:53 +07:00
XMRig
75283445fd
Update Console class. 2022-05-15 12:13:27 +07:00
XMRig
45084cb718
Update Watcher class. 2022-05-13 03:18:25 +07:00
XMRig
bc150fec04
Sync ConsoleLog class, base versions and TLS init. 2022-05-07 21:41:55 +07:00
XMRig
9a0cd68ea5
Update and move Title class. 2022-04-27 12:14:20 +07:00
XMRig
603eb261c5
Update Entry class. 2022-04-23 23:08:27 +07:00
XMRig
de97f3492e
Sync TLS changes. 2022-04-19 16:34:18 +07:00
XMRig
8a167cb2a7
Sync with base. 2022-04-17 06:03:39 +07:00
XMRig
d0953a507c
Merge branch 'dev' into sync-base 2022-04-16 02:57:59 +07:00
XMRig
fe8e198106
Update Arguments class. 2022-04-16 02:52:46 +07:00
XMRig
dfc3b4632a
Added backward compatibility support. 2022-04-15 14:13:45 +07:00
XMRig
6106bf30de
Backport non breaking changes from the new base. 2022-04-08 14:33:16 +07:00
XMRig
3ab07fe8c1
Rename App to MinerApp. 2021-09-04 21:10:28 +07:00
XMRig
824ba24134
Removed config option background. 2021-09-04 04:59:00 +07:00
XMRig
d7a6aaadea
Update for new Entry class. 2021-09-03 23:34:53 +07:00
XMRig
26819f01e1
Fixed Linux build. 2021-09-02 20:22:27 +07:00
XMRig
d94f6e9c3a
Fixed build. 2021-09-02 20:16:14 +07:00
XMRig
28312236fd
Update base. 2021-09-02 20:02:42 +07:00
XMRig
dbc53c5d46
Add submodule. 2021-08-31 21:28:57 +07:00
XMRig
a7e20ea5de
Remove base. 2021-08-31 21:22:44 +07:00
XMRig
bb9e35f5d2
Merge branch 'dev' into evo 2021-08-31 03:33:24 +07:00
XMRig
cb2ec2316a
Fixed build. 2021-08-31 00:02:55 +07:00
XMRig
e3b5bfeb36
Build fixes. 2021-08-30 23:41:53 +07:00
XMRig
cac1e4aa5e
Build "src/base" as static library. 2021-08-30 23:06:16 +07:00
XMRig
e1f0737a59
Update base. 2021-08-30 19:44:19 +07:00
XMRig
5c6c1299c8
Update base, fmt and llhttp. 2021-08-29 21:18:00 +07:00
XMRig
4f90075ea0
Merge branch 'dev' into evo 2021-08-29 20:45:37 +07:00
405 changed files with 371 additions and 122425 deletions

4
.gitmodules vendored Normal file
View file

@ -0,0 +1,4 @@
[submodule "src/base"]
path = src/base
url = https://github.com/xmrig/base.git
branch = master

6
CHANGELOG_NEXT.md Normal file
View file

@ -0,0 +1,6 @@
# v7.0.0
- `src/base` is now a git submodule for the [base](https://github.com/xmrig/base) project, build instructions require slight update.
- Removed config option `background` (only command line available). Switching to background now happens on a very early stage before any I/O.
# Previous versions
[doc/CHANGELOG_OLD.md](doc/CHANGELOG_OLD.md)

View file

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 2.8.12)
cmake_minimum_required(VERSION 3.1)
project(xmrig)
option(WITH_HWLOC "Enable hwloc support" ON)
@ -37,22 +37,26 @@ option(BUILD_STATIC "Build static binary" OFF)
option(ARM_TARGET "Force use specific ARM target 8 or 7" 0)
option(HWLOC_DEBUG "Enable hwloc debug helpers and log" OFF)
add_definitions(-DXMRIG_MINER_PROJECT)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
set(WITH_SODIUM OFF)
set(WITH_CRYPTONOTE ON)
set(WITH_CRYPTO_OPS ON)
set(WITH_COM OFF)
set(WITH_EVENTS OFF)
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/src/base/cmake" "${CMAKE_SOURCE_DIR}/cmake")
set(LIBS base)
include (CheckIncludeFile)
include (cmake/cpu.cmake)
include (cmake/os.cmake)
include (src/base/base.cmake)
include (src/backend/backend.cmake)
include(base)
add_subdirectory(src/base)
include(src/backend/backend.cmake)
set(HEADERS
"${HEADERS_BASE}"
"${HEADERS_BASE_HTTP}"
"${HEADERS_BACKEND}"
src/App.h
src/backend/common/interfaces/IMemoryPool.h
src/core/config/Config_default.h
src/core/config/Config_platform.h
src/core/config/Config.h
@ -61,17 +65,6 @@ set(HEADERS
src/core/Controller.h
src/core/Miner.h
src/core/Taskbar.h
src/net/interfaces/IJobResultListener.h
src/net/JobResult.h
src/net/JobResults.h
src/net/Network.h
src/net/strategies/DonateStrategy.h
src/Summary.h
src/version.h
)
set(HEADERS_CRYPTO
src/backend/common/interfaces/IMemoryPool.h
src/crypto/cn/asm/CryptonightR_template.h
src/crypto/cn/c_blake256.h
src/crypto/cn/c_groestl.h
@ -92,32 +85,29 @@ set(HEADERS_CRYPTO
src/crypto/common/Nonce.h
src/crypto/common/portable/mm_malloc.h
src/crypto/common/VirtualMemory.h
src/MinerApp.h
src/net/interfaces/IJobResultListener.h
src/net/JobResult.h
src/net/JobResults.h
src/net/Network.h
src/net/strategies/DonateStrategy.h
src/Summary.h
src/version.h
)
if (XMRIG_ARM)
set(HEADERS_CRYPTO "${HEADERS_CRYPTO}" src/crypto/cn/CryptoNight_arm.h)
list(APPEND HEADERS src/crypto/cn/CryptoNight_arm.h)
else()
set(HEADERS_CRYPTO "${HEADERS_CRYPTO}" src/crypto/cn/CryptoNight_x86.h)
list(APPEND HEADERS src/crypto/cn/CryptoNight_x86.h)
endif()
set(SOURCES
"${SOURCES_BASE}"
"${SOURCES_BASE_HTTP}"
"${SOURCES_BACKEND}"
src/App.cpp
src/core/config/Config.cpp
src/core/config/ConfigTransform.cpp
src/core/Controller.cpp
src/core/Miner.cpp
src/core/Taskbar.cpp
src/net/JobResults.cpp
src/net/Network.cpp
src/net/strategies/DonateStrategy.cpp
src/Summary.cpp
src/xmrig.cpp
)
set(SOURCES_CRYPTO
src/crypto/cn/c_blake256.c
src/crypto/cn/c_groestl.c
src/crypto/cn/c_jh.c
@ -128,6 +118,12 @@ set(SOURCES_CRYPTO
src/crypto/common/MemoryPool.cpp
src/crypto/common/Nonce.cpp
src/crypto/common/VirtualMemory.cpp
src/MinerApp.cpp
src/net/JobResults.cpp
src/net/Network.cpp
src/net/strategies/DonateStrategy.cpp
src/Summary.cpp
src/xmrig.cpp
)
if (CMAKE_C_COMPILER_ID MATCHES GNU)
@ -136,107 +132,58 @@ endif()
if (WITH_VAES)
add_definitions(-DXMRIG_VAES)
set(HEADERS_CRYPTO "${HEADERS_CRYPTO}" src/crypto/cn/CryptoNight_x86_vaes.h)
set(SOURCES_CRYPTO "${SOURCES_CRYPTO}" src/crypto/cn/CryptoNight_x86_vaes.cpp)
list(APPEND HEADERS src/crypto/cn/CryptoNight_x86_vaes.h)
list(APPEND SOURCES src/crypto/cn/CryptoNight_x86_vaes.cpp)
if (CMAKE_C_COMPILER_ID MATCHES GNU OR CMAKE_C_COMPILER_ID MATCHES Clang)
set_source_files_properties(src/crypto/cn/CryptoNight_x86_vaes.cpp PROPERTIES COMPILE_FLAGS "-Ofast -fno-tree-vectorize -mavx2 -mvaes")
endif()
endif()
if (WITH_HWLOC)
list(APPEND HEADERS_CRYPTO
list(APPEND HEADERS
src/crypto/common/NUMAMemoryPool.h
)
list(APPEND SOURCES_CRYPTO
list(APPEND SOURCES
src/crypto/common/NUMAMemoryPool.cpp
src/crypto/common/VirtualMemory_hwloc.cpp
)
endif()
if (XMRIG_OS_WIN)
list(APPEND SOURCES_OS
list(APPEND SOURCES
res/app.rc
src/App_win.cpp
src/crypto/common/VirtualMemory_win.cpp
)
set(EXTRA_LIBS ws2_32 psapi iphlpapi userenv)
elseif (XMRIG_OS_APPLE)
list(APPEND SOURCES_OS
src/App_unix.cpp
src/crypto/common/VirtualMemory_unix.cpp
)
find_library(IOKIT_LIBRARY IOKit)
find_library(CORESERVICES_LIBRARY CoreServices)
set(EXTRA_LIBS ${IOKIT_LIBRARY} ${CORESERVICES_LIBRARY})
else()
list(APPEND SOURCES_OS
src/App_unix.cpp
src/crypto/common/VirtualMemory_unix.cpp
)
list(APPEND SOURCES src/crypto/common/VirtualMemory_unix.cpp)
if (XMRIG_OS_ANDROID)
set(EXTRA_LIBS pthread rt dl log)
elseif (XMRIG_OS_LINUX)
list(APPEND SOURCES_OS
if (XMRIG_OS_LINUX AND NOT XMRIG_OS_ANDROID)
list(APPEND SOURCES
src/crypto/common/LinuxMemory.h
src/crypto/common/LinuxMemory.cpp
)
set(EXTRA_LIBS pthread rt dl)
elseif (XMRIG_OS_FREEBSD)
set(EXTRA_LIBS kvm pthread)
endif()
endif()
add_definitions(-DXMRIG_MINER_PROJECT -DXMRIG_JSON_SINGLE_LINE_ARRAY)
add_definitions(-D__STDC_FORMAT_MACROS -DUNICODE -D_FILE_OFFSET_BITS=64)
include_directories(src)
include_directories(src/3rdparty)
find_package(UV REQUIRED)
include(cmake/flags.cmake)
include(cmake/randomx.cmake)
include(cmake/argon2.cmake)
include(cmake/kawpow.cmake)
include(cmake/ghostrider.cmake)
include(cmake/OpenSSL.cmake)
include(cmake/asm.cmake)
if (WITH_CN_LITE)
add_definitions(/DXMRIG_ALGO_CN_LITE)
endif()
if (WITH_CN_HEAVY)
add_definitions(/DXMRIG_ALGO_CN_HEAVY)
endif()
if (WITH_CN_PICO)
add_definitions(/DXMRIG_ALGO_CN_PICO)
endif()
if (WITH_CN_FEMTO)
add_definitions(/DXMRIG_ALGO_CN_FEMTO)
endif()
include(randomx)
include(argon2)
include(kawpow)
include(ghostrider)
include(asm)
if (WITH_EMBEDDED_CONFIG)
add_definitions(/DXMRIG_FEATURE_EMBEDDED_CONFIG)
add_definitions(-DXMRIG_FEATURE_EMBEDDED_CONFIG)
endif()
include(src/hw/api/api.cmake)
include(src/hw/dmi/dmi.cmake)
include_directories(src)
include_directories(src/3rdparty)
include_directories(${UV_INCLUDE_DIR})
if (WITH_DEBUG_LOG)
add_definitions(/DAPP_DEBUG)
endif()
add_executable(${CMAKE_PROJECT_NAME} ${HEADERS} ${SOURCES} ${SOURCES_OS} ${HEADERS_CRYPTO} ${SOURCES_CRYPTO} ${SOURCES_SYSLOG} ${TLS_SOURCES} ${XMRIG_ASM_SOURCES})
target_link_libraries(${CMAKE_PROJECT_NAME} ${XMRIG_ASM_LIBRARY} ${OPENSSL_LIBRARIES} ${UV_LIBRARIES} ${EXTRA_LIBS} ${CPUID_LIB} ${ARGON2_LIBRARY} ${ETHASH_LIBRARY} ${GHOSTRIDER_LIBRARY})
add_executable(${CMAKE_PROJECT_NAME} ${HEADERS} ${SOURCES})
target_link_libraries(${CMAKE_PROJECT_NAME} ${LIBS})
if (WIN32)
add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/bin/WinRing0/WinRing0x64.sys" $<TARGET_FILE_DIR:${CMAKE_PROJECT_NAME}>)

View file

@ -1,25 +0,0 @@
find_path(
HWLOC_INCLUDE_DIR
NAMES hwloc.h
PATHS "${XMRIG_DEPS}" ENV "XMRIG_DEPS"
PATH_SUFFIXES "include"
NO_DEFAULT_PATH
)
find_path(HWLOC_INCLUDE_DIR NAMES hwloc.h)
find_library(
HWLOC_LIBRARY
NAMES hwloc.a hwloc libhwloc
PATHS "${XMRIG_DEPS}" ENV "XMRIG_DEPS"
PATH_SUFFIXES "lib"
NO_DEFAULT_PATH
)
find_library(HWLOC_LIBRARY NAMES hwloc.a hwloc libhwloc)
set(HWLOC_LIBRARIES ${HWLOC_LIBRARY})
set(HWLOC_INCLUDE_DIRS ${HWLOC_INCLUDE_DIR})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(HWLOC DEFAULT_MSG HWLOC_LIBRARY HWLOC_INCLUDE_DIR)

View file

@ -1,25 +0,0 @@
find_path(
UV_INCLUDE_DIR
NAMES uv.h
PATHS "${XMRIG_DEPS}" ENV "XMRIG_DEPS"
PATH_SUFFIXES "include"
NO_DEFAULT_PATH
)
find_path(UV_INCLUDE_DIR NAMES uv.h)
find_library(
UV_LIBRARY
NAMES libuv.a uv libuv
PATHS "${XMRIG_DEPS}" ENV "XMRIG_DEPS"
PATH_SUFFIXES "lib"
NO_DEFAULT_PATH
)
find_library(UV_LIBRARY NAMES libuv.a uv libuv)
set(UV_LIBRARIES ${UV_LIBRARY})
set(UV_INCLUDE_DIRS ${UV_INCLUDE_DIR})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(UV DEFAULT_MSG UV_LIBRARY UV_INCLUDE_DIR)

View file

@ -1,64 +0,0 @@
if (WITH_TLS)
set(OPENSSL_ROOT_DIR ${XMRIG_DEPS})
if (WIN32)
set(OPENSSL_USE_STATIC_LIBS TRUE)
set(OPENSSL_MSVC_STATIC_RT TRUE)
set(EXTRA_LIBS ${EXTRA_LIBS} crypt32)
elseif (APPLE)
set(OPENSSL_USE_STATIC_LIBS TRUE)
endif()
if (BUILD_STATIC)
set(OPENSSL_USE_STATIC_LIBS TRUE)
endif()
find_package(OpenSSL)
if (OPENSSL_FOUND)
set(TLS_SOURCES
src/base/net/stratum/Tls.cpp
src/base/net/stratum/Tls.h
src/base/net/tls/ServerTls.cpp
src/base/net/tls/ServerTls.h
src/base/net/tls/TlsConfig.cpp
src/base/net/tls/TlsConfig.h
src/base/net/tls/TlsContext.cpp
src/base/net/tls/TlsContext.h
src/base/net/tls/TlsGen.cpp
src/base/net/tls/TlsGen.h
)
include_directories(${OPENSSL_INCLUDE_DIR})
if (WITH_HTTP)
set(TLS_SOURCES ${TLS_SOURCES}
src/base/net/https/HttpsClient.cpp
src/base/net/https/HttpsClient.h
src/base/net/https/HttpsContext.cpp
src/base/net/https/HttpsContext.h
src/base/net/https/HttpsServer.cpp
src/base/net/https/HttpsServer.h
)
endif()
else()
message(FATAL_ERROR "OpenSSL NOT found: use `-DWITH_TLS=OFF` to build without TLS support")
endif()
add_definitions(/DXMRIG_FEATURE_TLS)
else()
set(TLS_SOURCES "")
set(OPENSSL_LIBRARIES "")
remove_definitions(/DXMRIG_FEATURE_TLS)
if (WITH_HTTP)
set(TLS_SOURCES ${TLS_SOURCES}
src/base/net/http/HttpServer.cpp
src/base/net/http/HttpServer.h
)
endif()
set(CMAKE_PROJECT_NAME "${CMAKE_PROJECT_NAME}-notls")
endif()

View file

@ -1,18 +1,13 @@
if (WITH_ARGON2)
add_definitions(/DXMRIG_ALGO_ARGON2)
list(APPEND HEADERS_CRYPTO
list(APPEND HEADERS
src/crypto/argon2/Hash.h
src/crypto/argon2/Impl.h
)
list(APPEND SOURCES_CRYPTO
list(APPEND SOURCES
src/crypto/argon2/Impl.cpp
)
add_subdirectory(src/3rdparty/argon2)
set(ARGON2_LIBRARY argon2)
else()
remove_definitions(/DXMRIG_ALGO_ARGON2)
set(ARGON2_LIBRARY "")
list(APPEND LIBS argon2)
endif()

View file

@ -36,17 +36,16 @@ if (WITH_ASM AND NOT XMRIG_ARM AND CMAKE_SIZEOF_VOID_P EQUAL 8)
endif()
add_library(${XMRIG_ASM_LIBRARY} STATIC ${XMRIG_ASM_FILES})
set(XMRIG_ASM_SOURCES
src/crypto/common/Assembly.h
list(APPEND HEADERS src/crypto/common/Assembly.h)
list(APPEND SOURCES
src/crypto/common/Assembly.cpp
src/crypto/cn/r/CryptonightR_gen.cpp
)
set_property(TARGET ${XMRIG_ASM_LIBRARY} PROPERTY LINKER_LANGUAGE C)
add_definitions(/DXMRIG_FEATURE_ASM)
list(APPEND LIBS ${XMRIG_ASM_LIBRARY})
add_definitions(-DXMRIG_FEATURE_ASM)
else()
set(XMRIG_ASM_SOURCES "")
set(XMRIG_ASM_LIBRARY "")
remove_definitions(/DXMRIG_FEATURE_ASM)
set(WITH_ASM OFF)
endif()

View file

@ -1,64 +0,0 @@
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
set(XMRIG_64_BIT ON)
add_definitions(-DXMRIG_64_BIT)
else()
set(XMRIG_64_BIT OFF)
endif()
if (NOT CMAKE_SYSTEM_PROCESSOR)
message(WARNING "CMAKE_SYSTEM_PROCESSOR not defined")
endif()
include(CheckCXXCompilerFlag)
if (CMAKE_CXX_COMPILER_ID MATCHES MSVC)
set(VAES_SUPPORTED ON)
else()
CHECK_CXX_COMPILER_FLAG("-mavx2 -mvaes" VAES_SUPPORTED)
endif()
if (NOT VAES_SUPPORTED)
set(WITH_VAES OFF)
endif()
if (XMRIG_64_BIT AND CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86_64|AMD64)$")
add_definitions(-DRAPIDJSON_SSE2)
else()
set(WITH_SSE4_1 OFF)
set(WITH_AVX2 OFF)
set(WITH_VAES OFF)
endif()
if (NOT ARM_TARGET)
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64|armv8-a)$")
set(ARM_TARGET 8)
elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "^(armv7|armv7f|armv7s|armv7k|armv7-a|armv7l|armv7ve)$")
set(ARM_TARGET 7)
endif()
endif()
if (ARM_TARGET AND ARM_TARGET GREATER 6)
set(XMRIG_ARM ON)
add_definitions(-DXMRIG_ARM=${ARM_TARGET})
message(STATUS "Use ARM_TARGET=${ARM_TARGET} (${CMAKE_SYSTEM_PROCESSOR})")
if (ARM_TARGET EQUAL 8)
CHECK_CXX_COMPILER_FLAG(-march=armv8-a+crypto XMRIG_ARM_CRYPTO)
if (XMRIG_ARM_CRYPTO)
add_definitions(-DXMRIG_ARM_CRYPTO)
set(ARM8_CXX_FLAGS "-march=armv8-a+crypto")
else()
set(ARM8_CXX_FLAGS "-march=armv8-a")
endif()
endif()
endif()
if (WITH_SSE4_1)
add_definitions(-DXMRIG_FEATURE_SSE4_1)
endif()
if (WITH_AVX2)
add_definitions(-DXMRIG_FEATURE_AVX2)
endif()

View file

@ -1,110 +0,0 @@
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)
if ("${CMAKE_BUILD_TYPE}" STREQUAL "")
set(CMAKE_BUILD_TYPE Release)
endif()
if (CMAKE_BUILD_TYPE STREQUAL "Release")
add_definitions(/DNDEBUG)
endif()
include(CheckSymbolExists)
if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-strict-aliasing")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fexceptions -fno-rtti -Wno-strict-aliasing -Wno-class-memaccess")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -s")
if (ARM_TARGET EQUAL 8)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ARM8_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARM8_CXX_FLAGS} -flax-vector-conversions")
elseif (ARM_TARGET EQUAL 7)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv7-a -mfpu=neon")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv7-a -mfpu=neon -flax-vector-conversions")
else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes")
add_definitions(/DHAVE_ROTR)
endif()
if (WIN32)
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
else()
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static -Wl,--large-address-aware")
endif()
else()
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")
endif()
if (BUILD_STATIC)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
endif()
add_definitions(/D_GNU_SOURCE)
if (${CMAKE_VERSION} VERSION_LESS "3.1.0")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
endif()
#set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -gdwarf-2")
add_definitions(/DHAVE_BUILTIN_CLEAR_CACHE)
elseif (CMAKE_CXX_COMPILER_ID MATCHES MSVC)
set(CMAKE_C_FLAGS_RELEASE "/MT /O2 /Oi /DNDEBUG /GL")
set(CMAKE_CXX_FLAGS_RELEASE "/MT /O2 /Oi /DNDEBUG /GL")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "/Ob1 /Zi /DRELWITHDEBINFO")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "/Ob1 /Zi /DRELWITHDEBINFO")
add_definitions(/D_CRT_SECURE_NO_WARNINGS)
add_definitions(/D_CRT_NONSTDC_NO_WARNINGS)
add_definitions(/DNOMINMAX)
add_definitions(/DHAVE_ROTR)
elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fmerge-all-constants")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fexceptions -fno-rtti -Wno-missing-braces")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -funroll-loops -fmerge-all-constants")
if (ARM_TARGET EQUAL 8)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ARM8_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARM8_CXX_FLAGS}")
elseif (ARM_TARGET EQUAL 7)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpu=neon -march=${CMAKE_SYSTEM_PROCESSOR}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon -march=${CMAKE_SYSTEM_PROCESSOR}")
else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes")
check_symbol_exists("_rotr" "x86intrin.h" HAVE_ROTR)
if (HAVE_ROTR)
add_definitions(/DHAVE_ROTR)
endif()
endif()
if (BUILD_STATIC)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
endif()
endif()
if (NOT WIN32)
check_symbol_exists("__builtin___clear_cache" "stdlib.h" HAVE_BUILTIN_CLEAR_CACHE)
if (HAVE_BUILTIN_CLEAR_CACHE)
add_definitions(/DHAVE_BUILTIN_CLEAR_CACHE)
endif()
endif()

View file

@ -1,8 +1,4 @@
if (WITH_GHOSTRIDER)
add_definitions(/DXMRIG_ALGO_GHOSTRIDER)
add_subdirectory(src/crypto/ghostrider)
set(GHOSTRIDER_LIBRARY ghostrider)
else()
remove_definitions(/DXMRIG_ALGO_GHOSTRIDER)
set(GHOSTRIDER_LIBRARY "")
list(APPEND LIBS ghostrider)
endif()

View file

@ -1,19 +1,14 @@
if (WITH_KAWPOW)
add_definitions(/DXMRIG_ALGO_KAWPOW)
list(APPEND HEADERS_CRYPTO
list(APPEND HEADERS
src/crypto/kawpow/KPCache.h
src/crypto/kawpow/KPHash.h
)
list(APPEND SOURCES_CRYPTO
list(APPEND SOURCES
src/crypto/kawpow/KPCache.cpp
src/crypto/kawpow/KPHash.cpp
)
add_subdirectory(src/3rdparty/libethash)
set(ETHASH_LIBRARY ethash)
else()
remove_definitions(/DXMRIG_ALGO_KAWPOW)
set(ETHASH_LIBRARY "")
add_subdirectory(src/base/3rdparty/libethash)
list(INSERT LIBS 0 ethash)
endif()

View file

@ -1,52 +0,0 @@
if (WIN32)
set(XMRIG_OS_WIN ON)
elseif (APPLE)
set(XMRIG_OS_APPLE ON)
if (IOS OR CMAKE_SYSTEM_NAME STREQUAL iOS)
set(XMRIG_OS_IOS ON)
else()
set(XMRIG_OS_MACOS ON)
endif()
else()
set(XMRIG_OS_UNIX ON)
if (ANDROID OR CMAKE_SYSTEM_NAME MATCHES "Android")
set(XMRIG_OS_ANDROID ON)
elseif(CMAKE_SYSTEM_NAME MATCHES "Linux")
set(XMRIG_OS_LINUX ON)
elseif(CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
set(XMRIG_OS_FREEBSD ON)
endif()
endif()
if (XMRIG_OS_WIN)
add_definitions(-DWIN32 -DXMRIG_OS_WIN)
elseif(XMRIG_OS_APPLE)
add_definitions(-DXMRIG_OS_APPLE)
if (XMRIG_OS_IOS)
add_definitions(-DXMRIG_OS_IOS)
else()
add_definitions(-DXMRIG_OS_MACOS)
endif()
if (XMRIG_ARM)
set(WITH_SECURE_JIT ON)
endif()
elseif(XMRIG_OS_UNIX)
add_definitions(-DXMRIG_OS_UNIX)
if (XMRIG_OS_ANDROID)
add_definitions(-DXMRIG_OS_ANDROID)
elseif (XMRIG_OS_LINUX)
add_definitions(-DXMRIG_OS_LINUX)
elseif (XMRIG_OS_FREEBSD)
add_definitions(-DXMRIG_OS_FREEBSD)
endif()
endif()
if (WITH_SECURE_JIT)
add_definitions(-DXMRIG_SECURE_JIT)
endif()

View file

@ -1,8 +1,5 @@
if (WITH_RANDOMX)
add_definitions(/DXMRIG_ALGO_RANDOMX)
set(WITH_ARGON2 ON)
list(APPEND HEADERS_CRYPTO
list(APPEND HEADERS
src/crypto/rx/Rx.h
src/crypto/rx/RxAlgo.h
src/crypto/rx/RxBasicStorage.h
@ -14,7 +11,7 @@ if (WITH_RANDOMX)
src/crypto/rx/RxVm.h
)
list(APPEND SOURCES_CRYPTO
list(APPEND SOURCES
src/crypto/randomx/aes_hash.cpp
src/crypto/randomx/allocator.cpp
src/crypto/randomx/blake2_generator.cpp
@ -44,19 +41,19 @@ if (WITH_RANDOMX)
if (WITH_ASM AND CMAKE_C_COMPILER_ID MATCHES MSVC)
enable_language(ASM_MASM)
list(APPEND SOURCES_CRYPTO
list(APPEND SOURCES
src/crypto/randomx/jit_compiler_x86_static.asm
src/crypto/randomx/jit_compiler_x86.cpp
)
elseif (WITH_ASM AND NOT XMRIG_ARM AND CMAKE_SIZEOF_VOID_P EQUAL 8)
list(APPEND SOURCES_CRYPTO
list(APPEND SOURCES
src/crypto/randomx/jit_compiler_x86_static.S
src/crypto/randomx/jit_compiler_x86.cpp
)
# cheat because cmake and ccache hate each other
set_property(SOURCE src/crypto/randomx/jit_compiler_x86_static.S PROPERTY LANGUAGE C)
elseif (XMRIG_ARM AND CMAKE_SIZEOF_VOID_P EQUAL 8)
list(APPEND SOURCES_CRYPTO
list(APPEND SOURCES
src/crypto/randomx/jit_compiler_a64_static.S
src/crypto/randomx/jit_compiler_a64.cpp
)
@ -67,13 +64,11 @@ if (WITH_RANDOMX)
set_property(SOURCE src/crypto/randomx/jit_compiler_a64_static.S PROPERTY LANGUAGE C)
endif()
else()
list(APPEND SOURCES_CRYPTO
src/crypto/randomx/jit_compiler_fallback.cpp
)
list(APPEND SOURCES src/crypto/randomx/jit_compiler_fallback.cpp)
endif()
if (WITH_SSE4_1)
list(APPEND SOURCES_CRYPTO src/crypto/randomx/blake2/blake2b_sse41.c)
list(APPEND SOURCES src/crypto/randomx/blake2/blake2b_sse41.c)
if (CMAKE_C_COMPILER_ID MATCHES GNU OR CMAKE_C_COMPILER_ID MATCHES Clang)
set_source_files_properties(src/crypto/randomx/blake2/blake2b_sse41.c PROPERTIES COMPILE_FLAGS "-Ofast -msse4.1")
@ -81,7 +76,7 @@ if (WITH_RANDOMX)
endif()
if (WITH_AVX2)
list(APPEND SOURCES_CRYPTO src/crypto/randomx/blake2/avx2/blake2b_avx2.c)
list(APPEND SOURCES src/crypto/randomx/blake2/avx2/blake2b_avx2.c)
if (CMAKE_C_COMPILER_ID MATCHES GNU OR CMAKE_C_COMPILER_ID MATCHES Clang)
set_source_files_properties(src/crypto/randomx/blake2/avx2/blake2b_avx2.c PROPERTIES COMPILE_FLAGS "-Ofast -mavx2")
@ -93,56 +88,49 @@ if (WITH_RANDOMX)
endif()
if (WITH_HWLOC)
list(APPEND HEADERS_CRYPTO
src/crypto/rx/RxNUMAStorage.h
)
list(APPEND SOURCES_CRYPTO
src/crypto/rx/RxNUMAStorage.cpp
)
list(APPEND HEADERS src/crypto/rx/RxNUMAStorage.h)
list(APPEND SOURCES src/crypto/rx/RxNUMAStorage.cpp)
endif()
if (WITH_MSR AND NOT XMRIG_ARM AND CMAKE_SIZEOF_VOID_P EQUAL 8 AND (XMRIG_OS_WIN OR XMRIG_OS_LINUX))
add_definitions(/DXMRIG_FEATURE_MSR)
add_definitions(/DXMRIG_FIX_RYZEN)
message("-- WITH_MSR=ON")
add_definitions(-DXMRIG_FEATURE_MSR -DXMRIG_FIX_RYZEN)
if (XMRIG_OS_WIN)
list(APPEND SOURCES_CRYPTO
list(APPEND SOURCES
src/crypto/rx/RxFix_win.cpp
src/hw/msr/Msr_win.cpp
)
elseif (XMRIG_OS_LINUX)
list(APPEND SOURCES_CRYPTO
list(APPEND SOURCES
src/crypto/rx/RxFix_linux.cpp
src/hw/msr/Msr_linux.cpp
)
endif()
list(APPEND HEADERS_CRYPTO
list(APPEND HEADERS
src/crypto/rx/RxFix.h
src/crypto/rx/RxMsr.h
src/hw/msr/Msr.h
src/hw/msr/MsrItem.h
)
list(APPEND SOURCES_CRYPTO
list(APPEND SOURCES
src/crypto/rx/RxMsr.cpp
src/hw/msr/Msr.cpp
src/hw/msr/MsrItem.cpp
)
else()
remove_definitions(/DXMRIG_FEATURE_MSR)
remove_definitions(/DXMRIG_FIX_RYZEN)
message("-- WITH_MSR=OFF")
set(WITH_MSR OFF)
endif()
if (WITH_PROFILING)
add_definitions(/DXMRIG_FEATURE_PROFILING)
add_definitions(-DXMRIG_FEATURE_PROFILING)
list(APPEND HEADERS_CRYPTO src/crypto/rx/Profiler.h)
list(APPEND SOURCES_CRYPTO src/crypto/rx/Profiler.cpp)
list(APPEND HEADERS src/crypto/rx/Profiler.h)
list(APPEND SOURCES src/crypto/rx/Profiler.cpp)
endif()
else()
remove_definitions(/DXMRIG_ALGO_RANDOMX)
endif()
message(STATUS "WITH_MSR \t= ${WITH_MSR}")
message(STATUS "WITH_PROFILING \t= ${WITH_PROFILING}")

View file

@ -20,7 +20,7 @@ VS_VERSION_INFO VERSIONINFO
BEGIN
BLOCK "000004b0"
BEGIN
VALUE "CompanyName", APP_SITE
VALUE "CompanyName", APP_DOMAIN
VALUE "FileDescription", APP_DESC
VALUE "FileVersion", APP_VERSION
VALUE "LegalCopyright", APP_COPYRIGHT

View file

@ -1,25 +0,0 @@
Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Andrey N. Sabelnikov nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL Andrey N. Sabelnikov BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -1 +0,0 @@
epee - is a small library of helpers, wrappers, tools and and so on, used to make my life easier.

View file

@ -1,176 +0,0 @@
// Copyright (c) 2017-2020, The Monero Project
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#pragma once
#include <algorithm>
#include <cstdint>
#include <memory>
#include <string>
#include <type_traits>
namespace epee
{
/*!
\brief Non-owning sequence of data. Does not deep copy
Inspired by `gsl::span` and/or `boost::iterator_range`. This class is
intended to be used as a parameter type for functions that need to take a
writable or read-only sequence of data. Most common cases are `span<char>`
and `span<std::uint8_t>`. Using as a class member is only recommended if
clearly documented as not doing a deep-copy. C-arrays are easily convertible
to this type.
\note Conversion from C string literal to `span<const char>` will include
the NULL-terminator.
\note Never allows derived-to-base pointer conversion; an array of derived
types is not an array of base types.
*/
template<typename T>
class span
{
template<typename U>
static constexpr bool safe_conversion() noexcept
{
// Allow exact matches or `T*` -> `const T*`.
using with_const = typename std::add_const<U>::type;
return std::is_same<T, U>() ||
(std::is_const<T>() && std::is_same<T, with_const>());
}
public:
using value_type = T;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
using pointer = T*;
using const_pointer = const T*;
using reference = T&;
using const_reference = const T&;
using iterator = pointer;
using const_iterator = const_pointer;
constexpr span() noexcept : ptr(nullptr), len(0) {}
constexpr span(std::nullptr_t) noexcept : span() {}
//! Prevent derived-to-base conversions; invalid in this context.
template<typename U, typename = typename std::enable_if<safe_conversion<U>()>::type>
constexpr span(U* const src_ptr, const std::size_t count) noexcept
: ptr(src_ptr), len(count) {}
//! Conversion from C-array. Prevents common bugs with sizeof + arrays.
template<std::size_t N>
constexpr span(T (&src)[N]) noexcept : span(src, N) {}
constexpr span(const span&) noexcept = default;
span& operator=(const span&) noexcept = default;
/*! Try to remove `amount` elements from beginning of span.
\return Number of elements removed. */
std::size_t remove_prefix(std::size_t amount) noexcept
{
amount = std::min(len, amount);
ptr += amount;
len -= amount;
return amount;
}
constexpr iterator begin() const noexcept { return ptr; }
constexpr const_iterator cbegin() const noexcept { return ptr; }
constexpr iterator end() const noexcept { return begin() + size(); }
constexpr const_iterator cend() const noexcept { return cbegin() + size(); }
constexpr bool empty() const noexcept { return size() == 0; }
constexpr pointer data() const noexcept { return ptr; }
constexpr std::size_t size() const noexcept { return len; }
constexpr std::size_t size_bytes() const noexcept { return size() * sizeof(value_type); }
T &operator[](size_t idx) noexcept { return ptr[idx]; }
const T &operator[](size_t idx) const noexcept { return ptr[idx]; }
private:
T* ptr;
std::size_t len;
};
//! \return `span<const T::value_type>` from a STL compatible `src`.
template<typename T>
constexpr span<const typename T::value_type> to_span(const T& src)
{
// compiler provides diagnostic if size() is not size_t.
return {src.data(), src.size()};
}
//! \return `span<T::value_type>` from a STL compatible `src`.
template<typename T>
constexpr span<typename T::value_type> to_mut_span(T& src)
{
// compiler provides diagnostic if size() is not size_t.
return {src.data(), src.size()};
}
template<typename T>
constexpr bool has_padding() noexcept
{
return !std::is_standard_layout<T>() || alignof(T) != 1;
}
//! \return Cast data from `src` as `span<const std::uint8_t>`.
template<typename T>
span<const std::uint8_t> to_byte_span(const span<const T> src) noexcept
{
static_assert(!has_padding<T>(), "source type may have padding");
return {reinterpret_cast<const std::uint8_t*>(src.data()), src.size_bytes()};
}
//! \return `span<const std::uint8_t>` which represents the bytes at `&src`.
template<typename T>
span<const std::uint8_t> as_byte_span(const T& src) noexcept
{
static_assert(!std::is_empty<T>(), "empty types will not work -> sizeof == 1");
static_assert(!has_padding<T>(), "source type may have padding");
return {reinterpret_cast<const std::uint8_t*>(std::addressof(src)), sizeof(T)};
}
//! \return `span<std::uint8_t>` which represents the bytes at `&src`.
template<typename T>
span<std::uint8_t> as_mut_byte_span(T& src) noexcept
{
static_assert(!std::is_empty<T>(), "empty types will not work -> sizeof == 1");
static_assert(!has_padding<T>(), "source type may have padding");
return {reinterpret_cast<std::uint8_t*>(std::addressof(src)), sizeof(T)};
}
//! make a span from a std::string
template<typename T>
span<const T> strspan(const std::string &s) noexcept
{
static_assert(std::is_same<T, char>() || std::is_same<T, unsigned char>() || std::is_same<T, int8_t>() || std::is_same<T, uint8_t>(), "Unexpected type");
return {reinterpret_cast<const T*>(s.data()), s.size()};
}
}

View file

@ -1,27 +0,0 @@
Copyright (c) 2012 - present, Victor Zverovich
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--- Optional exception to the license ---
As an exception, if, as a result of your compiling your source code, portions
of this Software are embedded into a machine-executable object form of such
source code, you may redistribute such embedded portions in such object form
without including the above copyright and permission notices.

View file

@ -1,505 +0,0 @@
{fmt}
=====
.. image:: https://travis-ci.org/fmtlib/fmt.png?branch=master
:target: https://travis-ci.org/fmtlib/fmt
.. image:: https://ci.appveyor.com/api/projects/status/ehjkiefde6gucy1v
:target: https://ci.appveyor.com/project/vitaut/fmt
.. image:: https://oss-fuzz-build-logs.storage.googleapis.com/badges/libfmt.svg
:alt: fmt is continuously fuzzed at oss-fuzz
:target: https://bugs.chromium.org/p/oss-fuzz/issues/list?\
colspec=ID%20Type%20Component%20Status%20Proj%20Reported%20Owner%20\
Summary&q=proj%3Dlibfmt&can=1
.. image:: https://img.shields.io/badge/stackoverflow-fmt-blue.svg
:alt: Ask questions at StackOverflow with the tag fmt
:target: https://stackoverflow.com/questions/tagged/fmt
**{fmt}** is an open-source formatting library providing a fast and safe
alternative to C stdio and C++ iostreams.
If you like this project, please consider donating to BYSOL,
an initiative to help victims of political repressions in Belarus:
https://www.facebook.com/donate/759400044849707/108388587646909/.
`Documentation <https://fmt.dev>`__
Q&A: ask questions on `StackOverflow with the tag fmt
<https://stackoverflow.com/questions/tagged/fmt>`_.
Try {fmt} in `Compiler Explorer <https://godbolt.org/z/Eq5763>`_.
Features
--------
* Simple `format API <https://fmt.dev/latest/api.html>`_ with positional arguments
for localization
* Implementation of `C++20 std::format
<https://en.cppreference.com/w/cpp/utility/format>`__
* `Format string syntax <https://fmt.dev/latest/syntax.html>`_ similar to Python's
`format <https://docs.python.org/3/library/stdtypes.html#str.format>`_
* Fast IEEE 754 floating-point formatter with correct rounding, shortness and
round-trip guarantees.
* Safe `printf implementation
<https://fmt.dev/latest/api.html#printf-formatting>`_ including the POSIX
extension for positional arguments
* Extensibility: `support for user-defined types
<https://fmt.dev/latest/api.html#formatting-user-defined-types>`_
* High performance: faster than common standard library implementations of
``(s)printf``, iostreams, ``to_string`` and ``to_chars``, see `Speed tests`_
and `Converting a hundred million integers to strings per second
<http://www.zverovich.net/2020/06/13/fast-int-to-string-revisited.html>`_
* Small code size both in terms of source code with the minimum configuration
consisting of just three files, ``core.h``, ``format.h`` and ``format-inl.h``,
and compiled code; see `Compile time and code bloat`_
* Reliability: the library has an extensive set of `tests
<https://github.com/fmtlib/fmt/tree/master/test>`_ and is `continuously fuzzed
<https://bugs.chromium.org/p/oss-fuzz/issues/list?colspec=ID%20Type%20
Component%20Status%20Proj%20Reported%20Owner%20Summary&q=proj%3Dlibfmt&can=1>`_
* Safety: the library is fully type safe, errors in format strings can be
reported at compile time, automatic memory management prevents buffer overflow
errors
* Ease of use: small self-contained code base, no external dependencies,
permissive MIT `license
<https://github.com/fmtlib/fmt/blob/master/LICENSE.rst>`_
* `Portability <https://fmt.dev/latest/index.html#portability>`_ with
consistent output across platforms and support for older compilers
* Clean warning-free codebase even on high warning levels such as
``-Wall -Wextra -pedantic``
* Locale-independence by default
* Optional header-only configuration enabled with the ``FMT_HEADER_ONLY`` macro
See the `documentation <https://fmt.dev>`_ for more details.
Examples
--------
**Print to stdout** (`run <https://godbolt.org/z/Tevcjh>`_)
.. code:: c++
#include <fmt/core.h>
int main() {
fmt::print("Hello, world!\n");
}
**Format a string** (`run <https://godbolt.org/z/oK8h33>`_)
.. code:: c++
std::string s = fmt::format("The answer is {}.", 42);
// s == "The answer is 42."
**Format a string using positional arguments** (`run <https://godbolt.org/z/Yn7Txe>`_)
.. code:: c++
std::string s = fmt::format("I'd rather be {1} than {0}.", "right", "happy");
// s == "I'd rather be happy than right."
**Print chrono durations** (`run <https://godbolt.org/z/K8s4Mc>`_)
.. code:: c++
#include <fmt/chrono.h>
int main() {
using namespace std::literals::chrono_literals;
fmt::print("Default format: {} {}\n", 42s, 100ms);
fmt::print("strftime-like format: {:%H:%M:%S}\n", 3h + 15min + 30s);
}
Output::
Default format: 42s 100ms
strftime-like format: 03:15:30
**Print a container** (`run <https://godbolt.org/z/MjsY7c>`_)
.. code:: c++
#include <vector>
#include <fmt/ranges.h>
int main() {
std::vector<int> v = {1, 2, 3};
fmt::print("{}\n", v);
}
Output::
{1, 2, 3}
**Check a format string at compile time**
.. code:: c++
std::string s = fmt::format(FMT_STRING("{:d}"), "don't panic");
This gives a compile-time error because ``d`` is an invalid format specifier for
a string.
**Write a file from a single thread**
.. code:: c++
#include <fmt/os.h>
int main() {
auto out = fmt::output_file("guide.txt");
out.print("Don't {}", "Panic");
}
This can be `5 to 9 times faster than fprintf
<http://www.zverovich.net/2020/08/04/optimal-file-buffer-size.html>`_.
**Print with colors and text styles**
.. code:: c++
#include <fmt/color.h>
int main() {
fmt::print(fg(fmt::color::crimson) | fmt::emphasis::bold,
"Hello, {}!\n", "world");
fmt::print(fg(fmt::color::floral_white) | bg(fmt::color::slate_gray) |
fmt::emphasis::underline, "Hello, {}!\n", "мир");
fmt::print(fg(fmt::color::steel_blue) | fmt::emphasis::italic,
"Hello, {}!\n", "世界");
}
Output on a modern terminal:
.. image:: https://user-images.githubusercontent.com/
576385/88485597-d312f600-cf2b-11ea-9cbe-61f535a86e28.png
Benchmarks
----------
Speed tests
~~~~~~~~~~~
================= ============= ===========
Library Method Run Time, s
================= ============= ===========
libc printf 1.04
libc++ std::ostream 3.05
{fmt} 6.1.1 fmt::print 0.75
Boost Format 1.67 boost::format 7.24
Folly Format folly::format 2.23
================= ============= ===========
{fmt} is the fastest of the benchmarked methods, ~35% faster than ``printf``.
The above results were generated by building ``tinyformat_test.cpp`` on macOS
10.14.6 with ``clang++ -O3 -DNDEBUG -DSPEED_TEST -DHAVE_FORMAT``, and taking the
best of three runs. In the test, the format string ``"%0.10f:%04d:%+g:%s:%p:%c:%%\n"``
or equivalent is filled 2,000,000 times with output sent to ``/dev/null``; for
further details refer to the `source
<https://github.com/fmtlib/format-benchmark/blob/master/tinyformat_test.cpp>`_.
{fmt} is up to 10x faster than ``std::ostringstream`` and ``sprintf`` on
floating-point formatting (`dtoa-benchmark <https://github.com/fmtlib/dtoa-benchmark>`_)
and faster than `double-conversion <https://github.com/google/double-conversion>`_:
.. image:: https://user-images.githubusercontent.com/576385/
69767160-cdaca400-112f-11ea-9fc5-347c9f83caad.png
:target: https://fmt.dev/unknown_mac64_clang10.0.html
Compile time and code bloat
~~~~~~~~~~~~~~~~~~~~~~~~~~~
The script `bloat-test.py
<https://github.com/fmtlib/format-benchmark/blob/master/bloat-test.py>`_
from `format-benchmark <https://github.com/fmtlib/format-benchmark>`_
tests compile time and code bloat for nontrivial projects.
It generates 100 translation units and uses ``printf()`` or its alternative
five times in each to simulate a medium sized project. The resulting
executable size and compile time (Apple LLVM version 8.1.0 (clang-802.0.42),
macOS Sierra, best of three) is shown in the following tables.
**Optimized build (-O3)**
============= =============== ==================== ==================
Method Compile Time, s Executable size, KiB Stripped size, KiB
============= =============== ==================== ==================
printf 2.6 29 26
printf+string 16.4 29 26
iostreams 31.1 59 55
{fmt} 19.0 37 34
Boost Format 91.9 226 203
Folly Format 115.7 101 88
============= =============== ==================== ==================
As you can see, {fmt} has 60% less overhead in terms of resulting binary code
size compared to iostreams and comes pretty close to ``printf``. Boost Format
and Folly Format have the largest overheads.
``printf+string`` is the same as ``printf`` but with extra ``<string>``
include to measure the overhead of the latter.
**Non-optimized build**
============= =============== ==================== ==================
Method Compile Time, s Executable size, KiB Stripped size, KiB
============= =============== ==================== ==================
printf 2.2 33 30
printf+string 16.0 33 30
iostreams 28.3 56 52
{fmt} 18.2 59 50
Boost Format 54.1 365 303
Folly Format 79.9 445 430
============= =============== ==================== ==================
``libc``, ``lib(std)c++`` and ``libfmt`` are all linked as shared libraries to
compare formatting function overhead only. Boost Format is a
header-only library so it doesn't provide any linkage options.
Running the tests
~~~~~~~~~~~~~~~~~
Please refer to `Building the library`__ for the instructions on how to build
the library and run the unit tests.
__ https://fmt.dev/latest/usage.html#building-the-library
Benchmarks reside in a separate repository,
`format-benchmarks <https://github.com/fmtlib/format-benchmark>`_,
so to run the benchmarks you first need to clone this repository and
generate Makefiles with CMake::
$ git clone --recursive https://github.com/fmtlib/format-benchmark.git
$ cd format-benchmark
$ cmake .
Then you can run the speed test::
$ make speed-test
or the bloat test::
$ make bloat-test
Projects using this library
---------------------------
* `0 A.D. <https://play0ad.com/>`_: A free, open-source, cross-platform
real-time strategy game
* `AMPL/MP <https://github.com/ampl/mp>`_:
An open-source library for mathematical programming
* `Aseprite <https://github.com/aseprite/aseprite>`_:
Animated sprite editor & pixel art tool
* `AvioBook <https://www.aviobook.aero/en>`_: A comprehensive aircraft
operations suite
* `Celestia <https://celestia.space/>`_: Real-time 3D visualization of space
* `Ceph <https://ceph.com/>`_: A scalable distributed storage system
* `ccache <https://ccache.dev/>`_: A compiler cache
* `ClickHouse <https://github.com/ClickHouse/ClickHouse>`_: analytical database
management system
* `CUAUV <http://cuauv.org/>`_: Cornell University's autonomous underwater
vehicle
* `Drake <https://drake.mit.edu/>`_: A planning, control, and analysis toolbox
for nonlinear dynamical systems (MIT)
* `Envoy <https://lyft.github.io/envoy/>`_: C++ L7 proxy and communication bus
(Lyft)
* `FiveM <https://fivem.net/>`_: a modification framework for GTA V
* `Folly <https://github.com/facebook/folly>`_: Facebook open-source library
* `HarpyWar/pvpgn <https://github.com/pvpgn/pvpgn-server>`_:
Player vs Player Gaming Network with tweaks
* `KBEngine <https://github.com/kbengine/kbengine>`_: An open-source MMOG server
engine
* `Keypirinha <https://keypirinha.com/>`_: A semantic launcher for Windows
* `Kodi <https://kodi.tv/>`_ (formerly xbmc): Home theater software
* `Knuth <https://kth.cash/>`_: High-performance Bitcoin full-node
* `Microsoft Verona <https://github.com/microsoft/verona>`_:
Research programming language for concurrent ownership
* `MongoDB <https://mongodb.com/>`_: Distributed document database
* `MongoDB Smasher <https://github.com/duckie/mongo_smasher>`_: A small tool to
generate randomized datasets
* `OpenSpace <https://openspaceproject.com/>`_: An open-source
astrovisualization framework
* `PenUltima Online (POL) <https://www.polserver.com/>`_:
An MMO server, compatible with most Ultima Online clients
* `PyTorch <https://github.com/pytorch/pytorch>`_: An open-source machine
learning library
* `quasardb <https://www.quasardb.net/>`_: A distributed, high-performance,
associative database
* `Quill <https://github.com/odygrd/quill>`_: Asynchronous low-latency logging library
* `QKW <https://github.com/ravijanjam/qkw>`_: Generalizing aliasing to simplify
navigation, and executing complex multi-line terminal command sequences
* `readpe <https://bitbucket.org/sys_dev/readpe>`_: Read Portable Executable
* `redis-cerberus <https://github.com/HunanTV/redis-cerberus>`_: A Redis cluster
proxy
* `redpanda <https://vectorized.io/redpanda>`_: A 10x faster Kafka® replacement
for mission critical systems written in C++
* `rpclib <http://rpclib.net/>`_: A modern C++ msgpack-RPC server and client
library
* `Salesforce Analytics Cloud
<https://www.salesforce.com/analytics-cloud/overview/>`_:
Business intelligence software
* `Scylla <https://www.scylladb.com/>`_: A Cassandra-compatible NoSQL data store
that can handle 1 million transactions per second on a single server
* `Seastar <http://www.seastar-project.org/>`_: An advanced, open-source C++
framework for high-performance server applications on modern hardware
* `spdlog <https://github.com/gabime/spdlog>`_: Super fast C++ logging library
* `Stellar <https://www.stellar.org/>`_: Financial platform
* `Touch Surgery <https://www.touchsurgery.com/>`_: Surgery simulator
* `TrinityCore <https://github.com/TrinityCore/TrinityCore>`_: Open-source
MMORPG framework
* `Windows Terminal <https://github.com/microsoft/terminal>`_: The new Windows
Terminal
`More... <https://github.com/search?q=fmtlib&type=Code>`_
If you are aware of other projects using this library, please let me know
by `email <mailto:victor.zverovich@gmail.com>`_ or by submitting an
`issue <https://github.com/fmtlib/fmt/issues>`_.
Motivation
----------
So why yet another formatting library?
There are plenty of methods for doing this task, from standard ones like
the printf family of function and iostreams to Boost Format and FastFormat
libraries. The reason for creating a new library is that every existing
solution that I found either had serious issues or didn't provide
all the features I needed.
printf
~~~~~~
The good thing about ``printf`` is that it is pretty fast and readily available
being a part of the C standard library. The main drawback is that it
doesn't support user-defined types. ``printf`` also has safety issues although
they are somewhat mitigated with `__attribute__ ((format (printf, ...))
<https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>`_ in GCC.
There is a POSIX extension that adds positional arguments required for
`i18n <https://en.wikipedia.org/wiki/Internationalization_and_localization>`_
to ``printf`` but it is not a part of C99 and may not be available on some
platforms.
iostreams
~~~~~~~~~
The main issue with iostreams is best illustrated with an example:
.. code:: c++
std::cout << std::setprecision(2) << std::fixed << 1.23456 << "\n";
which is a lot of typing compared to printf:
.. code:: c++
printf("%.2f\n", 1.23456);
Matthew Wilson, the author of FastFormat, called this "chevron hell". iostreams
don't support positional arguments by design.
The good part is that iostreams support user-defined types and are safe although
error handling is awkward.
Boost Format
~~~~~~~~~~~~
This is a very powerful library which supports both ``printf``-like format
strings and positional arguments. Its main drawback is performance. According to
various, benchmarks it is much slower than other methods considered here. Boost
Format also has excessive build times and severe code bloat issues (see
`Benchmarks`_).
FastFormat
~~~~~~~~~~
This is an interesting library which is fast, safe and has positional arguments.
However, it has significant limitations, citing its author:
Three features that have no hope of being accommodated within the
current design are:
* Leading zeros (or any other non-space padding)
* Octal/hexadecimal encoding
* Runtime width/alignment specification
It is also quite big and has a heavy dependency, STLSoft, which might be too
restrictive for using it in some projects.
Boost Spirit.Karma
~~~~~~~~~~~~~~~~~~
This is not really a formatting library but I decided to include it here for
completeness. As iostreams, it suffers from the problem of mixing verbatim text
with arguments. The library is pretty fast, but slower on integer formatting
than ``fmt::format_to`` with format string compilation on Karma's own benchmark,
see `Converting a hundred million integers to strings per second
<http://www.zverovich.net/2020/06/13/fast-int-to-string-revisited.html>`_.
License
-------
{fmt} is distributed under the MIT `license
<https://github.com/fmtlib/fmt/blob/master/LICENSE.rst>`_.
Documentation License
---------------------
The `Format String Syntax <https://fmt.dev/latest/syntax.html>`_
section in the documentation is based on the one from Python `string module
documentation <https://docs.python.org/3/library/string.html#module-string>`_.
For this reason the documentation is distributed under the Python Software
Foundation license available in `doc/python-license.txt
<https://raw.github.com/fmtlib/fmt/master/doc/python-license.txt>`_.
It only applies if you distribute the documentation of {fmt}.
Maintainers
-----------
The {fmt} library is maintained by Victor Zverovich (`vitaut
<https://github.com/vitaut>`_) and Jonathan Müller (`foonathan
<https://github.com/foonathan>`_) with contributions from many other people.
See `Contributors <https://github.com/fmtlib/fmt/graphs/contributors>`_ and
`Releases <https://github.com/fmtlib/fmt/releases>`_ for some of the names.
Let us know if your contribution is not listed or mentioned incorrectly and
we'll make it right.

File diff suppressed because it is too large Load diff

View file

@ -1,602 +0,0 @@
// Formatting library for C++ - color support
//
// Copyright (c) 2018 - present, Victor Zverovich and fmt contributors
// All rights reserved.
//
// For the license information refer to format.h.
#ifndef FMT_COLOR_H_
#define FMT_COLOR_H_
#include "format.h"
FMT_BEGIN_NAMESPACE
enum class color : uint32_t {
alice_blue = 0xF0F8FF, // rgb(240,248,255)
antique_white = 0xFAEBD7, // rgb(250,235,215)
aqua = 0x00FFFF, // rgb(0,255,255)
aquamarine = 0x7FFFD4, // rgb(127,255,212)
azure = 0xF0FFFF, // rgb(240,255,255)
beige = 0xF5F5DC, // rgb(245,245,220)
bisque = 0xFFE4C4, // rgb(255,228,196)
black = 0x000000, // rgb(0,0,0)
blanched_almond = 0xFFEBCD, // rgb(255,235,205)
blue = 0x0000FF, // rgb(0,0,255)
blue_violet = 0x8A2BE2, // rgb(138,43,226)
brown = 0xA52A2A, // rgb(165,42,42)
burly_wood = 0xDEB887, // rgb(222,184,135)
cadet_blue = 0x5F9EA0, // rgb(95,158,160)
chartreuse = 0x7FFF00, // rgb(127,255,0)
chocolate = 0xD2691E, // rgb(210,105,30)
coral = 0xFF7F50, // rgb(255,127,80)
cornflower_blue = 0x6495ED, // rgb(100,149,237)
cornsilk = 0xFFF8DC, // rgb(255,248,220)
crimson = 0xDC143C, // rgb(220,20,60)
cyan = 0x00FFFF, // rgb(0,255,255)
dark_blue = 0x00008B, // rgb(0,0,139)
dark_cyan = 0x008B8B, // rgb(0,139,139)
dark_golden_rod = 0xB8860B, // rgb(184,134,11)
dark_gray = 0xA9A9A9, // rgb(169,169,169)
dark_green = 0x006400, // rgb(0,100,0)
dark_khaki = 0xBDB76B, // rgb(189,183,107)
dark_magenta = 0x8B008B, // rgb(139,0,139)
dark_olive_green = 0x556B2F, // rgb(85,107,47)
dark_orange = 0xFF8C00, // rgb(255,140,0)
dark_orchid = 0x9932CC, // rgb(153,50,204)
dark_red = 0x8B0000, // rgb(139,0,0)
dark_salmon = 0xE9967A, // rgb(233,150,122)
dark_sea_green = 0x8FBC8F, // rgb(143,188,143)
dark_slate_blue = 0x483D8B, // rgb(72,61,139)
dark_slate_gray = 0x2F4F4F, // rgb(47,79,79)
dark_turquoise = 0x00CED1, // rgb(0,206,209)
dark_violet = 0x9400D3, // rgb(148,0,211)
deep_pink = 0xFF1493, // rgb(255,20,147)
deep_sky_blue = 0x00BFFF, // rgb(0,191,255)
dim_gray = 0x696969, // rgb(105,105,105)
dodger_blue = 0x1E90FF, // rgb(30,144,255)
fire_brick = 0xB22222, // rgb(178,34,34)
floral_white = 0xFFFAF0, // rgb(255,250,240)
forest_green = 0x228B22, // rgb(34,139,34)
fuchsia = 0xFF00FF, // rgb(255,0,255)
gainsboro = 0xDCDCDC, // rgb(220,220,220)
ghost_white = 0xF8F8FF, // rgb(248,248,255)
gold = 0xFFD700, // rgb(255,215,0)
golden_rod = 0xDAA520, // rgb(218,165,32)
gray = 0x808080, // rgb(128,128,128)
green = 0x008000, // rgb(0,128,0)
green_yellow = 0xADFF2F, // rgb(173,255,47)
honey_dew = 0xF0FFF0, // rgb(240,255,240)
hot_pink = 0xFF69B4, // rgb(255,105,180)
indian_red = 0xCD5C5C, // rgb(205,92,92)
indigo = 0x4B0082, // rgb(75,0,130)
ivory = 0xFFFFF0, // rgb(255,255,240)
khaki = 0xF0E68C, // rgb(240,230,140)
lavender = 0xE6E6FA, // rgb(230,230,250)
lavender_blush = 0xFFF0F5, // rgb(255,240,245)
lawn_green = 0x7CFC00, // rgb(124,252,0)
lemon_chiffon = 0xFFFACD, // rgb(255,250,205)
light_blue = 0xADD8E6, // rgb(173,216,230)
light_coral = 0xF08080, // rgb(240,128,128)
light_cyan = 0xE0FFFF, // rgb(224,255,255)
light_golden_rod_yellow = 0xFAFAD2, // rgb(250,250,210)
light_gray = 0xD3D3D3, // rgb(211,211,211)
light_green = 0x90EE90, // rgb(144,238,144)
light_pink = 0xFFB6C1, // rgb(255,182,193)
light_salmon = 0xFFA07A, // rgb(255,160,122)
light_sea_green = 0x20B2AA, // rgb(32,178,170)
light_sky_blue = 0x87CEFA, // rgb(135,206,250)
light_slate_gray = 0x778899, // rgb(119,136,153)
light_steel_blue = 0xB0C4DE, // rgb(176,196,222)
light_yellow = 0xFFFFE0, // rgb(255,255,224)
lime = 0x00FF00, // rgb(0,255,0)
lime_green = 0x32CD32, // rgb(50,205,50)
linen = 0xFAF0E6, // rgb(250,240,230)
magenta = 0xFF00FF, // rgb(255,0,255)
maroon = 0x800000, // rgb(128,0,0)
medium_aquamarine = 0x66CDAA, // rgb(102,205,170)
medium_blue = 0x0000CD, // rgb(0,0,205)
medium_orchid = 0xBA55D3, // rgb(186,85,211)
medium_purple = 0x9370DB, // rgb(147,112,219)
medium_sea_green = 0x3CB371, // rgb(60,179,113)
medium_slate_blue = 0x7B68EE, // rgb(123,104,238)
medium_spring_green = 0x00FA9A, // rgb(0,250,154)
medium_turquoise = 0x48D1CC, // rgb(72,209,204)
medium_violet_red = 0xC71585, // rgb(199,21,133)
midnight_blue = 0x191970, // rgb(25,25,112)
mint_cream = 0xF5FFFA, // rgb(245,255,250)
misty_rose = 0xFFE4E1, // rgb(255,228,225)
moccasin = 0xFFE4B5, // rgb(255,228,181)
navajo_white = 0xFFDEAD, // rgb(255,222,173)
navy = 0x000080, // rgb(0,0,128)
old_lace = 0xFDF5E6, // rgb(253,245,230)
olive = 0x808000, // rgb(128,128,0)
olive_drab = 0x6B8E23, // rgb(107,142,35)
orange = 0xFFA500, // rgb(255,165,0)
orange_red = 0xFF4500, // rgb(255,69,0)
orchid = 0xDA70D6, // rgb(218,112,214)
pale_golden_rod = 0xEEE8AA, // rgb(238,232,170)
pale_green = 0x98FB98, // rgb(152,251,152)
pale_turquoise = 0xAFEEEE, // rgb(175,238,238)
pale_violet_red = 0xDB7093, // rgb(219,112,147)
papaya_whip = 0xFFEFD5, // rgb(255,239,213)
peach_puff = 0xFFDAB9, // rgb(255,218,185)
peru = 0xCD853F, // rgb(205,133,63)
pink = 0xFFC0CB, // rgb(255,192,203)
plum = 0xDDA0DD, // rgb(221,160,221)
powder_blue = 0xB0E0E6, // rgb(176,224,230)
purple = 0x800080, // rgb(128,0,128)
rebecca_purple = 0x663399, // rgb(102,51,153)
red = 0xFF0000, // rgb(255,0,0)
rosy_brown = 0xBC8F8F, // rgb(188,143,143)
royal_blue = 0x4169E1, // rgb(65,105,225)
saddle_brown = 0x8B4513, // rgb(139,69,19)
salmon = 0xFA8072, // rgb(250,128,114)
sandy_brown = 0xF4A460, // rgb(244,164,96)
sea_green = 0x2E8B57, // rgb(46,139,87)
sea_shell = 0xFFF5EE, // rgb(255,245,238)
sienna = 0xA0522D, // rgb(160,82,45)
silver = 0xC0C0C0, // rgb(192,192,192)
sky_blue = 0x87CEEB, // rgb(135,206,235)
slate_blue = 0x6A5ACD, // rgb(106,90,205)
slate_gray = 0x708090, // rgb(112,128,144)
snow = 0xFFFAFA, // rgb(255,250,250)
spring_green = 0x00FF7F, // rgb(0,255,127)
steel_blue = 0x4682B4, // rgb(70,130,180)
tan = 0xD2B48C, // rgb(210,180,140)
teal = 0x008080, // rgb(0,128,128)
thistle = 0xD8BFD8, // rgb(216,191,216)
tomato = 0xFF6347, // rgb(255,99,71)
turquoise = 0x40E0D0, // rgb(64,224,208)
violet = 0xEE82EE, // rgb(238,130,238)
wheat = 0xF5DEB3, // rgb(245,222,179)
white = 0xFFFFFF, // rgb(255,255,255)
white_smoke = 0xF5F5F5, // rgb(245,245,245)
yellow = 0xFFFF00, // rgb(255,255,0)
yellow_green = 0x9ACD32 // rgb(154,205,50)
}; // enum class color
enum class terminal_color : uint8_t {
black = 30,
red,
green,
yellow,
blue,
magenta,
cyan,
white,
bright_black = 90,
bright_red,
bright_green,
bright_yellow,
bright_blue,
bright_magenta,
bright_cyan,
bright_white
};
enum class emphasis : uint8_t {
bold = 1,
italic = 1 << 1,
underline = 1 << 2,
strikethrough = 1 << 3
};
// rgb is a struct for red, green and blue colors.
// Using the name "rgb" makes some editors show the color in a tooltip.
struct rgb {
FMT_CONSTEXPR rgb() : r(0), g(0), b(0) {}
FMT_CONSTEXPR rgb(uint8_t r_, uint8_t g_, uint8_t b_) : r(r_), g(g_), b(b_) {}
FMT_CONSTEXPR rgb(uint32_t hex)
: r((hex >> 16) & 0xFF), g((hex >> 8) & 0xFF), b(hex & 0xFF) {}
FMT_CONSTEXPR rgb(color hex)
: r((uint32_t(hex) >> 16) & 0xFF),
g((uint32_t(hex) >> 8) & 0xFF),
b(uint32_t(hex) & 0xFF) {}
uint8_t r;
uint8_t g;
uint8_t b;
};
namespace detail {
// color is a struct of either a rgb color or a terminal color.
struct color_type {
FMT_CONSTEXPR color_type() FMT_NOEXCEPT : is_rgb(), value{} {}
FMT_CONSTEXPR color_type(color rgb_color) FMT_NOEXCEPT : is_rgb(true),
value{} {
value.rgb_color = static_cast<uint32_t>(rgb_color);
}
FMT_CONSTEXPR color_type(rgb rgb_color) FMT_NOEXCEPT : is_rgb(true), value{} {
value.rgb_color = (static_cast<uint32_t>(rgb_color.r) << 16) |
(static_cast<uint32_t>(rgb_color.g) << 8) | rgb_color.b;
}
FMT_CONSTEXPR color_type(terminal_color term_color) FMT_NOEXCEPT : is_rgb(),
value{} {
value.term_color = static_cast<uint8_t>(term_color);
}
bool is_rgb;
union color_union {
uint8_t term_color;
uint32_t rgb_color;
} value;
};
} // namespace detail
// Experimental text formatting support.
class text_style {
public:
FMT_CONSTEXPR text_style(emphasis em = emphasis()) FMT_NOEXCEPT
: set_foreground_color(),
set_background_color(),
ems(em) {}
FMT_CONSTEXPR text_style& operator|=(const text_style& rhs) {
if (!set_foreground_color) {
set_foreground_color = rhs.set_foreground_color;
foreground_color = rhs.foreground_color;
} else if (rhs.set_foreground_color) {
if (!foreground_color.is_rgb || !rhs.foreground_color.is_rgb)
FMT_THROW(format_error("can't OR a terminal color"));
foreground_color.value.rgb_color |= rhs.foreground_color.value.rgb_color;
}
if (!set_background_color) {
set_background_color = rhs.set_background_color;
background_color = rhs.background_color;
} else if (rhs.set_background_color) {
if (!background_color.is_rgb || !rhs.background_color.is_rgb)
FMT_THROW(format_error("can't OR a terminal color"));
background_color.value.rgb_color |= rhs.background_color.value.rgb_color;
}
ems = static_cast<emphasis>(static_cast<uint8_t>(ems) |
static_cast<uint8_t>(rhs.ems));
return *this;
}
friend FMT_CONSTEXPR text_style operator|(text_style lhs,
const text_style& rhs) {
return lhs |= rhs;
}
FMT_CONSTEXPR text_style& operator&=(const text_style& rhs) {
if (!set_foreground_color) {
set_foreground_color = rhs.set_foreground_color;
foreground_color = rhs.foreground_color;
} else if (rhs.set_foreground_color) {
if (!foreground_color.is_rgb || !rhs.foreground_color.is_rgb)
FMT_THROW(format_error("can't AND a terminal color"));
foreground_color.value.rgb_color &= rhs.foreground_color.value.rgb_color;
}
if (!set_background_color) {
set_background_color = rhs.set_background_color;
background_color = rhs.background_color;
} else if (rhs.set_background_color) {
if (!background_color.is_rgb || !rhs.background_color.is_rgb)
FMT_THROW(format_error("can't AND a terminal color"));
background_color.value.rgb_color &= rhs.background_color.value.rgb_color;
}
ems = static_cast<emphasis>(static_cast<uint8_t>(ems) &
static_cast<uint8_t>(rhs.ems));
return *this;
}
friend FMT_CONSTEXPR text_style operator&(text_style lhs,
const text_style& rhs) {
return lhs &= rhs;
}
FMT_CONSTEXPR bool has_foreground() const FMT_NOEXCEPT {
return set_foreground_color;
}
FMT_CONSTEXPR bool has_background() const FMT_NOEXCEPT {
return set_background_color;
}
FMT_CONSTEXPR bool has_emphasis() const FMT_NOEXCEPT {
return static_cast<uint8_t>(ems) != 0;
}
FMT_CONSTEXPR detail::color_type get_foreground() const FMT_NOEXCEPT {
FMT_ASSERT(has_foreground(), "no foreground specified for this style");
return foreground_color;
}
FMT_CONSTEXPR detail::color_type get_background() const FMT_NOEXCEPT {
FMT_ASSERT(has_background(), "no background specified for this style");
return background_color;
}
FMT_CONSTEXPR emphasis get_emphasis() const FMT_NOEXCEPT {
FMT_ASSERT(has_emphasis(), "no emphasis specified for this style");
return ems;
}
private:
FMT_CONSTEXPR text_style(bool is_foreground,
detail::color_type text_color) FMT_NOEXCEPT
: set_foreground_color(),
set_background_color(),
ems() {
if (is_foreground) {
foreground_color = text_color;
set_foreground_color = true;
} else {
background_color = text_color;
set_background_color = true;
}
}
friend FMT_CONSTEXPR_DECL text_style fg(detail::color_type foreground)
FMT_NOEXCEPT;
friend FMT_CONSTEXPR_DECL text_style bg(detail::color_type background)
FMT_NOEXCEPT;
detail::color_type foreground_color;
detail::color_type background_color;
bool set_foreground_color;
bool set_background_color;
emphasis ems;
};
FMT_CONSTEXPR text_style fg(detail::color_type foreground) FMT_NOEXCEPT {
return text_style(/*is_foreground=*/true, foreground);
}
FMT_CONSTEXPR text_style bg(detail::color_type background) FMT_NOEXCEPT {
return text_style(/*is_foreground=*/false, background);
}
FMT_CONSTEXPR text_style operator|(emphasis lhs, emphasis rhs) FMT_NOEXCEPT {
return text_style(lhs) | rhs;
}
namespace detail {
template <typename Char> struct ansi_color_escape {
FMT_CONSTEXPR ansi_color_escape(detail::color_type text_color,
const char* esc) FMT_NOEXCEPT {
// If we have a terminal color, we need to output another escape code
// sequence.
if (!text_color.is_rgb) {
bool is_background = esc == detail::data::background_color;
uint32_t value = text_color.value.term_color;
// Background ASCII codes are the same as the foreground ones but with
// 10 more.
if (is_background) value += 10u;
size_t index = 0;
buffer[index++] = static_cast<Char>('\x1b');
buffer[index++] = static_cast<Char>('[');
if (value >= 100u) {
buffer[index++] = static_cast<Char>('1');
value %= 100u;
}
buffer[index++] = static_cast<Char>('0' + value / 10u);
buffer[index++] = static_cast<Char>('0' + value % 10u);
buffer[index++] = static_cast<Char>('m');
buffer[index++] = static_cast<Char>('\0');
return;
}
for (int i = 0; i < 7; i++) {
buffer[i] = static_cast<Char>(esc[i]);
}
rgb color(text_color.value.rgb_color);
to_esc(color.r, buffer + 7, ';');
to_esc(color.g, buffer + 11, ';');
to_esc(color.b, buffer + 15, 'm');
buffer[19] = static_cast<Char>(0);
}
FMT_CONSTEXPR ansi_color_escape(emphasis em) FMT_NOEXCEPT {
uint8_t em_codes[4] = {};
uint8_t em_bits = static_cast<uint8_t>(em);
if (em_bits & static_cast<uint8_t>(emphasis::bold)) em_codes[0] = 1;
if (em_bits & static_cast<uint8_t>(emphasis::italic)) em_codes[1] = 3;
if (em_bits & static_cast<uint8_t>(emphasis::underline)) em_codes[2] = 4;
if (em_bits & static_cast<uint8_t>(emphasis::strikethrough))
em_codes[3] = 9;
size_t index = 0;
for (int i = 0; i < 4; ++i) {
if (!em_codes[i]) continue;
buffer[index++] = static_cast<Char>('\x1b');
buffer[index++] = static_cast<Char>('[');
buffer[index++] = static_cast<Char>('0' + em_codes[i]);
buffer[index++] = static_cast<Char>('m');
}
buffer[index++] = static_cast<Char>(0);
}
FMT_CONSTEXPR operator const Char*() const FMT_NOEXCEPT { return buffer; }
FMT_CONSTEXPR const Char* begin() const FMT_NOEXCEPT { return buffer; }
FMT_CONSTEXPR const Char* end() const FMT_NOEXCEPT {
return buffer + std::char_traits<Char>::length(buffer);
}
private:
Char buffer[7u + 3u * 4u + 1u];
static FMT_CONSTEXPR void to_esc(uint8_t c, Char* out,
char delimiter) FMT_NOEXCEPT {
out[0] = static_cast<Char>('0' + c / 100);
out[1] = static_cast<Char>('0' + c / 10 % 10);
out[2] = static_cast<Char>('0' + c % 10);
out[3] = static_cast<Char>(delimiter);
}
};
template <typename Char>
FMT_CONSTEXPR ansi_color_escape<Char> make_foreground_color(
detail::color_type foreground) FMT_NOEXCEPT {
return ansi_color_escape<Char>(foreground, detail::data::foreground_color);
}
template <typename Char>
FMT_CONSTEXPR ansi_color_escape<Char> make_background_color(
detail::color_type background) FMT_NOEXCEPT {
return ansi_color_escape<Char>(background, detail::data::background_color);
}
template <typename Char>
FMT_CONSTEXPR ansi_color_escape<Char> make_emphasis(emphasis em) FMT_NOEXCEPT {
return ansi_color_escape<Char>(em);
}
template <typename Char>
inline void fputs(const Char* chars, FILE* stream) FMT_NOEXCEPT {
std::fputs(chars, stream);
}
template <>
inline void fputs<wchar_t>(const wchar_t* chars, FILE* stream) FMT_NOEXCEPT {
std::fputws(chars, stream);
}
template <typename Char> inline void reset_color(FILE* stream) FMT_NOEXCEPT {
fputs(detail::data::reset_color, stream);
}
template <> inline void reset_color<wchar_t>(FILE* stream) FMT_NOEXCEPT {
fputs(detail::data::wreset_color, stream);
}
template <typename Char>
inline void reset_color(buffer<Char>& buffer) FMT_NOEXCEPT {
const char* begin = data::reset_color;
const char* end = begin + sizeof(data::reset_color) - 1;
buffer.append(begin, end);
}
template <typename Char>
void vformat_to(buffer<Char>& buf, const text_style& ts,
basic_string_view<Char> format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
bool has_style = false;
if (ts.has_emphasis()) {
has_style = true;
auto emphasis = detail::make_emphasis<Char>(ts.get_emphasis());
buf.append(emphasis.begin(), emphasis.end());
}
if (ts.has_foreground()) {
has_style = true;
auto foreground = detail::make_foreground_color<Char>(ts.get_foreground());
buf.append(foreground.begin(), foreground.end());
}
if (ts.has_background()) {
has_style = true;
auto background = detail::make_background_color<Char>(ts.get_background());
buf.append(background.begin(), background.end());
}
detail::vformat_to(buf, format_str, args);
if (has_style) detail::reset_color<Char>(buf);
}
} // namespace detail
template <typename S, typename Char = char_t<S>>
void vprint(std::FILE* f, const text_style& ts, const S& format,
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
basic_memory_buffer<Char> buf;
detail::vformat_to(buf, ts, to_string_view(format), args);
buf.push_back(Char(0));
detail::fputs(buf.data(), f);
}
/**
\rst
Formats a string and prints it to the specified file stream using ANSI
escape sequences to specify text formatting.
**Example**::
fmt::print(fmt::emphasis::bold | fg(fmt::color::red),
"Elapsed time: {0:.2f} seconds", 1.23);
\endrst
*/
template <typename S, typename... Args,
FMT_ENABLE_IF(detail::is_string<S>::value)>
void print(std::FILE* f, const text_style& ts, const S& format_str,
const Args&... args) {
vprint(f, ts, format_str,
fmt::make_args_checked<Args...>(format_str, args...));
}
/**
Formats a string and prints it to stdout using ANSI escape sequences to
specify text formatting.
Example:
fmt::print(fmt::emphasis::bold | fg(fmt::color::red),
"Elapsed time: {0:.2f} seconds", 1.23);
*/
template <typename S, typename... Args,
FMT_ENABLE_IF(detail::is_string<S>::value)>
void print(const text_style& ts, const S& format_str, const Args&... args) {
return print(stdout, ts, format_str, args...);
}
template <typename S, typename Char = char_t<S>>
inline std::basic_string<Char> vformat(
const text_style& ts, const S& format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
basic_memory_buffer<Char> buf;
detail::vformat_to(buf, ts, to_string_view(format_str), args);
return fmt::to_string(buf);
}
/**
\rst
Formats arguments and returns the result as a string using ANSI
escape sequences to specify text formatting.
**Example**::
#include <fmt/color.h>
std::string message = fmt::format(fmt::emphasis::bold | fg(fmt::color::red),
"The answer is {}", 42);
\endrst
*/
template <typename S, typename... Args, typename Char = char_t<S>>
inline std::basic_string<Char> format(const text_style& ts, const S& format_str,
const Args&... args) {
return vformat(ts, to_string_view(format_str),
fmt::make_args_checked<Args...>(format_str, args...));
}
/**
Formats a string with the given text_style and writes the output to ``out``.
*/
template <typename OutputIt, typename Char,
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt>::value)>
OutputIt vformat_to(
OutputIt out, const text_style& ts, basic_string_view<Char> format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
decltype(detail::get_buffer<Char>(out)) buf(detail::get_buffer_init(out));
detail::vformat_to(buf, ts, format_str, args);
return detail::get_iterator(buf);
}
/**
\rst
Formats arguments with the given text_style, writes the result to the output
iterator ``out`` and returns the iterator past the end of the output range.
**Example**::
std::vector<char> out;
fmt::format_to(std::back_inserter(out),
fmt::emphasis::bold | fg(fmt::color::red), "{}", 42);
\endrst
*/
template <typename OutputIt, typename S, typename... Args,
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt>::value&&
detail::is_string<S>::value)>
inline OutputIt format_to(OutputIt out, const text_style& ts,
const S& format_str, Args&&... args) {
return vformat_to(out, ts, to_string_view(format_str),
fmt::make_args_checked<Args...>(format_str, args...));
}
FMT_END_NAMESPACE
#endif // FMT_COLOR_H_

View file

@ -1,699 +0,0 @@
// Formatting library for C++ - experimental format string compilation
//
// Copyright (c) 2012 - present, Victor Zverovich and fmt contributors
// All rights reserved.
//
// For the license information refer to format.h.
#ifndef FMT_COMPILE_H_
#define FMT_COMPILE_H_
#include <vector>
#include "format.h"
FMT_BEGIN_NAMESPACE
namespace detail {
// A compile-time string which is compiled into fast formatting code.
class compiled_string {};
template <typename S>
struct is_compiled_string : std::is_base_of<compiled_string, S> {};
/**
\rst
Converts a string literal *s* into a format string that will be parsed at
compile time and converted into efficient formatting code. Requires C++17
``constexpr if`` compiler support.
**Example**::
// Converts 42 into std::string using the most efficient method and no
// runtime format string processing.
std::string s = fmt::format(FMT_COMPILE("{}"), 42);
\endrst
*/
#define FMT_COMPILE(s) FMT_STRING_IMPL(s, fmt::detail::compiled_string)
template <typename T, typename... Tail>
const T& first(const T& value, const Tail&...) {
return value;
}
// Part of a compiled format string. It can be either literal text or a
// replacement field.
template <typename Char> struct format_part {
enum class kind { arg_index, arg_name, text, replacement };
struct replacement {
arg_ref<Char> arg_id;
dynamic_format_specs<Char> specs;
};
kind part_kind;
union value {
int arg_index;
basic_string_view<Char> str;
replacement repl;
FMT_CONSTEXPR value(int index = 0) : arg_index(index) {}
FMT_CONSTEXPR value(basic_string_view<Char> s) : str(s) {}
FMT_CONSTEXPR value(replacement r) : repl(r) {}
} val;
// Position past the end of the argument id.
const Char* arg_id_end = nullptr;
FMT_CONSTEXPR format_part(kind k = kind::arg_index, value v = {})
: part_kind(k), val(v) {}
static FMT_CONSTEXPR format_part make_arg_index(int index) {
return format_part(kind::arg_index, index);
}
static FMT_CONSTEXPR format_part make_arg_name(basic_string_view<Char> name) {
return format_part(kind::arg_name, name);
}
static FMT_CONSTEXPR format_part make_text(basic_string_view<Char> text) {
return format_part(kind::text, text);
}
static FMT_CONSTEXPR format_part make_replacement(replacement repl) {
return format_part(kind::replacement, repl);
}
};
template <typename Char> struct part_counter {
unsigned num_parts = 0;
FMT_CONSTEXPR void on_text(const Char* begin, const Char* end) {
if (begin != end) ++num_parts;
}
FMT_CONSTEXPR int on_arg_id() { return ++num_parts, 0; }
FMT_CONSTEXPR int on_arg_id(int) { return ++num_parts, 0; }
FMT_CONSTEXPR int on_arg_id(basic_string_view<Char>) {
return ++num_parts, 0;
}
FMT_CONSTEXPR void on_replacement_field(int, const Char*) {}
FMT_CONSTEXPR const Char* on_format_specs(int, const Char* begin,
const Char* end) {
// Find the matching brace.
unsigned brace_counter = 0;
for (; begin != end; ++begin) {
if (*begin == '{') {
++brace_counter;
} else if (*begin == '}') {
if (brace_counter == 0u) break;
--brace_counter;
}
}
return begin;
}
FMT_CONSTEXPR void on_error(const char*) {}
};
// Counts the number of parts in a format string.
template <typename Char>
FMT_CONSTEXPR unsigned count_parts(basic_string_view<Char> format_str) {
part_counter<Char> counter;
parse_format_string<true>(format_str, counter);
return counter.num_parts;
}
template <typename Char, typename PartHandler>
class format_string_compiler : public error_handler {
private:
using part = format_part<Char>;
PartHandler handler_;
part part_;
basic_string_view<Char> format_str_;
basic_format_parse_context<Char> parse_context_;
public:
FMT_CONSTEXPR format_string_compiler(basic_string_view<Char> format_str,
PartHandler handler)
: handler_(handler),
format_str_(format_str),
parse_context_(format_str) {}
FMT_CONSTEXPR void on_text(const Char* begin, const Char* end) {
if (begin != end)
handler_(part::make_text({begin, to_unsigned(end - begin)}));
}
FMT_CONSTEXPR int on_arg_id() {
part_ = part::make_arg_index(parse_context_.next_arg_id());
return 0;
}
FMT_CONSTEXPR int on_arg_id(int id) {
parse_context_.check_arg_id(id);
part_ = part::make_arg_index(id);
return 0;
}
FMT_CONSTEXPR int on_arg_id(basic_string_view<Char> id) {
part_ = part::make_arg_name(id);
return 0;
}
FMT_CONSTEXPR void on_replacement_field(int, const Char* ptr) {
part_.arg_id_end = ptr;
handler_(part_);
}
FMT_CONSTEXPR const Char* on_format_specs(int, const Char* begin,
const Char* end) {
auto repl = typename part::replacement();
dynamic_specs_handler<basic_format_parse_context<Char>> handler(
repl.specs, parse_context_);
auto it = parse_format_specs(begin, end, handler);
if (*it != '}') on_error("missing '}' in format string");
repl.arg_id = part_.part_kind == part::kind::arg_index
? arg_ref<Char>(part_.val.arg_index)
: arg_ref<Char>(part_.val.str);
auto part = part::make_replacement(repl);
part.arg_id_end = begin;
handler_(part);
return it;
}
};
// Compiles a format string and invokes handler(part) for each parsed part.
template <bool IS_CONSTEXPR, typename Char, typename PartHandler>
FMT_CONSTEXPR void compile_format_string(basic_string_view<Char> format_str,
PartHandler handler) {
parse_format_string<IS_CONSTEXPR>(
format_str,
format_string_compiler<Char, PartHandler>(format_str, handler));
}
template <typename OutputIt, typename Context, typename Id>
void format_arg(
basic_format_parse_context<typename Context::char_type>& parse_ctx,
Context& ctx, Id arg_id) {
ctx.advance_to(visit_format_arg(
arg_formatter<OutputIt, typename Context::char_type>(ctx, &parse_ctx),
ctx.arg(arg_id)));
}
// vformat_to is defined in a subnamespace to prevent ADL.
namespace cf {
template <typename Context, typename OutputIt, typename CompiledFormat>
auto vformat_to(OutputIt out, CompiledFormat& cf,
basic_format_args<Context> args) -> typename Context::iterator {
using char_type = typename Context::char_type;
basic_format_parse_context<char_type> parse_ctx(
to_string_view(cf.format_str_));
Context ctx(out, args);
const auto& parts = cf.parts();
for (auto part_it = std::begin(parts); part_it != std::end(parts);
++part_it) {
const auto& part = *part_it;
const auto& value = part.val;
using format_part_t = format_part<char_type>;
switch (part.part_kind) {
case format_part_t::kind::text: {
const auto text = value.str;
auto output = ctx.out();
auto&& it = reserve(output, text.size());
it = std::copy_n(text.begin(), text.size(), it);
ctx.advance_to(output);
break;
}
case format_part_t::kind::arg_index:
advance_to(parse_ctx, part.arg_id_end);
detail::format_arg<OutputIt>(parse_ctx, ctx, value.arg_index);
break;
case format_part_t::kind::arg_name:
advance_to(parse_ctx, part.arg_id_end);
detail::format_arg<OutputIt>(parse_ctx, ctx, value.str);
break;
case format_part_t::kind::replacement: {
const auto& arg_id_value = value.repl.arg_id.val;
const auto arg = value.repl.arg_id.kind == arg_id_kind::index
? ctx.arg(arg_id_value.index)
: ctx.arg(arg_id_value.name);
auto specs = value.repl.specs;
handle_dynamic_spec<width_checker>(specs.width, specs.width_ref, ctx);
handle_dynamic_spec<precision_checker>(specs.precision,
specs.precision_ref, ctx);
error_handler h;
numeric_specs_checker<error_handler> checker(h, arg.type());
if (specs.align == align::numeric) checker.require_numeric_argument();
if (specs.sign != sign::none) checker.check_sign();
if (specs.alt) checker.require_numeric_argument();
if (specs.precision >= 0) checker.check_precision();
advance_to(parse_ctx, part.arg_id_end);
ctx.advance_to(
visit_format_arg(arg_formatter<OutputIt, typename Context::char_type>(
ctx, nullptr, &specs),
arg));
break;
}
}
}
return ctx.out();
}
} // namespace cf
struct basic_compiled_format {};
template <typename S, typename = void>
struct compiled_format_base : basic_compiled_format {
using char_type = char_t<S>;
using parts_container = std::vector<detail::format_part<char_type>>;
parts_container compiled_parts;
explicit compiled_format_base(basic_string_view<char_type> format_str) {
compile_format_string<false>(format_str,
[this](const format_part<char_type>& part) {
compiled_parts.push_back(part);
});
}
const parts_container& parts() const { return compiled_parts; }
};
template <typename Char, unsigned N> struct format_part_array {
format_part<Char> data[N] = {};
FMT_CONSTEXPR format_part_array() = default;
};
template <typename Char, unsigned N>
FMT_CONSTEXPR format_part_array<Char, N> compile_to_parts(
basic_string_view<Char> format_str) {
format_part_array<Char, N> parts;
unsigned counter = 0;
// This is not a lambda for compatibility with older compilers.
struct {
format_part<Char>* parts;
unsigned* counter;
FMT_CONSTEXPR void operator()(const format_part<Char>& part) {
parts[(*counter)++] = part;
}
} collector{parts.data, &counter};
compile_format_string<true>(format_str, collector);
if (counter < N) {
parts.data[counter] =
format_part<Char>::make_text(basic_string_view<Char>());
}
return parts;
}
template <typename T> constexpr const T& constexpr_max(const T& a, const T& b) {
return (a < b) ? b : a;
}
template <typename S>
struct compiled_format_base<S, enable_if_t<is_compile_string<S>::value>>
: basic_compiled_format {
using char_type = char_t<S>;
FMT_CONSTEXPR explicit compiled_format_base(basic_string_view<char_type>) {}
// Workaround for old compilers. Format string compilation will not be
// performed there anyway.
#if FMT_USE_CONSTEXPR
static FMT_CONSTEXPR_DECL const unsigned num_format_parts =
constexpr_max(count_parts(to_string_view(S())), 1u);
#else
static const unsigned num_format_parts = 1;
#endif
using parts_container = format_part<char_type>[num_format_parts];
const parts_container& parts() const {
static FMT_CONSTEXPR_DECL const auto compiled_parts =
compile_to_parts<char_type, num_format_parts>(
detail::to_string_view(S()));
return compiled_parts.data;
}
};
template <typename S, typename... Args>
class compiled_format : private compiled_format_base<S> {
public:
using typename compiled_format_base<S>::char_type;
private:
basic_string_view<char_type> format_str_;
template <typename Context, typename OutputIt, typename CompiledFormat>
friend auto cf::vformat_to(OutputIt out, CompiledFormat& cf,
basic_format_args<Context> args) ->
typename Context::iterator;
public:
compiled_format() = delete;
explicit constexpr compiled_format(basic_string_view<char_type> format_str)
: compiled_format_base<S>(format_str), format_str_(format_str) {}
};
#ifdef __cpp_if_constexpr
template <typename... Args> struct type_list {};
// Returns a reference to the argument at index N from [first, rest...].
template <int N, typename T, typename... Args>
constexpr const auto& get([[maybe_unused]] const T& first,
[[maybe_unused]] const Args&... rest) {
static_assert(N < 1 + sizeof...(Args), "index is out of bounds");
if constexpr (N == 0)
return first;
else
return get<N - 1>(rest...);
}
template <int N, typename> struct get_type_impl;
template <int N, typename... Args> struct get_type_impl<N, type_list<Args...>> {
using type = remove_cvref_t<decltype(get<N>(std::declval<Args>()...))>;
};
template <int N, typename T>
using get_type = typename get_type_impl<N, T>::type;
template <typename T> struct is_compiled_format : std::false_type {};
template <typename Char> struct text {
basic_string_view<Char> data;
using char_type = Char;
template <typename OutputIt, typename... Args>
OutputIt format(OutputIt out, const Args&...) const {
return write<Char>(out, data);
}
};
template <typename Char>
struct is_compiled_format<text<Char>> : std::true_type {};
template <typename Char>
constexpr text<Char> make_text(basic_string_view<Char> s, size_t pos,
size_t size) {
return {{&s[pos], size}};
}
template <typename Char> struct code_unit {
Char value;
using char_type = Char;
template <typename OutputIt, typename... Args>
OutputIt format(OutputIt out, const Args&...) const {
return write<Char>(out, value);
}
};
template <typename Char>
struct is_compiled_format<code_unit<Char>> : std::true_type {};
// A replacement field that refers to argument N.
template <typename Char, typename T, int N> struct field {
using char_type = Char;
template <typename OutputIt, typename... Args>
OutputIt format(OutputIt out, const Args&... args) const {
// This ensures that the argument type is convertile to `const T&`.
const T& arg = get<N>(args...);
return write<Char>(out, arg);
}
};
template <typename Char, typename T, int N>
struct is_compiled_format<field<Char, T, N>> : std::true_type {};
// A replacement field that refers to argument N and has format specifiers.
template <typename Char, typename T, int N> struct spec_field {
using char_type = Char;
mutable formatter<T, Char> fmt;
template <typename OutputIt, typename... Args>
OutputIt format(OutputIt out, const Args&... args) const {
// This ensures that the argument type is convertile to `const T&`.
const T& arg = get<N>(args...);
const auto& vargs =
make_format_args<basic_format_context<OutputIt, Char>>(args...);
basic_format_context<OutputIt, Char> ctx(out, vargs);
return fmt.format(arg, ctx);
}
};
template <typename Char, typename T, int N>
struct is_compiled_format<spec_field<Char, T, N>> : std::true_type {};
template <typename L, typename R> struct concat {
L lhs;
R rhs;
using char_type = typename L::char_type;
template <typename OutputIt, typename... Args>
OutputIt format(OutputIt out, const Args&... args) const {
out = lhs.format(out, args...);
return rhs.format(out, args...);
}
};
template <typename L, typename R>
struct is_compiled_format<concat<L, R>> : std::true_type {};
template <typename L, typename R>
constexpr concat<L, R> make_concat(L lhs, R rhs) {
return {lhs, rhs};
}
struct unknown_format {};
template <typename Char>
constexpr size_t parse_text(basic_string_view<Char> str, size_t pos) {
for (size_t size = str.size(); pos != size; ++pos) {
if (str[pos] == '{' || str[pos] == '}') break;
}
return pos;
}
template <typename Args, size_t POS, int ID, typename S>
constexpr auto compile_format_string(S format_str);
template <typename Args, size_t POS, int ID, typename T, typename S>
constexpr auto parse_tail(T head, S format_str) {
if constexpr (POS !=
basic_string_view<typename S::char_type>(format_str).size()) {
constexpr auto tail = compile_format_string<Args, POS, ID>(format_str);
if constexpr (std::is_same<remove_cvref_t<decltype(tail)>,
unknown_format>())
return tail;
else
return make_concat(head, tail);
} else {
return head;
}
}
template <typename T, typename Char> struct parse_specs_result {
formatter<T, Char> fmt;
size_t end;
int next_arg_id;
};
template <typename T, typename Char>
constexpr parse_specs_result<T, Char> parse_specs(basic_string_view<Char> str,
size_t pos, int arg_id) {
str.remove_prefix(pos);
auto ctx = basic_format_parse_context<Char>(str, {}, arg_id + 1);
auto f = formatter<T, Char>();
auto end = f.parse(ctx);
return {f, pos + (end - str.data()) + 1, ctx.next_arg_id()};
}
// Compiles a non-empty format string and returns the compiled representation
// or unknown_format() on unrecognized input.
template <typename Args, size_t POS, int ID, typename S>
constexpr auto compile_format_string(S format_str) {
using char_type = typename S::char_type;
constexpr basic_string_view<char_type> str = format_str;
if constexpr (str[POS] == '{') {
if (POS + 1 == str.size())
throw format_error("unmatched '{' in format string");
if constexpr (str[POS + 1] == '{') {
return parse_tail<Args, POS + 2, ID>(make_text(str, POS, 1), format_str);
} else if constexpr (str[POS + 1] == '}') {
using type = get_type<ID, Args>;
return parse_tail<Args, POS + 2, ID + 1>(field<char_type, type, ID>(),
format_str);
} else if constexpr (str[POS + 1] == ':') {
using type = get_type<ID, Args>;
constexpr auto result = parse_specs<type>(str, POS + 2, ID);
return parse_tail<Args, result.end, result.next_arg_id>(
spec_field<char_type, type, ID>{result.fmt}, format_str);
} else {
return unknown_format();
}
} else if constexpr (str[POS] == '}') {
if (POS + 1 == str.size())
throw format_error("unmatched '}' in format string");
return parse_tail<Args, POS + 2, ID>(make_text(str, POS, 1), format_str);
} else {
constexpr auto end = parse_text(str, POS + 1);
if constexpr (end - POS > 1) {
return parse_tail<Args, end, ID>(make_text(str, POS, end - POS),
format_str);
} else {
return parse_tail<Args, end, ID>(code_unit<char_type>{str[POS]},
format_str);
}
}
}
template <typename... Args, typename S,
FMT_ENABLE_IF(is_compile_string<S>::value ||
detail::is_compiled_string<S>::value)>
constexpr auto compile(S format_str) {
constexpr basic_string_view<typename S::char_type> str = format_str;
if constexpr (str.size() == 0) {
return detail::make_text(str, 0, 0);
} else {
constexpr auto result =
detail::compile_format_string<detail::type_list<Args...>, 0, 0>(
format_str);
if constexpr (std::is_same<remove_cvref_t<decltype(result)>,
detail::unknown_format>()) {
return detail::compiled_format<S, Args...>(to_string_view(format_str));
} else {
return result;
}
}
}
#else
template <typename... Args, typename S,
FMT_ENABLE_IF(is_compile_string<S>::value)>
constexpr auto compile(S format_str) -> detail::compiled_format<S, Args...> {
return detail::compiled_format<S, Args...>(to_string_view(format_str));
}
#endif // __cpp_if_constexpr
// Compiles the format string which must be a string literal.
template <typename... Args, typename Char, size_t N>
auto compile(const Char (&format_str)[N])
-> detail::compiled_format<const Char*, Args...> {
return detail::compiled_format<const Char*, Args...>(
basic_string_view<Char>(format_str, N - 1));
}
} // namespace detail
// DEPRECATED! use FMT_COMPILE instead.
template <typename... Args>
FMT_DEPRECATED auto compile(const Args&... args)
-> decltype(detail::compile(args...)) {
return detail::compile(args...);
}
#if FMT_USE_CONSTEXPR
# ifdef __cpp_if_constexpr
template <typename CompiledFormat, typename... Args,
typename Char = typename CompiledFormat::char_type,
FMT_ENABLE_IF(detail::is_compiled_format<CompiledFormat>::value)>
FMT_INLINE std::basic_string<Char> format(const CompiledFormat& cf,
const Args&... args) {
basic_memory_buffer<Char> buffer;
cf.format(detail::buffer_appender<Char>(buffer), args...);
return to_string(buffer);
}
template <typename OutputIt, typename CompiledFormat, typename... Args,
FMT_ENABLE_IF(detail::is_compiled_format<CompiledFormat>::value)>
OutputIt format_to(OutputIt out, const CompiledFormat& cf,
const Args&... args) {
return cf.format(out, args...);
}
# endif // __cpp_if_constexpr
#endif // FMT_USE_CONSTEXPR
template <typename CompiledFormat, typename... Args,
typename Char = typename CompiledFormat::char_type,
FMT_ENABLE_IF(std::is_base_of<detail::basic_compiled_format,
CompiledFormat>::value)>
std::basic_string<Char> format(const CompiledFormat& cf, const Args&... args) {
basic_memory_buffer<Char> buffer;
using context = buffer_context<Char>;
detail::cf::vformat_to<context>(detail::buffer_appender<Char>(buffer), cf,
make_format_args<context>(args...));
return to_string(buffer);
}
template <typename S, typename... Args,
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
FMT_INLINE std::basic_string<typename S::char_type> format(const S&,
Args&&... args) {
#ifdef __cpp_if_constexpr
if constexpr (std::is_same<typename S::char_type, char>::value) {
constexpr basic_string_view<typename S::char_type> str = S();
if (str.size() == 2 && str[0] == '{' && str[1] == '}')
return fmt::to_string(detail::first(args...));
}
#endif
constexpr auto compiled = detail::compile<Args...>(S());
return format(compiled, std::forward<Args>(args)...);
}
template <typename OutputIt, typename CompiledFormat, typename... Args,
FMT_ENABLE_IF(std::is_base_of<detail::basic_compiled_format,
CompiledFormat>::value)>
OutputIt format_to(OutputIt out, const CompiledFormat& cf,
const Args&... args) {
using char_type = typename CompiledFormat::char_type;
using context = format_context_t<OutputIt, char_type>;
return detail::cf::vformat_to<context>(out, cf,
make_format_args<context>(args...));
}
template <typename OutputIt, typename S, typename... Args,
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
OutputIt format_to(OutputIt out, const S&, const Args&... args) {
constexpr auto compiled = detail::compile<Args...>(S());
return format_to(out, compiled, args...);
}
template <
typename OutputIt, typename CompiledFormat, typename... Args,
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt>::value&& std::is_base_of<
detail::basic_compiled_format, CompiledFormat>::value)>
format_to_n_result<OutputIt> format_to_n(OutputIt out, size_t n,
const CompiledFormat& cf,
const Args&... args) {
auto it =
format_to(detail::truncating_iterator<OutputIt>(out, n), cf, args...);
return {it.base(), it.count()};
}
template <typename OutputIt, typename S, typename... Args,
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
format_to_n_result<OutputIt> format_to_n(OutputIt out, size_t n, const S&,
const Args&... args) {
constexpr auto compiled = detail::compile<Args...>(S());
auto it = format_to(detail::truncating_iterator<OutputIt>(out, n), compiled,
args...);
return {it.base(), it.count()};
}
template <typename CompiledFormat, typename... Args>
size_t formatted_size(const CompiledFormat& cf, const Args&... args) {
return format_to(detail::counting_iterator(), cf, args...).count();
}
FMT_END_NAMESPACE
#endif // FMT_COMPILE_H_

2129
src/3rdparty/fmt/core.h vendored

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,69 +0,0 @@
// Formatting library for C++
//
// Copyright (c) 2012 - 2016, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.
#include "3rdparty/fmt/format-inl.h"
FMT_BEGIN_NAMESPACE
namespace detail {
template <typename T>
int format_float(char* buf, std::size_t size, const char* format, int precision,
T value) {
#ifdef FMT_FUZZ
if (precision > 100000)
throw std::runtime_error(
"fuzz mode - avoid large allocation inside snprintf");
#endif
// Suppress the warning about nonliteral format string.
int (*snprintf_ptr)(char*, size_t, const char*, ...) = FMT_SNPRINTF;
return precision < 0 ? snprintf_ptr(buf, size, format, value)
: snprintf_ptr(buf, size, format, precision, value);
}
} // namespace detail
template struct FMT_INSTANTIATION_DEF_API detail::basic_data<void>;
// Workaround a bug in MSVC2013 that prevents instantiation of format_float.
int (*instantiate_format_float)(double, int, detail::float_specs,
detail::buffer<char>&) = detail::format_float;
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
template FMT_API detail::locale_ref::locale_ref(const std::locale& loc);
template FMT_API std::locale detail::locale_ref::get<std::locale>() const;
#endif
// Explicit instantiations for char.
template FMT_API std::string detail::grouping_impl<char>(locale_ref);
template FMT_API char detail::thousands_sep_impl(locale_ref);
template FMT_API char detail::decimal_point_impl(locale_ref);
template FMT_API void detail::buffer<char>::append(const char*, const char*);
template FMT_API FMT_BUFFER_CONTEXT(char)::iterator detail::vformat_to(
detail::buffer<char>&, string_view,
basic_format_args<FMT_BUFFER_CONTEXT(char)>);
template FMT_API int detail::snprintf_float(double, int, detail::float_specs,
detail::buffer<char>&);
template FMT_API int detail::snprintf_float(long double, int,
detail::float_specs,
detail::buffer<char>&);
template FMT_API int detail::format_float(double, int, detail::float_specs,
detail::buffer<char>&);
template FMT_API int detail::format_float(long double, int, detail::float_specs,
detail::buffer<char>&);
// Explicit instantiations for wchar_t.
template FMT_API std::string detail::grouping_impl<wchar_t>(locale_ref);
template FMT_API wchar_t detail::thousands_sep_impl(locale_ref);
template FMT_API wchar_t detail::decimal_point_impl(locale_ref);
template FMT_API void detail::buffer<wchar_t>::append(const wchar_t*,
const wchar_t*);
FMT_END_NAMESPACE

File diff suppressed because it is too large Load diff

View file

@ -1,78 +0,0 @@
// Formatting library for C++ - std::locale support
//
// Copyright (c) 2012 - present, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.
#ifndef FMT_LOCALE_H_
#define FMT_LOCALE_H_
#include <locale>
#include "format.h"
FMT_BEGIN_NAMESPACE
namespace detail {
template <typename Char>
typename buffer_context<Char>::iterator vformat_to(
const std::locale& loc, buffer<Char>& buf,
basic_string_view<Char> format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
using af = arg_formatter<typename buffer_context<Char>::iterator, Char>;
return vformat_to<af>(buffer_appender<Char>(buf), to_string_view(format_str),
args, detail::locale_ref(loc));
}
template <typename Char>
std::basic_string<Char> vformat(
const std::locale& loc, basic_string_view<Char> format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
basic_memory_buffer<Char> buffer;
detail::vformat_to(loc, buffer, format_str, args);
return fmt::to_string(buffer);
}
} // namespace detail
template <typename S, typename Char = char_t<S>>
inline std::basic_string<Char> vformat(
const std::locale& loc, const S& format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
return detail::vformat(loc, to_string_view(format_str), args);
}
template <typename S, typename... Args, typename Char = char_t<S>>
inline std::basic_string<Char> format(const std::locale& loc,
const S& format_str, Args&&... args) {
return detail::vformat(
loc, to_string_view(format_str),
fmt::make_args_checked<Args...>(format_str, args...));
}
template <typename S, typename OutputIt, typename... Args,
typename Char = enable_if_t<
detail::is_output_iterator<OutputIt>::value, char_t<S>>>
inline OutputIt vformat_to(
OutputIt out, const std::locale& loc, const S& format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
decltype(detail::get_buffer<Char>(out)) buf(detail::get_buffer_init(out));
using af =
detail::arg_formatter<typename buffer_context<Char>::iterator, Char>;
vformat_to<af>(detail::buffer_appender<Char>(buf), to_string_view(format_str),
args, detail::locale_ref(loc));
return detail::get_iterator(buf);
}
template <typename OutputIt, typename S, typename... Args,
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt>::value&&
detail::is_string<S>::value)>
inline OutputIt format_to(OutputIt out, const std::locale& loc,
const S& format_str, Args&&... args) {
const auto& vargs = fmt::make_args_checked<Args...>(format_str, args...);
return vformat_to(out, loc, to_string_view(format_str), vargs);
}
FMT_END_NAMESPACE
#endif // FMT_LOCALE_H_

322
src/3rdparty/fmt/os.cc vendored
View file

@ -1,322 +0,0 @@
// Formatting library for C++ - optional OS-specific functionality
//
// Copyright (c) 2012 - 2016, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.
// Disable bogus MSVC warnings.
#if !defined(_CRT_SECURE_NO_WARNINGS) && defined(_MSC_VER)
# define _CRT_SECURE_NO_WARNINGS
#endif
#include "fmt/os.h"
#include <climits>
#if FMT_USE_FCNTL
# include <sys/stat.h>
# include <sys/types.h>
# ifndef _WIN32
# include <unistd.h>
# else
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <io.h>
# include <windows.h>
# define O_CREAT _O_CREAT
# define O_TRUNC _O_TRUNC
# ifndef S_IRUSR
# define S_IRUSR _S_IREAD
# endif
# ifndef S_IWUSR
# define S_IWUSR _S_IWRITE
# endif
# ifdef __MINGW32__
# define _SH_DENYNO 0x40
# endif
# endif // _WIN32
#endif // FMT_USE_FCNTL
#ifdef _WIN32
# include <windows.h>
#endif
#ifdef fileno
# undef fileno
#endif
namespace {
#ifdef _WIN32
// Return type of read and write functions.
using RWResult = int;
// On Windows the count argument to read and write is unsigned, so convert
// it from size_t preventing integer overflow.
inline unsigned convert_rwcount(std::size_t count) {
return count <= UINT_MAX ? static_cast<unsigned>(count) : UINT_MAX;
}
#else
// Return type of read and write functions.
using RWResult = ssize_t;
inline std::size_t convert_rwcount(std::size_t count) { return count; }
#endif
} // namespace
FMT_BEGIN_NAMESPACE
#ifdef _WIN32
detail::utf16_to_utf8::utf16_to_utf8(wstring_view s) {
if (int error_code = convert(s)) {
FMT_THROW(windows_error(error_code,
"cannot convert string from UTF-16 to UTF-8"));
}
}
int detail::utf16_to_utf8::convert(wstring_view s) {
if (s.size() > INT_MAX) return ERROR_INVALID_PARAMETER;
int s_size = static_cast<int>(s.size());
if (s_size == 0) {
// WideCharToMultiByte does not support zero length, handle separately.
buffer_.resize(1);
buffer_[0] = 0;
return 0;
}
int length = WideCharToMultiByte(CP_UTF8, 0, s.data(), s_size, nullptr, 0,
nullptr, nullptr);
if (length == 0) return GetLastError();
buffer_.resize(length + 1);
length = WideCharToMultiByte(CP_UTF8, 0, s.data(), s_size, &buffer_[0],
length, nullptr, nullptr);
if (length == 0) return GetLastError();
buffer_[length] = 0;
return 0;
}
void windows_error::init(int err_code, string_view format_str,
format_args args) {
error_code_ = err_code;
memory_buffer buffer;
detail::format_windows_error(buffer, err_code, vformat(format_str, args));
std::runtime_error& base = *this;
base = std::runtime_error(to_string(buffer));
}
void detail::format_windows_error(detail::buffer<char>& out, int error_code,
string_view message) FMT_NOEXCEPT {
FMT_TRY {
wmemory_buffer buf;
buf.resize(inline_buffer_size);
for (;;) {
wchar_t* system_message = &buf[0];
int result = FormatMessageW(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr,
error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), system_message,
static_cast<uint32_t>(buf.size()), nullptr);
if (result != 0) {
utf16_to_utf8 utf8_message;
if (utf8_message.convert(system_message) == ERROR_SUCCESS) {
format_to(buffer_appender<char>(out), "{}: {}", message,
utf8_message);
return;
}
break;
}
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
break; // Can't get error message, report error code instead.
buf.resize(buf.size() * 2);
}
}
FMT_CATCH(...) {}
format_error_code(out, error_code, message);
}
void report_windows_error(int error_code,
fmt::string_view message) FMT_NOEXCEPT {
report_error(detail::format_windows_error, error_code, message);
}
#endif // _WIN32
buffered_file::~buffered_file() FMT_NOEXCEPT {
if (file_ && FMT_SYSTEM(fclose(file_)) != 0)
report_system_error(errno, "cannot close file");
}
buffered_file::buffered_file(cstring_view filename, cstring_view mode) {
FMT_RETRY_VAL(file_, FMT_SYSTEM(fopen(filename.c_str(), mode.c_str())),
nullptr);
if (!file_)
FMT_THROW(system_error(errno, "cannot open file {}", filename.c_str()));
}
void buffered_file::close() {
if (!file_) return;
int result = FMT_SYSTEM(fclose(file_));
file_ = nullptr;
if (result != 0) FMT_THROW(system_error(errno, "cannot close file"));
}
// A macro used to prevent expansion of fileno on broken versions of MinGW.
#define FMT_ARGS
int buffered_file::fileno() const {
int fd = FMT_POSIX_CALL(fileno FMT_ARGS(file_));
if (fd == -1) FMT_THROW(system_error(errno, "cannot get file descriptor"));
return fd;
}
#if FMT_USE_FCNTL
file::file(cstring_view path, int oflag) {
int mode = S_IRUSR | S_IWUSR;
# if defined(_WIN32) && !defined(__MINGW32__)
fd_ = -1;
FMT_POSIX_CALL(sopen_s(&fd_, path.c_str(), oflag, _SH_DENYNO, mode));
# else
FMT_RETRY(fd_, FMT_POSIX_CALL(open(path.c_str(), oflag, mode)));
# endif
if (fd_ == -1)
FMT_THROW(system_error(errno, "cannot open file {}", path.c_str()));
}
file::~file() FMT_NOEXCEPT {
// Don't retry close in case of EINTR!
// See http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
if (fd_ != -1 && FMT_POSIX_CALL(close(fd_)) != 0)
report_system_error(errno, "cannot close file");
}
void file::close() {
if (fd_ == -1) return;
// Don't retry close in case of EINTR!
// See http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
int result = FMT_POSIX_CALL(close(fd_));
fd_ = -1;
if (result != 0) FMT_THROW(system_error(errno, "cannot close file"));
}
long long file::size() const {
# ifdef _WIN32
// Use GetFileSize instead of GetFileSizeEx for the case when _WIN32_WINNT
// is less than 0x0500 as is the case with some default MinGW builds.
// Both functions support large file sizes.
DWORD size_upper = 0;
HANDLE handle = reinterpret_cast<HANDLE>(_get_osfhandle(fd_));
DWORD size_lower = FMT_SYSTEM(GetFileSize(handle, &size_upper));
if (size_lower == INVALID_FILE_SIZE) {
DWORD error = GetLastError();
if (error != NO_ERROR)
FMT_THROW(windows_error(GetLastError(), "cannot get file size"));
}
unsigned long long long_size = size_upper;
return (long_size << sizeof(DWORD) * CHAR_BIT) | size_lower;
# else
using Stat = struct stat;
Stat file_stat = Stat();
if (FMT_POSIX_CALL(fstat(fd_, &file_stat)) == -1)
FMT_THROW(system_error(errno, "cannot get file attributes"));
static_assert(sizeof(long long) >= sizeof(file_stat.st_size),
"return type of file::size is not large enough");
return file_stat.st_size;
# endif
}
std::size_t file::read(void* buffer, std::size_t count) {
RWResult result = 0;
FMT_RETRY(result, FMT_POSIX_CALL(read(fd_, buffer, convert_rwcount(count))));
if (result < 0) FMT_THROW(system_error(errno, "cannot read from file"));
return detail::to_unsigned(result);
}
std::size_t file::write(const void* buffer, std::size_t count) {
RWResult result = 0;
FMT_RETRY(result, FMT_POSIX_CALL(write(fd_, buffer, convert_rwcount(count))));
if (result < 0) FMT_THROW(system_error(errno, "cannot write to file"));
return detail::to_unsigned(result);
}
file file::dup(int fd) {
// Don't retry as dup doesn't return EINTR.
// http://pubs.opengroup.org/onlinepubs/009695399/functions/dup.html
int new_fd = FMT_POSIX_CALL(dup(fd));
if (new_fd == -1)
FMT_THROW(system_error(errno, "cannot duplicate file descriptor {}", fd));
return file(new_fd);
}
void file::dup2(int fd) {
int result = 0;
FMT_RETRY(result, FMT_POSIX_CALL(dup2(fd_, fd)));
if (result == -1) {
FMT_THROW(system_error(errno, "cannot duplicate file descriptor {} to {}",
fd_, fd));
}
}
void file::dup2(int fd, error_code& ec) FMT_NOEXCEPT {
int result = 0;
FMT_RETRY(result, FMT_POSIX_CALL(dup2(fd_, fd)));
if (result == -1) ec = error_code(errno);
}
void file::pipe(file& read_end, file& write_end) {
// Close the descriptors first to make sure that assignments don't throw
// and there are no leaks.
read_end.close();
write_end.close();
int fds[2] = {};
# ifdef _WIN32
// Make the default pipe capacity same as on Linux 2.6.11+.
enum { DEFAULT_CAPACITY = 65536 };
int result = FMT_POSIX_CALL(pipe(fds, DEFAULT_CAPACITY, _O_BINARY));
# else
// Don't retry as the pipe function doesn't return EINTR.
// http://pubs.opengroup.org/onlinepubs/009696799/functions/pipe.html
int result = FMT_POSIX_CALL(pipe(fds));
# endif
if (result != 0) FMT_THROW(system_error(errno, "cannot create pipe"));
// The following assignments don't throw because read_fd and write_fd
// are closed.
read_end = file(fds[0]);
write_end = file(fds[1]);
}
buffered_file file::fdopen(const char* mode) {
// Don't retry as fdopen doesn't return EINTR.
# if defined(__MINGW32__) && defined(_POSIX_)
FILE* f = ::fdopen(fd_, mode);
# else
FILE* f = FMT_POSIX_CALL(fdopen(fd_, mode));
# endif
if (!f)
FMT_THROW(
system_error(errno, "cannot associate stream with file descriptor"));
buffered_file bf(f);
fd_ = -1;
return bf;
}
long getpagesize() {
# ifdef _WIN32
SYSTEM_INFO si;
GetSystemInfo(&si);
return si.dwPageSize;
# else
long size = FMT_POSIX_CALL(sysconf(_SC_PAGESIZE));
if (size < 0) FMT_THROW(system_error(errno, "cannot get memory page size"));
return size;
# endif
}
void ostream::grow(size_t) {
if (this->size() == this->capacity()) flush();
}
#endif // FMT_USE_FCNTL
FMT_END_NAMESPACE

480
src/3rdparty/fmt/os.h vendored
View file

@ -1,480 +0,0 @@
// Formatting library for C++ - optional OS-specific functionality
//
// Copyright (c) 2012 - present, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.
#ifndef FMT_OS_H_
#define FMT_OS_H_
#if defined(__MINGW32__) || defined(__CYGWIN__)
// Workaround MinGW bug https://sourceforge.net/p/mingw/bugs/2024/.
# undef __STRICT_ANSI__
#endif
#include <cerrno>
#include <clocale> // for locale_t
#include <cstddef>
#include <cstdio>
#include <cstdlib> // for strtod_l
#if defined __APPLE__ || defined(__FreeBSD__)
# include <xlocale.h> // for LC_NUMERIC_MASK on OS X
#endif
#include "format.h"
// UWP doesn't provide _pipe.
#if FMT_HAS_INCLUDE("winapifamily.h")
# include <winapifamily.h>
#endif
#if (FMT_HAS_INCLUDE(<fcntl.h>) || defined(__APPLE__) || \
defined(__linux__)) && \
(!defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP))
# include <fcntl.h> // for O_RDONLY
# define FMT_USE_FCNTL 1
#else
# define FMT_USE_FCNTL 0
#endif
#ifndef FMT_POSIX
# if defined(_WIN32) && !defined(__MINGW32__)
// Fix warnings about deprecated symbols.
# define FMT_POSIX(call) _##call
# else
# define FMT_POSIX(call) call
# endif
#endif
// Calls to system functions are wrapped in FMT_SYSTEM for testability.
#ifdef FMT_SYSTEM
# define FMT_POSIX_CALL(call) FMT_SYSTEM(call)
#else
# define FMT_SYSTEM(call) ::call
# ifdef _WIN32
// Fix warnings about deprecated symbols.
# define FMT_POSIX_CALL(call) ::_##call
# else
# define FMT_POSIX_CALL(call) ::call
# endif
#endif
// Retries the expression while it evaluates to error_result and errno
// equals to EINTR.
#ifndef _WIN32
# define FMT_RETRY_VAL(result, expression, error_result) \
do { \
(result) = (expression); \
} while ((result) == (error_result) && errno == EINTR)
#else
# define FMT_RETRY_VAL(result, expression, error_result) result = (expression)
#endif
#define FMT_RETRY(result, expression) FMT_RETRY_VAL(result, expression, -1)
FMT_BEGIN_NAMESPACE
/**
\rst
A reference to a null-terminated string. It can be constructed from a C
string or ``std::string``.
You can use one of the following type aliases for common character types:
+---------------+-----------------------------+
| Type | Definition |
+===============+=============================+
| cstring_view | basic_cstring_view<char> |
+---------------+-----------------------------+
| wcstring_view | basic_cstring_view<wchar_t> |
+---------------+-----------------------------+
This class is most useful as a parameter type to allow passing
different types of strings to a function, for example::
template <typename... Args>
std::string format(cstring_view format_str, const Args & ... args);
format("{}", 42);
format(std::string("{}"), 42);
\endrst
*/
template <typename Char> class basic_cstring_view {
private:
const Char* data_;
public:
/** Constructs a string reference object from a C string. */
basic_cstring_view(const Char* s) : data_(s) {}
/**
\rst
Constructs a string reference from an ``std::string`` object.
\endrst
*/
basic_cstring_view(const std::basic_string<Char>& s) : data_(s.c_str()) {}
/** Returns the pointer to a C string. */
const Char* c_str() const { return data_; }
};
using cstring_view = basic_cstring_view<char>;
using wcstring_view = basic_cstring_view<wchar_t>;
// An error code.
class error_code {
private:
int value_;
public:
explicit error_code(int value = 0) FMT_NOEXCEPT : value_(value) {}
int get() const FMT_NOEXCEPT { return value_; }
};
#ifdef _WIN32
namespace detail {
// A converter from UTF-16 to UTF-8.
// It is only provided for Windows since other systems support UTF-8 natively.
class utf16_to_utf8 {
private:
memory_buffer buffer_;
public:
utf16_to_utf8() {}
FMT_API explicit utf16_to_utf8(wstring_view s);
operator string_view() const { return string_view(&buffer_[0], size()); }
size_t size() const { return buffer_.size() - 1; }
const char* c_str() const { return &buffer_[0]; }
std::string str() const { return std::string(&buffer_[0], size()); }
// Performs conversion returning a system error code instead of
// throwing exception on conversion error. This method may still throw
// in case of memory allocation error.
FMT_API int convert(wstring_view s);
};
FMT_API void format_windows_error(buffer<char>& out, int error_code,
string_view message) FMT_NOEXCEPT;
} // namespace detail
/** A Windows error. */
class windows_error : public system_error {
private:
FMT_API void init(int error_code, string_view format_str, format_args args);
public:
/**
\rst
Constructs a :class:`fmt::windows_error` object with the description
of the form
.. parsed-literal::
*<message>*: *<system-message>*
where *<message>* is the formatted message and *<system-message>* is the
system message corresponding to the error code.
*error_code* is a Windows error code as given by ``GetLastError``.
If *error_code* is not a valid error code such as -1, the system message
will look like "error -1".
**Example**::
// This throws a windows_error with the description
// cannot open file 'madeup': The system cannot find the file specified.
// or similar (system message may vary).
const char *filename = "madeup";
LPOFSTRUCT of = LPOFSTRUCT();
HFILE file = OpenFile(filename, &of, OF_READ);
if (file == HFILE_ERROR) {
throw fmt::windows_error(GetLastError(),
"cannot open file '{}'", filename);
}
\endrst
*/
template <typename... Args>
windows_error(int error_code, string_view message, const Args&... args) {
init(error_code, message, make_format_args(args...));
}
};
// Reports a Windows error without throwing an exception.
// Can be used to report errors from destructors.
FMT_API void report_windows_error(int error_code,
string_view message) FMT_NOEXCEPT;
#endif // _WIN32
// A buffered file.
class buffered_file {
private:
FILE* file_;
friend class file;
explicit buffered_file(FILE* f) : file_(f) {}
public:
buffered_file(const buffered_file&) = delete;
void operator=(const buffered_file&) = delete;
// Constructs a buffered_file object which doesn't represent any file.
buffered_file() FMT_NOEXCEPT : file_(nullptr) {}
// Destroys the object closing the file it represents if any.
FMT_API ~buffered_file() FMT_NOEXCEPT;
public:
buffered_file(buffered_file&& other) FMT_NOEXCEPT : file_(other.file_) {
other.file_ = nullptr;
}
buffered_file& operator=(buffered_file&& other) {
close();
file_ = other.file_;
other.file_ = nullptr;
return *this;
}
// Opens a file.
FMT_API buffered_file(cstring_view filename, cstring_view mode);
// Closes the file.
FMT_API void close();
// Returns the pointer to a FILE object representing this file.
FILE* get() const FMT_NOEXCEPT { return file_; }
// We place parentheses around fileno to workaround a bug in some versions
// of MinGW that define fileno as a macro.
FMT_API int(fileno)() const;
void vprint(string_view format_str, format_args args) {
fmt::vprint(file_, format_str, args);
}
template <typename... Args>
inline void print(string_view format_str, const Args&... args) {
vprint(format_str, make_format_args(args...));
}
};
#if FMT_USE_FCNTL
// A file. Closed file is represented by a file object with descriptor -1.
// Methods that are not declared with FMT_NOEXCEPT may throw
// fmt::system_error in case of failure. Note that some errors such as
// closing the file multiple times will cause a crash on Windows rather
// than an exception. You can get standard behavior by overriding the
// invalid parameter handler with _set_invalid_parameter_handler.
class file {
private:
int fd_; // File descriptor.
// Constructs a file object with a given descriptor.
explicit file(int fd) : fd_(fd) {}
public:
// Possible values for the oflag argument to the constructor.
enum {
RDONLY = FMT_POSIX(O_RDONLY), // Open for reading only.
WRONLY = FMT_POSIX(O_WRONLY), // Open for writing only.
RDWR = FMT_POSIX(O_RDWR), // Open for reading and writing.
CREATE = FMT_POSIX(O_CREAT), // Create if the file doesn't exist.
APPEND = FMT_POSIX(O_APPEND) // Open in append mode.
};
// Constructs a file object which doesn't represent any file.
file() FMT_NOEXCEPT : fd_(-1) {}
// Opens a file and constructs a file object representing this file.
FMT_API file(cstring_view path, int oflag);
public:
file(const file&) = delete;
void operator=(const file&) = delete;
file(file&& other) FMT_NOEXCEPT : fd_(other.fd_) { other.fd_ = -1; }
file& operator=(file&& other) FMT_NOEXCEPT {
close();
fd_ = other.fd_;
other.fd_ = -1;
return *this;
}
// Destroys the object closing the file it represents if any.
FMT_API ~file() FMT_NOEXCEPT;
// Returns the file descriptor.
int descriptor() const FMT_NOEXCEPT { return fd_; }
// Closes the file.
FMT_API void close();
// Returns the file size. The size has signed type for consistency with
// stat::st_size.
FMT_API long long size() const;
// Attempts to read count bytes from the file into the specified buffer.
FMT_API size_t read(void* buffer, size_t count);
// Attempts to write count bytes from the specified buffer to the file.
FMT_API size_t write(const void* buffer, size_t count);
// Duplicates a file descriptor with the dup function and returns
// the duplicate as a file object.
FMT_API static file dup(int fd);
// Makes fd be the copy of this file descriptor, closing fd first if
// necessary.
FMT_API void dup2(int fd);
// Makes fd be the copy of this file descriptor, closing fd first if
// necessary.
FMT_API void dup2(int fd, error_code& ec) FMT_NOEXCEPT;
// Creates a pipe setting up read_end and write_end file objects for reading
// and writing respectively.
FMT_API static void pipe(file& read_end, file& write_end);
// Creates a buffered_file object associated with this file and detaches
// this file object from the file.
FMT_API buffered_file fdopen(const char* mode);
};
// Returns the memory page size.
long getpagesize();
namespace detail {
struct buffer_size {
size_t value = 0;
buffer_size operator=(size_t val) const {
auto bs = buffer_size();
bs.value = val;
return bs;
}
};
struct ostream_params {
int oflag = file::WRONLY | file::CREATE;
size_t buffer_size = BUFSIZ > 32768 ? BUFSIZ : 32768;
ostream_params() {}
template <typename... T>
ostream_params(T... params, int oflag) : ostream_params(params...) {
this->oflag = oflag;
}
template <typename... T>
ostream_params(T... params, detail::buffer_size bs)
: ostream_params(params...) {
this->buffer_size = bs.value;
}
};
} // namespace detail
static constexpr detail::buffer_size buffer_size;
// A fast output stream which is not thread-safe.
class ostream : private detail::buffer<char> {
private:
file file_;
void flush() {
if (size() == 0) return;
file_.write(data(), size());
clear();
}
void grow(size_t) final;
ostream(cstring_view path, const detail::ostream_params& params)
: file_(path, params.oflag) {
set(new char[params.buffer_size], params.buffer_size);
}
public:
ostream(ostream&& other)
: detail::buffer<char>(other.data(), other.size(), other.capacity()),
file_(std::move(other.file_)) {
other.set(nullptr, 0);
}
~ostream() {
flush();
delete[] data();
}
template <typename... T>
friend ostream output_file(cstring_view path, T... params);
void close() {
flush();
file_.close();
}
template <typename S, typename... Args>
void print(const S& format_str, const Args&... args) {
format_to(detail::buffer_appender<char>(*this), format_str, args...);
}
};
/**
Opens a file for writing. Supported parameters passed in `params`:
* ``<integer>``: Output flags (``file::WRONLY | file::CREATE`` by default)
* ``buffer_size=<integer>``: Output buffer size
*/
template <typename... T>
inline ostream output_file(cstring_view path, T... params) {
return {path, detail::ostream_params(params...)};
}
#endif // FMT_USE_FCNTL
#ifdef FMT_LOCALE
// A "C" numeric locale.
class locale {
private:
# ifdef _WIN32
using locale_t = _locale_t;
static void freelocale(locale_t loc) { _free_locale(loc); }
static double strtod_l(const char* nptr, char** endptr, _locale_t loc) {
return _strtod_l(nptr, endptr, loc);
}
# endif
locale_t locale_;
public:
using type = locale_t;
locale(const locale&) = delete;
void operator=(const locale&) = delete;
locale() {
# ifndef _WIN32
locale_ = FMT_SYSTEM(newlocale(LC_NUMERIC_MASK, "C", nullptr));
# else
locale_ = _create_locale(LC_NUMERIC, "C");
# endif
if (!locale_) FMT_THROW(system_error(errno, "cannot create locale"));
}
~locale() { freelocale(locale_); }
type get() const { return locale_; }
// Converts string to floating-point number and advances str past the end
// of the parsed input.
double strtod(const char*& str) const {
char* end = nullptr;
double result = strtod_l(str, &end, locale_);
str = end;
return result;
}
};
using Locale FMT_DEPRECATED_ALIAS = locale;
#endif // FMT_LOCALE
FMT_END_NAMESPACE
#endif // FMT_OS_H_

View file

@ -1,177 +0,0 @@
// Formatting library for C++ - std::ostream support
//
// Copyright (c) 2012 - present, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.
#ifndef FMT_OSTREAM_H_
#define FMT_OSTREAM_H_
#include <ostream>
#include "format.h"
FMT_BEGIN_NAMESPACE
template <typename Char> class basic_printf_parse_context;
template <typename OutputIt, typename Char> class basic_printf_context;
namespace detail {
template <class Char> class formatbuf : public std::basic_streambuf<Char> {
private:
using int_type = typename std::basic_streambuf<Char>::int_type;
using traits_type = typename std::basic_streambuf<Char>::traits_type;
buffer<Char>& buffer_;
public:
formatbuf(buffer<Char>& buf) : buffer_(buf) {}
protected:
// The put-area is actually always empty. This makes the implementation
// simpler and has the advantage that the streambuf and the buffer are always
// in sync and sputc never writes into uninitialized memory. The obvious
// disadvantage is that each call to sputc always results in a (virtual) call
// to overflow. There is no disadvantage here for sputn since this always
// results in a call to xsputn.
int_type overflow(int_type ch = traits_type::eof()) FMT_OVERRIDE {
if (!traits_type::eq_int_type(ch, traits_type::eof()))
buffer_.push_back(static_cast<Char>(ch));
return ch;
}
std::streamsize xsputn(const Char* s, std::streamsize count) FMT_OVERRIDE {
buffer_.append(s, s + count);
return count;
}
};
struct converter {
template <typename T, FMT_ENABLE_IF(is_integral<T>::value)> converter(T);
};
template <typename Char> struct test_stream : std::basic_ostream<Char> {
private:
void_t<> operator<<(converter);
};
// Hide insertion operators for built-in types.
template <typename Char, typename Traits>
void_t<> operator<<(std::basic_ostream<Char, Traits>&, Char);
template <typename Char, typename Traits>
void_t<> operator<<(std::basic_ostream<Char, Traits>&, char);
template <typename Traits>
void_t<> operator<<(std::basic_ostream<char, Traits>&, char);
template <typename Traits>
void_t<> operator<<(std::basic_ostream<char, Traits>&, signed char);
template <typename Traits>
void_t<> operator<<(std::basic_ostream<char, Traits>&, unsigned char);
// Checks if T has a user-defined operator<< (e.g. not a member of
// std::ostream).
template <typename T, typename Char> class is_streamable {
private:
template <typename U>
static bool_constant<!std::is_same<decltype(std::declval<test_stream<Char>&>()
<< std::declval<U>()),
void_t<>>::value>
test(int);
template <typename> static std::false_type test(...);
using result = decltype(test<T>(0));
public:
static const bool value = result::value;
};
// Write the content of buf to os.
template <typename Char>
void write_buffer(std::basic_ostream<Char>& os, buffer<Char>& buf) {
const Char* buf_data = buf.data();
using unsigned_streamsize = std::make_unsigned<std::streamsize>::type;
unsigned_streamsize size = buf.size();
unsigned_streamsize max_size = to_unsigned(max_value<std::streamsize>());
do {
unsigned_streamsize n = size <= max_size ? size : max_size;
os.write(buf_data, static_cast<std::streamsize>(n));
buf_data += n;
size -= n;
} while (size != 0);
}
template <typename Char, typename T>
void format_value(buffer<Char>& buf, const T& value,
locale_ref loc = locale_ref()) {
formatbuf<Char> format_buf(buf);
std::basic_ostream<Char> output(&format_buf);
#if !defined(FMT_STATIC_THOUSANDS_SEPARATOR)
if (loc) output.imbue(loc.get<std::locale>());
#endif
output << value;
output.exceptions(std::ios_base::failbit | std::ios_base::badbit);
buf.try_resize(buf.size());
}
// Formats an object of type T that has an overloaded ostream operator<<.
template <typename T, typename Char>
struct fallback_formatter<T, Char, enable_if_t<is_streamable<T, Char>::value>>
: private formatter<basic_string_view<Char>, Char> {
FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& ctx)
-> decltype(ctx.begin()) {
return formatter<basic_string_view<Char>, Char>::parse(ctx);
}
template <typename ParseCtx,
FMT_ENABLE_IF(std::is_same<
ParseCtx, basic_printf_parse_context<Char>>::value)>
auto parse(ParseCtx& ctx) -> decltype(ctx.begin()) {
return ctx.begin();
}
template <typename OutputIt>
auto format(const T& value, basic_format_context<OutputIt, Char>& ctx)
-> OutputIt {
basic_memory_buffer<Char> buffer;
format_value(buffer, value, ctx.locale());
basic_string_view<Char> str(buffer.data(), buffer.size());
return formatter<basic_string_view<Char>, Char>::format(str, ctx);
}
template <typename OutputIt>
auto format(const T& value, basic_printf_context<OutputIt, Char>& ctx)
-> OutputIt {
basic_memory_buffer<Char> buffer;
format_value(buffer, value, ctx.locale());
return std::copy(buffer.begin(), buffer.end(), ctx.out());
}
};
} // namespace detail
template <typename Char>
void vprint(std::basic_ostream<Char>& os, basic_string_view<Char> format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
basic_memory_buffer<Char> buffer;
detail::vformat_to(buffer, format_str, args);
detail::write_buffer(os, buffer);
}
/**
\rst
Prints formatted data to the stream *os*.
**Example**::
fmt::print(cerr, "Don't {}!", "panic");
\endrst
*/
template <typename S, typename... Args,
typename Char = enable_if_t<detail::is_string<S>::value, char_t<S>>>
void print(std::basic_ostream<Char>& os, const S& format_str, Args&&... args) {
vprint(os, to_string_view(format_str),
fmt::make_args_checked<Args...>(format_str, args...));
}
FMT_END_NAMESPACE
#endif // FMT_OSTREAM_H_

View file

@ -1,2 +0,0 @@
#include "os.h"
#warning "fmt/posix.h is deprecated; use fmt/os.h instead"

View file

@ -1,751 +0,0 @@
// Formatting library for C++ - legacy printf implementation
//
// Copyright (c) 2012 - 2016, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.
#ifndef FMT_PRINTF_H_
#define FMT_PRINTF_H_
#include <algorithm> // std::max
#include <limits> // std::numeric_limits
#include "ostream.h"
FMT_BEGIN_NAMESPACE
namespace detail {
// Checks if a value fits in int - used to avoid warnings about comparing
// signed and unsigned integers.
template <bool IsSigned> struct int_checker {
template <typename T> static bool fits_in_int(T value) {
unsigned max = max_value<int>();
return value <= max;
}
static bool fits_in_int(bool) { return true; }
};
template <> struct int_checker<true> {
template <typename T> static bool fits_in_int(T value) {
return value >= (std::numeric_limits<int>::min)() &&
value <= max_value<int>();
}
static bool fits_in_int(int) { return true; }
};
class printf_precision_handler {
public:
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
int operator()(T value) {
if (!int_checker<std::numeric_limits<T>::is_signed>::fits_in_int(value))
FMT_THROW(format_error("number is too big"));
return (std::max)(static_cast<int>(value), 0);
}
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
int operator()(T) {
FMT_THROW(format_error("precision is not integer"));
return 0;
}
};
// An argument visitor that returns true iff arg is a zero integer.
class is_zero_int {
public:
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
bool operator()(T value) {
return value == 0;
}
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
bool operator()(T) {
return false;
}
};
template <typename T> struct make_unsigned_or_bool : std::make_unsigned<T> {};
template <> struct make_unsigned_or_bool<bool> { using type = bool; };
template <typename T, typename Context> class arg_converter {
private:
using char_type = typename Context::char_type;
basic_format_arg<Context>& arg_;
char_type type_;
public:
arg_converter(basic_format_arg<Context>& arg, char_type type)
: arg_(arg), type_(type) {}
void operator()(bool value) {
if (type_ != 's') operator()<bool>(value);
}
template <typename U, FMT_ENABLE_IF(std::is_integral<U>::value)>
void operator()(U value) {
bool is_signed = type_ == 'd' || type_ == 'i';
using target_type = conditional_t<std::is_same<T, void>::value, U, T>;
if (const_check(sizeof(target_type) <= sizeof(int))) {
// Extra casts are used to silence warnings.
if (is_signed) {
arg_ = detail::make_arg<Context>(
static_cast<int>(static_cast<target_type>(value)));
} else {
using unsigned_type = typename make_unsigned_or_bool<target_type>::type;
arg_ = detail::make_arg<Context>(
static_cast<unsigned>(static_cast<unsigned_type>(value)));
}
} else {
if (is_signed) {
// glibc's printf doesn't sign extend arguments of smaller types:
// std::printf("%lld", -42); // prints "4294967254"
// but we don't have to do the same because it's a UB.
arg_ = detail::make_arg<Context>(static_cast<long long>(value));
} else {
arg_ = detail::make_arg<Context>(
static_cast<typename make_unsigned_or_bool<U>::type>(value));
}
}
}
template <typename U, FMT_ENABLE_IF(!std::is_integral<U>::value)>
void operator()(U) {} // No conversion needed for non-integral types.
};
// Converts an integer argument to T for printf, if T is an integral type.
// If T is void, the argument is converted to corresponding signed or unsigned
// type depending on the type specifier: 'd' and 'i' - signed, other -
// unsigned).
template <typename T, typename Context, typename Char>
void convert_arg(basic_format_arg<Context>& arg, Char type) {
visit_format_arg(arg_converter<T, Context>(arg, type), arg);
}
// Converts an integer argument to char for printf.
template <typename Context> class char_converter {
private:
basic_format_arg<Context>& arg_;
public:
explicit char_converter(basic_format_arg<Context>& arg) : arg_(arg) {}
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
void operator()(T value) {
arg_ = detail::make_arg<Context>(
static_cast<typename Context::char_type>(value));
}
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
void operator()(T) {} // No conversion needed for non-integral types.
};
// An argument visitor that return a pointer to a C string if argument is a
// string or null otherwise.
template <typename Char> struct get_cstring {
template <typename T> const Char* operator()(T) { return nullptr; }
const Char* operator()(const Char* s) { return s; }
};
// Checks if an argument is a valid printf width specifier and sets
// left alignment if it is negative.
template <typename Char> class printf_width_handler {
private:
using format_specs = basic_format_specs<Char>;
format_specs& specs_;
public:
explicit printf_width_handler(format_specs& specs) : specs_(specs) {}
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
unsigned operator()(T value) {
auto width = static_cast<uint32_or_64_or_128_t<T>>(value);
if (detail::is_negative(value)) {
specs_.align = align::left;
width = 0 - width;
}
unsigned int_max = max_value<int>();
if (width > int_max) FMT_THROW(format_error("number is too big"));
return static_cast<unsigned>(width);
}
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
unsigned operator()(T) {
FMT_THROW(format_error("width is not integer"));
return 0;
}
};
template <typename Char, typename Context>
void vprintf(buffer<Char>& buf, basic_string_view<Char> format,
basic_format_args<Context> args) {
Context(buffer_appender<Char>(buf), format, args).format();
}
} // namespace detail
// For printing into memory_buffer.
template <typename Char, typename Context>
FMT_DEPRECATED void printf(detail::buffer<Char>& buf,
basic_string_view<Char> format,
basic_format_args<Context> args) {
return detail::vprintf(buf, format, args);
}
using detail::vprintf;
template <typename Char>
class basic_printf_parse_context : public basic_format_parse_context<Char> {
using basic_format_parse_context<Char>::basic_format_parse_context;
};
template <typename OutputIt, typename Char> class basic_printf_context;
/**
\rst
The ``printf`` argument formatter.
\endrst
*/
template <typename OutputIt, typename Char>
class printf_arg_formatter : public detail::arg_formatter_base<OutputIt, Char> {
public:
using iterator = OutputIt;
private:
using char_type = Char;
using base = detail::arg_formatter_base<OutputIt, Char>;
using context_type = basic_printf_context<OutputIt, Char>;
context_type& context_;
void write_null_pointer(char) {
this->specs()->type = 0;
this->write("(nil)");
}
void write_null_pointer(wchar_t) {
this->specs()->type = 0;
this->write(L"(nil)");
}
public:
using format_specs = typename base::format_specs;
/**
\rst
Constructs an argument formatter object.
*buffer* is a reference to the output buffer and *specs* contains format
specifier information for standard argument types.
\endrst
*/
printf_arg_formatter(iterator iter, format_specs& specs, context_type& ctx)
: base(iter, &specs, detail::locale_ref()), context_(ctx) {}
template <typename T, FMT_ENABLE_IF(fmt::detail::is_integral<T>::value)>
iterator operator()(T value) {
// MSVC2013 fails to compile separate overloads for bool and char_type so
// use std::is_same instead.
if (std::is_same<T, bool>::value) {
format_specs& fmt_specs = *this->specs();
if (fmt_specs.type != 's') return base::operator()(value ? 1 : 0);
fmt_specs.type = 0;
this->write(value != 0);
} else if (std::is_same<T, char_type>::value) {
format_specs& fmt_specs = *this->specs();
if (fmt_specs.type && fmt_specs.type != 'c')
return (*this)(static_cast<int>(value));
fmt_specs.sign = sign::none;
fmt_specs.alt = false;
fmt_specs.fill[0] = ' '; // Ignore '0' flag for char types.
// align::numeric needs to be overwritten here since the '0' flag is
// ignored for non-numeric types
if (fmt_specs.align == align::none || fmt_specs.align == align::numeric)
fmt_specs.align = align::right;
return base::operator()(value);
} else {
return base::operator()(value);
}
return this->out();
}
template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
iterator operator()(T value) {
return base::operator()(value);
}
/** Formats a null-terminated C string. */
iterator operator()(const char* value) {
if (value)
base::operator()(value);
else if (this->specs()->type == 'p')
write_null_pointer(char_type());
else
this->write("(null)");
return this->out();
}
/** Formats a null-terminated wide C string. */
iterator operator()(const wchar_t* value) {
if (value)
base::operator()(value);
else if (this->specs()->type == 'p')
write_null_pointer(char_type());
else
this->write(L"(null)");
return this->out();
}
iterator operator()(basic_string_view<char_type> value) {
return base::operator()(value);
}
iterator operator()(monostate value) { return base::operator()(value); }
/** Formats a pointer. */
iterator operator()(const void* value) {
if (value) return base::operator()(value);
this->specs()->type = 0;
write_null_pointer(char_type());
return this->out();
}
/** Formats an argument of a custom (user-defined) type. */
iterator operator()(typename basic_format_arg<context_type>::handle handle) {
handle.format(context_.parse_context(), context_);
return this->out();
}
};
template <typename T> struct printf_formatter {
printf_formatter() = delete;
template <typename ParseContext>
auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
return ctx.begin();
}
template <typename FormatContext>
auto format(const T& value, FormatContext& ctx) -> decltype(ctx.out()) {
detail::format_value(detail::get_container(ctx.out()), value);
return ctx.out();
}
};
/**
This template formats data and writes the output through an output iterator.
*/
template <typename OutputIt, typename Char> class basic_printf_context {
public:
/** The character type for the output. */
using char_type = Char;
using iterator = OutputIt;
using format_arg = basic_format_arg<basic_printf_context>;
using parse_context_type = basic_printf_parse_context<Char>;
template <typename T> using formatter_type = printf_formatter<T>;
private:
using format_specs = basic_format_specs<char_type>;
OutputIt out_;
basic_format_args<basic_printf_context> args_;
parse_context_type parse_ctx_;
static void parse_flags(format_specs& specs, const Char*& it,
const Char* end);
// Returns the argument with specified index or, if arg_index is -1, the next
// argument.
format_arg get_arg(int arg_index = -1);
// Parses argument index, flags and width and returns the argument index.
int parse_header(const Char*& it, const Char* end, format_specs& specs);
public:
/**
\rst
Constructs a ``printf_context`` object. References to the arguments are
stored in the context object so make sure they have appropriate lifetimes.
\endrst
*/
basic_printf_context(OutputIt out, basic_string_view<char_type> format_str,
basic_format_args<basic_printf_context> args)
: out_(out), args_(args), parse_ctx_(format_str) {}
OutputIt out() { return out_; }
void advance_to(OutputIt it) { out_ = it; }
detail::locale_ref locale() { return {}; }
format_arg arg(int id) const { return args_.get(id); }
parse_context_type& parse_context() { return parse_ctx_; }
FMT_CONSTEXPR void on_error(const char* message) {
parse_ctx_.on_error(message);
}
/** Formats stored arguments and writes the output to the range. */
template <typename ArgFormatter = printf_arg_formatter<OutputIt, Char>>
OutputIt format();
};
template <typename OutputIt, typename Char>
void basic_printf_context<OutputIt, Char>::parse_flags(format_specs& specs,
const Char*& it,
const Char* end) {
for (; it != end; ++it) {
switch (*it) {
case '-':
specs.align = align::left;
break;
case '+':
specs.sign = sign::plus;
break;
case '0':
specs.fill[0] = '0';
break;
case ' ':
if (specs.sign != sign::plus) {
specs.sign = sign::space;
}
break;
case '#':
specs.alt = true;
break;
default:
return;
}
}
}
template <typename OutputIt, typename Char>
typename basic_printf_context<OutputIt, Char>::format_arg
basic_printf_context<OutputIt, Char>::get_arg(int arg_index) {
if (arg_index < 0)
arg_index = parse_ctx_.next_arg_id();
else
parse_ctx_.check_arg_id(--arg_index);
return detail::get_arg(*this, arg_index);
}
template <typename OutputIt, typename Char>
int basic_printf_context<OutputIt, Char>::parse_header(const Char*& it,
const Char* end,
format_specs& specs) {
int arg_index = -1;
char_type c = *it;
if (c >= '0' && c <= '9') {
// Parse an argument index (if followed by '$') or a width possibly
// preceded with '0' flag(s).
detail::error_handler eh;
int value = parse_nonnegative_int(it, end, eh);
if (it != end && *it == '$') { // value is an argument index
++it;
arg_index = value;
} else {
if (c == '0') specs.fill[0] = '0';
if (value != 0) {
// Nonzero value means that we parsed width and don't need to
// parse it or flags again, so return now.
specs.width = value;
return arg_index;
}
}
}
parse_flags(specs, it, end);
// Parse width.
if (it != end) {
if (*it >= '0' && *it <= '9') {
detail::error_handler eh;
specs.width = parse_nonnegative_int(it, end, eh);
} else if (*it == '*') {
++it;
specs.width = static_cast<int>(visit_format_arg(
detail::printf_width_handler<char_type>(specs), get_arg()));
}
}
return arg_index;
}
template <typename OutputIt, typename Char>
template <typename ArgFormatter>
OutputIt basic_printf_context<OutputIt, Char>::format() {
auto out = this->out();
const Char* start = parse_ctx_.begin();
const Char* end = parse_ctx_.end();
auto it = start;
while (it != end) {
char_type c = *it++;
if (c != '%') continue;
if (it != end && *it == c) {
out = std::copy(start, it, out);
start = ++it;
continue;
}
out = std::copy(start, it - 1, out);
format_specs specs;
specs.align = align::right;
// Parse argument index, flags and width.
int arg_index = parse_header(it, end, specs);
if (arg_index == 0) on_error("argument not found");
// Parse precision.
if (it != end && *it == '.') {
++it;
c = it != end ? *it : 0;
if ('0' <= c && c <= '9') {
detail::error_handler eh;
specs.precision = parse_nonnegative_int(it, end, eh);
} else if (c == '*') {
++it;
specs.precision = static_cast<int>(
visit_format_arg(detail::printf_precision_handler(), get_arg()));
} else {
specs.precision = 0;
}
}
format_arg arg = get_arg(arg_index);
// For d, i, o, u, x, and X conversion specifiers, if a precision is
// specified, the '0' flag is ignored
if (specs.precision >= 0 && arg.is_integral())
specs.fill[0] =
' '; // Ignore '0' flag for non-numeric types or if '-' present.
if (specs.precision >= 0 && arg.type() == detail::type::cstring_type) {
auto str = visit_format_arg(detail::get_cstring<Char>(), arg);
auto str_end = str + specs.precision;
auto nul = std::find(str, str_end, Char());
arg = detail::make_arg<basic_printf_context>(basic_string_view<Char>(
str,
detail::to_unsigned(nul != str_end ? nul - str : specs.precision)));
}
if (specs.alt && visit_format_arg(detail::is_zero_int(), arg))
specs.alt = false;
if (specs.fill[0] == '0') {
if (arg.is_arithmetic() && specs.align != align::left)
specs.align = align::numeric;
else
specs.fill[0] = ' '; // Ignore '0' flag for non-numeric types or if '-'
// flag is also present.
}
// Parse length and convert the argument to the required type.
c = it != end ? *it++ : 0;
char_type t = it != end ? *it : 0;
using detail::convert_arg;
switch (c) {
case 'h':
if (t == 'h') {
++it;
t = it != end ? *it : 0;
convert_arg<signed char>(arg, t);
} else {
convert_arg<short>(arg, t);
}
break;
case 'l':
if (t == 'l') {
++it;
t = it != end ? *it : 0;
convert_arg<long long>(arg, t);
} else {
convert_arg<long>(arg, t);
}
break;
case 'j':
convert_arg<intmax_t>(arg, t);
break;
case 'z':
convert_arg<size_t>(arg, t);
break;
case 't':
convert_arg<std::ptrdiff_t>(arg, t);
break;
case 'L':
// printf produces garbage when 'L' is omitted for long double, no
// need to do the same.
break;
default:
--it;
convert_arg<void>(arg, c);
}
// Parse type.
if (it == end) FMT_THROW(format_error("invalid format string"));
specs.type = static_cast<char>(*it++);
if (arg.is_integral()) {
// Normalize type.
switch (specs.type) {
case 'i':
case 'u':
specs.type = 'd';
break;
case 'c':
visit_format_arg(detail::char_converter<basic_printf_context>(arg),
arg);
break;
}
}
start = it;
// Format argument.
out = visit_format_arg(ArgFormatter(out, specs, *this), arg);
}
return std::copy(start, it, out);
}
template <typename Char>
using basic_printf_context_t =
basic_printf_context<detail::buffer_appender<Char>, Char>;
using printf_context = basic_printf_context_t<char>;
using wprintf_context = basic_printf_context_t<wchar_t>;
using printf_args = basic_format_args<printf_context>;
using wprintf_args = basic_format_args<wprintf_context>;
/**
\rst
Constructs an `~fmt::format_arg_store` object that contains references to
arguments and can be implicitly converted to `~fmt::printf_args`.
\endrst
*/
template <typename... Args>
inline format_arg_store<printf_context, Args...> make_printf_args(
const Args&... args) {
return {args...};
}
/**
\rst
Constructs an `~fmt::format_arg_store` object that contains references to
arguments and can be implicitly converted to `~fmt::wprintf_args`.
\endrst
*/
template <typename... Args>
inline format_arg_store<wprintf_context, Args...> make_wprintf_args(
const Args&... args) {
return {args...};
}
template <typename S, typename Char = char_t<S>>
inline std::basic_string<Char> vsprintf(
const S& format,
basic_format_args<basic_printf_context_t<type_identity_t<Char>>> args) {
basic_memory_buffer<Char> buffer;
vprintf(buffer, to_string_view(format), args);
return to_string(buffer);
}
/**
\rst
Formats arguments and returns the result as a string.
**Example**::
std::string message = fmt::sprintf("The answer is %d", 42);
\endrst
*/
template <typename S, typename... Args,
typename Char = enable_if_t<detail::is_string<S>::value, char_t<S>>>
inline std::basic_string<Char> sprintf(const S& format, const Args&... args) {
using context = basic_printf_context_t<Char>;
return vsprintf(to_string_view(format), make_format_args<context>(args...));
}
template <typename S, typename Char = char_t<S>>
inline int vfprintf(
std::FILE* f, const S& format,
basic_format_args<basic_printf_context_t<type_identity_t<Char>>> args) {
basic_memory_buffer<Char> buffer;
vprintf(buffer, to_string_view(format), args);
size_t size = buffer.size();
return std::fwrite(buffer.data(), sizeof(Char), size, f) < size
? -1
: static_cast<int>(size);
}
/**
\rst
Prints formatted data to the file *f*.
**Example**::
fmt::fprintf(stderr, "Don't %s!", "panic");
\endrst
*/
template <typename S, typename... Args,
typename Char = enable_if_t<detail::is_string<S>::value, char_t<S>>>
inline int fprintf(std::FILE* f, const S& format, const Args&... args) {
using context = basic_printf_context_t<Char>;
return vfprintf(f, to_string_view(format),
make_format_args<context>(args...));
}
template <typename S, typename Char = char_t<S>>
inline int vprintf(
const S& format,
basic_format_args<basic_printf_context_t<type_identity_t<Char>>> args) {
return vfprintf(stdout, to_string_view(format), args);
}
/**
\rst
Prints formatted data to ``stdout``.
**Example**::
fmt::printf("Elapsed time: %.2f seconds", 1.23);
\endrst
*/
template <typename S, typename... Args,
FMT_ENABLE_IF(detail::is_string<S>::value)>
inline int printf(const S& format_str, const Args&... args) {
using context = basic_printf_context_t<char_t<S>>;
return vprintf(to_string_view(format_str),
make_format_args<context>(args...));
}
template <typename S, typename Char = char_t<S>>
inline int vfprintf(
std::basic_ostream<Char>& os, const S& format,
basic_format_args<basic_printf_context_t<type_identity_t<Char>>> args) {
basic_memory_buffer<Char> buffer;
vprintf(buffer, to_string_view(format), args);
detail::write_buffer(os, buffer);
return static_cast<int>(buffer.size());
}
/** Formats arguments and writes the output to the range. */
template <typename ArgFormatter, typename Char,
typename Context =
basic_printf_context<typename ArgFormatter::iterator, Char>>
typename ArgFormatter::iterator vprintf(
detail::buffer<Char>& out, basic_string_view<Char> format_str,
basic_format_args<type_identity_t<Context>> args) {
typename ArgFormatter::iterator iter(out);
Context(iter, format_str, args).template format<ArgFormatter>();
return iter;
}
/**
\rst
Prints formatted data to the stream *os*.
**Example**::
fmt::fprintf(cerr, "Don't %s!", "panic");
\endrst
*/
template <typename S, typename... Args, typename Char = char_t<S>>
inline int fprintf(std::basic_ostream<Char>& os, const S& format_str,
const Args&... args) {
using context = basic_printf_context_t<Char>;
return vfprintf(os, to_string_view(format_str),
make_format_args<context>(args...));
}
FMT_END_NAMESPACE
#endif // FMT_PRINTF_H_

View file

@ -1,393 +0,0 @@
// Formatting library for C++ - experimental range support
//
// Copyright (c) 2012 - present, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.
//
// Copyright (c) 2018 - present, Remotion (Igor Schulz)
// All Rights Reserved
// {fmt} support for ranges, containers and types tuple interface.
#ifndef FMT_RANGES_H_
#define FMT_RANGES_H_
#include <initializer_list>
#include <type_traits>
#include "format.h"
// output only up to N items from the range.
#ifndef FMT_RANGE_OUTPUT_LENGTH_LIMIT
# define FMT_RANGE_OUTPUT_LENGTH_LIMIT 256
#endif
FMT_BEGIN_NAMESPACE
template <typename Char> struct formatting_base {
template <typename ParseContext>
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
return ctx.begin();
}
};
template <typename Char, typename Enable = void>
struct formatting_range : formatting_base<Char> {
static FMT_CONSTEXPR_DECL const size_t range_length_limit =
FMT_RANGE_OUTPUT_LENGTH_LIMIT; // output only up to N items from the
// range.
Char prefix;
Char delimiter;
Char postfix;
formatting_range() : prefix('{'), delimiter(','), postfix('}') {}
static FMT_CONSTEXPR_DECL const bool add_delimiter_spaces = true;
static FMT_CONSTEXPR_DECL const bool add_prepostfix_space = false;
};
template <typename Char, typename Enable = void>
struct formatting_tuple : formatting_base<Char> {
Char prefix;
Char delimiter;
Char postfix;
formatting_tuple() : prefix('('), delimiter(','), postfix(')') {}
static FMT_CONSTEXPR_DECL const bool add_delimiter_spaces = true;
static FMT_CONSTEXPR_DECL const bool add_prepostfix_space = false;
};
namespace detail {
template <typename RangeT, typename OutputIterator>
OutputIterator copy(const RangeT& range, OutputIterator out) {
for (auto it = range.begin(), end = range.end(); it != end; ++it)
*out++ = *it;
return out;
}
template <typename OutputIterator>
OutputIterator copy(const char* str, OutputIterator out) {
while (*str) *out++ = *str++;
return out;
}
template <typename OutputIterator>
OutputIterator copy(char ch, OutputIterator out) {
*out++ = ch;
return out;
}
/// Return true value if T has std::string interface, like std::string_view.
template <typename T> class is_like_std_string {
template <typename U>
static auto check(U* p)
-> decltype((void)p->find('a'), p->length(), (void)p->data(), int());
template <typename> static void check(...);
public:
static FMT_CONSTEXPR_DECL const bool value =
is_string<T>::value || !std::is_void<decltype(check<T>(nullptr))>::value;
};
template <typename Char>
struct is_like_std_string<fmt::basic_string_view<Char>> : std::true_type {};
template <typename... Ts> struct conditional_helper {};
template <typename T, typename _ = void> struct is_range_ : std::false_type {};
#if !FMT_MSC_VER || FMT_MSC_VER > 1800
template <typename T>
struct is_range_<
T, conditional_t<false,
conditional_helper<decltype(std::declval<T>().begin()),
decltype(std::declval<T>().end())>,
void>> : std::true_type {};
#endif
/// tuple_size and tuple_element check.
template <typename T> class is_tuple_like_ {
template <typename U>
static auto check(U* p) -> decltype(std::tuple_size<U>::value, int());
template <typename> static void check(...);
public:
static FMT_CONSTEXPR_DECL const bool value =
!std::is_void<decltype(check<T>(nullptr))>::value;
};
// Check for integer_sequence
#if defined(__cpp_lib_integer_sequence) || FMT_MSC_VER >= 1900
template <typename T, T... N>
using integer_sequence = std::integer_sequence<T, N...>;
template <size_t... N> using index_sequence = std::index_sequence<N...>;
template <size_t N> using make_index_sequence = std::make_index_sequence<N>;
#else
template <typename T, T... N> struct integer_sequence {
using value_type = T;
static FMT_CONSTEXPR size_t size() { return sizeof...(N); }
};
template <size_t... N> using index_sequence = integer_sequence<size_t, N...>;
template <typename T, size_t N, T... Ns>
struct make_integer_sequence : make_integer_sequence<T, N - 1, N - 1, Ns...> {};
template <typename T, T... Ns>
struct make_integer_sequence<T, 0, Ns...> : integer_sequence<T, Ns...> {};
template <size_t N>
using make_index_sequence = make_integer_sequence<size_t, N>;
#endif
template <class Tuple, class F, size_t... Is>
void for_each(index_sequence<Is...>, Tuple&& tup, F&& f) FMT_NOEXCEPT {
using std::get;
// using free function get<I>(T) now.
const int _[] = {0, ((void)f(get<Is>(tup)), 0)...};
(void)_; // blocks warnings
}
template <class T>
FMT_CONSTEXPR make_index_sequence<std::tuple_size<T>::value> get_indexes(
T const&) {
return {};
}
template <class Tuple, class F> void for_each(Tuple&& tup, F&& f) {
const auto indexes = get_indexes(tup);
for_each(indexes, std::forward<Tuple>(tup), std::forward<F>(f));
}
template <typename Range>
using value_type = remove_cvref_t<decltype(*std::declval<Range>().begin())>;
template <typename Arg, FMT_ENABLE_IF(!is_like_std_string<
typename std::decay<Arg>::type>::value)>
FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const Arg&) {
return add_space ? " {}" : "{}";
}
template <typename Arg, FMT_ENABLE_IF(is_like_std_string<
typename std::decay<Arg>::type>::value)>
FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const Arg&) {
return add_space ? " \"{}\"" : "\"{}\"";
}
FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const char*) {
return add_space ? " \"{}\"" : "\"{}\"";
}
FMT_CONSTEXPR const wchar_t* format_str_quoted(bool add_space, const wchar_t*) {
return add_space ? L" \"{}\"" : L"\"{}\"";
}
FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const char) {
return add_space ? " '{}'" : "'{}'";
}
FMT_CONSTEXPR const wchar_t* format_str_quoted(bool add_space, const wchar_t) {
return add_space ? L" '{}'" : L"'{}'";
}
} // namespace detail
template <typename T> struct is_tuple_like {
static FMT_CONSTEXPR_DECL const bool value =
detail::is_tuple_like_<T>::value && !detail::is_range_<T>::value;
};
template <typename TupleT, typename Char>
struct formatter<TupleT, Char, enable_if_t<fmt::is_tuple_like<TupleT>::value>> {
private:
// C++11 generic lambda for format()
template <typename FormatContext> struct format_each {
template <typename T> void operator()(const T& v) {
if (i > 0) {
if (formatting.add_prepostfix_space) {
*out++ = ' ';
}
out = detail::copy(formatting.delimiter, out);
}
out = format_to(out,
detail::format_str_quoted(
(formatting.add_delimiter_spaces && i > 0), v),
v);
++i;
}
formatting_tuple<Char>& formatting;
size_t& i;
typename std::add_lvalue_reference<decltype(
std::declval<FormatContext>().out())>::type out;
};
public:
formatting_tuple<Char> formatting;
template <typename ParseContext>
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
return formatting.parse(ctx);
}
template <typename FormatContext = format_context>
auto format(const TupleT& values, FormatContext& ctx) -> decltype(ctx.out()) {
auto out = ctx.out();
size_t i = 0;
detail::copy(formatting.prefix, out);
detail::for_each(values, format_each<FormatContext>{formatting, i, out});
if (formatting.add_prepostfix_space) {
*out++ = ' ';
}
detail::copy(formatting.postfix, out);
return ctx.out();
}
};
template <typename T, typename Char> struct is_range {
static FMT_CONSTEXPR_DECL const bool value =
detail::is_range_<T>::value && !detail::is_like_std_string<T>::value &&
!std::is_convertible<T, std::basic_string<Char>>::value &&
!std::is_constructible<detail::std_string_view<Char>, T>::value;
};
template <typename T, typename Char>
struct formatter<
T, Char,
enable_if_t<fmt::is_range<T, Char>::value
// Workaround a bug in MSVC 2017 and earlier.
#if !FMT_MSC_VER || FMT_MSC_VER >= 1927
&& has_formatter<detail::value_type<T>, format_context>::value
#endif
>> {
formatting_range<Char> formatting;
template <typename ParseContext>
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
return formatting.parse(ctx);
}
template <typename FormatContext>
typename FormatContext::iterator format(const T& values, FormatContext& ctx) {
auto out = detail::copy(formatting.prefix, ctx.out());
size_t i = 0;
auto it = values.begin();
auto end = values.end();
for (; it != end; ++it) {
if (i > 0) {
if (formatting.add_prepostfix_space) *out++ = ' ';
out = detail::copy(formatting.delimiter, out);
}
out = format_to(out,
detail::format_str_quoted(
(formatting.add_delimiter_spaces && i > 0), *it),
*it);
if (++i > formatting.range_length_limit) {
out = format_to(out, " ... <other elements>");
break;
}
}
if (formatting.add_prepostfix_space) *out++ = ' ';
return detail::copy(formatting.postfix, out);
}
};
template <typename Char, typename... T> struct tuple_arg_join : detail::view {
const std::tuple<T...>& tuple;
basic_string_view<Char> sep;
tuple_arg_join(const std::tuple<T...>& t, basic_string_view<Char> s)
: tuple{t}, sep{s} {}
};
template <typename Char, typename... T>
struct formatter<tuple_arg_join<Char, T...>, Char> {
template <typename ParseContext>
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
return ctx.begin();
}
template <typename FormatContext>
typename FormatContext::iterator format(
const tuple_arg_join<Char, T...>& value, FormatContext& ctx) {
return format(value, ctx, detail::make_index_sequence<sizeof...(T)>{});
}
private:
template <typename FormatContext, size_t... N>
typename FormatContext::iterator format(
const tuple_arg_join<Char, T...>& value, FormatContext& ctx,
detail::index_sequence<N...>) {
return format_args(value, ctx, std::get<N>(value.tuple)...);
}
template <typename FormatContext>
typename FormatContext::iterator format_args(
const tuple_arg_join<Char, T...>&, FormatContext& ctx) {
// NOTE: for compilers that support C++17, this empty function instantiation
// can be replaced with a constexpr branch in the variadic overload.
return ctx.out();
}
template <typename FormatContext, typename Arg, typename... Args>
typename FormatContext::iterator format_args(
const tuple_arg_join<Char, T...>& value, FormatContext& ctx,
const Arg& arg, const Args&... args) {
using base = formatter<typename std::decay<Arg>::type, Char>;
auto out = ctx.out();
out = base{}.format(arg, ctx);
if (sizeof...(Args) > 0) {
out = std::copy(value.sep.begin(), value.sep.end(), out);
ctx.advance_to(out);
return format_args(value, ctx, args...);
}
return out;
}
};
/**
\rst
Returns an object that formats `tuple` with elements separated by `sep`.
**Example**::
std::tuple<int, char> t = {1, 'a'};
fmt::print("{}", fmt::join(t, ", "));
// Output: "1, a"
\endrst
*/
template <typename... T>
FMT_CONSTEXPR tuple_arg_join<char, T...> join(const std::tuple<T...>& tuple,
string_view sep) {
return {tuple, sep};
}
template <typename... T>
FMT_CONSTEXPR tuple_arg_join<wchar_t, T...> join(const std::tuple<T...>& tuple,
wstring_view sep) {
return {tuple, sep};
}
/**
\rst
Returns an object that formats `initializer_list` with elements separated by
`sep`.
**Example**::
fmt::print("{}", fmt::join({1, 2, 3}, ", "));
// Output: "1, 2, 3"
\endrst
*/
template <typename T>
arg_join<const T*, const T*, char> join(std::initializer_list<T> list,
string_view sep) {
return join(std::begin(list), std::end(list), sep);
}
template <typename T>
arg_join<const T*, const T*, wchar_t> join(std::initializer_list<T> list,
wstring_view sep) {
return join(std::begin(list), std::end(list), sep);
}
FMT_END_NAMESPACE
#endif // FMT_RANGES_H_

View file

@ -1,45 +0,0 @@
hwloc Authors
=============
The following cumulative list contains the names of most individuals
who have committed code to the hwloc repository
(either directly or through a third party).
Name Affiliation(s)
--------------------------- --------------------
Grzegorz Andrejczuk Intel
Cédric Augonnet University of Bordeaux
Guillaume Beauchamp Inria
Ahmad Boissetri Binzagr Inria
Cyril Bordage Inria
Nicholas Buroker UWL
Christopher M. Cantalupo Intel
Jérôme Clet-Ortega University of Bordeaux
Ludovic Courtès Inria
Clément Foyer Inria
Nathalie Furmento CNRS
Bryon Gloden
Brice Goglin Inria
Gilles Gouaillardet RIST
Valentin Hoyet Inria
Joshua Hursey UWL
Alexey Kardashevskiy IBM
Rob Latham ANL
Douglas MacFarland UWL
Marc Marí BSC
Jonathan L Peyton Intel
Piotr Luc Intel
Antoine Rougier intern from University of Bordeaux
Jeff Squyres Cisco
Samuel Thibault University of Bordeaux
Jean-Yves VET DDN
Benjamin Worpitz
Jeff Zhao Zhaoxin
Affiliaion abbreviations:
-------------------------
ANL = Argonne National Lab
BSC = Barcelona Supercomputing Center
Cisco = Cisco Systems, Inc.
CNRS = Centre national de la recherche scientifique (France)
UWL = University of Wisconsin-La Crosse

View file

@ -1,40 +0,0 @@
cmake_minimum_required (VERSION 2.8.12)
project (hwloc C)
include_directories(include)
include_directories(src)
add_definitions(/D_CRT_SECURE_NO_WARNINGS)
set(CMAKE_C_FLAGS_RELEASE "/MT /O2 /Ob2 /DNDEBUG")
set(HEADERS
include/hwloc.h
src/static-components.h
)
set(SOURCES
src/base64.c
src/bind.c
src/bitmap.c
src/components.c
src/diff.c
src/distances.c
src/misc.c
src/pci-common.c
src/shmem.c
src/topology.c
src/topology-noos.c
src/topology-synthetic.c
src/topology-windows.c
src/topology-x86.c
src/topology-xml.c
src/topology-xml-nolibxml.c
src/traversal.c
src/memattrs.c
src/cpukinds.c
)
add_library(hwloc STATIC
${HEADERS}
${SOURCES}
)

View file

@ -1,39 +0,0 @@
Copyright © 2004-2006 The Trustees of Indiana University and Indiana University Research and Technology Corporation. All rights reserved.
Copyright © 2004-2005 The University of Tennessee and The University of Tennessee Research Foundation. All rights reserved.
Copyright © 2004-2005 High Performance Computing Center Stuttgart, University of Stuttgart. All rights reserved.
Copyright © 2004-2005 The Regents of the University of California. All rights reserved.
Copyright © 2009 CNRS
Copyright © 2009-2016 Inria. All rights reserved.
Copyright © 2009-2015 Université Bordeaux
Copyright © 2009-2015 Cisco Systems, Inc. All rights reserved.
Copyright © 2009-2012 Oracle and/or its affiliates. All rights reserved.
Copyright © 2010 IBM
Copyright © 2010 Jirka Hladky
Copyright © 2012 Aleksej Saushev, The NetBSD Foundation
Copyright © 2012 Blue Brain Project, EPFL. All rights reserved.
Copyright © 2013-2014 University of Wisconsin-La Crosse. All rights reserved.
Copyright © 2015 Research Organization for Information Science and Technology (RIST). All rights reserved.
Copyright © 2015-2016 Intel, Inc. All rights reserved.
See COPYING in top-level directory.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

1978
src/3rdparty/hwloc/NEWS vendored

File diff suppressed because it is too large Load diff

View file

@ -1,85 +0,0 @@
Introduction
The Hardware Locality (hwloc) software project aims at easing the process of
discovering hardware resources in parallel architectures. It offers
command-line tools and a C API for consulting these resources, their locality,
attributes, and interconnection. hwloc primarily aims at helping
high-performance computing (HPC) applications, but is also applicable to any
project seeking to exploit code and/or data locality on modern computing
platforms.
hwloc is actually made of two subprojects distributed together:
* The original hwloc project for describing the internals of computing nodes.
It is described in details starting at section Hardware Locality (hwloc)
Introduction.
* The network-oriented companion called netloc (Network Locality), described
in details starting with section Network Locality (netloc).
See also the Related pages tab above for links to other sections.
Netloc may be disabled, but the original hwloc cannot. Both hwloc and netloc
APIs are documented after these sections.
Installation
hwloc (https://www.open-mpi.org/projects/hwloc/) is available under the BSD
license. It is hosted as a sub-project of the overall Open MPI project (https:/
/www.open-mpi.org/). Note that hwloc does not require any functionality from
Open MPI -- it is a wholly separate (and much smaller!) project and code base.
It just happens to be hosted as part of the overall Open MPI project.
Basic Installation
Installation is the fairly common GNU-based process:
shell$ ./configure --prefix=...
shell$ make
shell$ make install
hwloc- and netloc-specific configure options and requirements are documented in
sections hwloc Installation and Netloc Installation respectively.
Also note that if you install supplemental libraries in non-standard locations,
hwloc's configure script may not be able to find them without some help. You
may need to specify additional CPPFLAGS, LDFLAGS, or PKG_CONFIG_PATH values on
the configure command line.
For example, if libpciaccess was installed into /opt/pciaccess, hwloc's
configure script may not find it be default. Try adding PKG_CONFIG_PATH to the
./configure command line, like this:
./configure PKG_CONFIG_PATH=/opt/pciaccess/lib/pkgconfig ...
Running the "lstopo" tool is a good way to check as a graphical output whether
hwloc properly detected the architecture of your node. Netloc command-line
tools can be used to display the network topology interconnecting your nodes.
Installing from a Git clone
Additionally, the code can be directly cloned from Git:
shell$ git clone https://github.com/open-mpi/hwloc.git
shell$ cd hwloc
shell$ ./autogen.sh
Note that GNU Autoconf >=2.63, Automake >=1.11 and Libtool >=2.2.6 are required
when building from a Git clone.
Nightly development snapshots are available on the web site, they can be
configured and built without any need for Git or GNU Autotools.
Questions and Bugs
Bugs should be reported in the tracker (https://github.com/open-mpi/hwloc/
issues). Opening a new issue automatically displays lots of hints about how to
debug and report issues.
Questions may be sent to the users or developers mailing lists (https://
www.open-mpi.org/community/lists/hwloc.php).
There is also a #hwloc IRC channel on Freenode (irc.freenode.net).
See https://www.open-mpi.org/projects/hwloc/doc/ for more hwloc documentation.

View file

@ -1,47 +0,0 @@
# This is the VERSION file for hwloc, describing the precise version
# of hwloc in this distribution. The various components of the version
# number below are combined to form a single version number string.
# major, minor, and release are generally combined in the form
# <major>.<minor>.<release>. If release is zero, then it is omitted.
# Please update HWLOC_VERSION* in contrib/windows/hwloc_config.h too.
major=2
minor=7
release=1
# greek is used for alpha or beta release tags. If it is non-empty,
# it will be appended to the version number. It does not have to be
# numeric. Common examples include a1 (alpha release 1), b1 (beta
# release 1), sc2005 (Super Computing 2005 release). The only
# requirement is that it must be entirely printable ASCII characters
# and have no white space.
greek=
# The date when this release was created
date="Mar 20, 2022"
# If snapshot=1, then use the value from snapshot_version as the
# entire hwloc version (i.e., ignore major, minor, release, and
# greek). This is only set to 1 when making snapshot tarballs.
snapshot=0
snapshot_version=${major}.${minor}.${release}${greek}-git
# The shared library version of hwloc's public library. This version
# is maintained in accordance with the "Library Interface Versions"
# chapter from the GNU Libtool documentation. Notes:
# 1. Since version numbers are associated with *releases*, the version
# number maintained on the hwloc git master (and developer branches)
# is always 0:0:0.
# 2. Version numbers are described in the Libtool current:revision:age
# format.
libhwloc_so_version=20:3:5
libnetloc_so_version=0:0:0
# Please also update the <TargetName> lines in contrib/windows/libhwloc.vcxproj

File diff suppressed because it is too large Load diff

View file

@ -1,59 +0,0 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2021 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
/* The configuration file */
#ifndef HWLOC_CONFIG_H
#define HWLOC_CONFIG_H
#define HWLOC_VERSION "2.7.1"
#define HWLOC_VERSION_MAJOR 2
#define HWLOC_VERSION_MINOR 7
#define HWLOC_VERSION_RELEASE 1
#define HWLOC_VERSION_GREEK ""
#define __hwloc_restrict
#define __hwloc_inline __inline
#define __hwloc_attribute_unused
#define __hwloc_attribute_malloc
#define __hwloc_attribute_const
#define __hwloc_attribute_pure
#define __hwloc_attribute_deprecated
#define __hwloc_attribute_may_alias
#define __hwloc_attribute_warn_unused_result
/* Defined to 1 if you have the `windows.h' header. */
#define HWLOC_HAVE_WINDOWS_H 1
#define hwloc_pid_t HANDLE
#define hwloc_thread_t HANDLE
#include <windows.h>
#include <BaseTsd.h>
typedef DWORDLONG hwloc_uint64_t;
#if defined( _USRDLL ) /* dynamic linkage */
#if defined( DECLSPEC_EXPORTS )
#define HWLOC_DECLSPEC __declspec(dllexport)
#else
#define HWLOC_DECLSPEC __declspec(dllimport)
#endif
#else /* static linkage */
#define HWLOC_DECLSPEC
#endif
/* Whether we need to re-define all the hwloc public symbols or not */
#define HWLOC_SYM_TRANSFORM 0
/* The hwloc symbol prefix */
#define HWLOC_SYM_PREFIX hwloc_
/* The hwloc symbol prefix in all caps */
#define HWLOC_SYM_PREFIX_CAPS HWLOC_
#endif /* HWLOC_CONFIG_H */

View file

@ -1,494 +0,0 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2020 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
/** \file
* \brief The bitmap API, for use in hwloc itself.
*/
#ifndef HWLOC_BITMAP_H
#define HWLOC_BITMAP_H
#include "hwloc/autogen/config.h"
#include <assert.h>
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup hwlocality_bitmap The bitmap API
*
* The ::hwloc_bitmap_t type represents a set of integers (positive or null).
* A bitmap may be of infinite size (all bits are set after some point).
* A bitmap may even be full if all bits are set.
*
* Bitmaps are used by hwloc for sets of OS processors
* (which may actually be hardware threads) as by ::hwloc_cpuset_t
* (a typedef for ::hwloc_bitmap_t), or sets of NUMA memory nodes
* as ::hwloc_nodeset_t (also a typedef for ::hwloc_bitmap_t).
* Those are used for cpuset and nodeset fields in the ::hwloc_obj structure,
* see \ref hwlocality_object_sets.
*
* <em>Both CPU and node sets are always indexed by OS physical number.</em>
* However users should usually not build CPU and node sets manually
* (e.g. with hwloc_bitmap_set()).
* One should rather use existing object sets and combine them with
* hwloc_bitmap_or(), etc.
* For instance, binding the current thread on a pair of cores may be performed with:
* \code
* hwloc_obj_t core1 = ... , core2 = ... ;
* hwloc_bitmap_t set = hwloc_bitmap_alloc();
* hwloc_bitmap_or(set, core1->cpuset, core2->cpuset);
* hwloc_set_cpubind(topology, set, HWLOC_CPUBIND_THREAD);
* hwloc_bitmap_free(set);
* \endcode
*
* \note Most functions below return an int that may be negative in case of
* error. The usual error case would be an internal failure to realloc/extend
* the storage of the bitmap (\p errno would be set to \c ENOMEM).
*
* \note Several examples of using the bitmap API are available under the
* doc/examples/ directory in the source tree.
* Regression tests such as tests/hwloc/hwloc_bitmap*.c also make intensive use
* of this API.
* @{
*/
/** \brief
* Set of bits represented as an opaque pointer to an internal bitmap.
*/
typedef struct hwloc_bitmap_s * hwloc_bitmap_t;
/** \brief a non-modifiable ::hwloc_bitmap_t */
typedef const struct hwloc_bitmap_s * hwloc_const_bitmap_t;
/*
* Bitmap allocation, freeing and copying.
*/
/** \brief Allocate a new empty bitmap.
*
* \returns A valid bitmap or \c NULL.
*
* The bitmap should be freed by a corresponding call to
* hwloc_bitmap_free().
*/
HWLOC_DECLSPEC hwloc_bitmap_t hwloc_bitmap_alloc(void) __hwloc_attribute_malloc;
/** \brief Allocate a new full bitmap. */
HWLOC_DECLSPEC hwloc_bitmap_t hwloc_bitmap_alloc_full(void) __hwloc_attribute_malloc;
/** \brief Free bitmap \p bitmap.
*
* If \p bitmap is \c NULL, no operation is performed.
*/
HWLOC_DECLSPEC void hwloc_bitmap_free(hwloc_bitmap_t bitmap);
/** \brief Duplicate bitmap \p bitmap by allocating a new bitmap and copying \p bitmap contents.
*
* If \p bitmap is \c NULL, \c NULL is returned.
*/
HWLOC_DECLSPEC hwloc_bitmap_t hwloc_bitmap_dup(hwloc_const_bitmap_t bitmap) __hwloc_attribute_malloc;
/** \brief Copy the contents of bitmap \p src into the already allocated bitmap \p dst */
HWLOC_DECLSPEC int hwloc_bitmap_copy(hwloc_bitmap_t dst, hwloc_const_bitmap_t src);
/*
* Bitmap/String Conversion
*/
/** \brief Stringify a bitmap.
*
* Up to \p buflen characters may be written in buffer \p buf.
*
* If \p buflen is 0, \p buf may safely be \c NULL.
*
* \return the number of character that were actually written if not truncating,
* or that would have been written (not including the ending \\0).
*/
HWLOC_DECLSPEC int hwloc_bitmap_snprintf(char * __hwloc_restrict buf, size_t buflen, hwloc_const_bitmap_t bitmap);
/** \brief Stringify a bitmap into a newly allocated string.
*
* \return -1 on error.
*/
HWLOC_DECLSPEC int hwloc_bitmap_asprintf(char ** strp, hwloc_const_bitmap_t bitmap);
/** \brief Parse a bitmap string and stores it in bitmap \p bitmap.
*/
HWLOC_DECLSPEC int hwloc_bitmap_sscanf(hwloc_bitmap_t bitmap, const char * __hwloc_restrict string);
/** \brief Stringify a bitmap in the list format.
*
* Lists are comma-separated indexes or ranges.
* Ranges are dash separated indexes.
* The last range may not have an ending indexes if the bitmap is infinitely set.
*
* Up to \p buflen characters may be written in buffer \p buf.
*
* If \p buflen is 0, \p buf may safely be \c NULL.
*
* \return the number of character that were actually written if not truncating,
* or that would have been written (not including the ending \\0).
*/
HWLOC_DECLSPEC int hwloc_bitmap_list_snprintf(char * __hwloc_restrict buf, size_t buflen, hwloc_const_bitmap_t bitmap);
/** \brief Stringify a bitmap into a newly allocated list string.
*
* \return -1 on error.
*/
HWLOC_DECLSPEC int hwloc_bitmap_list_asprintf(char ** strp, hwloc_const_bitmap_t bitmap);
/** \brief Parse a list string and stores it in bitmap \p bitmap.
*/
HWLOC_DECLSPEC int hwloc_bitmap_list_sscanf(hwloc_bitmap_t bitmap, const char * __hwloc_restrict string);
/** \brief Stringify a bitmap in the taskset-specific format.
*
* The taskset command manipulates bitmap strings that contain a single
* (possible very long) hexadecimal number starting with 0x.
*
* Up to \p buflen characters may be written in buffer \p buf.
*
* If \p buflen is 0, \p buf may safely be \c NULL.
*
* \return the number of character that were actually written if not truncating,
* or that would have been written (not including the ending \\0).
*/
HWLOC_DECLSPEC int hwloc_bitmap_taskset_snprintf(char * __hwloc_restrict buf, size_t buflen, hwloc_const_bitmap_t bitmap);
/** \brief Stringify a bitmap into a newly allocated taskset-specific string.
*
* \return -1 on error.
*/
HWLOC_DECLSPEC int hwloc_bitmap_taskset_asprintf(char ** strp, hwloc_const_bitmap_t bitmap);
/** \brief Parse a taskset-specific bitmap string and stores it in bitmap \p bitmap.
*/
HWLOC_DECLSPEC int hwloc_bitmap_taskset_sscanf(hwloc_bitmap_t bitmap, const char * __hwloc_restrict string);
/*
* Building bitmaps.
*/
/** \brief Empty the bitmap \p bitmap */
HWLOC_DECLSPEC void hwloc_bitmap_zero(hwloc_bitmap_t bitmap);
/** \brief Fill bitmap \p bitmap with all possible indexes (even if those objects don't exist or are otherwise unavailable) */
HWLOC_DECLSPEC void hwloc_bitmap_fill(hwloc_bitmap_t bitmap);
/** \brief Empty the bitmap \p bitmap and add bit \p id */
HWLOC_DECLSPEC int hwloc_bitmap_only(hwloc_bitmap_t bitmap, unsigned id);
/** \brief Fill the bitmap \p and clear the index \p id */
HWLOC_DECLSPEC int hwloc_bitmap_allbut(hwloc_bitmap_t bitmap, unsigned id);
/** \brief Setup bitmap \p bitmap from unsigned long \p mask */
HWLOC_DECLSPEC int hwloc_bitmap_from_ulong(hwloc_bitmap_t bitmap, unsigned long mask);
/** \brief Setup bitmap \p bitmap from unsigned long \p mask used as \p i -th subset */
HWLOC_DECLSPEC int hwloc_bitmap_from_ith_ulong(hwloc_bitmap_t bitmap, unsigned i, unsigned long mask);
/** \brief Setup bitmap \p bitmap from unsigned longs \p masks used as first \p nr subsets */
HWLOC_DECLSPEC int hwloc_bitmap_from_ulongs(hwloc_bitmap_t bitmap, unsigned nr, const unsigned long *masks);
/*
* Modifying bitmaps.
*/
/** \brief Add index \p id in bitmap \p bitmap */
HWLOC_DECLSPEC int hwloc_bitmap_set(hwloc_bitmap_t bitmap, unsigned id);
/** \brief Add indexes from \p begin to \p end in bitmap \p bitmap.
*
* If \p end is \c -1, the range is infinite.
*/
HWLOC_DECLSPEC int hwloc_bitmap_set_range(hwloc_bitmap_t bitmap, unsigned begin, int end);
/** \brief Replace \p i -th subset of bitmap \p bitmap with unsigned long \p mask */
HWLOC_DECLSPEC int hwloc_bitmap_set_ith_ulong(hwloc_bitmap_t bitmap, unsigned i, unsigned long mask);
/** \brief Remove index \p id from bitmap \p bitmap */
HWLOC_DECLSPEC int hwloc_bitmap_clr(hwloc_bitmap_t bitmap, unsigned id);
/** \brief Remove indexes from \p begin to \p end in bitmap \p bitmap.
*
* If \p end is \c -1, the range is infinite.
*/
HWLOC_DECLSPEC int hwloc_bitmap_clr_range(hwloc_bitmap_t bitmap, unsigned begin, int end);
/** \brief Keep a single index among those set in bitmap \p bitmap
*
* May be useful before binding so that the process does not
* have a chance of migrating between multiple processors
* in the original mask.
* Instead of running the task on any PU inside the given CPU set,
* the operating system scheduler will be forced to run it on a single
* of these PUs.
* It avoids a migration overhead and cache-line ping-pongs between PUs.
*
* \note This function is NOT meant to distribute multiple processes
* within a single CPU set. It always return the same single bit when
* called multiple times on the same input set. hwloc_distrib() may
* be used for generating CPU sets to distribute multiple tasks below
* a single multi-PU object.
*
* \note This function cannot be applied to an object set directly. It
* should be applied to a copy (which may be obtained with hwloc_bitmap_dup()).
*/
HWLOC_DECLSPEC int hwloc_bitmap_singlify(hwloc_bitmap_t bitmap);
/*
* Consulting bitmaps.
*/
/** \brief Convert the beginning part of bitmap \p bitmap into unsigned long \p mask */
HWLOC_DECLSPEC unsigned long hwloc_bitmap_to_ulong(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure;
/** \brief Convert the \p i -th subset of bitmap \p bitmap into unsigned long mask */
HWLOC_DECLSPEC unsigned long hwloc_bitmap_to_ith_ulong(hwloc_const_bitmap_t bitmap, unsigned i) __hwloc_attribute_pure;
/** \brief Convert the first \p nr subsets of bitmap \p bitmap into the array of \p nr unsigned long \p masks
*
* \p nr may be determined earlier with hwloc_bitmap_nr_ulongs().
*
* \return 0
*/
HWLOC_DECLSPEC int hwloc_bitmap_to_ulongs(hwloc_const_bitmap_t bitmap, unsigned nr, unsigned long *masks);
/** \brief Return the number of unsigned longs required for storing bitmap \p bitmap entirely
*
* This is the number of contiguous unsigned longs from the very first bit of the bitmap
* (even if unset) up to the last set bit.
* This is useful for knowing the \p nr parameter to pass to hwloc_bitmap_to_ulongs()
* (or which calls to hwloc_bitmap_to_ith_ulong() are needed)
* to entirely convert a bitmap into multiple unsigned longs.
*
* When called on the output of hwloc_topology_get_topology_cpuset(),
* the returned number is large enough for all cpusets of the topology.
*
* \return -1 if \p bitmap is infinite.
*/
HWLOC_DECLSPEC int hwloc_bitmap_nr_ulongs(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure;
/** \brief Test whether index \p id is part of bitmap \p bitmap.
*
* \return 1 if the bit at index \p id is set in bitmap \p bitmap, 0 otherwise.
*/
HWLOC_DECLSPEC int hwloc_bitmap_isset(hwloc_const_bitmap_t bitmap, unsigned id) __hwloc_attribute_pure;
/** \brief Test whether bitmap \p bitmap is empty
*
* \return 1 if bitmap is empty, 0 otherwise.
*/
HWLOC_DECLSPEC int hwloc_bitmap_iszero(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure;
/** \brief Test whether bitmap \p bitmap is completely full
*
* \return 1 if bitmap is full, 0 otherwise.
*
* \note A full bitmap is always infinitely set.
*/
HWLOC_DECLSPEC int hwloc_bitmap_isfull(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure;
/** \brief Compute the first index (least significant bit) in bitmap \p bitmap
*
* \return -1 if no index is set in \p bitmap.
*/
HWLOC_DECLSPEC int hwloc_bitmap_first(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure;
/** \brief Compute the next index in bitmap \p bitmap which is after index \p prev
*
* If \p prev is -1, the first index is returned.
*
* \return -1 if no index with higher index is set in \p bitmap.
*/
HWLOC_DECLSPEC int hwloc_bitmap_next(hwloc_const_bitmap_t bitmap, int prev) __hwloc_attribute_pure;
/** \brief Compute the last index (most significant bit) in bitmap \p bitmap
*
* \return -1 if no index is set in \p bitmap, or if \p bitmap is infinitely set.
*/
HWLOC_DECLSPEC int hwloc_bitmap_last(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure;
/** \brief Compute the "weight" of bitmap \p bitmap (i.e., number of
* indexes that are in the bitmap).
*
* \return the number of indexes that are in the bitmap.
*
* \return -1 if \p bitmap is infinitely set.
*/
HWLOC_DECLSPEC int hwloc_bitmap_weight(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure;
/** \brief Compute the first unset index (least significant bit) in bitmap \p bitmap
*
* \return -1 if no index is unset in \p bitmap.
*/
HWLOC_DECLSPEC int hwloc_bitmap_first_unset(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure;
/** \brief Compute the next unset index in bitmap \p bitmap which is after index \p prev
*
* If \p prev is -1, the first unset index is returned.
*
* \return -1 if no index with higher index is unset in \p bitmap.
*/
HWLOC_DECLSPEC int hwloc_bitmap_next_unset(hwloc_const_bitmap_t bitmap, int prev) __hwloc_attribute_pure;
/** \brief Compute the last unset index (most significant bit) in bitmap \p bitmap
*
* \return -1 if no index is unset in \p bitmap, or if \p bitmap is infinitely set.
*/
HWLOC_DECLSPEC int hwloc_bitmap_last_unset(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure;
/** \brief Loop macro iterating on bitmap \p bitmap
*
* The loop must start with hwloc_bitmap_foreach_begin() and end
* with hwloc_bitmap_foreach_end() followed by a terminating ';'.
*
* \p index is the loop variable; it should be an unsigned int. The
* first iteration will set \p index to the lowest index in the bitmap.
* Successive iterations will iterate through, in order, all remaining
* indexes set in the bitmap. To be specific: each iteration will return a
* value for \p index such that hwloc_bitmap_isset(bitmap, index) is true.
*
* The assert prevents the loop from being infinite if the bitmap is infinitely set.
*
* \hideinitializer
*/
#define hwloc_bitmap_foreach_begin(id, bitmap) \
do { \
assert(hwloc_bitmap_weight(bitmap) != -1); \
for (id = hwloc_bitmap_first(bitmap); \
(unsigned) id != (unsigned) -1; \
id = hwloc_bitmap_next(bitmap, id)) {
/** \brief End of loop macro iterating on a bitmap.
*
* Needs a terminating ';'.
*
* \sa hwloc_bitmap_foreach_begin()
* \hideinitializer
*/
#define hwloc_bitmap_foreach_end() \
} \
} while (0)
/*
* Combining bitmaps.
*/
/** \brief Or bitmaps \p bitmap1 and \p bitmap2 and store the result in bitmap \p res
*
* \p res can be the same as \p bitmap1 or \p bitmap2
*/
HWLOC_DECLSPEC int hwloc_bitmap_or (hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2);
/** \brief And bitmaps \p bitmap1 and \p bitmap2 and store the result in bitmap \p res
*
* \p res can be the same as \p bitmap1 or \p bitmap2
*/
HWLOC_DECLSPEC int hwloc_bitmap_and (hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2);
/** \brief And bitmap \p bitmap1 and the negation of \p bitmap2 and store the result in bitmap \p res
*
* \p res can be the same as \p bitmap1 or \p bitmap2
*/
HWLOC_DECLSPEC int hwloc_bitmap_andnot (hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2);
/** \brief Xor bitmaps \p bitmap1 and \p bitmap2 and store the result in bitmap \p res
*
* \p res can be the same as \p bitmap1 or \p bitmap2
*/
HWLOC_DECLSPEC int hwloc_bitmap_xor (hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2);
/** \brief Negate bitmap \p bitmap and store the result in bitmap \p res
*
* \p res can be the same as \p bitmap
*/
HWLOC_DECLSPEC int hwloc_bitmap_not (hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap);
/*
* Comparing bitmaps.
*/
/** \brief Test whether bitmaps \p bitmap1 and \p bitmap2 intersects.
*
* \return 1 if bitmaps intersect, 0 otherwise.
*/
HWLOC_DECLSPEC int hwloc_bitmap_intersects (hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) __hwloc_attribute_pure;
/** \brief Test whether bitmap \p sub_bitmap is part of bitmap \p super_bitmap.
*
* \return 1 if \p sub_bitmap is included in \p super_bitmap, 0 otherwise.
*
* \note The empty bitmap is considered included in any other bitmap.
*/
HWLOC_DECLSPEC int hwloc_bitmap_isincluded (hwloc_const_bitmap_t sub_bitmap, hwloc_const_bitmap_t super_bitmap) __hwloc_attribute_pure;
/** \brief Test whether bitmap \p bitmap1 is equal to bitmap \p bitmap2.
*
* \return 1 if bitmaps are equal, 0 otherwise.
*/
HWLOC_DECLSPEC int hwloc_bitmap_isequal (hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) __hwloc_attribute_pure;
/** \brief Compare bitmaps \p bitmap1 and \p bitmap2 using their lowest index.
*
* A bitmap is considered smaller if its least significant bit is smaller.
* The empty bitmap is considered higher than anything (because its least significant bit does not exist).
*
* \return -1 if \p bitmap1 is considered smaller than \p bitmap2.
* \return 1 if \p bitmap1 is considered larger than \p bitmap2.
*
* For instance comparing binary bitmaps 0011 and 0110 returns -1
* (hence 0011 is considered smaller than 0110)
* because least significant bit of 0011 (0001) is smaller than least significant bit of 0110 (0010).
* Comparing 01001 and 00110 would also return -1 for the same reason.
*
* \return 0 if bitmaps are considered equal, even if they are not strictly equal.
* They just need to have the same least significant bit.
* For instance, comparing binary bitmaps 0010 and 0110 returns 0 because they have the same least significant bit.
*/
HWLOC_DECLSPEC int hwloc_bitmap_compare_first(hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) __hwloc_attribute_pure;
/** \brief Compare bitmaps \p bitmap1 and \p bitmap2 in lexicographic order.
*
* Lexicographic comparison of bitmaps, starting for their highest indexes.
* Compare last indexes first, then second, etc.
* The empty bitmap is considered lower than anything.
*
* \return -1 if \p bitmap1 is considered smaller than \p bitmap2.
* \return 1 if \p bitmap1 is considered larger than \p bitmap2.
* \return 0 if bitmaps are equal (contrary to hwloc_bitmap_compare_first()).
*
* For instance comparing binary bitmaps 0011 and 0110 returns -1
* (hence 0011 is considered smaller than 0110).
* Comparing 00101 and 01010 returns -1 too.
*
* \note This is different from the non-existing hwloc_bitmap_compare_last()
* which would only compare the highest index of each bitmap.
*/
HWLOC_DECLSPEC int hwloc_bitmap_compare(hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) __hwloc_attribute_pure;
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_BITMAP_H */

View file

@ -1,193 +0,0 @@
/*
* Copyright © 2020-2021 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
/** \file
* \brief Kinds of CPU cores.
*/
#ifndef HWLOC_CPUKINDS_H
#define HWLOC_CPUKINDS_H
#include "hwloc.h"
#ifdef __cplusplus
extern "C" {
#elif 0
}
#endif
/** \defgroup hwlocality_cpukinds Kinds of CPU cores
*
* Platforms with heterogeneous CPUs may have some cores with
* different features or frequencies.
* This API exposes identical PUs in sets called CPU kinds.
* Each PU of the topology may only be in a single kind.
*
* The number of kinds may be obtained with hwloc_cpukinds_get_nr().
* If the platform is homogeneous, there may be a single kind
* with all PUs.
* If the platform or operating system does not expose any
* information about CPU cores, there may be no kind at all.
*
* The index of the kind that describes a given CPU set
* (if any, and not partially)
* may be obtained with hwloc_cpukinds_get_by_cpuset().
*
* From the index of a kind, it is possible to retrieve information
* with hwloc_cpukinds_get_info():
* an abstracted efficiency value,
* and an array of info attributes
* (for instance the "CoreType" and "FrequencyMaxMHz",
* see \ref topoattrs_cpukinds).
*
* A higher efficiency value means greater intrinsic performance
* (and possibly less performance/power efficiency).
* Kinds with lower efficiency values are ranked first:
* Passing 0 as \p kind_index to hwloc_cpukinds_get_info() will
* return information about the CPU kind with lower performance
* but higher energy-efficiency.
* Higher \p kind_index values would rather return information
* about power-hungry high-performance cores.
*
* When available, efficiency values are gathered from the operating system.
* If so, \p cpukind_efficiency is set in the struct hwloc_topology_discovery_support array.
* This is currently available on Windows 10, Mac OS X (Darwin),
* and on some Linux platforms where core "capacity" is exposed in sysfs.
*
* If the operating system does not expose core efficiencies natively,
* hwloc tries to compute efficiencies by comparing CPU kinds using
* frequencies (on ARM), or core types and frequencies (on other architectures).
* The environment variable HWLOC_CPUKINDS_RANKING may be used
* to change this heuristics, see \ref envvar.
*
* If hwloc fails to rank any kind, for instance because the operating
* system does not expose efficiencies and core frequencies,
* all kinds will have an unknown efficiency (\c -1),
* and they are not indexed/ordered in any specific way.
*
* @{
*/
/** \brief Get the number of different kinds of CPU cores in the topology.
*
* \p flags must be \c 0 for now.
*
* \return The number of CPU kinds (positive integer) on success.
* \return \c 0 if no information about kinds was found.
* \return \c -1 with \p errno set to \c EINVAL if \p flags is invalid.
*/
HWLOC_DECLSPEC int
hwloc_cpukinds_get_nr(hwloc_topology_t topology,
unsigned long flags);
/** \brief Get the index of the CPU kind that contains CPUs listed in \p cpuset.
*
* \p flags must be \c 0 for now.
*
* \return The index of the CPU kind (positive integer or 0) on success.
* \return \c -1 with \p errno set to \c EXDEV if \p cpuset is
* only partially included in the some kind.
* \return \c -1 with \p errno set to \c ENOENT if \p cpuset is
* not included in any kind, even partially.
* \return \c -1 with \p errno set to \c EINVAL if parameters are invalid.
*/
HWLOC_DECLSPEC int
hwloc_cpukinds_get_by_cpuset(hwloc_topology_t topology,
hwloc_const_bitmap_t cpuset,
unsigned long flags);
/** \brief Get the CPU set and infos about a CPU kind in the topology.
*
* \p kind_index identifies one kind of CPU between 0 and the number
* of kinds returned by hwloc_cpukinds_get_nr() minus 1.
*
* If not \c NULL, the bitmap \p cpuset will be filled with
* the set of PUs of this kind.
*
* The integer pointed by \p efficiency, if not \c NULL will, be filled
* with the ranking of this kind of CPU in term of efficiency (see above).
* It ranges from \c 0 to the number of kinds
* (as reported by hwloc_cpukinds_get_nr()) minus 1.
*
* Kinds with lower efficiency are reported first.
*
* If there is a single kind in the topology, its efficiency \c 0.
* If the efficiency of some kinds of cores is unknown,
* the efficiency of all kinds is set to \c -1,
* and kinds are reported in no specific order.
*
* The array of info attributes (for instance the "CoreType",
* "FrequencyMaxMHz" or "FrequencyBaseMHz", see \ref topoattrs_cpukinds)
* and its length are returned in \p infos or \p nr_infos.
* The array belongs to the topology, it should not be freed or modified.
*
* If \p nr_infos or \p infos is \c NULL, no info is returned.
*
* \p flags must be \c 0 for now.
*
* \return \c 0 on success.
* \return \c -1 with \p errno set to \c ENOENT if \p kind_index does not match any CPU kind.
* \return \c -1 with \p errno set to \c EINVAL if parameters are invalid.
*/
HWLOC_DECLSPEC int
hwloc_cpukinds_get_info(hwloc_topology_t topology,
unsigned kind_index,
hwloc_bitmap_t cpuset,
int *efficiency,
unsigned *nr_infos, struct hwloc_info_s **infos,
unsigned long flags);
/** \brief Register a kind of CPU in the topology.
*
* Mark the PUs listed in \p cpuset as being of the same kind
* with respect to the given attributes.
*
* \p forced_efficiency should be \c -1 if unknown.
* Otherwise it is an abstracted efficiency value to enforce
* the ranking of all kinds if all of them have valid (and
* different) efficiencies.
*
* The array \p infos of size \p nr_infos may be used to provide
* info names and values describing this kind of PUs.
*
* \p flags must be \c 0 for now.
*
* Parameters \p cpuset and \p infos will be duplicated internally,
* the caller is responsible for freeing them.
*
* If \p cpuset overlaps with some existing kinds, those might get
* modified or split. For instance if existing kind A contains
* PUs 0 and 1, and one registers another kind for PU 1 and 2,
* there will be 3 resulting kinds:
* existing kind A is restricted to only PU 0;
* new kind B contains only PU 1 and combines information from A
* and from the newly-registered kind;
* new kind C contains only PU 2 and only gets information from
* the newly-registered kind.
*
* \note The efficiency \p forced_efficiency provided to this function
* may be different from the one reported later by hwloc_cpukinds_get_info()
* because hwloc will scale efficiency values down to
* between 0 and the number of kinds minus 1.
*
* \return \c 0 on success.
* \return \c -1 with \p errno set to \c EINVAL if some parameters are invalid,
* for instance if \p cpuset is \c NULL or empty.
*/
HWLOC_DECLSPEC int
hwloc_cpukinds_register(hwloc_topology_t topology,
hwloc_bitmap_t cpuset,
int forced_efficiency,
unsigned nr_infos, struct hwloc_info_s *infos,
unsigned long flags);
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_CPUKINDS_H */

View file

@ -1,220 +0,0 @@
/*
* Copyright © 2010-2021 Inria. All rights reserved.
* Copyright © 2010-2011 Université Bordeaux
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
/** \file
* \brief Macros to help interaction between hwloc and the CUDA Driver API.
*
* Applications that use both hwloc and the CUDA Driver API may want to
* include this file so as to get topology information for CUDA devices.
*
*/
#ifndef HWLOC_CUDA_H
#define HWLOC_CUDA_H
#include "hwloc.h"
#include "hwloc/autogen/config.h"
#include "hwloc/helper.h"
#ifdef HWLOC_LINUX_SYS
#include "hwloc/linux.h"
#endif
#include <cuda.h>
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup hwlocality_cuda Interoperability with the CUDA Driver API
*
* This interface offers ways to retrieve topology information about
* CUDA devices when using the CUDA Driver API.
*
* @{
*/
/** \brief Return the domain, bus and device IDs of the CUDA device \p cudevice.
*
* Device \p cudevice must match the local machine.
*/
static __hwloc_inline int
hwloc_cuda_get_device_pci_ids(hwloc_topology_t topology __hwloc_attribute_unused,
CUdevice cudevice, int *domain, int *bus, int *dev)
{
CUresult cres;
#if CUDA_VERSION >= 4000
cres = cuDeviceGetAttribute(domain, CU_DEVICE_ATTRIBUTE_PCI_DOMAIN_ID, cudevice);
if (cres != CUDA_SUCCESS) {
errno = ENOSYS;
return -1;
}
#else
*domain = 0;
#endif
cres = cuDeviceGetAttribute(bus, CU_DEVICE_ATTRIBUTE_PCI_BUS_ID, cudevice);
if (cres != CUDA_SUCCESS) {
errno = ENOSYS;
return -1;
}
cres = cuDeviceGetAttribute(dev, CU_DEVICE_ATTRIBUTE_PCI_DEVICE_ID, cudevice);
if (cres != CUDA_SUCCESS) {
errno = ENOSYS;
return -1;
}
return 0;
}
/** \brief Get the CPU set of processors that are physically
* close to device \p cudevice.
*
* Store in \p set the CPU-set describing the locality of the CUDA device \p cudevice.
*
* Topology \p topology and device \p cudevice must match the local machine.
* I/O devices detection and the CUDA component are not needed in the topology.
*
* The function only returns the locality of the device.
* If more information about the device is needed, OS objects should
* be used instead, see hwloc_cuda_get_device_osdev()
* and hwloc_cuda_get_device_osdev_by_index().
*
* This function is currently only implemented in a meaningful way for
* Linux; other systems will simply get a full cpuset.
*/
static __hwloc_inline int
hwloc_cuda_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
CUdevice cudevice, hwloc_cpuset_t set)
{
#ifdef HWLOC_LINUX_SYS
/* If we're on Linux, use the sysfs mechanism to get the local cpus */
#define HWLOC_CUDA_DEVICE_SYSFS_PATH_MAX 128
char path[HWLOC_CUDA_DEVICE_SYSFS_PATH_MAX];
int domainid, busid, deviceid;
if (hwloc_cuda_get_device_pci_ids(topology, cudevice, &domainid, &busid, &deviceid))
return -1;
if (!hwloc_topology_is_thissystem(topology)) {
errno = EINVAL;
return -1;
}
sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.0/local_cpus", domainid, busid, deviceid);
if (hwloc_linux_read_path_as_cpumask(path, set) < 0
|| hwloc_bitmap_iszero(set))
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
#else
/* Non-Linux systems simply get a full cpuset */
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
#endif
return 0;
}
/** \brief Get the hwloc PCI device object corresponding to the
* CUDA device \p cudevice.
*
* \return The hwloc PCI device object describing the CUDA device \p cudevice.
* \return \c NULL if none could be found.
*
* Topology \p topology and device \p cudevice must match the local machine.
* I/O devices detection must be enabled in topology \p topology.
* The CUDA component is not needed in the topology.
*/
static __hwloc_inline hwloc_obj_t
hwloc_cuda_get_device_pcidev(hwloc_topology_t topology, CUdevice cudevice)
{
int domain, bus, dev;
if (hwloc_cuda_get_device_pci_ids(topology, cudevice, &domain, &bus, &dev))
return NULL;
return hwloc_get_pcidev_by_busid(topology, domain, bus, dev, 0);
}
/** \brief Get the hwloc OS device object corresponding to CUDA device \p cudevice.
*
* \return The hwloc OS device object that describes the given CUDA device \p cudevice.
* \return \c NULL if none could be found.
*
* Topology \p topology and device \p cudevice must match the local machine.
* I/O devices detection and the CUDA component must be enabled in the topology.
* If not, the locality of the object may still be found using
* hwloc_cuda_get_device_cpuset().
*
* \note This function cannot work if PCI devices are filtered out.
*
* \note The corresponding hwloc PCI device may be found by looking
* at the result parent pointer (unless PCI devices are filtered out).
*/
static __hwloc_inline hwloc_obj_t
hwloc_cuda_get_device_osdev(hwloc_topology_t topology, CUdevice cudevice)
{
hwloc_obj_t osdev = NULL;
int domain, bus, dev;
if (hwloc_cuda_get_device_pci_ids(topology, cudevice, &domain, &bus, &dev))
return NULL;
osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
hwloc_obj_t pcidev = osdev->parent;
if (strncmp(osdev->name, "cuda", 4))
continue;
if (pcidev
&& pcidev->type == HWLOC_OBJ_PCI_DEVICE
&& (int) pcidev->attr->pcidev.domain == domain
&& (int) pcidev->attr->pcidev.bus == bus
&& (int) pcidev->attr->pcidev.dev == dev
&& pcidev->attr->pcidev.func == 0)
return osdev;
/* if PCI are filtered out, we need a info attr to match on */
}
return NULL;
}
/** \brief Get the hwloc OS device object corresponding to the
* CUDA device whose index is \p idx.
*
* \return The hwloc OS device object describing the CUDA device whose index is \p idx.
* \return \c NULL if none could be found.
*
* The topology \p topology does not necessarily have to match the current
* machine. For instance the topology may be an XML import of a remote host.
* I/O devices detection and the CUDA component must be enabled in the topology.
*
* \note The corresponding PCI device object can be obtained by looking
* at the OS device parent object (unless PCI devices are filtered out).
*
* \note This function is identical to hwloc_cudart_get_device_osdev_by_index().
*/
static __hwloc_inline hwloc_obj_t
hwloc_cuda_get_device_osdev_by_index(hwloc_topology_t topology, unsigned idx)
{
hwloc_obj_t osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
if (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type
&& osdev->name
&& !strncmp("cuda", osdev->name, 4)
&& atoi(osdev->name + 4) == (int) idx)
return osdev;
}
return NULL;
}
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_CUDA_H */

View file

@ -1,177 +0,0 @@
/*
* Copyright © 2010-2021 Inria. All rights reserved.
* Copyright © 2010-2011 Université Bordeaux
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
/** \file
* \brief Macros to help interaction between hwloc and the CUDA Runtime API.
*
* Applications that use both hwloc and the CUDA Runtime API may want to
* include this file so as to get topology information for CUDA devices.
*
*/
#ifndef HWLOC_CUDART_H
#define HWLOC_CUDART_H
#include "hwloc.h"
#include "hwloc/autogen/config.h"
#include "hwloc/helper.h"
#ifdef HWLOC_LINUX_SYS
#include "hwloc/linux.h"
#endif
#include <cuda.h> /* for CUDA_VERSION */
#include <cuda_runtime_api.h>
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup hwlocality_cudart Interoperability with the CUDA Runtime API
*
* This interface offers ways to retrieve topology information about
* CUDA devices when using the CUDA Runtime API.
*
* @{
*/
/** \brief Return the domain, bus and device IDs of the CUDA device whose index is \p idx.
*
* Device index \p idx must match the local machine.
*/
static __hwloc_inline int
hwloc_cudart_get_device_pci_ids(hwloc_topology_t topology __hwloc_attribute_unused,
int idx, int *domain, int *bus, int *dev)
{
cudaError_t cerr;
struct cudaDeviceProp prop;
cerr = cudaGetDeviceProperties(&prop, idx);
if (cerr) {
errno = ENOSYS;
return -1;
}
#if CUDA_VERSION >= 4000
*domain = prop.pciDomainID;
#else
*domain = 0;
#endif
*bus = prop.pciBusID;
*dev = prop.pciDeviceID;
return 0;
}
/** \brief Get the CPU set of processors that are physically
* close to device \p idx.
*
* Store in \p set the CPU-set describing the locality of the CUDA device
* whose index is \p idx.
*
* Topology \p topology and device \p idx must match the local machine.
* I/O devices detection and the CUDA component are not needed in the topology.
*
* The function only returns the locality of the device.
* If more information about the device is needed, OS objects should
* be used instead, see hwloc_cudart_get_device_osdev_by_index().
*
* This function is currently only implemented in a meaningful way for
* Linux; other systems will simply get a full cpuset.
*/
static __hwloc_inline int
hwloc_cudart_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
int idx, hwloc_cpuset_t set)
{
#ifdef HWLOC_LINUX_SYS
/* If we're on Linux, use the sysfs mechanism to get the local cpus */
#define HWLOC_CUDART_DEVICE_SYSFS_PATH_MAX 128
char path[HWLOC_CUDART_DEVICE_SYSFS_PATH_MAX];
int domain, bus, dev;
if (hwloc_cudart_get_device_pci_ids(topology, idx, &domain, &bus, &dev))
return -1;
if (!hwloc_topology_is_thissystem(topology)) {
errno = EINVAL;
return -1;
}
sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.0/local_cpus", (unsigned) domain, (unsigned) bus, (unsigned) dev);
if (hwloc_linux_read_path_as_cpumask(path, set) < 0
|| hwloc_bitmap_iszero(set))
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
#else
/* Non-Linux systems simply get a full cpuset */
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
#endif
return 0;
}
/** \brief Get the hwloc PCI device object corresponding to the
* CUDA device whose index is \p idx.
*
* \return The hwloc PCI device object describing the CUDA device whose index is \p idx.
* \return \c NULL if none could be found.
*
* Topology \p topology and device \p idx must match the local machine.
* I/O devices detection must be enabled in topology \p topology.
* The CUDA component is not needed in the topology.
*/
static __hwloc_inline hwloc_obj_t
hwloc_cudart_get_device_pcidev(hwloc_topology_t topology, int idx)
{
int domain, bus, dev;
if (hwloc_cudart_get_device_pci_ids(topology, idx, &domain, &bus, &dev))
return NULL;
return hwloc_get_pcidev_by_busid(topology, domain, bus, dev, 0);
}
/** \brief Get the hwloc OS device object corresponding to the
* CUDA device whose index is \p idx.
*
* \return The hwloc OS device object describing the CUDA device whose index is \p idx.
* \return \c NULL if none could be found.
*
* The topology \p topology does not necessarily have to match the current
* machine. For instance the topology may be an XML import of a remote host.
* I/O devices detection and the CUDA component must be enabled in the topology.
* If not, the locality of the object may still be found using
* hwloc_cudart_get_device_cpuset().
*
* \note The corresponding PCI device object can be obtained by looking
* at the OS device parent object (unless PCI devices are filtered out).
*
* \note This function is identical to hwloc_cuda_get_device_osdev_by_index().
*/
static __hwloc_inline hwloc_obj_t
hwloc_cudart_get_device_osdev_by_index(hwloc_topology_t topology, unsigned idx)
{
hwloc_obj_t osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
if (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type
&& osdev->name
&& !strncmp("cuda", osdev->name, 4)
&& atoi(osdev->name + 4) == (int) idx)
return osdev;
}
return NULL;
}
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_CUDART_H */

View file

@ -1,217 +0,0 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2021 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux
* Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
/**
* This file contains the inline code of functions declared in hwloc.h
*/
#ifndef HWLOC_DEPRECATED_H
#define HWLOC_DEPRECATED_H
#ifndef HWLOC_H
#error Please include the main hwloc.h instead
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* backward compat with v2.0 before WHOLE_SYSTEM renaming */
#define HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM HWLOC_TOPOLOGY_FLAG_INCLUDE_DISALLOWED
/* backward compat with v1.11 before System removal */
#define HWLOC_OBJ_SYSTEM HWLOC_OBJ_MACHINE
/* backward compat with v1.10 before Socket->Package renaming */
#define HWLOC_OBJ_SOCKET HWLOC_OBJ_PACKAGE
/* backward compat with v1.10 before Node->NUMANode clarification */
#define HWLOC_OBJ_NODE HWLOC_OBJ_NUMANODE
/** \brief Add a distances structure.
*
* Superseded by hwloc_distances_add_create()+hwloc_distances_add_values()+hwloc_distances_add_commit()
* in v2.5.
*/
HWLOC_DECLSPEC int hwloc_distances_add(hwloc_topology_t topology,
unsigned nbobjs, hwloc_obj_t *objs, hwloc_uint64_t *values,
unsigned long kind, unsigned long flags) __hwloc_attribute_deprecated;
/** \brief Insert a misc object by parent.
*
* Identical to hwloc_topology_insert_misc_object().
*/
static __hwloc_inline hwloc_obj_t
hwloc_topology_insert_misc_object_by_parent(hwloc_topology_t topology, hwloc_obj_t parent, const char *name) __hwloc_attribute_deprecated;
static __hwloc_inline hwloc_obj_t
hwloc_topology_insert_misc_object_by_parent(hwloc_topology_t topology, hwloc_obj_t parent, const char *name)
{
return hwloc_topology_insert_misc_object(topology, parent, name);
}
/** \brief Stringify the cpuset containing a set of objects.
*
* If \p size is 0, \p string may safely be \c NULL.
*
* \return the number of character that were actually written if not truncating,
* or that would have been written (not including the ending \\0).
*/
static __hwloc_inline int
hwloc_obj_cpuset_snprintf(char *str, size_t size, size_t nobj, struct hwloc_obj * const *objs) __hwloc_attribute_deprecated;
static __hwloc_inline int
hwloc_obj_cpuset_snprintf(char *str, size_t size, size_t nobj, struct hwloc_obj * const *objs)
{
hwloc_bitmap_t set = hwloc_bitmap_alloc();
int res;
unsigned i;
hwloc_bitmap_zero(set);
for(i=0; i<nobj; i++)
if (objs[i]->cpuset)
hwloc_bitmap_or(set, set, objs[i]->cpuset);
res = hwloc_bitmap_snprintf(str, size, set);
hwloc_bitmap_free(set);
return res;
}
/** \brief Convert a type string into a type and some attributes.
*
* Deprecated by hwloc_type_sscanf()
*/
static __hwloc_inline int
hwloc_obj_type_sscanf(const char *string, hwloc_obj_type_t *typep, int *depthattrp, void *typeattrp, size_t typeattrsize) __hwloc_attribute_deprecated;
static __hwloc_inline int
hwloc_obj_type_sscanf(const char *string, hwloc_obj_type_t *typep, int *depthattrp, void *typeattrp, size_t typeattrsize)
{
union hwloc_obj_attr_u attr;
int err = hwloc_type_sscanf(string, typep, &attr, sizeof(attr));
if (err < 0)
return err;
if (hwloc_obj_type_is_cache(*typep)) {
if (depthattrp)
*depthattrp = (int) attr.cache.depth;
if (typeattrp && typeattrsize >= sizeof(hwloc_obj_cache_type_t))
memcpy(typeattrp, &attr.cache.type, sizeof(hwloc_obj_cache_type_t));
} else if (*typep == HWLOC_OBJ_GROUP) {
if (depthattrp)
*depthattrp = (int) attr.group.depth;
}
return 0;
}
/** \brief Set the default memory binding policy of the current
* process or thread to prefer the NUMA node(s) specified by physical \p nodeset
*/
static __hwloc_inline int
hwloc_set_membind_nodeset(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags) __hwloc_attribute_deprecated;
static __hwloc_inline int
hwloc_set_membind_nodeset(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
{
return hwloc_set_membind(topology, nodeset, policy, flags | HWLOC_MEMBIND_BYNODESET);
}
/** \brief Query the default memory binding policy and physical locality of the
* current process or thread.
*/
static __hwloc_inline int
hwloc_get_membind_nodeset(hwloc_topology_t topology, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags) __hwloc_attribute_deprecated;
static __hwloc_inline int
hwloc_get_membind_nodeset(hwloc_topology_t topology, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags)
{
return hwloc_get_membind(topology, nodeset, policy, flags | HWLOC_MEMBIND_BYNODESET);
}
/** \brief Set the default memory binding policy of the specified
* process to prefer the NUMA node(s) specified by physical \p nodeset
*/
static __hwloc_inline int
hwloc_set_proc_membind_nodeset(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags) __hwloc_attribute_deprecated;
static __hwloc_inline int
hwloc_set_proc_membind_nodeset(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
{
return hwloc_set_proc_membind(topology, pid, nodeset, policy, flags | HWLOC_MEMBIND_BYNODESET);
}
/** \brief Query the default memory binding policy and physical locality of the
* specified process.
*/
static __hwloc_inline int
hwloc_get_proc_membind_nodeset(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags) __hwloc_attribute_deprecated;
static __hwloc_inline int
hwloc_get_proc_membind_nodeset(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags)
{
return hwloc_get_proc_membind(topology, pid, nodeset, policy, flags | HWLOC_MEMBIND_BYNODESET);
}
/** \brief Bind the already-allocated memory identified by (addr, len)
* to the NUMA node(s) in physical \p nodeset.
*/
static __hwloc_inline int
hwloc_set_area_membind_nodeset(hwloc_topology_t topology, const void *addr, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags) __hwloc_attribute_deprecated;
static __hwloc_inline int
hwloc_set_area_membind_nodeset(hwloc_topology_t topology, const void *addr, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
{
return hwloc_set_area_membind(topology, addr, len, nodeset, policy, flags | HWLOC_MEMBIND_BYNODESET);
}
/** \brief Query the physical NUMA node(s) and binding policy of the memory
* identified by (\p addr, \p len ).
*/
static __hwloc_inline int
hwloc_get_area_membind_nodeset(hwloc_topology_t topology, const void *addr, size_t len, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags) __hwloc_attribute_deprecated;
static __hwloc_inline int
hwloc_get_area_membind_nodeset(hwloc_topology_t topology, const void *addr, size_t len, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags)
{
return hwloc_get_area_membind(topology, addr, len, nodeset, policy, flags | HWLOC_MEMBIND_BYNODESET);
}
/** \brief Allocate some memory on the given physical nodeset \p nodeset
*/
static __hwloc_inline void *
hwloc_alloc_membind_nodeset(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags) __hwloc_attribute_malloc __hwloc_attribute_deprecated;
static __hwloc_inline void *
hwloc_alloc_membind_nodeset(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
{
return hwloc_alloc_membind(topology, len, nodeset, policy, flags | HWLOC_MEMBIND_BYNODESET);
}
/** \brief Allocate some memory on the given nodeset \p nodeset.
*/
static __hwloc_inline void *
hwloc_alloc_membind_policy_nodeset(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags) __hwloc_attribute_malloc __hwloc_attribute_deprecated;
static __hwloc_inline void *
hwloc_alloc_membind_policy_nodeset(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
{
return hwloc_alloc_membind_policy(topology, len, nodeset, policy, flags | HWLOC_MEMBIND_BYNODESET);
}
/** \brief Convert a CPU set into a NUMA node set and handle non-NUMA cases
*/
static __hwloc_inline void
hwloc_cpuset_to_nodeset_strict(hwloc_topology_t topology, hwloc_const_cpuset_t _cpuset, hwloc_nodeset_t nodeset) __hwloc_attribute_deprecated;
static __hwloc_inline void
hwloc_cpuset_to_nodeset_strict(hwloc_topology_t topology, hwloc_const_cpuset_t _cpuset, hwloc_nodeset_t nodeset)
{
hwloc_cpuset_to_nodeset(topology, _cpuset, nodeset);
}
/** \brief Convert a NUMA node set into a CPU set and handle non-NUMA cases
*/
static __hwloc_inline void
hwloc_cpuset_from_nodeset_strict(hwloc_topology_t topology, hwloc_cpuset_t _cpuset, hwloc_const_nodeset_t nodeset) __hwloc_attribute_deprecated;
static __hwloc_inline void
hwloc_cpuset_from_nodeset_strict(hwloc_topology_t topology, hwloc_cpuset_t _cpuset, hwloc_const_nodeset_t nodeset)
{
hwloc_cpuset_from_nodeset(topology, _cpuset, nodeset);
}
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_DEPRECATED_H */

View file

@ -1,289 +0,0 @@
/*
* Copyright © 2013-2020 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
/** \file
* \brief Topology differences.
*/
#ifndef HWLOC_DIFF_H
#define HWLOC_DIFF_H
#ifndef HWLOC_H
#error Please include the main hwloc.h instead
#endif
#ifdef __cplusplus
extern "C" {
#elif 0
}
#endif
/** \defgroup hwlocality_diff Topology differences
*
* Applications that manipulate many similar topologies, for instance
* one for each node of a homogeneous cluster, may want to compress
* topologies to reduce the memory footprint.
*
* This file offers a way to manipulate the difference between topologies
* and export/import it to/from XML.
* Compression may therefore be achieved by storing one topology
* entirely while the others are only described by their differences
* with the former.
* The actual topology can be reconstructed when actually needed by
* applying the precomputed difference to the reference topology.
*
* This interface targets very similar nodes.
* Only very simple differences between topologies are actually
* supported, for instance a change in the memory size, the name
* of the object, or some info attribute.
* More complex differences such as adding or removing objects cannot
* be represented in the difference structures and therefore return
* errors.
* Differences between object sets or topology-wide allowed sets,
* cannot be represented either.
*
* It means that there is no need to apply the difference when
* looking at the tree organization (how many levels, how many
* objects per level, what kind of objects, CPU and node sets, etc)
* and when binding to objects.
* However the difference must be applied when looking at object
* attributes such as the name, the memory size or info attributes.
*
* @{
*/
/** \brief Type of one object attribute difference.
*/
typedef enum hwloc_topology_diff_obj_attr_type_e {
/** \brief The object local memory is modified.
* The union is a hwloc_topology_diff_obj_attr_u::hwloc_topology_diff_obj_attr_uint64_s
* (and the index field is ignored).
*/
HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_SIZE,
/** \brief The object name is modified.
* The union is a hwloc_topology_diff_obj_attr_u::hwloc_topology_diff_obj_attr_string_s
* (and the name field is ignored).
*/
HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_NAME,
/** \brief the value of an info attribute is modified.
* The union is a hwloc_topology_diff_obj_attr_u::hwloc_topology_diff_obj_attr_string_s.
*/
HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_INFO
} hwloc_topology_diff_obj_attr_type_t;
/** \brief One object attribute difference.
*/
union hwloc_topology_diff_obj_attr_u {
struct hwloc_topology_diff_obj_attr_generic_s {
/* each part of the union must start with these */
hwloc_topology_diff_obj_attr_type_t type;
} generic;
/** \brief Integer attribute modification with an optional index. */
struct hwloc_topology_diff_obj_attr_uint64_s {
/* used for storing integer attributes */
hwloc_topology_diff_obj_attr_type_t type;
hwloc_uint64_t index; /* not used for SIZE */
hwloc_uint64_t oldvalue;
hwloc_uint64_t newvalue;
} uint64;
/** \brief String attribute modification with an optional name */
struct hwloc_topology_diff_obj_attr_string_s {
/* used for storing name and info pairs */
hwloc_topology_diff_obj_attr_type_t type;
char *name; /* not used for NAME */
char *oldvalue;
char *newvalue;
} string;
};
/** \brief Type of one element of a difference list.
*/
typedef enum hwloc_topology_diff_type_e {
/** \brief An object attribute was changed.
* The union is a hwloc_topology_diff_u::hwloc_topology_diff_obj_attr_s.
*/
HWLOC_TOPOLOGY_DIFF_OBJ_ATTR,
/** \brief The difference is too complex,
* it cannot be represented. The difference below
* this object has not been checked.
* hwloc_topology_diff_build() will return 1.
*
* The union is a hwloc_topology_diff_u::hwloc_topology_diff_too_complex_s.
*/
HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX
} hwloc_topology_diff_type_t;
/** \brief One element of a difference list between two topologies.
*/
typedef union hwloc_topology_diff_u {
struct hwloc_topology_diff_generic_s {
/* each part of the union must start with these */
hwloc_topology_diff_type_t type;
union hwloc_topology_diff_u * next; /* pointer to the next element of the list, or NULL */
} generic;
/* A difference in an object attribute. */
struct hwloc_topology_diff_obj_attr_s {
hwloc_topology_diff_type_t type; /* must be ::HWLOC_TOPOLOGY_DIFF_OBJ_ATTR */
union hwloc_topology_diff_u * next;
/* List of attribute differences for a single object */
int obj_depth;
unsigned obj_index;
union hwloc_topology_diff_obj_attr_u diff;
} obj_attr;
/* A difference that is too complex. */
struct hwloc_topology_diff_too_complex_s {
hwloc_topology_diff_type_t type; /* must be ::HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX */
union hwloc_topology_diff_u * next;
/* Where we had to stop computing the diff in the first topology */
int obj_depth;
unsigned obj_index;
} too_complex;
} * hwloc_topology_diff_t;
/** \brief Compute the difference between 2 topologies.
*
* The difference is stored as a list of ::hwloc_topology_diff_t entries
* starting at \p diff.
* It is computed by doing a depth-first traversal of both topology trees
* simultaneously.
*
* If the difference between 2 objects is too complex to be represented
* (for instance if some objects have different types, or different numbers
* of children), a special diff entry of type ::HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX
* is queued.
* The computation of the diff does not continue below these objects.
* So each such diff entry means that the difference between two subtrees
* could not be computed.
*
* \return 0 if the difference can be represented properly.
*
* \return 0 with \p diff pointing to NULL if there is no difference
* between the topologies.
*
* \return 1 if the difference is too complex (see above). Some entries in
* the list will be of type ::HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX.
*
* \return -1 on any other error.
*
* \note \p flags is currently not used. It should be 0.
*
* \note The output diff has to be freed with hwloc_topology_diff_destroy().
*
* \note The output diff can only be exported to XML or passed to
* hwloc_topology_diff_apply() if 0 was returned, i.e. if no entry of type
* ::HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX is listed.
*
* \note The output diff may be modified by removing some entries from
* the list. The removed entries should be freed by passing them to
* to hwloc_topology_diff_destroy() (possible as another list).
*/
HWLOC_DECLSPEC int hwloc_topology_diff_build(hwloc_topology_t topology, hwloc_topology_t newtopology, unsigned long flags, hwloc_topology_diff_t *diff);
/** \brief Flags to be given to hwloc_topology_diff_apply().
*/
enum hwloc_topology_diff_apply_flags_e {
/** \brief Apply topology diff in reverse direction.
* \hideinitializer
*/
HWLOC_TOPOLOGY_DIFF_APPLY_REVERSE = (1UL<<0)
};
/** \brief Apply a topology diff to an existing topology.
*
* \p flags is an OR'ed set of ::hwloc_topology_diff_apply_flags_e.
*
* The new topology is modified in place. hwloc_topology_dup()
* may be used to duplicate it before patching.
*
* If the difference cannot be applied entirely, all previous applied
* elements are unapplied before returning.
*
* \return 0 on success.
*
* \return -N if applying the difference failed while trying
* to apply the N-th part of the difference. For instance -1
* is returned if the very first difference element could not
* be applied.
*/
HWLOC_DECLSPEC int hwloc_topology_diff_apply(hwloc_topology_t topology, hwloc_topology_diff_t diff, unsigned long flags);
/** \brief Destroy a list of topology differences.
*/
HWLOC_DECLSPEC int hwloc_topology_diff_destroy(hwloc_topology_diff_t diff);
/** \brief Load a list of topology differences from a XML file.
*
* If not \c NULL, \p refname will be filled with the identifier
* string of the reference topology for the difference file,
* if any was specified in the XML file.
* This identifier is usually the name of the other XML file
* that contains the reference topology.
*
* \note the pointer returned in refname should later be freed
* by the caller.
*/
HWLOC_DECLSPEC int hwloc_topology_diff_load_xml(const char *xmlpath, hwloc_topology_diff_t *diff, char **refname);
/** \brief Export a list of topology differences to a XML file.
*
* If not \c NULL, \p refname defines an identifier string
* for the reference topology which was used as a base when
* computing this difference.
* This identifier is usually the name of the other XML file
* that contains the reference topology.
* This attribute is given back when reading the diff from XML.
*/
HWLOC_DECLSPEC int hwloc_topology_diff_export_xml(hwloc_topology_diff_t diff, const char *refname, const char *xmlpath);
/** \brief Load a list of topology differences from a XML buffer.
*
* If not \c NULL, \p refname will be filled with the identifier
* string of the reference topology for the difference file,
* if any was specified in the XML file.
* This identifier is usually the name of the other XML file
* that contains the reference topology.
*
* \note the pointer returned in refname should later be freed
* by the caller.
*/
HWLOC_DECLSPEC int hwloc_topology_diff_load_xmlbuffer(const char *xmlbuffer, int buflen, hwloc_topology_diff_t *diff, char **refname);
/** \brief Export a list of topology differences to a XML buffer.
*
* If not \c NULL, \p refname defines an identifier string
* for the reference topology which was used as a base when
* computing this difference.
* This identifier is usually the name of the other XML file
* that contains the reference topology.
* This attribute is given back when reading the diff from XML.
*
* The returned buffer ends with a \0 that is included in the returned
* length.
*
* \note The XML buffer should later be freed with hwloc_free_xmlbuffer().
*/
HWLOC_DECLSPEC int hwloc_topology_diff_export_xmlbuffer(hwloc_topology_diff_t diff, const char *refname, char **xmlbuffer, int *buflen);
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_DIFF_H */

View file

@ -1,471 +0,0 @@
/*
* Copyright © 2010-2021 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
/** \file
* \brief Object distances.
*/
#ifndef HWLOC_DISTANCES_H
#define HWLOC_DISTANCES_H
#ifndef HWLOC_H
#error Please include the main hwloc.h instead
#endif
#ifdef __cplusplus
extern "C" {
#elif 0
}
#endif
/** \defgroup hwlocality_distances_get Retrieve distances between objects
* @{
*/
/** \brief Matrix of distances between a set of objects.
*
* This matrix often contains latencies between NUMA nodes
* (as reported in the System Locality Distance Information Table (SLIT)
* in the ACPI specification), which may or may not be physically accurate.
* It corresponds to the latency for accessing the memory of one node
* from a core in another node.
* The corresponding kind is ::HWLOC_DISTANCES_KIND_FROM_OS | ::HWLOC_DISTANCES_KIND_FROM_USER.
* The name of this distances structure is "NUMALatency".
* Others distance structures include and "XGMIBandwidth", "XGMIHops"
* and "NVLinkBandwidth".
*
* The matrix may also contain bandwidths between random sets of objects,
* possibly provided by the user, as specified in the \p kind attribute.
*
* Pointers \p objs and \p values should not be replaced, reallocated, freed, etc.
* However callers are allowed to modify \p kind as well as the contents
* of \p objs and \p values arrays.
* For instance, if there is a single NUMA node per Package,
* hwloc_get_obj_with_same_locality() may be used to convert between them
* and replace NUMA nodes in the \p objs array with the corresponding Packages.
* See also hwloc_distances_transform() for applying some transformations
* to the structure.
*/
struct hwloc_distances_s {
unsigned nbobjs; /**< \brief Number of objects described by the distance matrix. */
hwloc_obj_t *objs; /**< \brief Array of objects described by the distance matrix.
* These objects are not in any particular order,
* see hwloc_distances_obj_index() and hwloc_distances_obj_pair_values()
* for easy ways to find objects in this array and their corresponding values.
*/
unsigned long kind; /**< \brief OR'ed set of ::hwloc_distances_kind_e. */
hwloc_uint64_t *values; /**< \brief Matrix of distances between objects, stored as a one-dimension array.
*
* Distance from i-th to j-th object is stored in slot i*nbobjs+j.
* The meaning of the value depends on the \p kind attribute.
*/
};
/** \brief Kinds of distance matrices.
*
* The \p kind attribute of struct hwloc_distances_s is a OR'ed set
* of kinds.
*
* A kind of format HWLOC_DISTANCES_KIND_FROM_* specifies where the
* distance information comes from, if known.
*
* A kind of format HWLOC_DISTANCES_KIND_MEANS_* specifies whether
* values are latencies or bandwidths, if applicable.
*/
enum hwloc_distances_kind_e {
/** \brief These distances were obtained from the operating system or hardware.
* \hideinitializer
*/
HWLOC_DISTANCES_KIND_FROM_OS = (1UL<<0),
/** \brief These distances were provided by the user.
* \hideinitializer
*/
HWLOC_DISTANCES_KIND_FROM_USER = (1UL<<1),
/** \brief Distance values are similar to latencies between objects.
* Values are smaller for closer objects, hence minimal on the diagonal
* of the matrix (distance between an object and itself).
* It could also be the number of network hops between objects, etc.
* \hideinitializer
*/
HWLOC_DISTANCES_KIND_MEANS_LATENCY = (1UL<<2),
/** \brief Distance values are similar to bandwidths between objects.
* Values are higher for closer objects, hence maximal on the diagonal
* of the matrix (distance between an object and itself).
* Such values are currently ignored for distance-based grouping.
* \hideinitializer
*/
HWLOC_DISTANCES_KIND_MEANS_BANDWIDTH = (1UL<<3),
/** \brief This distances structure covers objects of different types.
* This may apply to the "NVLinkBandwidth" structure in presence
* of a NVSwitch or POWER processor NVLink port.
* \hideinitializer
*/
HWLOC_DISTANCES_KIND_HETEROGENEOUS_TYPES = (1UL<<4)
};
/** \brief Retrieve distance matrices.
*
* Retrieve distance matrices from the topology into the \p distances array.
*
* \p flags is currently unused, should be \c 0.
*
* \p kind serves as a filter. If \c 0, all distance matrices are returned.
* If it contains some HWLOC_DISTANCES_KIND_FROM_*, only distance matrices
* whose kind matches one of these are returned.
* If it contains some HWLOC_DISTANCES_KIND_MEANS_*, only distance matrices
* whose kind matches one of these are returned.
*
* On input, \p nr points to the number of distance matrices that may be stored
* in \p distances.
* On output, \p nr points to the number of distance matrices that were actually
* found, even if some of them couldn't be stored in \p distances.
* Distance matrices that couldn't be stored are ignored, but the function still
* returns success (\c 0). The caller may find out by comparing the value pointed
* by \p nr before and after the function call.
*
* Each distance matrix returned in the \p distances array should be released
* by the caller using hwloc_distances_release().
*/
HWLOC_DECLSPEC int
hwloc_distances_get(hwloc_topology_t topology,
unsigned *nr, struct hwloc_distances_s **distances,
unsigned long kind, unsigned long flags);
/** \brief Retrieve distance matrices for object at a specific depth in the topology.
*
* Identical to hwloc_distances_get() with the additional \p depth filter.
*/
HWLOC_DECLSPEC int
hwloc_distances_get_by_depth(hwloc_topology_t topology, int depth,
unsigned *nr, struct hwloc_distances_s **distances,
unsigned long kind, unsigned long flags);
/** \brief Retrieve distance matrices for object of a specific type.
*
* Identical to hwloc_distances_get() with the additional \p type filter.
*/
HWLOC_DECLSPEC int
hwloc_distances_get_by_type(hwloc_topology_t topology, hwloc_obj_type_t type,
unsigned *nr, struct hwloc_distances_s **distances,
unsigned long kind, unsigned long flags);
/** \brief Retrieve a distance matrix with the given name.
*
* Usually only one distances structure may match a given name.
*
* The name of the most common structure is "NUMALatency".
* Others include "XGMIBandwidth", "XGMIHops" and "NVLinkBandwidth".
*/
HWLOC_DECLSPEC int
hwloc_distances_get_by_name(hwloc_topology_t topology, const char *name,
unsigned *nr, struct hwloc_distances_s **distances,
unsigned long flags);
/** \brief Get a description of what a distances structure contains.
*
* For instance "NUMALatency" for hardware-provided NUMA distances (ACPI SLIT),
* or NULL if unknown.
*/
HWLOC_DECLSPEC const char *
hwloc_distances_get_name(hwloc_topology_t topology, struct hwloc_distances_s *distances);
/** \brief Release a distance matrix structure previously returned by hwloc_distances_get().
*
* \note This function is not required if the structure is removed with hwloc_distances_release_remove().
*/
HWLOC_DECLSPEC void
hwloc_distances_release(hwloc_topology_t topology, struct hwloc_distances_s *distances);
/** \brief Transformations of distances structures. */
enum hwloc_distances_transform_e {
/** \brief Remove \c NULL objects from the distances structure.
*
* Every object that was replaced with \c NULL in the \p objs array
* is removed and the \p values array is updated accordingly.
*
* At least \c 2 objects must remain, otherwise hwloc_distances_transform()
* will return \c -1 with \p errno set to \c EINVAL.
*
* \p kind will be updated with or without ::HWLOC_DISTANCES_KIND_HETEROGENEOUS_TYPES
* according to the remaining objects.
*
* \hideinitializer
*/
HWLOC_DISTANCES_TRANSFORM_REMOVE_NULL = 0,
/** \brief Replace bandwidth values with a number of links.
*
* Usually all values will be either \c 0 (no link) or \c 1 (one link).
* However some matrices could get larger values if some pairs of
* peers are connected by different numbers of links.
*
* Values on the diagonal are set to \c 0.
*
* This transformation only applies to bandwidth matrices.
*
* \hideinitializer
*/
HWLOC_DISTANCES_TRANSFORM_LINKS = 1,
/** \brief Merge switches with multiple ports into a single object.
* This currently only applies to NVSwitches where GPUs seem connected to different
* separate switch ports in the NVLinkBandwidth matrix. This transformation will
* replace all of them with the same port connected to all GPUs.
* Other ports are removed by applying ::HWLOC_DISTANCES_TRANSFORM_REMOVE_NULL internally.
* \hideinitializer
*/
HWLOC_DISTANCES_TRANSFORM_MERGE_SWITCH_PORTS = 2,
/** \brief Apply a transitive closure to the matrix to connect objects across switches.
* This currently only applies to GPUs and NVSwitches in the NVLinkBandwidth matrix.
* All pairs of GPUs will be reported as directly connected.
* \hideinitializer
*/
HWLOC_DISTANCES_TRANSFORM_TRANSITIVE_CLOSURE = 3
};
/** \brief Apply a transformation to a distances structure.
*
* Modify a distances structure that was previously obtained with
* hwloc_distances_get() or one of its variants.
*
* This modifies the local copy of the distances structures but does
* not modify the distances information stored inside the topology
* (retrieved by another call to hwloc_distances_get() or exported to XML).
* To do so, one should add a new distances structure with same
* name, kind, objects and values (see \ref hwlocality_distances_add)
* and then remove this old one with hwloc_distances_release_remove().
*
* \p transform must be one of the transformations listed
* in ::hwloc_distances_transform_e.
*
* These transformations may modify the contents of the \p objs or \p values arrays.
*
* \p transform_attr must be \c NULL for now.
*
* \p flags must be \c 0 for now.
*
* \note Objects in distances array \p objs may be directly modified
* in place without using hwloc_distances_transform().
* One may use hwloc_get_obj_with_same_locality() to easily convert
* between similar objects of different types.
*/
HWLOC_DECLSPEC int hwloc_distances_transform(hwloc_topology_t topology, struct hwloc_distances_s *distances,
enum hwloc_distances_transform_e transform,
void *transform_attr,
unsigned long flags);
/** @} */
/** \defgroup hwlocality_distances_consult Helpers for consulting distance matrices
* @{
*/
/** \brief Find the index of an object in a distances structure.
*
* \return -1 if object \p obj is not involved in structure \p distances.
*/
static __hwloc_inline int
hwloc_distances_obj_index(struct hwloc_distances_s *distances, hwloc_obj_t obj)
{
unsigned i;
for(i=0; i<distances->nbobjs; i++)
if (distances->objs[i] == obj)
return (int)i;
return -1;
}
/** \brief Find the values between two objects in a distance matrices.
*
* The distance from \p obj1 to \p obj2 is stored in the value pointed by
* \p value1to2 and reciprocally.
*
* \return -1 if object \p obj1 or \p obj2 is not involved in structure \p distances.
*/
static __hwloc_inline int
hwloc_distances_obj_pair_values(struct hwloc_distances_s *distances,
hwloc_obj_t obj1, hwloc_obj_t obj2,
hwloc_uint64_t *value1to2, hwloc_uint64_t *value2to1)
{
int i1 = hwloc_distances_obj_index(distances, obj1);
int i2 = hwloc_distances_obj_index(distances, obj2);
if (i1 < 0 || i2 < 0)
return -1;
*value1to2 = distances->values[i1 * distances->nbobjs + i2];
*value2to1 = distances->values[i2 * distances->nbobjs + i1];
return 0;
}
/** @} */
/** \defgroup hwlocality_distances_add Add distances between objects
*
* The usual way to add distances is:
* \code
* hwloc_distances_add_handle_t handle;
* int err = -1;
* handle = hwloc_distances_add_create(topology, "name", kind, 0);
* if (handle) {
* err = hwloc_distances_add_values(topology, handle, nbobjs, objs, values, 0);
* if (!err)
* err = hwloc_distances_add_commit(topology, handle, flags);
* }
* \endcode
* If \p err is \c 0 at the end, then addition was successful.
*
* @{
*/
/** \brief Handle to a new distances structure during its addition to the topology. */
typedef void * hwloc_distances_add_handle_t;
/** \brief Create a new empty distances structure.
*
* Create an empty distances structure
* to be filled with hwloc_distances_add_values()
* and then committed with hwloc_distances_add_commit().
*
* Parameter \p name is optional, it may be \c NULL.
* Otherwise, it will be copied internally and may later be freed by the caller.
*
* \p kind specifies the kind of distance as a OR'ed set of ::hwloc_distances_kind_e.
* Kind ::HWLOC_DISTANCES_KIND_HETEROGENEOUS_TYPES will be automatically set
* according to objects having different types in hwloc_distances_add_values().
*
* \p flags must be \c 0 for now.
*
* \return A hwloc_distances_add_handle_t that should then be passed
* to hwloc_distances_add_values() and hwloc_distances_add_commit().
*
* \return \c NULL on error.
*/
HWLOC_DECLSPEC hwloc_distances_add_handle_t
hwloc_distances_add_create(hwloc_topology_t topology,
const char *name, unsigned long kind,
unsigned long flags);
/** \brief Specify the objects and values in a new empty distances structure.
*
* Specify the objects and values for a new distances structure
* that was returned as a handle by hwloc_distances_add_create().
* The structure must then be committed with hwloc_distances_add_commit().
*
* The number of objects is \p nbobjs and the array of objects is \p objs.
* Distance values are stored as a one-dimension array in \p values.
* The distance from object i to object j is in slot i*nbobjs+j.
*
* \p nbobjs must be at least 2.
*
* Arrays \p objs and \p values will be copied internally,
* they may later be freed by the caller.
*
* On error, the temporary distances structure and its content are destroyed.
*
* \p flags must be \c 0 for now.
*
* \return \c 0 on success.
* \return \c -1 on error.
*/
HWLOC_DECLSPEC int hwloc_distances_add_values(hwloc_topology_t topology,
hwloc_distances_add_handle_t handle,
unsigned nbobjs, hwloc_obj_t *objs,
hwloc_uint64_t *values,
unsigned long flags);
/** \brief Flags for adding a new distances to a topology. */
enum hwloc_distances_add_flag_e {
/** \brief Try to group objects based on the newly provided distance information.
* This is ignored for distances between objects of different types.
* \hideinitializer
*/
HWLOC_DISTANCES_ADD_FLAG_GROUP = (1UL<<0),
/** \brief If grouping, consider the distance values as inaccurate and relax the
* comparisons during the grouping algorithms. The actual accuracy may be modified
* through the HWLOC_GROUPING_ACCURACY environment variable (see \ref envvar).
* \hideinitializer
*/
HWLOC_DISTANCES_ADD_FLAG_GROUP_INACCURATE = (1UL<<1)
};
/** \brief Commit a new distances structure.
*
* This function finalizes the distances structure and inserts in it the topology.
*
* Parameter \p handle was previously returned by hwloc_distances_add_create().
* Then objects and values were specified with hwloc_distances_add_values().
*
* \p flags configures the behavior of the function using an optional OR'ed set of
* ::hwloc_distances_add_flag_e.
* It may be used to request the grouping of existing objects based on distances.
*
* On error, the temporary distances structure and its content are destroyed.
*
* \return \c 0 on success.
* \return \c -1 on error.
*/
HWLOC_DECLSPEC int hwloc_distances_add_commit(hwloc_topology_t topology,
hwloc_distances_add_handle_t handle,
unsigned long flags);
/** @} */
/** \defgroup hwlocality_distances_remove Remove distances between objects
* @{
*/
/** \brief Remove all distance matrices from a topology.
*
* Remove all distance matrices, either provided by the user or
* gathered through the OS.
*
* If these distances were used to group objects, these additional
* Group objects are not removed from the topology.
*/
HWLOC_DECLSPEC int hwloc_distances_remove(hwloc_topology_t topology);
/** \brief Remove distance matrices for objects at a specific depth in the topology.
*
* Identical to hwloc_distances_remove() but only applies to one level of the topology.
*/
HWLOC_DECLSPEC int hwloc_distances_remove_by_depth(hwloc_topology_t topology, int depth);
/** \brief Remove distance matrices for objects of a specific type in the topology.
*
* Identical to hwloc_distances_remove() but only applies to one level of the topology.
*/
static __hwloc_inline int
hwloc_distances_remove_by_type(hwloc_topology_t topology, hwloc_obj_type_t type)
{
int depth = hwloc_get_type_depth(topology, type);
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
return 0;
return hwloc_distances_remove_by_depth(topology, depth);
}
/** \brief Release and remove the given distance matrice from the topology.
*
* This function includes a call to hwloc_distances_release().
*/
HWLOC_DECLSPEC int hwloc_distances_release_remove(hwloc_topology_t topology, struct hwloc_distances_s *distances);
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_DISTANCES_H */

View file

@ -1,278 +0,0 @@
/*
* Copyright © 2009-2018 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
/** \file
* \brief Exporting Topologies to XML or to Synthetic strings.
*/
#ifndef HWLOC_EXPORT_H
#define HWLOC_EXPORT_H
#ifndef HWLOC_H
#error Please include the main hwloc.h instead
#endif
#ifdef __cplusplus
extern "C" {
#elif 0
}
#endif
/** \defgroup hwlocality_xmlexport Exporting Topologies to XML
* @{
*/
/** \brief Flags for exporting XML topologies.
*
* Flags to be given as a OR'ed set to hwloc_topology_export_xml().
*/
enum hwloc_topology_export_xml_flags_e {
/** \brief Export XML that is loadable by hwloc v1.x.
* However, the export may miss some details about the topology.
* \hideinitializer
*/
HWLOC_TOPOLOGY_EXPORT_XML_FLAG_V1 = (1UL<<0)
};
/** \brief Export the topology into an XML file.
*
* This file may be loaded later through hwloc_topology_set_xml().
*
* By default, the latest export format is used, which means older hwloc
* releases (e.g. v1.x) will not be able to import it.
* Exporting to v1.x specific XML format is possible using flag
* ::HWLOC_TOPOLOGY_EXPORT_XML_FLAG_V1 but it may miss some details
* about the topology.
* If there is any chance that the exported file may ever be imported
* back by a process using hwloc 1.x, one should consider detecting
* it at runtime and using the corresponding export format.
*
* \p flags is a OR'ed set of ::hwloc_topology_export_xml_flags_e.
*
* \return -1 if a failure occured.
*
* \note See also hwloc_topology_set_userdata_export_callback()
* for exporting application-specific object userdata.
*
* \note The topology-specific userdata pointer is ignored when exporting to XML.
*
* \note Only printable characters may be exported to XML string attributes.
* Any other character, especially any non-ASCII character, will be silently
* dropped.
*
* \note If \p name is "-", the XML output is sent to the standard output.
*/
HWLOC_DECLSPEC int hwloc_topology_export_xml(hwloc_topology_t topology, const char *xmlpath, unsigned long flags);
/** \brief Export the topology into a newly-allocated XML memory buffer.
*
* \p xmlbuffer is allocated by the callee and should be freed with
* hwloc_free_xmlbuffer() later in the caller.
*
* This memory buffer may be loaded later through hwloc_topology_set_xmlbuffer().
*
* By default, the latest export format is used, which means older hwloc
* releases (e.g. v1.x) will not be able to import it.
* Exporting to v1.x specific XML format is possible using flag
* ::HWLOC_TOPOLOGY_EXPORT_XML_FLAG_V1 but it may miss some details
* about the topology.
* If there is any chance that the exported buffer may ever be imported
* back by a process using hwloc 1.x, one should consider detecting
* it at runtime and using the corresponding export format.
*
* The returned buffer ends with a \0 that is included in the returned
* length.
*
* \p flags is a OR'ed set of ::hwloc_topology_export_xml_flags_e.
*
* \return -1 if a failure occured.
*
* \note See also hwloc_topology_set_userdata_export_callback()
* for exporting application-specific object userdata.
*
* \note The topology-specific userdata pointer is ignored when exporting to XML.
*
* \note Only printable characters may be exported to XML string attributes.
* Any other character, especially any non-ASCII character, will be silently
* dropped.
*/
HWLOC_DECLSPEC int hwloc_topology_export_xmlbuffer(hwloc_topology_t topology, char **xmlbuffer, int *buflen, unsigned long flags);
/** \brief Free a buffer allocated by hwloc_topology_export_xmlbuffer() */
HWLOC_DECLSPEC void hwloc_free_xmlbuffer(hwloc_topology_t topology, char *xmlbuffer);
/** \brief Set the application-specific callback for exporting object userdata
*
* The object userdata pointer is not exported to XML by default because hwloc
* does not know what it contains.
*
* This function lets applications set \p export_cb to a callback function
* that converts this opaque userdata into an exportable string.
*
* \p export_cb is invoked during XML export for each object whose
* \p userdata pointer is not \c NULL.
* The callback should use hwloc_export_obj_userdata() or
* hwloc_export_obj_userdata_base64() to actually export
* something to XML (possibly multiple times per object).
*
* \p export_cb may be set to \c NULL if userdata should not be exported to XML.
*
* \note The topology-specific userdata pointer is ignored when exporting to XML.
*/
HWLOC_DECLSPEC void hwloc_topology_set_userdata_export_callback(hwloc_topology_t topology,
void (*export_cb)(void *reserved, hwloc_topology_t topology, hwloc_obj_t obj));
/** \brief Export some object userdata to XML
*
* This function may only be called from within the export() callback passed
* to hwloc_topology_set_userdata_export_callback().
* It may be invoked one of multiple times to export some userdata to XML.
* The \p buffer content of length \p length is stored with optional name
* \p name.
*
* When importing this XML file, the import() callback (if set) will be
* called exactly as many times as hwloc_export_obj_userdata() was called
* during export(). It will receive the corresponding \p name, \p buffer
* and \p length arguments.
*
* \p reserved, \p topology and \p obj must be the first three parameters
* that were given to the export callback.
*
* Only printable characters may be exported to XML string attributes.
* If a non-printable character is passed in \p name or \p buffer,
* the function returns -1 with errno set to EINVAL.
*
* If exporting binary data, the application should first encode into
* printable characters only (or use hwloc_export_obj_userdata_base64()).
* It should also take care of portability issues if the export may
* be reimported on a different architecture.
*/
HWLOC_DECLSPEC int hwloc_export_obj_userdata(void *reserved, hwloc_topology_t topology, hwloc_obj_t obj, const char *name, const void *buffer, size_t length);
/** \brief Encode and export some object userdata to XML
*
* This function is similar to hwloc_export_obj_userdata() but it encodes
* the input buffer into printable characters before exporting.
* On import, decoding is automatically performed before the data is given
* to the import() callback if any.
*
* This function may only be called from within the export() callback passed
* to hwloc_topology_set_userdata_export_callback().
*
* The function does not take care of portability issues if the export
* may be reimported on a different architecture.
*/
HWLOC_DECLSPEC int hwloc_export_obj_userdata_base64(void *reserved, hwloc_topology_t topology, hwloc_obj_t obj, const char *name, const void *buffer, size_t length);
/** \brief Set the application-specific callback for importing userdata
*
* On XML import, userdata is ignored by default because hwloc does not know
* how to store it in memory.
*
* This function lets applications set \p import_cb to a callback function
* that will get the XML-stored userdata and store it in the object as expected
* by the application.
*
* \p import_cb is called during hwloc_topology_load() as many times as
* hwloc_export_obj_userdata() was called during export. The topology
* is not entirely setup yet. Object attributes are ready to consult,
* but links between objects are not.
*
* \p import_cb may be \c NULL if userdata should be ignored during import.
*
* \note \p buffer contains \p length characters followed by a null byte ('\0').
*
* \note This function should be called before hwloc_topology_load().
*
* \note The topology-specific userdata pointer is ignored when importing from XML.
*/
HWLOC_DECLSPEC void hwloc_topology_set_userdata_import_callback(hwloc_topology_t topology,
void (*import_cb)(hwloc_topology_t topology, hwloc_obj_t obj, const char *name, const void *buffer, size_t length));
/** @} */
/** \defgroup hwlocality_syntheticexport Exporting Topologies to Synthetic
* @{
*/
/** \brief Flags for exporting synthetic topologies.
*
* Flags to be given as a OR'ed set to hwloc_topology_export_synthetic().
*/
enum hwloc_topology_export_synthetic_flags_e {
/** \brief Export extended types such as L2dcache as basic types such as Cache.
*
* This is required if loading the synthetic description with hwloc < 1.9.
* \hideinitializer
*/
HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_EXTENDED_TYPES = (1UL<<0),
/** \brief Do not export level attributes.
*
* Ignore level attributes such as memory/cache sizes or PU indexes.
* This is required if loading the synthetic description with hwloc < 1.10.
* \hideinitializer
*/
HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_ATTRS = (1UL<<1),
/** \brief Export the memory hierarchy as expected in hwloc 1.x.
*
* Instead of attaching memory children to levels, export single NUMA node child
* as normal intermediate levels, when possible.
* This is required if loading the synthetic description with hwloc 1.x.
* However this may fail if some objects have multiple local NUMA nodes.
* \hideinitializer
*/
HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_V1 = (1UL<<2),
/** \brief Do not export memory information.
*
* Only export the actual hierarchy of normal CPU-side objects and ignore
* where memory is attached.
* This is useful for when the hierarchy of CPUs is what really matters,
* but it behaves as if there was a single machine-wide NUMA node.
* \hideinitializer
*/
HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_IGNORE_MEMORY = (1UL<<3)
};
/** \brief Export the topology as a synthetic string.
*
* At most \p buflen characters will be written in \p buffer,
* including the terminating \0.
*
* This exported string may be given back to hwloc_topology_set_synthetic().
*
* \p flags is a OR'ed set of ::hwloc_topology_export_synthetic_flags_e.
*
* \return The number of characters that were written,
* not including the terminating \0.
*
* \return -1 if the topology could not be exported,
* for instance if it is not symmetric.
*
* \note I/O and Misc children are ignored, the synthetic string only
* describes normal children.
*
* \note A 1024-byte buffer should be large enough for exporting
* topologies in the vast majority of cases.
*/
HWLOC_DECLSPEC int hwloc_topology_export_synthetic(hwloc_topology_t topology, char *buffer, size_t buflen, unsigned long flags);
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_EXPORT_H */

View file

@ -1,136 +0,0 @@
/*
* Copyright © 2012 Blue Brain Project, EPFL. All rights reserved.
* Copyright © 2012-2021 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
/** \file
* \brief Macros to help interaction between hwloc and OpenGL displays.
*
* Applications that use both hwloc and OpenGL may want to include
* this file so as to get topology information for OpenGL displays.
*/
#ifndef HWLOC_GL_H
#define HWLOC_GL_H
#include "hwloc.h"
#include <stdio.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup hwlocality_gl Interoperability with OpenGL displays
*
* This interface offers ways to retrieve topology information about
* OpenGL displays.
*
* Only the NVIDIA display locality information is currently available,
* using the NV-CONTROL X11 extension and the NVCtrl library.
*
* @{
*/
/** \brief Get the hwloc OS device object corresponding to the
* OpenGL display given by port and device index.
*
* \return The hwloc OS device object describing the OpenGL display
* whose port (server) is \p port and device (screen) is \p device.
* \return \c NULL if none could be found.
*
* The topology \p topology does not necessarily have to match the current
* machine. For instance the topology may be an XML import of a remote host.
* I/O devices detection and the GL component must be enabled in the topology.
*
* \note The corresponding PCI device object can be obtained by looking
* at the OS device parent object (unless PCI devices are filtered out).
*/
static __hwloc_inline hwloc_obj_t
hwloc_gl_get_display_osdev_by_port_device(hwloc_topology_t topology,
unsigned port, unsigned device)
{
unsigned x = (unsigned) -1, y = (unsigned) -1;
hwloc_obj_t osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
if (HWLOC_OBJ_OSDEV_GPU == osdev->attr->osdev.type
&& osdev->name
&& sscanf(osdev->name, ":%u.%u", &x, &y) == 2
&& port == x && device == y)
return osdev;
}
errno = EINVAL;
return NULL;
}
/** \brief Get the hwloc OS device object corresponding to the
* OpenGL display given by name.
*
* \return The hwloc OS device object describing the OpenGL display
* whose name is \p name, built as ":port.device" such as ":0.0" .
* \return \c NULL if none could be found.
*
* The topology \p topology does not necessarily have to match the current
* machine. For instance the topology may be an XML import of a remote host.
* I/O devices detection and the GL component must be enabled in the topology.
*
* \note The corresponding PCI device object can be obtained by looking
* at the OS device parent object (unless PCI devices are filtered out).
*/
static __hwloc_inline hwloc_obj_t
hwloc_gl_get_display_osdev_by_name(hwloc_topology_t topology,
const char *name)
{
hwloc_obj_t osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
if (HWLOC_OBJ_OSDEV_GPU == osdev->attr->osdev.type
&& osdev->name
&& !strcmp(name, osdev->name))
return osdev;
}
errno = EINVAL;
return NULL;
}
/** \brief Get the OpenGL display port and device corresponding
* to the given hwloc OS object.
*
* Retrieves the OpenGL display port (server) in \p port and device (screen)
* in \p screen that correspond to the given hwloc OS device object.
*
* \return \c -1 if none could be found.
*
* The topology \p topology does not necessarily have to match the current
* machine. For instance the topology may be an XML import of a remote host.
* I/O devices detection and the GL component must be enabled in the topology.
*/
static __hwloc_inline int
hwloc_gl_get_display_by_osdev(hwloc_topology_t topology __hwloc_attribute_unused,
hwloc_obj_t osdev,
unsigned *port, unsigned *device)
{
unsigned x = -1, y = -1;
if (HWLOC_OBJ_OSDEV_GPU == osdev->attr->osdev.type
&& sscanf(osdev->name, ":%u.%u", &x, &y) == 2) {
*port = x;
*device = y;
return 0;
}
errno = EINVAL;
return -1;
}
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_GL_H */

View file

@ -1,126 +0,0 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2020 Inria. All rights reserved.
* Copyright © 2009-2011 Université Bordeaux
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
/** \file
* \brief Macros to help interaction between hwloc and glibc scheduling routines.
*
* Applications that use both hwloc and glibc scheduling routines such as
* sched_getaffinity() or pthread_attr_setaffinity_np() may want to include
* this file so as to ease conversion between their respective types.
*/
#ifndef HWLOC_GLIBC_SCHED_H
#define HWLOC_GLIBC_SCHED_H
#include "hwloc.h"
#include "hwloc/helper.h"
#include <assert.h>
#if !defined _GNU_SOURCE || (!defined _SCHED_H && !defined _SCHED_H_) || (!defined CPU_SETSIZE && !defined sched_priority)
#error Please make sure to include sched.h before including glibc-sched.h, and define _GNU_SOURCE before any inclusion of sched.h
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifdef HWLOC_HAVE_CPU_SET
/** \defgroup hwlocality_glibc_sched Interoperability with glibc sched affinity
*
* This interface offers ways to convert between hwloc cpusets and glibc cpusets
* such as those manipulated by sched_getaffinity() or pthread_attr_setaffinity_np().
*
* \note Topology \p topology must match the current machine.
*
* @{
*/
/** \brief Convert hwloc CPU set \p toposet into glibc sched affinity CPU set \p schedset
*
* This function may be used before calling sched_setaffinity or any other function
* that takes a cpu_set_t as input parameter.
*
* \p schedsetsize should be sizeof(cpu_set_t) unless \p schedset was dynamically allocated with CPU_ALLOC
*/
static __hwloc_inline int
hwloc_cpuset_to_glibc_sched_affinity(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t hwlocset,
cpu_set_t *schedset, size_t schedsetsize)
{
#ifdef CPU_ZERO_S
unsigned cpu;
CPU_ZERO_S(schedsetsize, schedset);
hwloc_bitmap_foreach_begin(cpu, hwlocset)
CPU_SET_S(cpu, schedsetsize, schedset);
hwloc_bitmap_foreach_end();
#else /* !CPU_ZERO_S */
unsigned cpu;
CPU_ZERO(schedset);
assert(schedsetsize == sizeof(cpu_set_t));
hwloc_bitmap_foreach_begin(cpu, hwlocset)
CPU_SET(cpu, schedset);
hwloc_bitmap_foreach_end();
#endif /* !CPU_ZERO_S */
return 0;
}
/** \brief Convert glibc sched affinity CPU set \p schedset into hwloc CPU set
*
* This function may be used before calling sched_setaffinity or any other function
* that takes a cpu_set_t as input parameter.
*
* \p schedsetsize should be sizeof(cpu_set_t) unless \p schedset was dynamically allocated with CPU_ALLOC
*/
static __hwloc_inline int
hwloc_cpuset_from_glibc_sched_affinity(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_cpuset_t hwlocset,
const cpu_set_t *schedset, size_t schedsetsize)
{
int cpu;
#ifdef CPU_ZERO_S
int count;
#endif
hwloc_bitmap_zero(hwlocset);
#ifdef CPU_ZERO_S
count = CPU_COUNT_S(schedsetsize, schedset);
cpu = 0;
while (count) {
if (CPU_ISSET_S(cpu, schedsetsize, schedset)) {
hwloc_bitmap_set(hwlocset, cpu);
count--;
}
cpu++;
}
#else /* !CPU_ZERO_S */
/* sched.h does not support dynamic cpu_set_t (introduced in glibc 2.7),
* assume we have a very old interface without CPU_COUNT (added in 2.6)
*/
assert(schedsetsize == sizeof(cpu_set_t));
for(cpu=0; cpu<CPU_SETSIZE; cpu++)
if (CPU_ISSET(cpu, schedset))
hwloc_bitmap_set(hwlocset, cpu);
#endif /* !CPU_ZERO_S */
return 0;
}
/** @} */
#endif /* CPU_SET */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_GLIBC_SCHED_H */

File diff suppressed because it is too large Load diff

View file

@ -1,146 +0,0 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2018 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux
* Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
/**
* This file contains the inline code of functions declared in hwloc.h
*/
#ifndef HWLOC_INLINES_H
#define HWLOC_INLINES_H
#ifndef HWLOC_H
#error Please include the main hwloc.h instead
#endif
#include <stdlib.h>
#include <errno.h>
#ifdef __cplusplus
extern "C" {
#endif
static __hwloc_inline int
hwloc_get_type_or_below_depth (hwloc_topology_t topology, hwloc_obj_type_t type)
{
int depth = hwloc_get_type_depth(topology, type);
if (depth != HWLOC_TYPE_DEPTH_UNKNOWN)
return depth;
/* find the highest existing level with type order >= */
for(depth = hwloc_get_type_depth(topology, HWLOC_OBJ_PU); ; depth--)
if (hwloc_compare_types(hwloc_get_depth_type(topology, depth), type) < 0)
return depth+1;
/* Shouldn't ever happen, as there is always a Machine level with lower order and known depth. */
/* abort(); */
}
static __hwloc_inline int
hwloc_get_type_or_above_depth (hwloc_topology_t topology, hwloc_obj_type_t type)
{
int depth = hwloc_get_type_depth(topology, type);
if (depth != HWLOC_TYPE_DEPTH_UNKNOWN)
return depth;
/* find the lowest existing level with type order <= */
for(depth = 0; ; depth++)
if (hwloc_compare_types(hwloc_get_depth_type(topology, depth), type) > 0)
return depth-1;
/* Shouldn't ever happen, as there is always a PU level with higher order and known depth. */
/* abort(); */
}
static __hwloc_inline int
hwloc_get_nbobjs_by_type (hwloc_topology_t topology, hwloc_obj_type_t type)
{
int depth = hwloc_get_type_depth(topology, type);
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
return 0;
if (depth == HWLOC_TYPE_DEPTH_MULTIPLE)
return -1; /* FIXME: agregate nbobjs from different levels? */
return (int) hwloc_get_nbobjs_by_depth(topology, depth);
}
static __hwloc_inline hwloc_obj_t
hwloc_get_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type, unsigned idx)
{
int depth = hwloc_get_type_depth(topology, type);
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
return NULL;
if (depth == HWLOC_TYPE_DEPTH_MULTIPLE)
return NULL;
return hwloc_get_obj_by_depth(topology, depth, idx);
}
static __hwloc_inline hwloc_obj_t
hwloc_get_next_obj_by_depth (hwloc_topology_t topology, int depth, hwloc_obj_t prev)
{
if (!prev)
return hwloc_get_obj_by_depth (topology, depth, 0);
if (prev->depth != depth)
return NULL;
return prev->next_cousin;
}
static __hwloc_inline hwloc_obj_t
hwloc_get_next_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type,
hwloc_obj_t prev)
{
int depth = hwloc_get_type_depth(topology, type);
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
return NULL;
return hwloc_get_next_obj_by_depth (topology, depth, prev);
}
static __hwloc_inline hwloc_obj_t
hwloc_get_root_obj (hwloc_topology_t topology)
{
return hwloc_get_obj_by_depth (topology, 0, 0);
}
static __hwloc_inline const char *
hwloc_obj_get_info_by_name(hwloc_obj_t obj, const char *name)
{
unsigned i;
for(i=0; i<obj->infos_count; i++) {
struct hwloc_info_s *info = &obj->infos[i];
if (!strcmp(info->name, name))
return info->value;
}
return NULL;
}
static __hwloc_inline void *
hwloc_alloc_membind_policy(hwloc_topology_t topology, size_t len, hwloc_const_cpuset_t set, hwloc_membind_policy_t policy, int flags)
{
void *p = hwloc_alloc_membind(topology, len, set, policy, flags);
if (p)
return p;
if (hwloc_set_membind(topology, set, policy, flags) < 0)
/* hwloc_set_membind() takes care of ignoring errors if non-STRICT */
return NULL;
p = hwloc_alloc(topology, len);
if (p && policy != HWLOC_MEMBIND_FIRSTTOUCH)
/* Enforce the binding by touching the data */
memset(p, 0, len);
return p;
}
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_INLINES_H */

View file

@ -1,136 +0,0 @@
/*
* Copyright © 2013-2016 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
/** \file
* \brief Macros to help interaction between hwloc and Intel Xeon Phi (MIC).
*
* Applications that use both hwloc and Intel Xeon Phi (MIC) may want to
* include this file so as to get topology information for MIC devices.
*/
#ifndef HWLOC_INTEL_MIC_H
#define HWLOC_INTEL_MIC_H
#include "hwloc.h"
#include "hwloc/autogen/config.h"
#include "hwloc/helper.h"
#ifdef HWLOC_LINUX_SYS
#include "hwloc/linux.h"
#include <dirent.h>
#include <string.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup hwlocality_intel_mic Interoperability with Intel Xeon Phi (MIC)
*
* This interface offers ways to retrieve topology information about
* Intel Xeon Phi (MIC) devices.
*
* @{
*/
/** \brief Get the CPU set of logical processors that are physically
* close to MIC device whose index is \p idx.
*
* Return the CPU set describing the locality of the MIC device whose index is \p idx.
*
* Topology \p topology and device index \p idx must match the local machine.
* I/O devices detection is not needed in the topology.
*
* The function only returns the locality of the device.
* If more information about the device is needed, OS objects should
* be used instead, see hwloc_intel_mic_get_device_osdev_by_index().
*
* This function is currently only implemented in a meaningful way for
* Linux; other systems will simply get a full cpuset.
*/
static __hwloc_inline int
hwloc_intel_mic_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
int idx __hwloc_attribute_unused,
hwloc_cpuset_t set)
{
#ifdef HWLOC_LINUX_SYS
/* If we're on Linux, use the sysfs mechanism to get the local cpus */
#define HWLOC_INTEL_MIC_DEVICE_SYSFS_PATH_MAX 128
char path[HWLOC_INTEL_MIC_DEVICE_SYSFS_PATH_MAX];
DIR *sysdir = NULL;
struct dirent *dirent;
unsigned pcibus, pcidev, pcifunc;
if (!hwloc_topology_is_thissystem(topology)) {
errno = EINVAL;
return -1;
}
sprintf(path, "/sys/class/mic/mic%d", idx);
sysdir = opendir(path);
if (!sysdir)
return -1;
while ((dirent = readdir(sysdir)) != NULL) {
if (sscanf(dirent->d_name, "pci_%02x:%02x.%02x", &pcibus, &pcidev, &pcifunc) == 3) {
sprintf(path, "/sys/class/mic/mic%d/pci_%02x:%02x.%02x/local_cpus", idx, pcibus, pcidev, pcifunc);
if (hwloc_linux_read_path_as_cpumask(path, set) < 0
|| hwloc_bitmap_iszero(set))
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
break;
}
}
closedir(sysdir);
#else
/* Non-Linux systems simply get a full cpuset */
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
#endif
return 0;
}
/** \brief Get the hwloc OS device object corresponding to the
* MIC device for the given index.
*
* Return the OS device object describing the MIC device whose index is \p idx.
* Return NULL if there is none.
*
* The topology \p topology does not necessarily have to match the current
* machine. For instance the topology may be an XML import of a remote host.
* I/O devices detection must be enabled in the topology.
*
* \note The corresponding PCI device object can be obtained by looking
* at the OS device parent object.
*/
static __hwloc_inline hwloc_obj_t
hwloc_intel_mic_get_device_osdev_by_index(hwloc_topology_t topology,
unsigned idx)
{
hwloc_obj_t osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
if (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type
&& osdev->name
&& !strncmp("mic", osdev->name, 3)
&& atoi(osdev->name + 3) == (int) idx)
return osdev;
}
return NULL;
}
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_INTEL_MIC_H */

View file

@ -1,157 +0,0 @@
/*
* Copyright © 2021 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
/** \file
* \brief Macros to help interaction between hwloc and the oneAPI Level Zero interface.
*
* Applications that use both hwloc and Level Zero may want to
* include this file so as to get topology information for L0 devices.
*/
#ifndef HWLOC_LEVELZERO_H
#define HWLOC_LEVELZERO_H
#include "hwloc.h"
#include "hwloc/autogen/config.h"
#include "hwloc/helper.h"
#ifdef HWLOC_LINUX_SYS
#include "hwloc/linux.h"
#endif
#include <level_zero/ze_api.h>
#include <level_zero/zes_api.h>
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup hwlocality_levelzero Interoperability with the oneAPI Level Zero interface.
*
* This interface offers ways to retrieve topology information about
* devices managed by the Level Zero API.
*
* @{
*/
/** \brief Get the CPU set of logical processors that are physically
* close to the Level Zero device \p device
*
* Store in \p set the CPU-set describing the locality of
* the Level Zero device \p device.
*
* Topology \p topology and device \p device must match the local machine.
* The Level Zero must have been initialized with Sysman enabled
* (ZES_ENABLE_SYSMAN=1 in the environment).
* I/O devices detection and the Level Zero component are not needed in the
* topology.
*
* The function only returns the locality of the device.
* If more information about the device is needed, OS objects should
* be used instead, see hwloc_levelzero_get_device_osdev().
*
* This function is currently only implemented in a meaningful way for
* Linux; other systems will simply get a full cpuset.
*/
static __hwloc_inline int
hwloc_levelzero_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
ze_device_handle_t device, hwloc_cpuset_t set)
{
#ifdef HWLOC_LINUX_SYS
/* If we're on Linux, use the sysfs mechanism to get the local cpus */
#define HWLOC_LEVELZERO_DEVICE_SYSFS_PATH_MAX 128
char path[HWLOC_LEVELZERO_DEVICE_SYSFS_PATH_MAX];
zes_pci_properties_t pci;
zes_device_handle_t sdevice = device;
ze_result_t res;
if (!hwloc_topology_is_thissystem(topology)) {
errno = EINVAL;
return -1;
}
res = zesDevicePciGetProperties(sdevice, &pci);
if (res != ZE_RESULT_SUCCESS) {
errno = EINVAL;
return -1;
}
sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/local_cpus",
pci.address.domain, pci.address.bus, pci.address.device, pci.address.function);
if (hwloc_linux_read_path_as_cpumask(path, set) < 0
|| hwloc_bitmap_iszero(set))
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
#else
/* Non-Linux systems simply get a full cpuset */
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
#endif
return 0;
}
/** \brief Get the hwloc OS device object corresponding to Level Zero device
* \p device.
*
* \return The hwloc OS device object that describes the given Level Zero device \p device.
* \return \c NULL if none could be found.
*
* Topology \p topology and device \p dv_ind must match the local machine.
* I/O devices detection and the Level Zero component must be enabled in the
* topology. If not, the locality of the object may still be found using
* hwloc_levelzero_get_device_cpuset().
*
* \note The corresponding hwloc PCI device may be found by looking
* at the result parent pointer (unless PCI devices are filtered out).
*/
static __hwloc_inline hwloc_obj_t
hwloc_levelzero_get_device_osdev(hwloc_topology_t topology, ze_device_handle_t device)
{
zes_device_handle_t sdevice = device;
zes_pci_properties_t pci;
ze_result_t res;
hwloc_obj_t osdev;
if (!hwloc_topology_is_thissystem(topology)) {
errno = EINVAL;
return NULL;
}
res = zesDevicePciGetProperties(sdevice, &pci);
if (res != ZE_RESULT_SUCCESS) {
/* L0 was likely initialized without sysman, don't bother */
errno = EINVAL;
return NULL;
}
osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
hwloc_obj_t pcidev = osdev->parent;
if (strncmp(osdev->name, "ze", 2))
continue;
if (pcidev
&& pcidev->type == HWLOC_OBJ_PCI_DEVICE
&& pcidev->attr->pcidev.domain == pci.address.domain
&& pcidev->attr->pcidev.bus == pci.address.bus
&& pcidev->attr->pcidev.dev == pci.address.device
&& pcidev->attr->pcidev.func == pci.address.function)
return osdev;
/* FIXME: when we'll have serialnumber, try it in case PCI is filtered-out */
}
return NULL;
}
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_LEVELZERO_H */

View file

@ -1,274 +0,0 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2017 Inria. All rights reserved.
* Copyright © 2009-2010, 2012 Université Bordeaux
* See COPYING in top-level directory.
*/
/** \file
* \brief Macros to help interaction between hwloc and Linux libnuma.
*
* Applications that use both Linux libnuma and hwloc may want to
* include this file so as to ease conversion between their respective types.
*/
#ifndef HWLOC_LINUX_LIBNUMA_H
#define HWLOC_LINUX_LIBNUMA_H
#include "hwloc.h"
#include <numa.h>
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup hwlocality_linux_libnuma_ulongs Interoperability with Linux libnuma unsigned long masks
*
* This interface helps converting between Linux libnuma unsigned long masks
* and hwloc cpusets and nodesets.
*
* \note Topology \p topology must match the current machine.
*
* \note The behavior of libnuma is undefined if the kernel is not NUMA-aware.
* (when CONFIG_NUMA is not set in the kernel configuration).
* This helper and libnuma may thus not be strictly compatible in this case,
* which may be detected by checking whether numa_available() returns -1.
*
* @{
*/
/** \brief Convert hwloc CPU set \p cpuset into the array of unsigned long \p mask
*
* \p mask is the array of unsigned long that will be filled.
* \p maxnode contains the maximal node number that may be stored in \p mask.
* \p maxnode will be set to the maximal node number that was found, plus one.
*
* This function may be used before calling set_mempolicy, mbind, migrate_pages
* or any other function that takes an array of unsigned long and a maximal
* node number as input parameter.
*/
static __hwloc_inline int
hwloc_cpuset_to_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset,
unsigned long *mask, unsigned long *maxnode)
{
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
unsigned long outmaxnode = -1;
hwloc_obj_t node = NULL;
/* round-up to the next ulong and clear all bytes */
*maxnode = (*maxnode + 8*sizeof(*mask) - 1) & ~(8*sizeof(*mask) - 1);
memset(mask, 0, *maxnode/8);
while ((node = hwloc_get_next_obj_covering_cpuset_by_depth(topology, cpuset, depth, node)) != NULL) {
if (node->os_index >= *maxnode)
continue;
mask[node->os_index/sizeof(*mask)/8] |= 1UL << (node->os_index % (sizeof(*mask)*8));
if (outmaxnode == (unsigned long) -1 || outmaxnode < node->os_index)
outmaxnode = node->os_index;
}
*maxnode = outmaxnode+1;
return 0;
}
/** \brief Convert hwloc NUMA node set \p nodeset into the array of unsigned long \p mask
*
* \p mask is the array of unsigned long that will be filled.
* \p maxnode contains the maximal node number that may be stored in \p mask.
* \p maxnode will be set to the maximal node number that was found, plus one.
*
* This function may be used before calling set_mempolicy, mbind, migrate_pages
* or any other function that takes an array of unsigned long and a maximal
* node number as input parameter.
*/
static __hwloc_inline int
hwloc_nodeset_to_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset,
unsigned long *mask, unsigned long *maxnode)
{
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
unsigned long outmaxnode = -1;
hwloc_obj_t node = NULL;
/* round-up to the next ulong and clear all bytes */
*maxnode = (*maxnode + 8*sizeof(*mask) - 1) & ~(8*sizeof(*mask) - 1);
memset(mask, 0, *maxnode/8);
while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL) {
if (node->os_index >= *maxnode)
continue;
if (!hwloc_bitmap_isset(nodeset, node->os_index))
continue;
mask[node->os_index/sizeof(*mask)/8] |= 1UL << (node->os_index % (sizeof(*mask)*8));
if (outmaxnode == (unsigned long) -1 || outmaxnode < node->os_index)
outmaxnode = node->os_index;
}
*maxnode = outmaxnode+1;
return 0;
}
/** \brief Convert the array of unsigned long \p mask into hwloc CPU set
*
* \p mask is a array of unsigned long that will be read.
* \p maxnode contains the maximal node number that may be read in \p mask.
*
* This function may be used after calling get_mempolicy or any other function
* that takes an array of unsigned long as output parameter (and possibly
* a maximal node number as input parameter).
*/
static __hwloc_inline int
hwloc_cpuset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_cpuset_t cpuset,
const unsigned long *mask, unsigned long maxnode)
{
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
hwloc_obj_t node = NULL;
hwloc_bitmap_zero(cpuset);
while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)
if (node->os_index < maxnode
&& (mask[node->os_index/sizeof(*mask)/8] & (1UL << (node->os_index % (sizeof(*mask)*8)))))
hwloc_bitmap_or(cpuset, cpuset, node->cpuset);
return 0;
}
/** \brief Convert the array of unsigned long \p mask into hwloc NUMA node set
*
* \p mask is a array of unsigned long that will be read.
* \p maxnode contains the maximal node number that may be read in \p mask.
*
* This function may be used after calling get_mempolicy or any other function
* that takes an array of unsigned long as output parameter (and possibly
* a maximal node number as input parameter).
*/
static __hwloc_inline int
hwloc_nodeset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_nodeset_t nodeset,
const unsigned long *mask, unsigned long maxnode)
{
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
hwloc_obj_t node = NULL;
hwloc_bitmap_zero(nodeset);
while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)
if (node->os_index < maxnode
&& (mask[node->os_index/sizeof(*mask)/8] & (1UL << (node->os_index % (sizeof(*mask)*8)))))
hwloc_bitmap_set(nodeset, node->os_index);
return 0;
}
/** @} */
/** \defgroup hwlocality_linux_libnuma_bitmask Interoperability with Linux libnuma bitmask
*
* This interface helps converting between Linux libnuma bitmasks
* and hwloc cpusets and nodesets.
*
* \note Topology \p topology must match the current machine.
*
* \note The behavior of libnuma is undefined if the kernel is not NUMA-aware.
* (when CONFIG_NUMA is not set in the kernel configuration).
* This helper and libnuma may thus not be strictly compatible in this case,
* which may be detected by checking whether numa_available() returns -1.
*
* @{
*/
/** \brief Convert hwloc CPU set \p cpuset into the returned libnuma bitmask
*
* The returned bitmask should later be freed with numa_bitmask_free.
*
* This function may be used before calling many numa_ functions
* that use a struct bitmask as an input parameter.
*
* \return newly allocated struct bitmask.
*/
static __hwloc_inline struct bitmask *
hwloc_cpuset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset) __hwloc_attribute_malloc;
static __hwloc_inline struct bitmask *
hwloc_cpuset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset)
{
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
hwloc_obj_t node = NULL;
struct bitmask *bitmask = numa_allocate_cpumask();
if (!bitmask)
return NULL;
while ((node = hwloc_get_next_obj_covering_cpuset_by_depth(topology, cpuset, depth, node)) != NULL)
if (node->attr->numanode.local_memory)
numa_bitmask_setbit(bitmask, node->os_index);
return bitmask;
}
/** \brief Convert hwloc NUMA node set \p nodeset into the returned libnuma bitmask
*
* The returned bitmask should later be freed with numa_bitmask_free.
*
* This function may be used before calling many numa_ functions
* that use a struct bitmask as an input parameter.
*
* \return newly allocated struct bitmask.
*/
static __hwloc_inline struct bitmask *
hwloc_nodeset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset) __hwloc_attribute_malloc;
static __hwloc_inline struct bitmask *
hwloc_nodeset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset)
{
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
hwloc_obj_t node = NULL;
struct bitmask *bitmask = numa_allocate_cpumask();
if (!bitmask)
return NULL;
while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)
if (hwloc_bitmap_isset(nodeset, node->os_index) && node->attr->numanode.local_memory)
numa_bitmask_setbit(bitmask, node->os_index);
return bitmask;
}
/** \brief Convert libnuma bitmask \p bitmask into hwloc CPU set \p cpuset
*
* This function may be used after calling many numa_ functions
* that use a struct bitmask as an output parameter.
*/
static __hwloc_inline int
hwloc_cpuset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_cpuset_t cpuset,
const struct bitmask *bitmask)
{
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
hwloc_obj_t node = NULL;
hwloc_bitmap_zero(cpuset);
while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)
if (numa_bitmask_isbitset(bitmask, node->os_index))
hwloc_bitmap_or(cpuset, cpuset, node->cpuset);
return 0;
}
/** \brief Convert libnuma bitmask \p bitmask into hwloc NUMA node set \p nodeset
*
* This function may be used after calling many numa_ functions
* that use a struct bitmask as an output parameter.
*/
static __hwloc_inline int
hwloc_nodeset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_nodeset_t nodeset,
const struct bitmask *bitmask)
{
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
hwloc_obj_t node = NULL;
hwloc_bitmap_zero(nodeset);
while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)
if (numa_bitmask_isbitset(bitmask, node->os_index))
hwloc_bitmap_set(nodeset, node->os_index);
return 0;
}
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_LINUX_NUMA_H */

View file

@ -1,87 +0,0 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2021 Inria. All rights reserved.
* Copyright © 2009-2011 Université Bordeaux
* See COPYING in top-level directory.
*/
/** \file
* \brief Macros to help interaction between hwloc and Linux.
*
* Applications that use hwloc on Linux may want to include this file
* if using some low-level Linux features.
*/
#ifndef HWLOC_LINUX_H
#define HWLOC_LINUX_H
#include "hwloc.h"
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup hwlocality_linux Linux-specific helpers
*
* This includes helpers for manipulating Linux kernel cpumap files, and hwloc
* equivalents of the Linux sched_setaffinity and sched_getaffinity system calls.
*
* @{
*/
/** \brief Bind a thread \p tid on cpus given in cpuset \p set
*
* The behavior is exactly the same as the Linux sched_setaffinity system call,
* but uses a hwloc cpuset.
*
* \note This is equivalent to calling hwloc_set_proc_cpubind() with
* HWLOC_CPUBIND_THREAD as flags.
*/
HWLOC_DECLSPEC int hwloc_linux_set_tid_cpubind(hwloc_topology_t topology, pid_t tid, hwloc_const_cpuset_t set);
/** \brief Get the current binding of thread \p tid
*
* The CPU-set \p set (previously allocated by the caller)
* is filled with the list of PUs which the thread
* was last bound to.
*
* The behavior is exactly the same as the Linux sched_getaffinity system call,
* but uses a hwloc cpuset.
*
* \note This is equivalent to calling hwloc_get_proc_cpubind() with
* ::HWLOC_CPUBIND_THREAD as flags.
*/
HWLOC_DECLSPEC int hwloc_linux_get_tid_cpubind(hwloc_topology_t topology, pid_t tid, hwloc_cpuset_t set);
/** \brief Get the last physical CPU where thread \p tid ran.
*
* The CPU-set \p set (previously allocated by the caller)
* is filled with the PU which the thread last ran on.
*
* \note This is equivalent to calling hwloc_get_proc_last_cpu_location() with
* ::HWLOC_CPUBIND_THREAD as flags.
*/
HWLOC_DECLSPEC int hwloc_linux_get_tid_last_cpu_location(hwloc_topology_t topology, pid_t tid, hwloc_bitmap_t set);
/** \brief Convert a linux kernel cpumask file \p path into a hwloc bitmap \p set.
*
* Might be used when reading CPU set from sysfs attributes such as topology
* and caches for processors, or local_cpus for devices.
*
* \note This function ignores the HWLOC_FSROOT environment variable.
*/
HWLOC_DECLSPEC int hwloc_linux_read_path_as_cpumask(const char *path, hwloc_bitmap_t set);
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_LINUX_H */

View file

@ -1,455 +0,0 @@
/*
* Copyright © 2019-2022 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
/** \file
* \brief Memory node attributes.
*/
#ifndef HWLOC_MEMATTR_H
#define HWLOC_MEMATTR_H
#include "hwloc.h"
#ifdef __cplusplus
extern "C" {
#elif 0
}
#endif
/** \defgroup hwlocality_memattrs Comparing memory node attributes for finding where to allocate on
*
* Platforms with heterogeneous memory require ways to decide whether
* a buffer should be allocated on "fast" memory (such as HBM),
* "normal" memory (DDR) or even "slow" but large-capacity memory
* (non-volatile memory).
* These memory nodes are called "Targets" while the CPU accessing them
* is called the "Initiator". Access performance depends on their
* locality (NUMA platforms) as well as the intrinsic performance
* of the targets (heterogeneous platforms).
*
* The following attributes describe the performance of memory accesses
* from an Initiator to a memory Target, for instance their latency
* or bandwidth.
* Initiators performing these memory accesses are usually some PUs or Cores
* (described as a CPU set).
* Hence a Core may choose where to allocate a memory buffer by comparing
* the attributes of different target memory nodes nearby.
*
* There are also some attributes that are system-wide.
* Their value does not depend on a specific initiator performing
* an access.
* The memory node Capacity is an example of such attribute without
* initiator.
*
* One way to use this API is to start with a cpuset describing the Cores where
* a program is bound. The best target NUMA node for allocating memory in this
* program on these Cores may be obtained by passing this cpuset as an initiator
* to hwloc_memattr_get_best_target() with the relevant memory attribute.
* For instance, if the code is latency limited, use the Latency attribute.
*
* A more flexible approach consists in getting the list of local NUMA nodes
* by passing this cpuset to hwloc_get_local_numanode_objs().
* Attribute values for these nodes, if any, may then be obtained with
* hwloc_memattr_get_value() and manually compared with the desired criteria.
*
* \note The API also supports specific objects as initiator,
* but it is currently not used internally by hwloc.
* Users may for instance use it to provide custom performance
* values for host memory accesses performed by GPUs.
*
* \note The interface actually also accepts targets that are not NUMA nodes.
* @{
*/
/** \brief Memory node attributes. */
enum hwloc_memattr_id_e {
/** \brief "Capacity".
* The capacity is returned in bytes
* (local_memory attribute in objects).
*
* Best capacity nodes are nodes with <b>higher capacity</b>.
*
* No initiator is involved when looking at this attribute.
* The corresponding attribute flags are ::HWLOC_MEMATTR_FLAG_HIGHER_FIRST.
*/
HWLOC_MEMATTR_ID_CAPACITY = 0,
/** \brief "Locality".
* The locality is returned as the number of PUs in that locality
* (e.g. the weight of its cpuset).
*
* Best locality nodes are nodes with <b>smaller locality</b>
* (nodes that are local to very few PUs).
* Poor locality nodes are nodes with larger locality
* (nodes that are local to the entire machine).
*
* No initiator is involved when looking at this attribute.
* The corresponding attribute flags are ::HWLOC_MEMATTR_FLAG_HIGHER_FIRST.
*/
HWLOC_MEMATTR_ID_LOCALITY = 1,
/** \brief "Bandwidth".
* The bandwidth is returned in MiB/s, as seen from the given initiator location.
* Best bandwidth nodes are nodes with <b>higher bandwidth</b>.
* The corresponding attribute flags are ::HWLOC_MEMATTR_FLAG_HIGHER_FIRST
* and ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR.
*/
HWLOC_MEMATTR_ID_BANDWIDTH = 2,
/** \brief "Latency".
* The latency is returned as nanoseconds, as seen from the given initiator location.
* Best latency nodes are nodes with <b>smaller latency</b>.
* The corresponding attribute flags are ::HWLOC_MEMATTR_FLAG_LOWER_FIRST
* and ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR.
*/
HWLOC_MEMATTR_ID_LATENCY = 3
/* TODO read vs write, persistence? */
};
/** \brief A memory attribute identifier.
* May be either one of ::hwloc_memattr_id_e or a new id returned by hwloc_memattr_register().
*/
typedef unsigned hwloc_memattr_id_t;
/** \brief Return the identifier of the memory attribute with the given name.
*/
HWLOC_DECLSPEC int
hwloc_memattr_get_by_name(hwloc_topology_t topology,
const char *name,
hwloc_memattr_id_t *id);
/** \brief Type of location. */
enum hwloc_location_type_e {
/** \brief Location is given as a cpuset, in the location cpuset union field. \hideinitializer */
HWLOC_LOCATION_TYPE_CPUSET = 1,
/** \brief Location is given as an object, in the location object union field. \hideinitializer */
HWLOC_LOCATION_TYPE_OBJECT = 0
};
/** \brief Where to measure attributes from. */
struct hwloc_location {
/** \brief Type of location. */
enum hwloc_location_type_e type;
/** \brief Actual location. */
union hwloc_location_u {
/** \brief Location as a cpuset, when the location type is ::HWLOC_LOCATION_TYPE_CPUSET. */
hwloc_cpuset_t cpuset;
/** \brief Location as an object, when the location type is ::HWLOC_LOCATION_TYPE_OBJECT. */
hwloc_obj_t object;
} location;
};
/** \brief Flags for selecting target NUMA nodes. */
enum hwloc_local_numanode_flag_e {
/** \brief Select NUMA nodes whose locality is larger than the given cpuset.
* For instance, if a single PU (or its cpuset) is given in \p initiator,
* select all nodes close to the package that contains this PU.
* \hideinitializer
*/
HWLOC_LOCAL_NUMANODE_FLAG_LARGER_LOCALITY = (1UL<<0),
/** \brief Select NUMA nodes whose locality is smaller than the given cpuset.
* For instance, if a package (or its cpuset) is given in \p initiator,
* also select nodes that are attached to only a half of that package.
* \hideinitializer
*/
HWLOC_LOCAL_NUMANODE_FLAG_SMALLER_LOCALITY = (1UL<<1),
/** \brief Select all NUMA nodes in the topology.
* The initiator \p initiator is ignored.
* \hideinitializer
*/
HWLOC_LOCAL_NUMANODE_FLAG_ALL = (1UL<<2)
};
/** \brief Return an array of local NUMA nodes.
*
* By default only select the NUMA nodes whose locality is exactly
* the given \p location. More nodes may be selected if additional flags
* are given as a OR'ed set of ::hwloc_local_numanode_flag_e.
*
* If \p location is given as an explicit object, its CPU set is used
* to find NUMA nodes with the corresponding locality.
* If the object does not have a CPU set (e.g. I/O object), the CPU
* parent (where the I/O object is attached) is used.
*
* On input, \p nr points to the number of nodes that may be stored
* in the \p nodes array.
* On output, \p nr will be changed to the number of stored nodes,
* or the number of nodes that would have been stored if there were
* enough room.
*
* \note Some of these NUMA nodes may not have any memory attribute
* values and hence not be reported as actual targets in other functions.
*
* \note The number of NUMA nodes in the topology (obtained by
* hwloc_bitmap_weight() on the root object nodeset) may be used
* to allocate the \p nodes array.
*
* \note When an object CPU set is given as locality, for instance a Package,
* and when flags contain both ::HWLOC_LOCAL_NUMANODE_FLAG_LARGER_LOCALITY
* and ::HWLOC_LOCAL_NUMANODE_FLAG_SMALLER_LOCALITY,
* the returned array corresponds to the nodeset of that object.
*/
HWLOC_DECLSPEC int
hwloc_get_local_numanode_objs(hwloc_topology_t topology,
struct hwloc_location *location,
unsigned *nr,
hwloc_obj_t *nodes,
unsigned long flags);
/** \brief Return an attribute value for a specific target NUMA node.
*
* If the attribute does not relate to a specific initiator
* (it does not have the flag ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR),
* location \p initiator is ignored and may be \c NULL.
*
* \p flags must be \c 0 for now.
*
* \note The initiator \p initiator should be of type ::HWLOC_LOCATION_TYPE_CPUSET
* when refering to accesses performed by CPU cores.
* ::HWLOC_LOCATION_TYPE_OBJECT is currently unused internally by hwloc,
* but users may for instance use it to provide custom information about
* host memory accesses performed by GPUs.
*/
HWLOC_DECLSPEC int
hwloc_memattr_get_value(hwloc_topology_t topology,
hwloc_memattr_id_t attribute,
hwloc_obj_t target_node,
struct hwloc_location *initiator,
unsigned long flags,
hwloc_uint64_t *value);
/** \brief Return the best target NUMA node for the given attribute and initiator.
*
* If the attribute does not relate to a specific initiator
* (it does not have the flag ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR),
* location \p initiator is ignored and may be \c NULL.
*
* If \p value is non \c NULL, the corresponding value is returned there.
*
* If multiple targets have the same attribute values, only one is
* returned (and there is no way to clarify how that one is chosen).
* Applications that want to detect targets with identical/similar
* values, or that want to look at values for multiple attributes,
* should rather get all values using hwloc_memattr_get_value()
* and manually select the target they consider the best.
*
* \p flags must be \c 0 for now.
*
* If there are no matching targets, \c -1 is returned with \p errno set to \c ENOENT;
*
* \note The initiator \p initiator should be of type ::HWLOC_LOCATION_TYPE_CPUSET
* when refering to accesses performed by CPU cores.
* ::HWLOC_LOCATION_TYPE_OBJECT is currently unused internally by hwloc,
* but users may for instance use it to provide custom information about
* host memory accesses performed by GPUs.
*/
HWLOC_DECLSPEC int
hwloc_memattr_get_best_target(hwloc_topology_t topology,
hwloc_memattr_id_t attribute,
struct hwloc_location *initiator,
unsigned long flags,
hwloc_obj_t *best_target, hwloc_uint64_t *value);
/** \brief Return the best initiator for the given attribute and target NUMA node.
*
* If the attribute does not relate to a specific initiator
* (it does not have the flag ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR),
* \c -1 is returned and \p errno is set to \c EINVAL.
*
* If \p value is non \c NULL, the corresponding value is returned there.
*
* If multiple initiators have the same attribute values, only one is
* returned (and there is no way to clarify how that one is chosen).
* Applications that want to detect initiators with identical/similar
* values, or that want to look at values for multiple attributes,
* should rather get all values using hwloc_memattr_get_value()
* and manually select the initiator they consider the best.
*
* The returned initiator should not be modified or freed,
* it belongs to the topology.
*
* \p flags must be \c 0 for now.
*
* If there are no matching initiators, \c -1 is returned with \p errno set to \c ENOENT;
*/
HWLOC_DECLSPEC int
hwloc_memattr_get_best_initiator(hwloc_topology_t topology,
hwloc_memattr_id_t attribute,
hwloc_obj_t target,
unsigned long flags,
struct hwloc_location *best_initiator, hwloc_uint64_t *value);
/** @} */
/** \defgroup hwlocality_memattrs_manage Managing memory attributes
* @{
*/
/** \brief Return the name of a memory attribute.
*/
HWLOC_DECLSPEC int
hwloc_memattr_get_name(hwloc_topology_t topology,
hwloc_memattr_id_t attribute,
const char **name);
/** \brief Return the flags of the given attribute.
*
* Flags are a OR'ed set of ::hwloc_memattr_flag_e.
*/
HWLOC_DECLSPEC int
hwloc_memattr_get_flags(hwloc_topology_t topology,
hwloc_memattr_id_t attribute,
unsigned long *flags);
/** \brief Memory attribute flags.
* Given to hwloc_memattr_register() and returned by hwloc_memattr_get_flags().
*/
enum hwloc_memattr_flag_e {
/** \brief The best nodes for this memory attribute are those with the higher values.
* For instance Bandwidth.
*/
HWLOC_MEMATTR_FLAG_HIGHER_FIRST = (1UL<<0),
/** \brief The best nodes for this memory attribute are those with the lower values.
* For instance Latency.
*/
HWLOC_MEMATTR_FLAG_LOWER_FIRST = (1UL<<1),
/** \brief The value returned for this memory attribute depends on the given initiator.
* For instance Bandwidth and Latency, but not Capacity.
*/
HWLOC_MEMATTR_FLAG_NEED_INITIATOR = (1UL<<2)
};
/** \brief Register a new memory attribute.
*
* Add a specific memory attribute that is not defined in ::hwloc_memattr_id_e.
* Flags are a OR'ed set of ::hwloc_memattr_flag_e. It must contain at least
* one of ::HWLOC_MEMATTR_FLAG_HIGHER_FIRST or ::HWLOC_MEMATTR_FLAG_LOWER_FIRST.
*/
HWLOC_DECLSPEC int
hwloc_memattr_register(hwloc_topology_t topology,
const char *name,
unsigned long flags,
hwloc_memattr_id_t *id);
/** \brief Set an attribute value for a specific target NUMA node.
*
* If the attribute does not relate to a specific initiator
* (it does not have the flag ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR),
* location \p initiator is ignored and may be \c NULL.
*
* The initiator will be copied into the topology,
* the caller should free anything allocated to store the initiator,
* for instance the cpuset.
*
* \p flags must be \c 0 for now.
*
* \note The initiator \p initiator should be of type ::HWLOC_LOCATION_TYPE_CPUSET
* when referring to accesses performed by CPU cores.
* ::HWLOC_LOCATION_TYPE_OBJECT is currently unused internally by hwloc,
* but users may for instance use it to provide custom information about
* host memory accesses performed by GPUs.
*/
HWLOC_DECLSPEC int
hwloc_memattr_set_value(hwloc_topology_t topology,
hwloc_memattr_id_t attribute,
hwloc_obj_t target_node,
struct hwloc_location *initiator,
unsigned long flags,
hwloc_uint64_t value);
/** \brief Return the target NUMA nodes that have some values for a given attribute.
*
* Return targets for the given attribute in the \p targets array
* (for the given initiator if any).
* If \p values is not \c NULL, the corresponding attribute values
* are stored in the array it points to.
*
* On input, \p nr points to the number of targets that may be stored
* in the array \p targets (and \p values).
* On output, \p nr points to the number of targets (and values) that
* were actually found, even if some of them couldn't be stored in the array.
* Targets that couldn't be stored are ignored, but the function still
* returns success (\c 0). The caller may find out by comparing the value pointed
* by \p nr before and after the function call.
*
* The returned targets should not be modified or freed,
* they belong to the topology.
*
* Argument \p initiator is ignored if the attribute does not relate to a specific
* initiator (it does not have the flag ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR).
* Otherwise \p initiator may be non \c NULL to report only targets
* that have a value for that initiator.
*
* \p flags must be \c 0 for now.
*
* \note This function is meant for tools and debugging (listing internal information)
* rather than for application queries. Applications should rather select useful
* NUMA nodes with hwloc_get_local_numanode_objs() and then look at their attribute
* values.
*
* \note The initiator \p initiator should be of type ::HWLOC_LOCATION_TYPE_CPUSET
* when referring to accesses performed by CPU cores.
* ::HWLOC_LOCATION_TYPE_OBJECT is currently unused internally by hwloc,
* but users may for instance use it to provide custom information about
* host memory accesses performed by GPUs.
*/
HWLOC_DECLSPEC int
hwloc_memattr_get_targets(hwloc_topology_t topology,
hwloc_memattr_id_t attribute,
struct hwloc_location *initiator,
unsigned long flags,
unsigned *nr, hwloc_obj_t *targets, hwloc_uint64_t *values);
/** \brief Return the initiators that have values for a given attribute for a specific target NUMA node.
*
* Return initiators for the given attribute and target node in the
* \p initiators array.
* If \p values is not \c NULL, the corresponding attribute values
* are stored in the array it points to.
*
* On input, \p nr points to the number of initiators that may be stored
* in the array \p initiators (and \p values).
* On output, \p nr points to the number of initiators (and values) that
* were actually found, even if some of them couldn't be stored in the array.
* Initiators that couldn't be stored are ignored, but the function still
* returns success (\c 0). The caller may find out by comparing the value pointed
* by \p nr before and after the function call.
*
* The returned initiators should not be modified or freed,
* they belong to the topology.
*
* \p flags must be \c 0 for now.
*
* If the attribute does not relate to a specific initiator
* (it does not have the flag ::HWLOC_MEMATTR_FLAG_NEED_INITIATOR),
* no initiator is returned.
*
* \note This function is meant for tools and debugging (listing internal information)
* rather than for application queries. Applications should rather select useful
* NUMA nodes with hwloc_get_local_numanode_objs() and then look at their attribute
* values for some relevant initiators.
*/
HWLOC_DECLSPEC int
hwloc_memattr_get_initiators(hwloc_topology_t topology,
hwloc_memattr_id_t attribute,
hwloc_obj_t target_node,
unsigned long flags,
unsigned *nr, struct hwloc_location *initiators, hwloc_uint64_t *values);
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_MEMATTR_H */

View file

@ -1,181 +0,0 @@
/*
* Copyright © 2012-2021 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
/** \file
* \brief Macros to help interaction between hwloc and the NVIDIA Management Library.
*
* Applications that use both hwloc and the NVIDIA Management Library may want to
* include this file so as to get topology information for NVML devices.
*/
#ifndef HWLOC_NVML_H
#define HWLOC_NVML_H
#include "hwloc.h"
#include "hwloc/autogen/config.h"
#include "hwloc/helper.h"
#ifdef HWLOC_LINUX_SYS
#include "hwloc/linux.h"
#endif
#include <nvml.h>
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup hwlocality_nvml Interoperability with the NVIDIA Management Library
*
* This interface offers ways to retrieve topology information about
* devices managed by the NVIDIA Management Library (NVML).
*
* @{
*/
/** \brief Get the CPU set of processors that are physically
* close to NVML device \p device.
*
* Store in \p set the CPU-set describing the locality of the NVML device \p device.
*
* Topology \p topology and device \p device must match the local machine.
* I/O devices detection and the NVML component are not needed in the topology.
*
* The function only returns the locality of the device.
* If more information about the device is needed, OS objects should
* be used instead, see hwloc_nvml_get_device_osdev()
* and hwloc_nvml_get_device_osdev_by_index().
*
* This function is currently only implemented in a meaningful way for
* Linux; other systems will simply get a full cpuset.
*/
static __hwloc_inline int
hwloc_nvml_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
nvmlDevice_t device, hwloc_cpuset_t set)
{
#ifdef HWLOC_LINUX_SYS
/* If we're on Linux, use the sysfs mechanism to get the local cpus */
#define HWLOC_NVML_DEVICE_SYSFS_PATH_MAX 128
char path[HWLOC_NVML_DEVICE_SYSFS_PATH_MAX];
nvmlReturn_t nvres;
nvmlPciInfo_t pci;
if (!hwloc_topology_is_thissystem(topology)) {
errno = EINVAL;
return -1;
}
nvres = nvmlDeviceGetPciInfo(device, &pci);
if (NVML_SUCCESS != nvres) {
errno = EINVAL;
return -1;
}
sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.0/local_cpus", pci.domain, pci.bus, pci.device);
if (hwloc_linux_read_path_as_cpumask(path, set) < 0
|| hwloc_bitmap_iszero(set))
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
#else
/* Non-Linux systems simply get a full cpuset */
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
#endif
return 0;
}
/** \brief Get the hwloc OS device object corresponding to the
* NVML device whose index is \p idx.
*
* \return The hwloc OS device object describing the NVML device whose index is \p idx.
* \return \c NULL if none could be found.
*
* The topology \p topology does not necessarily have to match the current
* machine. For instance the topology may be an XML import of a remote host.
* I/O devices detection and the NVML component must be enabled in the topology.
*
* \note The corresponding PCI device object can be obtained by looking
* at the OS device parent object (unless PCI devices are filtered out).
*/
static __hwloc_inline hwloc_obj_t
hwloc_nvml_get_device_osdev_by_index(hwloc_topology_t topology, unsigned idx)
{
hwloc_obj_t osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
if (HWLOC_OBJ_OSDEV_GPU == osdev->attr->osdev.type
&& osdev->name
&& !strncmp("nvml", osdev->name, 4)
&& atoi(osdev->name + 4) == (int) idx)
return osdev;
}
return NULL;
}
/** \brief Get the hwloc OS device object corresponding to NVML device \p device.
*
* \return The hwloc OS device object that describes the given NVML device \p device.
* \return \c NULL if none could be found.
*
* Topology \p topology and device \p device must match the local machine.
* I/O devices detection and the NVML component must be enabled in the topology.
* If not, the locality of the object may still be found using
* hwloc_nvml_get_device_cpuset().
*
* \note The corresponding hwloc PCI device may be found by looking
* at the result parent pointer (unless PCI devices are filtered out).
*/
static __hwloc_inline hwloc_obj_t
hwloc_nvml_get_device_osdev(hwloc_topology_t topology, nvmlDevice_t device)
{
hwloc_obj_t osdev;
nvmlReturn_t nvres;
nvmlPciInfo_t pci;
char uuid[64];
if (!hwloc_topology_is_thissystem(topology)) {
errno = EINVAL;
return NULL;
}
nvres = nvmlDeviceGetPciInfo(device, &pci);
if (NVML_SUCCESS != nvres)
return NULL;
nvres = nvmlDeviceGetUUID(device, uuid, sizeof(uuid));
if (NVML_SUCCESS != nvres)
uuid[0] = '\0';
osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
hwloc_obj_t pcidev = osdev->parent;
const char *info;
if (strncmp(osdev->name, "nvml", 4))
continue;
if (pcidev
&& pcidev->type == HWLOC_OBJ_PCI_DEVICE
&& pcidev->attr->pcidev.domain == pci.domain
&& pcidev->attr->pcidev.bus == pci.bus
&& pcidev->attr->pcidev.dev == pci.device
&& pcidev->attr->pcidev.func == 0)
return osdev;
info = hwloc_obj_get_info_by_name(osdev, "NVIDIAUUID");
if (info && !strcmp(info, uuid))
return osdev;
}
return NULL;
}
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_NVML_H */

View file

@ -1,252 +0,0 @@
/*
* Copyright © 2012-2021 Inria. All rights reserved.
* Copyright © 2013, 2018 Université Bordeaux. All right reserved.
* See COPYING in top-level directory.
*/
/** \file
* \brief Macros to help interaction between hwloc and the OpenCL interface.
*
* Applications that use both hwloc and OpenCL may want to
* include this file so as to get topology information for OpenCL devices.
*/
#ifndef HWLOC_OPENCL_H
#define HWLOC_OPENCL_H
#include "hwloc.h"
#include "hwloc/autogen/config.h"
#include "hwloc/helper.h"
#ifdef HWLOC_LINUX_SYS
#include "hwloc/linux.h"
#endif
#ifdef __APPLE__
#include <OpenCL/cl.h>
#else
#include <CL/cl.h>
#endif
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
/* OpenCL extensions aren't always shipped with default headers, and
* they don't always reflect what the installed implementations support.
* Try everything and let the implementation return errors when non supported.
*/
/* Copyright (c) 2008-2018 The Khronos Group Inc. */
/* needs "cl_amd_device_attribute_query" device extension, but not strictly required for clGetDeviceInfo() */
#define HWLOC_CL_DEVICE_TOPOLOGY_AMD 0x4037
typedef union {
struct { cl_uint type; cl_uint data[5]; } raw;
struct { cl_uint type; cl_char unused[17]; cl_char bus; cl_char device; cl_char function; } pcie;
} hwloc_cl_device_topology_amd;
#define HWLOC_CL_DEVICE_TOPOLOGY_TYPE_PCIE_AMD 1
/* needs "cl_nv_device_attribute_query" device extension, but not strictly required for clGetDeviceInfo() */
#define HWLOC_CL_DEVICE_PCI_BUS_ID_NV 0x4008
#define HWLOC_CL_DEVICE_PCI_SLOT_ID_NV 0x4009
#define HWLOC_CL_DEVICE_PCI_DOMAIN_ID_NV 0x400A
/** \defgroup hwlocality_opencl Interoperability with OpenCL
*
* This interface offers ways to retrieve topology information about
* OpenCL devices.
*
* Only AMD and NVIDIA OpenCL implementations currently offer useful locality
* information about their devices.
*
* @{
*/
/** \brief Return the domain, bus and device IDs of the OpenCL device \p device.
*
* Device \p device must match the local machine.
*/
static __hwloc_inline int
hwloc_opencl_get_device_pci_busid(cl_device_id device,
unsigned *domain, unsigned *bus, unsigned *dev, unsigned *func)
{
hwloc_cl_device_topology_amd amdtopo;
cl_uint nvbus, nvslot, nvdomain;
cl_int clret;
clret = clGetDeviceInfo(device, HWLOC_CL_DEVICE_TOPOLOGY_AMD, sizeof(amdtopo), &amdtopo, NULL);
if (CL_SUCCESS == clret
&& HWLOC_CL_DEVICE_TOPOLOGY_TYPE_PCIE_AMD == amdtopo.raw.type) {
*domain = 0; /* can't do anything better */
/* cl_device_topology_amd stores bus ID in cl_char, dont convert those signed char directly to unsigned int */
*bus = (unsigned) (unsigned char) amdtopo.pcie.bus;
*dev = (unsigned) (unsigned char) amdtopo.pcie.device;
*func = (unsigned) (unsigned char) amdtopo.pcie.function;
return 0;
}
clret = clGetDeviceInfo(device, HWLOC_CL_DEVICE_PCI_BUS_ID_NV, sizeof(nvbus), &nvbus, NULL);
if (CL_SUCCESS == clret) {
clret = clGetDeviceInfo(device, HWLOC_CL_DEVICE_PCI_SLOT_ID_NV, sizeof(nvslot), &nvslot, NULL);
if (CL_SUCCESS == clret) {
clret = clGetDeviceInfo(device, HWLOC_CL_DEVICE_PCI_DOMAIN_ID_NV, sizeof(nvdomain), &nvdomain, NULL);
if (CL_SUCCESS == clret) { /* available since CUDA 10.2 */
*domain = nvdomain;
} else {
*domain = 0;
}
*bus = nvbus & 0xff;
/* non-documented but used in many other projects */
*dev = nvslot >> 3;
*func = nvslot & 0x7;
return 0;
}
}
return -1;
}
/** \brief Get the CPU set of processors that are physically
* close to OpenCL device \p device.
*
* Store in \p set the CPU-set describing the locality of the OpenCL device \p device.
*
* Topology \p topology and device \p device must match the local machine.
* I/O devices detection and the OpenCL component are not needed in the topology.
*
* The function only returns the locality of the device.
* If more information about the device is needed, OS objects should
* be used instead, see hwloc_opencl_get_device_osdev()
* and hwloc_opencl_get_device_osdev_by_index().
*
* This function is currently only implemented in a meaningful way for
* Linux with the AMD or NVIDIA OpenCL implementation; other systems will simply
* get a full cpuset.
*/
static __hwloc_inline int
hwloc_opencl_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
cl_device_id device __hwloc_attribute_unused,
hwloc_cpuset_t set)
{
#if (defined HWLOC_LINUX_SYS)
/* If we're on Linux, try AMD/NVIDIA extensions + the sysfs mechanism to get the local cpus */
#define HWLOC_OPENCL_DEVICE_SYSFS_PATH_MAX 128
char path[HWLOC_OPENCL_DEVICE_SYSFS_PATH_MAX];
unsigned pcidomain, pcibus, pcidev, pcifunc;
if (!hwloc_topology_is_thissystem(topology)) {
errno = EINVAL;
return -1;
}
if (hwloc_opencl_get_device_pci_busid(device, &pcidomain, &pcibus, &pcidev, &pcifunc) < 0) {
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
return 0;
}
sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/local_cpus", pcidomain, pcibus, pcidev, pcifunc);
if (hwloc_linux_read_path_as_cpumask(path, set) < 0
|| hwloc_bitmap_iszero(set))
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
#else
/* Non-Linux systems simply get a full cpuset */
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
#endif
return 0;
}
/** \brief Get the hwloc OS device object corresponding to the
* OpenCL device for the given indexes.
*
* \return The hwloc OS device object describing the OpenCL device
* whose platform index is \p platform_index,
* and whose device index within this platform if \p device_index.
* \return \c NULL if there is none.
*
* The topology \p topology does not necessarily have to match the current
* machine. For instance the topology may be an XML import of a remote host.
* I/O devices detection and the OpenCL component must be enabled in the topology.
*
* \note The corresponding PCI device object can be obtained by looking
* at the OS device parent object (unless PCI devices are filtered out).
*/
static __hwloc_inline hwloc_obj_t
hwloc_opencl_get_device_osdev_by_index(hwloc_topology_t topology,
unsigned platform_index, unsigned device_index)
{
unsigned x = (unsigned) -1, y = (unsigned) -1;
hwloc_obj_t osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
if (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type
&& osdev->name
&& sscanf(osdev->name, "opencl%ud%u", &x, &y) == 2
&& platform_index == x && device_index == y)
return osdev;
}
return NULL;
}
/** \brief Get the hwloc OS device object corresponding to OpenCL device \p deviceX.
*
* \return The hwloc OS device object corresponding to the given OpenCL device \p device.
* \return \c NULL if none could be found, for instance
* if required OpenCL attributes are not available.
*
* This function currently only works on AMD and NVIDIA OpenCL devices that support
* relevant OpenCL extensions. hwloc_opencl_get_device_osdev_by_index()
* should be preferred whenever possible, i.e. when platform and device index
* are known.
*
* Topology \p topology and device \p device must match the local machine.
* I/O devices detection and the OpenCL component must be enabled in the topology.
* If not, the locality of the object may still be found using
* hwloc_opencl_get_device_cpuset().
*
* \note This function cannot work if PCI devices are filtered out.
*
* \note The corresponding hwloc PCI device may be found by looking
* at the result parent pointer (unless PCI devices are filtered out).
*/
static __hwloc_inline hwloc_obj_t
hwloc_opencl_get_device_osdev(hwloc_topology_t topology __hwloc_attribute_unused,
cl_device_id device __hwloc_attribute_unused)
{
hwloc_obj_t osdev;
unsigned pcidomain, pcibus, pcidevice, pcifunc;
if (hwloc_opencl_get_device_pci_busid(device, &pcidomain, &pcibus, &pcidevice, &pcifunc) < 0) {
errno = EINVAL;
return NULL;
}
osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
hwloc_obj_t pcidev = osdev->parent;
if (strncmp(osdev->name, "opencl", 6))
continue;
if (pcidev
&& pcidev->type == HWLOC_OBJ_PCI_DEVICE
&& pcidev->attr->pcidev.domain == pcidomain
&& pcidev->attr->pcidev.bus == pcibus
&& pcidev->attr->pcidev.dev == pcidevice
&& pcidev->attr->pcidev.func == pcifunc)
return osdev;
/* if PCI are filtered out, we need a info attr to match on */
}
return NULL;
}
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_OPENCL_H */

View file

@ -1,152 +0,0 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2021 Inria. All rights reserved.
* Copyright © 2009-2010 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
/** \file
* \brief Macros to help interaction between hwloc and OpenFabrics
* verbs.
*
* Applications that use both hwloc and OpenFabrics verbs may want to
* include this file so as to get topology information for OpenFabrics
* hardware (InfiniBand, etc).
*
*/
#ifndef HWLOC_OPENFABRICS_VERBS_H
#define HWLOC_OPENFABRICS_VERBS_H
#include "hwloc.h"
#include "hwloc/autogen/config.h"
#ifdef HWLOC_LINUX_SYS
#include "hwloc/linux.h"
#endif
#include <infiniband/verbs.h>
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup hwlocality_openfabrics Interoperability with OpenFabrics
*
* This interface offers ways to retrieve topology information about
* OpenFabrics devices (InfiniBand, Omni-Path, usNIC, etc).
*
* @{
*/
/** \brief Get the CPU set of processors that are physically
* close to device \p ibdev.
*
* Store in \p set the CPU-set describing the locality of the OpenFabrics
* device \p ibdev (InfiniBand, etc).
*
* Topology \p topology and device \p ibdev must match the local machine.
* I/O devices detection is not needed in the topology.
*
* The function only returns the locality of the device.
* If more information about the device is needed, OS objects should
* be used instead, see hwloc_ibv_get_device_osdev()
* and hwloc_ibv_get_device_osdev_by_name().
*
* This function is currently only implemented in a meaningful way for
* Linux; other systems will simply get a full cpuset.
*/
static __hwloc_inline int
hwloc_ibv_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
struct ibv_device *ibdev, hwloc_cpuset_t set)
{
#ifdef HWLOC_LINUX_SYS
/* If we're on Linux, use the verbs-provided sysfs mechanism to
get the local cpus */
#define HWLOC_OPENFABRICS_VERBS_SYSFS_PATH_MAX 128
char path[HWLOC_OPENFABRICS_VERBS_SYSFS_PATH_MAX];
if (!hwloc_topology_is_thissystem(topology)) {
errno = EINVAL;
return -1;
}
sprintf(path, "/sys/class/infiniband/%s/device/local_cpus",
ibv_get_device_name(ibdev));
if (hwloc_linux_read_path_as_cpumask(path, set) < 0
|| hwloc_bitmap_iszero(set))
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
#else
/* Non-Linux systems simply get a full cpuset */
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
#endif
return 0;
}
/** \brief Get the hwloc OS device object corresponding to the OpenFabrics
* device named \p ibname.
*
* \return The hwloc OS device object describing the OpenFabrics device
* (InfiniBand, Omni-Path, usNIC, etc) whose name is \p ibname
* (mlx5_0, hfi1_0, usnic_0, qib0, etc).
* \return \c NULL if none could be found.
*
* The name \p ibname is usually obtained from ibv_get_device_name().
*
* The topology \p topology does not necessarily have to match the current
* machine. For instance the topology may be an XML import of a remote host.
* I/O devices detection must be enabled in the topology.
*
* \note The corresponding PCI device object can be obtained by looking
* at the OS device parent object.
*/
static __hwloc_inline hwloc_obj_t
hwloc_ibv_get_device_osdev_by_name(hwloc_topology_t topology,
const char *ibname)
{
hwloc_obj_t osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
if (HWLOC_OBJ_OSDEV_OPENFABRICS == osdev->attr->osdev.type
&& osdev->name && !strcmp(ibname, osdev->name))
return osdev;
}
return NULL;
}
/** \brief Get the hwloc OS device object corresponding to the OpenFabrics
* device \p ibdev.
*
* \return The hwloc OS device object describing the OpenFabrics
* device \p ibdev (InfiniBand, etc).
* \return \c NULL if none could be found.
*
* Topology \p topology and device \p ibdev must match the local machine.
* I/O devices detection must be enabled in the topology.
* If not, the locality of the object may still be found using
* hwloc_ibv_get_device_cpuset().
*
* \note The corresponding PCI device object can be obtained by looking
* at the OS device parent object.
*/
static __hwloc_inline hwloc_obj_t
hwloc_ibv_get_device_osdev(hwloc_topology_t topology,
struct ibv_device *ibdev)
{
if (!hwloc_topology_is_thissystem(topology)) {
errno = EINVAL;
return NULL;
}
return hwloc_ibv_get_device_osdev_by_name(topology, ibv_get_device_name(ibdev));
}
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_OPENFABRICS_VERBS_H */

View file

@ -1,689 +0,0 @@
/*
* Copyright © 2013-2021 Inria. All rights reserved.
* Copyright © 2016 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
#ifndef HWLOC_PLUGINS_H
#define HWLOC_PLUGINS_H
/** \file
* \brief Public interface for building hwloc plugins.
*/
struct hwloc_backend;
#include "hwloc.h"
#ifdef HWLOC_INSIDE_PLUGIN
/* needed for hwloc_plugin_check_namespace() */
#ifdef HWLOC_HAVE_LTDL
#include <ltdl.h>
#else
#include <dlfcn.h>
#endif
#endif
/** \defgroup hwlocality_disc_components Components and Plugins: Discovery components
*
* \note These structures and functions may change when ::HWLOC_COMPONENT_ABI is modified.
*
* @{
*/
/** \brief Discovery component structure
*
* This is the major kind of components, taking care of the discovery.
* They are registered by generic components, either statically-built or as plugins.
*/
struct hwloc_disc_component {
/** \brief Name.
* If this component is built as a plugin, this name does not have to match the plugin filename.
*/
const char *name;
/** \brief Discovery phases performed by this component.
* OR'ed set of ::hwloc_disc_phase_t
*/
unsigned phases;
/** \brief Component phases to exclude, as an OR'ed set of ::hwloc_disc_phase_t.
*
* For a GLOBAL component, this usually includes all other phases (\c ~UL).
*
* Other components only exclude types that may bring conflicting
* topology information. MISC components should likely not be excluded
* since they usually bring non-primary additional information.
*/
unsigned excluded_phases;
/** \brief Instantiate callback to create a backend from the component.
* Parameters data1, data2, data3 are NULL except for components
* that have special enabling routines such as hwloc_topology_set_xml(). */
struct hwloc_backend * (*instantiate)(struct hwloc_topology *topology, struct hwloc_disc_component *component, unsigned excluded_phases, const void *data1, const void *data2, const void *data3);
/** \brief Component priority.
* Used to sort topology->components, higher priority first.
* Also used to decide between two components with the same name.
*
* Usual values are
* 50 for native OS (or platform) components,
* 45 for x86,
* 40 for no-OS fallback,
* 30 for global components (xml, synthetic),
* 20 for pci,
* 10 for other misc components (opencl etc.).
*/
unsigned priority;
/** \brief Enabled by default.
* If unset, if will be disabled unless explicitly requested.
*/
unsigned enabled_by_default;
/** \private Used internally to list components by priority on topology->components
* (the component structure is usually read-only,
* the core copies it before using this field for queueing)
*/
struct hwloc_disc_component * next;
};
/** @} */
/** \defgroup hwlocality_disc_backends Components and Plugins: Discovery backends
*
* \note These structures and functions may change when ::HWLOC_COMPONENT_ABI is modified.
*
* @{
*/
/** \brief Discovery phase */
typedef enum hwloc_disc_phase_e {
/** \brief xml or synthetic, platform-specific components such as bgq.
* Discovers everything including CPU, memory, I/O and everything else.
* A component with a Global phase usually excludes all other phases.
* \hideinitializer */
HWLOC_DISC_PHASE_GLOBAL = (1U<<0),
/** \brief CPU discovery.
* \hideinitializer */
HWLOC_DISC_PHASE_CPU = (1U<<1),
/** \brief Attach memory to existing CPU objects.
* \hideinitializer */
HWLOC_DISC_PHASE_MEMORY = (1U<<2),
/** \brief Attach PCI devices and bridges to existing CPU objects.
* \hideinitializer */
HWLOC_DISC_PHASE_PCI = (1U<<3),
/** \brief I/O discovery that requires PCI devices (OS devices such as OpenCL, CUDA, etc.).
* \hideinitializer */
HWLOC_DISC_PHASE_IO = (1U<<4),
/** \brief Misc objects that gets added below anything else.
* \hideinitializer */
HWLOC_DISC_PHASE_MISC = (1U<<5),
/** \brief Annotating existing objects, adding distances, etc.
* \hideinitializer */
HWLOC_DISC_PHASE_ANNOTATE = (1U<<6),
/** \brief Final tweaks to a ready-to-use topology.
* This phase runs once the topology is loaded, before it is returned to the topology.
* Hence it may only use the main hwloc API for modifying the topology,
* for instance by restricting it, adding info attributes, etc.
* \hideinitializer */
HWLOC_DISC_PHASE_TWEAK = (1U<<7)
} hwloc_disc_phase_t;
/** \brief Discovery status flags */
enum hwloc_disc_status_flag_e {
/** \brief The sets of allowed resources were already retrieved \hideinitializer */
HWLOC_DISC_STATUS_FLAG_GOT_ALLOWED_RESOURCES = (1UL<<1)
};
/** \brief Discovery status structure
*
* Used by the core and backends to inform about what has been/is being done
* during the discovery process.
*/
struct hwloc_disc_status {
/** \brief The current discovery phase that is performed.
* Must match one of the phases in the component phases field.
*/
hwloc_disc_phase_t phase;
/** \brief Dynamically excluded phases.
* If a component decides during discovery that some phases are no longer needed.
*/
unsigned excluded_phases;
/** \brief OR'ed set of hwloc_disc_status_flag_e */
unsigned long flags;
};
/** \brief Discovery backend structure
*
* A backend is the instantiation of a discovery component.
* When a component gets enabled for a topology,
* its instantiate() callback creates a backend.
*
* hwloc_backend_alloc() initializes all fields to default values
* that the component may change (except "component" and "next")
* before enabling the backend with hwloc_backend_enable().
*
* Most backends assume that the topology is_thissystem flag is
* set because they talk to the underlying operating system.
* However they may still be used in topologies without the
* is_thissystem flag for debugging reasons.
* In practice, they are usually auto-disabled in such cases
* (excluded by xml or synthetic backends, or by environment
* variables when changing the Linux fsroot or the x86 cpuid path).
*/
struct hwloc_backend {
/** \private Reserved for the core, set by hwloc_backend_alloc() */
struct hwloc_disc_component * component;
/** \private Reserved for the core, set by hwloc_backend_enable() */
struct hwloc_topology * topology;
/** \private Reserved for the core. Set to 1 if forced through envvar, 0 otherwise. */
int envvar_forced;
/** \private Reserved for the core. Used internally to list backends topology->backends. */
struct hwloc_backend * next;
/** \brief Discovery phases performed by this component, possibly without some of them if excluded by other components.
* OR'ed set of ::hwloc_disc_phase_t
*/
unsigned phases;
/** \brief Backend flags, currently always 0. */
unsigned long flags;
/** \brief Backend-specific 'is_thissystem' property.
* Set to 0 if the backend disables the thissystem flag for this topology
* (e.g. loading from xml or synthetic string,
* or using a different fsroot on Linux, or a x86 CPUID dump).
* Set to -1 if the backend doesn't care (default).
*/
int is_thissystem;
/** \brief Backend private data, or NULL if none. */
void * private_data;
/** \brief Callback for freeing the private_data.
* May be NULL.
*/
void (*disable)(struct hwloc_backend *backend);
/** \brief Main discovery callback.
* returns -1 on error, either because it couldn't add its objects ot the existing topology,
* or because of an actual discovery/gathering failure.
* May be NULL.
*/
int (*discover)(struct hwloc_backend *backend, struct hwloc_disc_status *status);
/** \brief Callback to retrieve the locality of a PCI object.
* Called by the PCI core when attaching PCI hierarchy to CPU objects.
* May be NULL.
*/
int (*get_pci_busid_cpuset)(struct hwloc_backend *backend, struct hwloc_pcidev_attr_s *busid, hwloc_bitmap_t cpuset);
};
/** \brief Allocate a backend structure, set good default values, initialize backend->component and topology, etc.
* The caller will then modify whatever needed, and call hwloc_backend_enable().
*/
HWLOC_DECLSPEC struct hwloc_backend * hwloc_backend_alloc(struct hwloc_topology *topology, struct hwloc_disc_component *component);
/** \brief Enable a previously allocated and setup backend. */
HWLOC_DECLSPEC int hwloc_backend_enable(struct hwloc_backend *backend);
/** @} */
/** \defgroup hwlocality_generic_components Components and Plugins: Generic components
*
* \note These structures and functions may change when ::HWLOC_COMPONENT_ABI is modified.
*
* @{
*/
/** \brief Generic component type */
typedef enum hwloc_component_type_e {
/** \brief The data field must point to a struct hwloc_disc_component. */
HWLOC_COMPONENT_TYPE_DISC,
/** \brief The data field must point to a struct hwloc_xml_component. */
HWLOC_COMPONENT_TYPE_XML
} hwloc_component_type_t;
/** \brief Generic component structure
*
* Generic components structure, either statically listed by configure in static-components.h
* or dynamically loaded as a plugin.
*/
struct hwloc_component {
/** \brief Component ABI version, set to ::HWLOC_COMPONENT_ABI */
unsigned abi;
/** \brief Process-wide component initialization callback.
*
* This optional callback is called when the component is registered
* to the hwloc core (after loading the plugin).
*
* When the component is built as a plugin, this callback
* should call hwloc_check_plugin_namespace()
* and return an negative error code on error.
*
* \p flags is always 0 for now.
*
* \return 0 on success, or a negative code on error.
*
* \note If the component uses ltdl for loading its own plugins,
* it should load/unload them only in init() and finalize(),
* to avoid race conditions with hwloc's use of ltdl.
*/
int (*init)(unsigned long flags);
/** \brief Process-wide component termination callback.
*
* This optional callback is called after unregistering the component
* from the hwloc core (before unloading the plugin).
*
* \p flags is always 0 for now.
*
* \note If the component uses ltdl for loading its own plugins,
* it should load/unload them only in init() and finalize(),
* to avoid race conditions with hwloc's use of ltdl.
*/
void (*finalize)(unsigned long flags);
/** \brief Component type */
hwloc_component_type_t type;
/** \brief Component flags, unused for now */
unsigned long flags;
/** \brief Component data, pointing to a struct hwloc_disc_component or struct hwloc_xml_component. */
void * data;
};
/** @} */
/** \defgroup hwlocality_components_core_funcs Components and Plugins: Core functions to be used by components
*
* \note These structures and functions may change when ::HWLOC_COMPONENT_ABI is modified.
*
* @{
*/
/** \brief Check whether error messages are hidden.
*
* Callers should print critical error messages
* (e.g. invalid hw topo info, invalid config)
* only if this function returns strictly less than 2.
*
* Callers should print non-critical error messages
* (e.g. failure to initialize CUDA)
* if this function returns 0.
*
* This function return 1 by default (show critical only),
* 0 in lstopo (show all),
* or anything set in HWLOC_HIDE_ERRORS in the environment.
*/
HWLOC_DECLSPEC int hwloc_hide_errors(void);
/** \brief Add an object to the topology.
*
* Insert new object \p obj in the topology starting under existing object \p root
* (if \c NULL, the topology root object is used).
*
* It is sorted along the tree of other objects according to the inclusion of
* cpusets, to eventually be added as a child of the smallest object including
* this object.
*
* If the cpuset is empty, the type of the object (and maybe some attributes)
* must be enough to find where to insert the object. This is especially true
* for NUMA nodes with memory and no CPUs.
*
* The given object should not have children.
*
* This shall only be called before levels are built.
*
* The caller should check whether the object type is filtered-out before calling this function.
*
* The topology cpuset/nodesets will be enlarged to include the object sets.
*
* \p reason is a unique string identifying where and why this insertion call was performed
* (it will be displayed in case of internal insertion error).
*
* Returns the object on success.
* Returns NULL and frees obj on error.
* Returns another object and frees obj if it was merged with an identical pre-existing object.
*/
HWLOC_DECLSPEC hwloc_obj_t
hwloc__insert_object_by_cpuset(struct hwloc_topology *topology, hwloc_obj_t root,
hwloc_obj_t obj, const char *reason);
/** \brief Insert an object somewhere in the topology.
*
* It is added as the last child of the given parent.
* The cpuset is completely ignored, so strange objects such as I/O devices should
* preferably be inserted with this.
*
* When used for "normal" children with cpusets (when importing from XML
* when duplicating a topology), the caller should make sure that:
* - children are inserted in order,
* - children cpusets do not intersect.
*
* The given object may have normal, I/O or Misc children, as long as they are in order as well.
* These children must have valid parent and next_sibling pointers.
*
* The caller should check whether the object type is filtered-out before calling this function.
*/
HWLOC_DECLSPEC void hwloc_insert_object_by_parent(struct hwloc_topology *topology, hwloc_obj_t parent, hwloc_obj_t obj);
/** \brief Allocate and initialize an object of the given type and physical index.
*
* If \p os_index is unknown or irrelevant, use \c HWLOC_UNKNOWN_INDEX.
*/
HWLOC_DECLSPEC hwloc_obj_t hwloc_alloc_setup_object(hwloc_topology_t topology, hwloc_obj_type_t type, unsigned os_index);
/** \brief Setup object cpusets/nodesets by OR'ing its children.
*
* Used when adding an object late in the topology.
* Will update the new object by OR'ing all its new children sets.
*
* Used when PCI backend adds a hostbridge parent, when distances
* add a new Group, etc.
*/
HWLOC_DECLSPEC int hwloc_obj_add_children_sets(hwloc_obj_t obj);
/** \brief Request a reconnection of children and levels in the topology.
*
* May be used by backends during discovery if they need arrays or lists
* of object within levels or children to be fully connected.
*
* \p flags is currently unused, must 0.
*/
HWLOC_DECLSPEC int hwloc_topology_reconnect(hwloc_topology_t topology, unsigned long flags __hwloc_attribute_unused);
/** \brief Make sure that plugins can lookup core symbols.
*
* This is a sanity check to avoid lazy-lookup failures when libhwloc
* is loaded within a plugin, and later tries to load its own plugins.
* This may fail (and abort the program) if libhwloc symbols are in a
* private namespace.
*
* \return 0 on success.
* \return -1 if the plugin cannot be successfully loaded. The caller
* plugin init() callback should return a negative error code as well.
*
* Plugins should call this function in their init() callback to avoid
* later crashes if lazy symbol resolution is used by the upper layer that
* loaded hwloc (e.g. OpenCL implementations using dlopen with RTLD_LAZY).
*
* \note The build system must define HWLOC_INSIDE_PLUGIN if and only if
* building the caller as a plugin.
*
* \note This function should remain inline so plugins can call it even
* when they cannot find libhwloc symbols.
*/
static __hwloc_inline int
hwloc_plugin_check_namespace(const char *pluginname __hwloc_attribute_unused, const char *symbol __hwloc_attribute_unused)
{
#ifdef HWLOC_INSIDE_PLUGIN
void *sym;
#ifdef HWLOC_HAVE_LTDL
lt_dlhandle handle = lt_dlopen(NULL);
#else
void *handle = dlopen(NULL, RTLD_NOW|RTLD_LOCAL);
#endif
if (!handle)
/* cannot check, assume things will work */
return 0;
#ifdef HWLOC_HAVE_LTDL
sym = lt_dlsym(handle, symbol);
lt_dlclose(handle);
#else
sym = dlsym(handle, symbol);
dlclose(handle);
#endif
if (!sym) {
static int verboseenv_checked = 0;
static int verboseenv_value = 0;
if (!verboseenv_checked) {
const char *verboseenv = getenv("HWLOC_PLUGINS_VERBOSE");
verboseenv_value = verboseenv ? atoi(verboseenv) : 0;
verboseenv_checked = 1;
}
if (verboseenv_value)
fprintf(stderr, "Plugin `%s' disabling itself because it cannot find the `%s' core symbol.\n",
pluginname, symbol);
return -1;
}
#endif /* HWLOC_INSIDE_PLUGIN */
return 0;
}
/** @} */
/** \defgroup hwlocality_components_filtering Components and Plugins: Filtering objects
*
* \note These structures and functions may change when ::HWLOC_COMPONENT_ABI is modified.
*
* @{
*/
/** \brief Check whether the given PCI device classid is important.
*
* \return 1 if important, 0 otherwise.
*/
static __hwloc_inline int
hwloc_filter_check_pcidev_subtype_important(unsigned classid)
{
unsigned baseclass = classid >> 8;
return (baseclass == 0x03 /* PCI_BASE_CLASS_DISPLAY */
|| baseclass == 0x02 /* PCI_BASE_CLASS_NETWORK */
|| baseclass == 0x01 /* PCI_BASE_CLASS_STORAGE */
|| baseclass == 0x00 /* Unclassified, for Atos/Bull BXI */
|| baseclass == 0x0b /* PCI_BASE_CLASS_PROCESSOR */
|| classid == 0x0c04 /* PCI_CLASS_SERIAL_FIBER */
|| classid == 0x0c06 /* PCI_CLASS_SERIAL_INFINIBAND */
|| baseclass == 0x06 /* PCI_BASE_CLASS_BRIDGE with non-PCI downstream. the core will drop the useless ones later */
|| baseclass == 0x12 /* Processing Accelerators */);
}
/** \brief Check whether the given OS device subtype is important.
*
* \return 1 if important, 0 otherwise.
*/
static __hwloc_inline int
hwloc_filter_check_osdev_subtype_important(hwloc_obj_osdev_type_t subtype)
{
return (subtype != HWLOC_OBJ_OSDEV_DMA);
}
/** \brief Check whether a non-I/O object type should be filtered-out.
*
* Cannot be used for I/O objects.
*
* \return 1 if the object type should be kept, 0 otherwise.
*/
static __hwloc_inline int
hwloc_filter_check_keep_object_type(hwloc_topology_t topology, hwloc_obj_type_t type)
{
enum hwloc_type_filter_e filter = HWLOC_TYPE_FILTER_KEEP_NONE;
hwloc_topology_get_type_filter(topology, type, &filter);
assert(filter != HWLOC_TYPE_FILTER_KEEP_IMPORTANT); /* IMPORTANT only used for I/O */
return filter == HWLOC_TYPE_FILTER_KEEP_NONE ? 0 : 1;
}
/** \brief Check whether the given object should be filtered-out.
*
* \return 1 if the object type should be kept, 0 otherwise.
*/
static __hwloc_inline int
hwloc_filter_check_keep_object(hwloc_topology_t topology, hwloc_obj_t obj)
{
hwloc_obj_type_t type = obj->type;
enum hwloc_type_filter_e filter = HWLOC_TYPE_FILTER_KEEP_NONE;
hwloc_topology_get_type_filter(topology, type, &filter);
if (filter == HWLOC_TYPE_FILTER_KEEP_NONE)
return 0;
if (filter == HWLOC_TYPE_FILTER_KEEP_IMPORTANT) {
if (type == HWLOC_OBJ_PCI_DEVICE)
return hwloc_filter_check_pcidev_subtype_important(obj->attr->pcidev.class_id);
if (type == HWLOC_OBJ_OS_DEVICE)
return hwloc_filter_check_osdev_subtype_important(obj->attr->osdev.type);
}
return 1;
}
/** @} */
/** \defgroup hwlocality_components_pcidisc Components and Plugins: helpers for PCI discovery
*
* \note These structures and functions may change when ::HWLOC_COMPONENT_ABI is modified.
*
* @{
*/
/** \brief Return the offset of the given capability in the PCI config space buffer
*
* This function requires a 256-bytes config space. Unknown/unavailable bytes should be set to 0xff.
*/
HWLOC_DECLSPEC unsigned hwloc_pcidisc_find_cap(const unsigned char *config, unsigned cap);
/** \brief Fill linkspeed by reading the PCI config space where PCI_CAP_ID_EXP is at position offset.
*
* Needs 20 bytes of EXP capability block starting at offset in the config space
* for registers up to link status.
*/
HWLOC_DECLSPEC int hwloc_pcidisc_find_linkspeed(const unsigned char *config, unsigned offset, float *linkspeed);
/** \brief Return the hwloc object type (PCI device or Bridge) for the given class and configuration space.
*
* This function requires 16 bytes of common configuration header at the beginning of config.
*/
HWLOC_DECLSPEC hwloc_obj_type_t hwloc_pcidisc_check_bridge_type(unsigned device_class, const unsigned char *config);
/** \brief Fills the attributes of the given PCI bridge using the given PCI config space.
*
* This function requires 32 bytes of common configuration header at the beginning of config.
*
* Returns -1 and destroys /p obj if bridge fields are invalid.
*/
HWLOC_DECLSPEC int hwloc_pcidisc_find_bridge_buses(unsigned domain, unsigned bus, unsigned dev, unsigned func,
unsigned *secondary_busp, unsigned *subordinate_busp,
const unsigned char *config);
/** \brief Insert a PCI object in the given PCI tree by looking at PCI bus IDs.
*
* If \p treep points to \c NULL, the new object is inserted there.
*/
HWLOC_DECLSPEC void hwloc_pcidisc_tree_insert_by_busid(struct hwloc_obj **treep, struct hwloc_obj *obj);
/** \brief Add some hostbridges on top of the given tree of PCI objects and attach them to the topology.
*
* Other backends may lookup PCI objects or localities (for instance to attach OS devices)
* by using hwloc_pcidisc_find_by_busid() or hwloc_pcidisc_find_busid_parent().
*/
HWLOC_DECLSPEC int hwloc_pcidisc_tree_attach(struct hwloc_topology *topology, struct hwloc_obj *tree);
/** @} */
/** \defgroup hwlocality_components_pcifind Components and Plugins: finding PCI objects during other discoveries
*
* \note These structures and functions may change when ::HWLOC_COMPONENT_ABI is modified.
*
* @{
*/
/** \brief Find the object or a parent of a PCI bus ID.
*
* When attaching a new object (typically an OS device) whose locality
* is specified by PCI bus ID, this function returns the PCI object
* to use as a parent for attaching.
*
* If the exact PCI device with this bus ID exists, it is returned.
* Otherwise (for instance if it was filtered out), the function returns
* another object with similar locality (for instance a parent bridge,
* or the local CPU Package).
*/
HWLOC_DECLSPEC struct hwloc_obj * hwloc_pci_find_parent_by_busid(struct hwloc_topology *topology, unsigned domain, unsigned bus, unsigned dev, unsigned func);
/** \brief Find the PCI device or bridge matching a PCI bus ID exactly.
*
* This is useful for adding specific information about some objects
* based on their PCI id. When it comes to attaching objects based on
* PCI locality, hwloc_pci_find_parent_by_busid() should be preferred.
*/
HWLOC_DECLSPEC struct hwloc_obj * hwloc_pci_find_by_busid(struct hwloc_topology *topology, unsigned domain, unsigned bus, unsigned dev, unsigned func);
/** \brief Handle to a new distances structure during its addition to the topology. */
typedef void * hwloc_backend_distances_add_handle_t;
/** \brief Create a new empty distances structure.
*
* This is identical to hwloc_distances_add_create()
* but this variant is designed for backend inserting
* distances during topology discovery.
*/
HWLOC_DECLSPEC hwloc_backend_distances_add_handle_t
hwloc_backend_distances_add_create(hwloc_topology_t topology,
const char *name, unsigned long kind,
unsigned long flags);
/** \brief Specify the objects and values in a new empty distances structure.
*
* This is similar to hwloc_distances_add_values()
* but this variant is designed for backend inserting
* distances during topology discovery.
*
* The only semantical difference is that \p objs and \p values
* are not duplicated, but directly attached to the topology.
* On success, these arrays are given to the core and should not
* ever be freed by the caller anymore.
*/
HWLOC_DECLSPEC int
hwloc_backend_distances_add_values(hwloc_topology_t topology,
hwloc_backend_distances_add_handle_t handle,
unsigned nbobjs, hwloc_obj_t *objs,
hwloc_uint64_t *values,
unsigned long flags);
/** \brief Commit a new distances structure.
*
* This is similar to hwloc_distances_add_commit()
* but this variant is designed for backend inserting
* distances during topology discovery.
*/
HWLOC_DECLSPEC int
hwloc_backend_distances_add_commit(hwloc_topology_t topology,
hwloc_backend_distances_add_handle_t handle,
unsigned long flags);
/** @} */
#endif /* HWLOC_PLUGINS_H */

View file

@ -1,901 +0,0 @@
/*
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* Copyright © 2010-2021 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
#ifndef HWLOC_RENAME_H
#define HWLOC_RENAME_H
#include "hwloc/autogen/config.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Only enact these defines if we're actually renaming the symbols
(i.e., avoid trying to have no-op defines if we're *not*
renaming). */
#if HWLOC_SYM_TRANSFORM
/* Use a preprocessor two-step in order to get the prefixing right.
Make 2 macros: HWLOC_NAME and HWLOC_NAME_CAPS for renaming
things. */
#define HWLOC_MUNGE_NAME(a, b) HWLOC_MUNGE_NAME2(a, b)
#define HWLOC_MUNGE_NAME2(a, b) a ## b
#define HWLOC_NAME(name) HWLOC_MUNGE_NAME(HWLOC_SYM_PREFIX, hwloc_ ## name)
/* FIXME: should be "HWLOC_ ## name" below, unchanged because it doesn't matter much and could break some embedders hacks */
#define HWLOC_NAME_CAPS(name) HWLOC_MUNGE_NAME(HWLOC_SYM_PREFIX_CAPS, hwloc_ ## name)
/* Now define all the "real" names to be the prefixed names. This
allows us to use the real names throughout the code base (i.e.,
"hwloc_<foo>"); the preprocessor will adjust to have the prefixed
name under the covers. */
/* Names from hwloc.h */
#define hwloc_get_api_version HWLOC_NAME(get_api_version)
#define hwloc_topology HWLOC_NAME(topology)
#define hwloc_topology_t HWLOC_NAME(topology_t)
#define hwloc_cpuset_t HWLOC_NAME(cpuset_t)
#define hwloc_const_cpuset_t HWLOC_NAME(const_cpuset_t)
#define hwloc_nodeset_t HWLOC_NAME(nodeset_t)
#define hwloc_const_nodeset_t HWLOC_NAME(const_nodeset_t)
#define HWLOC_OBJ_MACHINE HWLOC_NAME_CAPS(OBJ_MACHINE)
#define HWLOC_OBJ_NUMANODE HWLOC_NAME_CAPS(OBJ_NUMANODE)
#define HWLOC_OBJ_MEMCACHE HWLOC_NAME_CAPS(OBJ_MEMCACHE)
#define HWLOC_OBJ_PACKAGE HWLOC_NAME_CAPS(OBJ_PACKAGE)
#define HWLOC_OBJ_DIE HWLOC_NAME_CAPS(OBJ_DIE)
#define HWLOC_OBJ_CORE HWLOC_NAME_CAPS(OBJ_CORE)
#define HWLOC_OBJ_PU HWLOC_NAME_CAPS(OBJ_PU)
#define HWLOC_OBJ_L1CACHE HWLOC_NAME_CAPS(OBJ_L1CACHE)
#define HWLOC_OBJ_L2CACHE HWLOC_NAME_CAPS(OBJ_L2CACHE)
#define HWLOC_OBJ_L3CACHE HWLOC_NAME_CAPS(OBJ_L3CACHE)
#define HWLOC_OBJ_L4CACHE HWLOC_NAME_CAPS(OBJ_L4CACHE)
#define HWLOC_OBJ_L5CACHE HWLOC_NAME_CAPS(OBJ_L5CACHE)
#define HWLOC_OBJ_L1ICACHE HWLOC_NAME_CAPS(OBJ_L1ICACHE)
#define HWLOC_OBJ_L2ICACHE HWLOC_NAME_CAPS(OBJ_L2ICACHE)
#define HWLOC_OBJ_L3ICACHE HWLOC_NAME_CAPS(OBJ_L3ICACHE)
#define HWLOC_OBJ_MISC HWLOC_NAME_CAPS(OBJ_MISC)
#define HWLOC_OBJ_GROUP HWLOC_NAME_CAPS(OBJ_GROUP)
#define HWLOC_OBJ_BRIDGE HWLOC_NAME_CAPS(OBJ_BRIDGE)
#define HWLOC_OBJ_PCI_DEVICE HWLOC_NAME_CAPS(OBJ_PCI_DEVICE)
#define HWLOC_OBJ_OS_DEVICE HWLOC_NAME_CAPS(OBJ_OS_DEVICE)
#define HWLOC_OBJ_TYPE_MAX HWLOC_NAME_CAPS(OBJ_TYPE_MAX)
#define hwloc_obj_type_t HWLOC_NAME(obj_type_t)
#define hwloc_obj_cache_type_e HWLOC_NAME(obj_cache_type_e)
#define hwloc_obj_cache_type_t HWLOC_NAME(obj_cache_type_t)
#define HWLOC_OBJ_CACHE_UNIFIED HWLOC_NAME_CAPS(OBJ_CACHE_UNIFIED)
#define HWLOC_OBJ_CACHE_DATA HWLOC_NAME_CAPS(OBJ_CACHE_DATA)
#define HWLOC_OBJ_CACHE_INSTRUCTION HWLOC_NAME_CAPS(OBJ_CACHE_INSTRUCTION)
#define hwloc_obj_bridge_type_e HWLOC_NAME(obj_bridge_type_e)
#define hwloc_obj_bridge_type_t HWLOC_NAME(obj_bridge_type_t)
#define HWLOC_OBJ_BRIDGE_HOST HWLOC_NAME_CAPS(OBJ_BRIDGE_HOST)
#define HWLOC_OBJ_BRIDGE_PCI HWLOC_NAME_CAPS(OBJ_BRIDGE_PCI)
#define hwloc_obj_osdev_type_e HWLOC_NAME(obj_osdev_type_e)
#define hwloc_obj_osdev_type_t HWLOC_NAME(obj_osdev_type_t)
#define HWLOC_OBJ_OSDEV_BLOCK HWLOC_NAME_CAPS(OBJ_OSDEV_BLOCK)
#define HWLOC_OBJ_OSDEV_GPU HWLOC_NAME_CAPS(OBJ_OSDEV_GPU)
#define HWLOC_OBJ_OSDEV_NETWORK HWLOC_NAME_CAPS(OBJ_OSDEV_NETWORK)
#define HWLOC_OBJ_OSDEV_OPENFABRICS HWLOC_NAME_CAPS(OBJ_OSDEV_OPENFABRICS)
#define HWLOC_OBJ_OSDEV_DMA HWLOC_NAME_CAPS(OBJ_OSDEV_DMA)
#define HWLOC_OBJ_OSDEV_COPROC HWLOC_NAME_CAPS(OBJ_OSDEV_COPROC)
#define hwloc_compare_types HWLOC_NAME(compare_types)
#define hwloc_obj HWLOC_NAME(obj)
#define hwloc_obj_t HWLOC_NAME(obj_t)
#define hwloc_info_s HWLOC_NAME(info_s)
#define hwloc_obj_attr_u HWLOC_NAME(obj_attr_u)
#define hwloc_numanode_attr_s HWLOC_NAME(numanode_attr_s)
#define hwloc_memory_page_type_s HWLOC_NAME(memory_page_type_s)
#define hwloc_cache_attr_s HWLOC_NAME(cache_attr_s)
#define hwloc_group_attr_s HWLOC_NAME(group_attr_s)
#define hwloc_pcidev_attr_s HWLOC_NAME(pcidev_attr_s)
#define hwloc_bridge_attr_s HWLOC_NAME(bridge_attr_s)
#define hwloc_osdev_attr_s HWLOC_NAME(osdev_attr_s)
#define hwloc_topology_init HWLOC_NAME(topology_init)
#define hwloc_topology_load HWLOC_NAME(topology_load)
#define hwloc_topology_destroy HWLOC_NAME(topology_destroy)
#define hwloc_topology_dup HWLOC_NAME(topology_dup)
#define hwloc_topology_abi_check HWLOC_NAME(topology_abi_check)
#define hwloc_topology_check HWLOC_NAME(topology_check)
#define hwloc_topology_flags_e HWLOC_NAME(topology_flags_e)
#define HWLOC_TOPOLOGY_FLAG_INCLUDE_DISALLOWED HWLOC_NAME_CAPS(TOPOLOGY_FLAG_WITH_DISALLOWED)
#define HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM HWLOC_NAME_CAPS(TOPOLOGY_FLAG_IS_THISSYSTEM)
#define HWLOC_TOPOLOGY_FLAG_THISSYSTEM_ALLOWED_RESOURCES HWLOC_NAME_CAPS(TOPOLOGY_FLAG_THISSYSTEM_ALLOWED_RESOURCES)
#define HWLOC_TOPOLOGY_FLAG_IMPORT_SUPPORT HWLOC_NAME_CAPS(TOPOLOGY_FLAG_IMPORT_SUPPORT)
#define HWLOC_TOPOLOGY_FLAG_RESTRICT_TO_CPUBINDING HWLOC_NAME_CAPS(TOPOLOGY_FLAG_RESTRICT_TO_CPUBINDING)
#define HWLOC_TOPOLOGY_FLAG_RESTRICT_TO_MEMBINDING HWLOC_NAME_CAPS(TOPOLOGY_FLAG_RESTRICT_TO_MEMBINDING)
#define HWLOC_TOPOLOGY_FLAG_DONT_CHANGE_BINDING HWLOC_NAME_CAPS(TOPOLOGY_FLAG_DONT_CHANGE_BINDING)
#define hwloc_topology_set_pid HWLOC_NAME(topology_set_pid)
#define hwloc_topology_set_synthetic HWLOC_NAME(topology_set_synthetic)
#define hwloc_topology_set_xml HWLOC_NAME(topology_set_xml)
#define hwloc_topology_set_xmlbuffer HWLOC_NAME(topology_set_xmlbuffer)
#define hwloc_topology_components_flag_e HWLOC_NAME(hwloc_topology_components_flag_e)
#define HWLOC_TOPOLOGY_COMPONENTS_FLAG_BLACKLIST HWLOC_NAME_CAPS(TOPOLOGY_COMPONENTS_FLAG_BLACKLIST)
#define hwloc_topology_set_components HWLOC_NAME(topology_set_components)
#define hwloc_topology_set_flags HWLOC_NAME(topology_set_flags)
#define hwloc_topology_is_thissystem HWLOC_NAME(topology_is_thissystem)
#define hwloc_topology_get_flags HWLOC_NAME(topology_get_flags)
#define hwloc_topology_discovery_support HWLOC_NAME(topology_discovery_support)
#define hwloc_topology_cpubind_support HWLOC_NAME(topology_cpubind_support)
#define hwloc_topology_membind_support HWLOC_NAME(topology_membind_support)
#define hwloc_topology_misc_support HWLOC_NAME(topology_misc_support)
#define hwloc_topology_support HWLOC_NAME(topology_support)
#define hwloc_topology_get_support HWLOC_NAME(topology_get_support)
#define hwloc_type_filter_e HWLOC_NAME(type_filter_e)
#define HWLOC_TYPE_FILTER_KEEP_ALL HWLOC_NAME_CAPS(TYPE_FILTER_KEEP_ALL)
#define HWLOC_TYPE_FILTER_KEEP_NONE HWLOC_NAME_CAPS(TYPE_FILTER_KEEP_NONE)
#define HWLOC_TYPE_FILTER_KEEP_STRUCTURE HWLOC_NAME_CAPS(TYPE_FILTER_KEEP_STRUCTURE)
#define HWLOC_TYPE_FILTER_KEEP_IMPORTANT HWLOC_NAME_CAPS(TYPE_FILTER_KEEP_IMPORTANT)
#define hwloc_topology_set_type_filter HWLOC_NAME(topology_set_type_filter)
#define hwloc_topology_get_type_filter HWLOC_NAME(topology_get_type_filter)
#define hwloc_topology_set_all_types_filter HWLOC_NAME(topology_set_all_types_filter)
#define hwloc_topology_set_cache_types_filter HWLOC_NAME(topology_set_cache_types_filter)
#define hwloc_topology_set_icache_types_filter HWLOC_NAME(topology_set_icache_types_filter)
#define hwloc_topology_set_io_types_filter HWLOC_NAME(topology_set_io_types_filter)
#define hwloc_topology_set_userdata HWLOC_NAME(topology_set_userdata)
#define hwloc_topology_get_userdata HWLOC_NAME(topology_get_userdata)
#define hwloc_restrict_flags_e HWLOC_NAME(restrict_flags_e)
#define HWLOC_RESTRICT_FLAG_REMOVE_CPULESS HWLOC_NAME_CAPS(RESTRICT_FLAG_REMOVE_CPULESS)
#define HWLOC_RESTRICT_FLAG_BYNODESET HWLOC_NAME_CAPS(RESTRICT_FLAG_BYNODESET)
#define HWLOC_RESTRICT_FLAG_REMOVE_MEMLESS HWLOC_NAME_CAPS(RESTRICT_FLAG_REMOVE_MEMLESS)
#define HWLOC_RESTRICT_FLAG_ADAPT_MISC HWLOC_NAME_CAPS(RESTRICT_FLAG_ADAPT_MISC)
#define HWLOC_RESTRICT_FLAG_ADAPT_IO HWLOC_NAME_CAPS(RESTRICT_FLAG_ADAPT_IO)
#define hwloc_topology_restrict HWLOC_NAME(topology_restrict)
#define hwloc_allow_flags_e HWLOC_NAME(allow_flags_e)
#define HWLOC_ALLOW_FLAG_ALL HWLOC_NAME_CAPS(ALLOW_FLAG_ALL)
#define HWLOC_ALLOW_FLAG_LOCAL_RESTRICTIONS HWLOC_NAME_CAPS(ALLOW_FLAG_LOCAL_RESTRICTIONS)
#define HWLOC_ALLOW_FLAG_CUSTOM HWLOC_NAME_CAPS(ALLOW_FLAG_CUSTOM)
#define hwloc_topology_allow HWLOC_NAME(topology_allow)
#define hwloc_topology_insert_misc_object HWLOC_NAME(topology_insert_misc_object)
#define hwloc_topology_alloc_group_object HWLOC_NAME(topology_alloc_group_object)
#define hwloc_topology_insert_group_object HWLOC_NAME(topology_insert_group_object)
#define hwloc_obj_add_other_obj_sets HWLOC_NAME(obj_add_other_obj_sets)
#define hwloc_topology_refresh HWLOC_NAME(topology_refresh)
#define hwloc_topology_get_depth HWLOC_NAME(topology_get_depth)
#define hwloc_get_type_depth HWLOC_NAME(get_type_depth)
#define hwloc_get_memory_parents_depth HWLOC_NAME(get_memory_parents_depth)
#define hwloc_get_type_depth_e HWLOC_NAME(get_type_depth_e)
#define HWLOC_TYPE_DEPTH_UNKNOWN HWLOC_NAME_CAPS(TYPE_DEPTH_UNKNOWN)
#define HWLOC_TYPE_DEPTH_MULTIPLE HWLOC_NAME_CAPS(TYPE_DEPTH_MULTIPLE)
#define HWLOC_TYPE_DEPTH_BRIDGE HWLOC_NAME_CAPS(TYPE_DEPTH_BRIDGE)
#define HWLOC_TYPE_DEPTH_PCI_DEVICE HWLOC_NAME_CAPS(TYPE_DEPTH_PCI_DEVICE)
#define HWLOC_TYPE_DEPTH_OS_DEVICE HWLOC_NAME_CAPS(TYPE_DEPTH_OS_DEVICE)
#define HWLOC_TYPE_DEPTH_MISC HWLOC_NAME_CAPS(TYPE_DEPTH_MISC)
#define HWLOC_TYPE_DEPTH_NUMANODE HWLOC_NAME_CAPS(TYPE_DEPTH_NUMANODE)
#define HWLOC_TYPE_DEPTH_MEMCACHE HWLOC_NAME_CAPS(TYPE_DEPTH_MEMCACHE)
#define hwloc_get_depth_type HWLOC_NAME(get_depth_type)
#define hwloc_get_nbobjs_by_depth HWLOC_NAME(get_nbobjs_by_depth)
#define hwloc_get_nbobjs_by_type HWLOC_NAME(get_nbobjs_by_type)
#define hwloc_get_obj_by_depth HWLOC_NAME(get_obj_by_depth )
#define hwloc_get_obj_by_type HWLOC_NAME(get_obj_by_type )
#define hwloc_obj_type_string HWLOC_NAME(obj_type_string )
#define hwloc_obj_type_snprintf HWLOC_NAME(obj_type_snprintf )
#define hwloc_obj_attr_snprintf HWLOC_NAME(obj_attr_snprintf )
#define hwloc_type_sscanf HWLOC_NAME(type_sscanf)
#define hwloc_type_sscanf_as_depth HWLOC_NAME(type_sscanf_as_depth)
#define hwloc_obj_get_info_by_name HWLOC_NAME(obj_get_info_by_name)
#define hwloc_obj_add_info HWLOC_NAME(obj_add_info)
#define HWLOC_CPUBIND_PROCESS HWLOC_NAME_CAPS(CPUBIND_PROCESS)
#define HWLOC_CPUBIND_THREAD HWLOC_NAME_CAPS(CPUBIND_THREAD)
#define HWLOC_CPUBIND_STRICT HWLOC_NAME_CAPS(CPUBIND_STRICT)
#define HWLOC_CPUBIND_NOMEMBIND HWLOC_NAME_CAPS(CPUBIND_NOMEMBIND)
#define hwloc_cpubind_flags_t HWLOC_NAME(cpubind_flags_t)
#define hwloc_set_cpubind HWLOC_NAME(set_cpubind)
#define hwloc_get_cpubind HWLOC_NAME(get_cpubind)
#define hwloc_set_proc_cpubind HWLOC_NAME(set_proc_cpubind)
#define hwloc_get_proc_cpubind HWLOC_NAME(get_proc_cpubind)
#define hwloc_set_thread_cpubind HWLOC_NAME(set_thread_cpubind)
#define hwloc_get_thread_cpubind HWLOC_NAME(get_thread_cpubind)
#define hwloc_get_last_cpu_location HWLOC_NAME(get_last_cpu_location)
#define hwloc_get_proc_last_cpu_location HWLOC_NAME(get_proc_last_cpu_location)
#define HWLOC_MEMBIND_DEFAULT HWLOC_NAME_CAPS(MEMBIND_DEFAULT)
#define HWLOC_MEMBIND_FIRSTTOUCH HWLOC_NAME_CAPS(MEMBIND_FIRSTTOUCH)
#define HWLOC_MEMBIND_BIND HWLOC_NAME_CAPS(MEMBIND_BIND)
#define HWLOC_MEMBIND_INTERLEAVE HWLOC_NAME_CAPS(MEMBIND_INTERLEAVE)
#define HWLOC_MEMBIND_NEXTTOUCH HWLOC_NAME_CAPS(MEMBIND_NEXTTOUCH)
#define HWLOC_MEMBIND_MIXED HWLOC_NAME_CAPS(MEMBIND_MIXED)
#define hwloc_membind_policy_t HWLOC_NAME(membind_policy_t)
#define HWLOC_MEMBIND_PROCESS HWLOC_NAME_CAPS(MEMBIND_PROCESS)
#define HWLOC_MEMBIND_THREAD HWLOC_NAME_CAPS(MEMBIND_THREAD)
#define HWLOC_MEMBIND_STRICT HWLOC_NAME_CAPS(MEMBIND_STRICT)
#define HWLOC_MEMBIND_MIGRATE HWLOC_NAME_CAPS(MEMBIND_MIGRATE)
#define HWLOC_MEMBIND_NOCPUBIND HWLOC_NAME_CAPS(MEMBIND_NOCPUBIND)
#define HWLOC_MEMBIND_BYNODESET HWLOC_NAME_CAPS(MEMBIND_BYNODESET)
#define hwloc_membind_flags_t HWLOC_NAME(membind_flags_t)
#define hwloc_set_membind HWLOC_NAME(set_membind)
#define hwloc_get_membind HWLOC_NAME(get_membind)
#define hwloc_set_proc_membind HWLOC_NAME(set_proc_membind)
#define hwloc_get_proc_membind HWLOC_NAME(get_proc_membind)
#define hwloc_set_area_membind HWLOC_NAME(set_area_membind)
#define hwloc_get_area_membind HWLOC_NAME(get_area_membind)
#define hwloc_get_area_memlocation HWLOC_NAME(get_area_memlocation)
#define hwloc_alloc_membind HWLOC_NAME(alloc_membind)
#define hwloc_alloc HWLOC_NAME(alloc)
#define hwloc_free HWLOC_NAME(free)
#define hwloc_get_non_io_ancestor_obj HWLOC_NAME(get_non_io_ancestor_obj)
#define hwloc_get_next_pcidev HWLOC_NAME(get_next_pcidev)
#define hwloc_get_pcidev_by_busid HWLOC_NAME(get_pcidev_by_busid)
#define hwloc_get_pcidev_by_busidstring HWLOC_NAME(get_pcidev_by_busidstring)
#define hwloc_get_next_osdev HWLOC_NAME(get_next_osdev)
#define hwloc_get_next_bridge HWLOC_NAME(get_next_bridge)
#define hwloc_bridge_covers_pcibus HWLOC_NAME(bridge_covers_pcibus)
/* hwloc/bitmap.h */
#define hwloc_bitmap_s HWLOC_NAME(bitmap_s)
#define hwloc_bitmap_t HWLOC_NAME(bitmap_t)
#define hwloc_const_bitmap_t HWLOC_NAME(const_bitmap_t)
#define hwloc_bitmap_alloc HWLOC_NAME(bitmap_alloc)
#define hwloc_bitmap_alloc_full HWLOC_NAME(bitmap_alloc_full)
#define hwloc_bitmap_free HWLOC_NAME(bitmap_free)
#define hwloc_bitmap_dup HWLOC_NAME(bitmap_dup)
#define hwloc_bitmap_copy HWLOC_NAME(bitmap_copy)
#define hwloc_bitmap_snprintf HWLOC_NAME(bitmap_snprintf)
#define hwloc_bitmap_asprintf HWLOC_NAME(bitmap_asprintf)
#define hwloc_bitmap_sscanf HWLOC_NAME(bitmap_sscanf)
#define hwloc_bitmap_list_snprintf HWLOC_NAME(bitmap_list_snprintf)
#define hwloc_bitmap_list_asprintf HWLOC_NAME(bitmap_list_asprintf)
#define hwloc_bitmap_list_sscanf HWLOC_NAME(bitmap_list_sscanf)
#define hwloc_bitmap_taskset_snprintf HWLOC_NAME(bitmap_taskset_snprintf)
#define hwloc_bitmap_taskset_asprintf HWLOC_NAME(bitmap_taskset_asprintf)
#define hwloc_bitmap_taskset_sscanf HWLOC_NAME(bitmap_taskset_sscanf)
#define hwloc_bitmap_zero HWLOC_NAME(bitmap_zero)
#define hwloc_bitmap_fill HWLOC_NAME(bitmap_fill)
#define hwloc_bitmap_from_ulong HWLOC_NAME(bitmap_from_ulong)
#define hwloc_bitmap_from_ulongs HWLOC_NAME(bitmap_from_ulongs)
#define hwloc_bitmap_from_ith_ulong HWLOC_NAME(bitmap_from_ith_ulong)
#define hwloc_bitmap_to_ulong HWLOC_NAME(bitmap_to_ulong)
#define hwloc_bitmap_to_ith_ulong HWLOC_NAME(bitmap_to_ith_ulong)
#define hwloc_bitmap_to_ulongs HWLOC_NAME(bitmap_to_ulongs)
#define hwloc_bitmap_nr_ulongs HWLOC_NAME(bitmap_nr_ulongs)
#define hwloc_bitmap_only HWLOC_NAME(bitmap_only)
#define hwloc_bitmap_allbut HWLOC_NAME(bitmap_allbut)
#define hwloc_bitmap_set HWLOC_NAME(bitmap_set)
#define hwloc_bitmap_set_range HWLOC_NAME(bitmap_set_range)
#define hwloc_bitmap_set_ith_ulong HWLOC_NAME(bitmap_set_ith_ulong)
#define hwloc_bitmap_clr HWLOC_NAME(bitmap_clr)
#define hwloc_bitmap_clr_range HWLOC_NAME(bitmap_clr_range)
#define hwloc_bitmap_isset HWLOC_NAME(bitmap_isset)
#define hwloc_bitmap_iszero HWLOC_NAME(bitmap_iszero)
#define hwloc_bitmap_isfull HWLOC_NAME(bitmap_isfull)
#define hwloc_bitmap_isequal HWLOC_NAME(bitmap_isequal)
#define hwloc_bitmap_intersects HWLOC_NAME(bitmap_intersects)
#define hwloc_bitmap_isincluded HWLOC_NAME(bitmap_isincluded)
#define hwloc_bitmap_or HWLOC_NAME(bitmap_or)
#define hwloc_bitmap_and HWLOC_NAME(bitmap_and)
#define hwloc_bitmap_andnot HWLOC_NAME(bitmap_andnot)
#define hwloc_bitmap_xor HWLOC_NAME(bitmap_xor)
#define hwloc_bitmap_not HWLOC_NAME(bitmap_not)
#define hwloc_bitmap_first HWLOC_NAME(bitmap_first)
#define hwloc_bitmap_last HWLOC_NAME(bitmap_last)
#define hwloc_bitmap_next HWLOC_NAME(bitmap_next)
#define hwloc_bitmap_first_unset HWLOC_NAME(bitmap_first_unset)
#define hwloc_bitmap_last_unset HWLOC_NAME(bitmap_last_unset)
#define hwloc_bitmap_next_unset HWLOC_NAME(bitmap_next_unset)
#define hwloc_bitmap_singlify HWLOC_NAME(bitmap_singlify)
#define hwloc_bitmap_compare_first HWLOC_NAME(bitmap_compare_first)
#define hwloc_bitmap_compare HWLOC_NAME(bitmap_compare)
#define hwloc_bitmap_weight HWLOC_NAME(bitmap_weight)
/* hwloc/helper.h */
#define hwloc_get_type_or_below_depth HWLOC_NAME(get_type_or_below_depth)
#define hwloc_get_type_or_above_depth HWLOC_NAME(get_type_or_above_depth)
#define hwloc_get_root_obj HWLOC_NAME(get_root_obj)
#define hwloc_get_ancestor_obj_by_depth HWLOC_NAME(get_ancestor_obj_by_depth)
#define hwloc_get_ancestor_obj_by_type HWLOC_NAME(get_ancestor_obj_by_type)
#define hwloc_get_next_obj_by_depth HWLOC_NAME(get_next_obj_by_depth)
#define hwloc_get_next_obj_by_type HWLOC_NAME(get_next_obj_by_type)
#define hwloc_bitmap_singlify_per_core HWLOC_NAME(bitmap_singlify_by_core)
#define hwloc_get_pu_obj_by_os_index HWLOC_NAME(get_pu_obj_by_os_index)
#define hwloc_get_numanode_obj_by_os_index HWLOC_NAME(get_numanode_obj_by_os_index)
#define hwloc_get_next_child HWLOC_NAME(get_next_child)
#define hwloc_get_common_ancestor_obj HWLOC_NAME(get_common_ancestor_obj)
#define hwloc_obj_is_in_subtree HWLOC_NAME(obj_is_in_subtree)
#define hwloc_get_first_largest_obj_inside_cpuset HWLOC_NAME(get_first_largest_obj_inside_cpuset)
#define hwloc_get_largest_objs_inside_cpuset HWLOC_NAME(get_largest_objs_inside_cpuset)
#define hwloc_get_next_obj_inside_cpuset_by_depth HWLOC_NAME(get_next_obj_inside_cpuset_by_depth)
#define hwloc_get_next_obj_inside_cpuset_by_type HWLOC_NAME(get_next_obj_inside_cpuset_by_type)
#define hwloc_get_obj_inside_cpuset_by_depth HWLOC_NAME(get_obj_inside_cpuset_by_depth)
#define hwloc_get_obj_inside_cpuset_by_type HWLOC_NAME(get_obj_inside_cpuset_by_type)
#define hwloc_get_nbobjs_inside_cpuset_by_depth HWLOC_NAME(get_nbobjs_inside_cpuset_by_depth)
#define hwloc_get_nbobjs_inside_cpuset_by_type HWLOC_NAME(get_nbobjs_inside_cpuset_by_type)
#define hwloc_get_obj_index_inside_cpuset HWLOC_NAME(get_obj_index_inside_cpuset)
#define hwloc_get_child_covering_cpuset HWLOC_NAME(get_child_covering_cpuset)
#define hwloc_get_obj_covering_cpuset HWLOC_NAME(get_obj_covering_cpuset)
#define hwloc_get_next_obj_covering_cpuset_by_depth HWLOC_NAME(get_next_obj_covering_cpuset_by_depth)
#define hwloc_get_next_obj_covering_cpuset_by_type HWLOC_NAME(get_next_obj_covering_cpuset_by_type)
#define hwloc_obj_type_is_normal HWLOC_NAME(obj_type_is_normal)
#define hwloc_obj_type_is_memory HWLOC_NAME(obj_type_is_memory)
#define hwloc_obj_type_is_io HWLOC_NAME(obj_type_is_io)
#define hwloc_obj_type_is_cache HWLOC_NAME(obj_type_is_cache)
#define hwloc_obj_type_is_dcache HWLOC_NAME(obj_type_is_dcache)
#define hwloc_obj_type_is_icache HWLOC_NAME(obj_type_is_icache)
#define hwloc_get_cache_type_depth HWLOC_NAME(get_cache_type_depth)
#define hwloc_get_cache_covering_cpuset HWLOC_NAME(get_cache_covering_cpuset)
#define hwloc_get_shared_cache_covering_obj HWLOC_NAME(get_shared_cache_covering_obj)
#define hwloc_get_closest_objs HWLOC_NAME(get_closest_objs)
#define hwloc_get_obj_below_by_type HWLOC_NAME(get_obj_below_by_type)
#define hwloc_get_obj_below_array_by_type HWLOC_NAME(get_obj_below_array_by_type)
#define hwloc_get_obj_with_same_locality HWLOC_NAME(get_obj_with_same_locality)
#define hwloc_distrib_flags_e HWLOC_NAME(distrib_flags_e)
#define HWLOC_DISTRIB_FLAG_REVERSE HWLOC_NAME_CAPS(DISTRIB_FLAG_REVERSE)
#define hwloc_distrib HWLOC_NAME(distrib)
#define hwloc_alloc_membind_policy HWLOC_NAME(alloc_membind_policy)
#define hwloc_alloc_membind_policy_nodeset HWLOC_NAME(alloc_membind_policy_nodeset)
#define hwloc_topology_get_complete_cpuset HWLOC_NAME(topology_get_complete_cpuset)
#define hwloc_topology_get_topology_cpuset HWLOC_NAME(topology_get_topology_cpuset)
#define hwloc_topology_get_allowed_cpuset HWLOC_NAME(topology_get_allowed_cpuset)
#define hwloc_topology_get_complete_nodeset HWLOC_NAME(topology_get_complete_nodeset)
#define hwloc_topology_get_topology_nodeset HWLOC_NAME(topology_get_topology_nodeset)
#define hwloc_topology_get_allowed_nodeset HWLOC_NAME(topology_get_allowed_nodeset)
#define hwloc_cpuset_to_nodeset HWLOC_NAME(cpuset_to_nodeset)
#define hwloc_cpuset_from_nodeset HWLOC_NAME(cpuset_from_nodeset)
/* memattrs.h */
#define hwloc_memattr_id_e HWLOC_NAME(memattr_id_e)
#define HWLOC_MEMATTR_ID_CAPACITY HWLOC_NAME_CAPS(MEMATTR_ID_CAPACITY)
#define HWLOC_MEMATTR_ID_LOCALITY HWLOC_NAME_CAPS(MEMATTR_ID_LOCALITY)
#define HWLOC_MEMATTR_ID_BANDWIDTH HWLOC_NAME_CAPS(MEMATTR_ID_BANDWIDTH)
#define HWLOC_MEMATTR_ID_LATENCY HWLOC_NAME_CAPS(MEMATTR_ID_LATENCY)
#define hwloc_memattr_id_t HWLOC_NAME(memattr_id_t)
#define hwloc_memattr_get_by_name HWLOC_NAME(memattr_get_by_name)
#define hwloc_location HWLOC_NAME(location)
#define hwloc_location_type_e HWLOC_NAME(location_type_e)
#define HWLOC_LOCATION_TYPE_OBJECT HWLOC_NAME_CAPS(LOCATION_TYPE_OBJECT)
#define HWLOC_LOCATION_TYPE_CPUSET HWLOC_NAME_CAPS(LOCATION_TYPE_CPUSET)
#define hwloc_location_u HWLOC_NAME(location_u)
#define hwloc_memattr_get_value HWLOC_NAME(memattr_get_value)
#define hwloc_memattr_get_best_target HWLOC_NAME(memattr_get_best_target)
#define hwloc_memattr_get_best_initiator HWLOC_NAME(memattr_get_best_initiator)
#define hwloc_local_numanode_flag_e HWLOC_NAME(local_numanode_flag_e)
#define HWLOC_LOCAL_NUMANODE_FLAG_LARGER_LOCALITY HWLOC_NAME_CAPS(LOCAL_NUMANODE_FLAG_LARGER_LOCALITY)
#define HWLOC_LOCAL_NUMANODE_FLAG_SMALLER_LOCALITY HWLOC_NAME_CAPS(LOCAL_NUMANODE_FLAG_SMALLER_LOCALITY)
#define HWLOC_LOCAL_NUMANODE_FLAG_ALL HWLOC_NAME_CAPS(LOCAL_NUMANODE_FLAG_ALL)
#define hwloc_get_local_numanode_objs HWLOC_NAME(get_local_numanode_objs)
#define hwloc_memattr_get_name HWLOC_NAME(memattr_get_name)
#define hwloc_memattr_get_flags HWLOC_NAME(memattr_get_flags)
#define hwloc_memattr_flag_e HWLOC_NAME(memattr_flag_e)
#define HWLOC_MEMATTR_FLAG_HIGHER_FIRST HWLOC_NAME_CAPS(MEMATTR_FLAG_HIGHER_FIRST)
#define HWLOC_MEMATTR_FLAG_LOWER_FIRST HWLOC_NAME_CAPS(MEMATTR_FLAG_LOWER_FIRST)
#define HWLOC_MEMATTR_FLAG_NEED_INITIATOR HWLOC_NAME_CAPS(MEMATTR_FLAG_NEED_INITIATOR)
#define hwloc_memattr_register HWLOC_NAME(memattr_register)
#define hwloc_memattr_set_value HWLOC_NAME(memattr_set_value)
#define hwloc_memattr_get_targets HWLOC_NAME(memattr_get_targets)
#define hwloc_memattr_get_initiators HWLOC_NAME(memattr_get_initiators)
/* cpukinds.h */
#define hwloc_cpukinds_get_nr HWLOC_NAME(cpukinds_get_nr)
#define hwloc_cpukinds_get_by_cpuset HWLOC_NAME(cpukinds_get_by_cpuset)
#define hwloc_cpukinds_get_info HWLOC_NAME(cpukinds_get_info)
#define hwloc_cpukinds_register HWLOC_NAME(cpukinds_register)
/* export.h */
#define hwloc_topology_export_xml_flags_e HWLOC_NAME(topology_export_xml_flags_e)
#define HWLOC_TOPOLOGY_EXPORT_XML_FLAG_V1 HWLOC_NAME_CAPS(TOPOLOGY_EXPORT_XML_FLAG_V1)
#define hwloc_topology_export_xml HWLOC_NAME(topology_export_xml)
#define hwloc_topology_export_xmlbuffer HWLOC_NAME(topology_export_xmlbuffer)
#define hwloc_free_xmlbuffer HWLOC_NAME(free_xmlbuffer)
#define hwloc_topology_set_userdata_export_callback HWLOC_NAME(topology_set_userdata_export_callback)
#define hwloc_export_obj_userdata HWLOC_NAME(export_obj_userdata)
#define hwloc_export_obj_userdata_base64 HWLOC_NAME(export_obj_userdata_base64)
#define hwloc_topology_set_userdata_import_callback HWLOC_NAME(topology_set_userdata_import_callback)
#define hwloc_topology_export_synthetic_flags_e HWLOC_NAME(topology_export_synthetic_flags_e)
#define HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_EXTENDED_TYPES HWLOC_NAME_CAPS(TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_EXTENDED_TYPES)
#define HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_ATTRS HWLOC_NAME_CAPS(TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_ATTRS)
#define HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_V1 HWLOC_NAME_CAPS(TOPOLOGY_EXPORT_SYNTHETIC_FLAG_V1)
#define HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_IGNORE_MEMORY HWLOC_NAME_CAPS(TOPOLOGY_EXPORT_SYNTHETIC_FLAG_IGNORE_MEMORY)
#define hwloc_topology_export_synthetic HWLOC_NAME(topology_export_synthetic)
/* distances.h */
#define hwloc_distances_s HWLOC_NAME(distances_s)
#define hwloc_distances_kind_e HWLOC_NAME(distances_kind_e)
#define HWLOC_DISTANCES_KIND_FROM_OS HWLOC_NAME_CAPS(DISTANCES_KIND_FROM_OS)
#define HWLOC_DISTANCES_KIND_FROM_USER HWLOC_NAME_CAPS(DISTANCES_KIND_FROM_USER)
#define HWLOC_DISTANCES_KIND_MEANS_LATENCY HWLOC_NAME_CAPS(DISTANCES_KIND_MEANS_LATENCY)
#define HWLOC_DISTANCES_KIND_MEANS_BANDWIDTH HWLOC_NAME_CAPS(DISTANCES_KIND_MEANS_BANDWIDTH)
#define HWLOC_DISTANCES_KIND_HETEROGENEOUS_TYPES HWLOC_NAME_CAPS(DISTANCES_KIND_HETEROGENEOUS_TYPES)
#define hwloc_distances_get HWLOC_NAME(distances_get)
#define hwloc_distances_get_by_depth HWLOC_NAME(distances_get_by_depth)
#define hwloc_distances_get_by_type HWLOC_NAME(distances_get_by_type)
#define hwloc_distances_get_by_name HWLOC_NAME(distances_get_by_name)
#define hwloc_distances_get_name HWLOC_NAME(distances_get_name)
#define hwloc_distances_release HWLOC_NAME(distances_release)
#define hwloc_distances_obj_index HWLOC_NAME(distances_obj_index)
#define hwloc_distances_obj_pair_values HWLOC_NAME(distances_pair_values)
#define hwloc_distances_transform_e HWLOC_NAME(distances_transform_e)
#define HWLOC_DISTANCES_TRANSFORM_REMOVE_NULL HWLOC_NAME_CAPS(DISTANCES_TRANSFORM_REMOVE_NULL)
#define HWLOC_DISTANCES_TRANSFORM_LINKS HWLOC_NAME_CAPS(DISTANCES_TRANSFORM_LINKS)
#define HWLOC_DISTANCES_TRANSFORM_MERGE_SWITCH_PORTS HWLOC_NAME_CAPS(DISTANCES_TRANSFORM_MERGE_SWITCH_PORTS)
#define HWLOC_DISTANCES_TRANSFORM_TRANSITIVE_CLOSURE HWLOC_NAME_CAPS(DISTANCES_TRANSFORM_TRANSITIVE_CLOSURE)
#define hwloc_distances_transform HWLOC_NAME(distances_transform)
#define hwloc_distances_add_flag_e HWLOC_NAME(distances_add_flag_e)
#define HWLOC_DISTANCES_ADD_FLAG_GROUP HWLOC_NAME_CAPS(DISTANCES_ADD_FLAG_GROUP)
#define HWLOC_DISTANCES_ADD_FLAG_GROUP_INACCURATE HWLOC_NAME_CAPS(DISTANCES_ADD_FLAG_GROUP_INACCURATE)
#define hwloc_distances_add_handle_t HWLOC_NAME(distances_add_handle_t)
#define hwloc_distances_add_create HWLOC_NAME(distances_add_create)
#define hwloc_distances_add_values HWLOC_NAME(distances_add_values)
#define hwloc_distances_add_commit HWLOC_NAME(distances_add_commit)
#define hwloc_distances_remove HWLOC_NAME(distances_remove)
#define hwloc_distances_remove_by_depth HWLOC_NAME(distances_remove_by_depth)
#define hwloc_distances_remove_by_type HWLOC_NAME(distances_remove_by_type)
#define hwloc_distances_release_remove HWLOC_NAME(distances_release_remove)
/* diff.h */
#define hwloc_topology_diff_obj_attr_type_e HWLOC_NAME(topology_diff_obj_attr_type_e)
#define hwloc_topology_diff_obj_attr_type_t HWLOC_NAME(topology_diff_obj_attr_type_t)
#define HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_SIZE HWLOC_NAME_CAPS(TOPOLOGY_DIFF_OBJ_ATTR_SIZE)
#define HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_NAME HWLOC_NAME_CAPS(TOPOLOGY_DIFF_OBJ_ATTR_NAME)
#define HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_INFO HWLOC_NAME_CAPS(TOPOLOGY_DIFF_OBJ_ATTR_INFO)
#define hwloc_topology_diff_obj_attr_u HWLOC_NAME(topology_diff_obj_attr_u)
#define hwloc_topology_diff_obj_attr_generic_s HWLOC_NAME(topology_diff_obj_attr_generic_s)
#define hwloc_topology_diff_obj_attr_uint64_s HWLOC_NAME(topology_diff_obj_attr_uint64_s)
#define hwloc_topology_diff_obj_attr_string_s HWLOC_NAME(topology_diff_obj_attr_string_s)
#define hwloc_topology_diff_type_e HWLOC_NAME(topology_diff_type_e)
#define hwloc_topology_diff_type_t HWLOC_NAME(topology_diff_type_t)
#define HWLOC_TOPOLOGY_DIFF_OBJ_ATTR HWLOC_NAME_CAPS(TOPOLOGY_DIFF_OBJ_ATTR)
#define HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX HWLOC_NAME_CAPS(TOPOLOGY_DIFF_TOO_COMPLEX)
#define hwloc_topology_diff_u HWLOC_NAME(topology_diff_u)
#define hwloc_topology_diff_t HWLOC_NAME(topology_diff_t)
#define hwloc_topology_diff_generic_s HWLOC_NAME(topology_diff_generic_s)
#define hwloc_topology_diff_obj_attr_s HWLOC_NAME(topology_diff_obj_attr_s)
#define hwloc_topology_diff_too_complex_s HWLOC_NAME(topology_diff_too_complex_s)
#define hwloc_topology_diff_build HWLOC_NAME(topology_diff_build)
#define hwloc_topology_diff_apply_flags_e HWLOC_NAME(topology_diff_apply_flags_e)
#define HWLOC_TOPOLOGY_DIFF_APPLY_REVERSE HWLOC_NAME_CAPS(TOPOLOGY_DIFF_APPLY_REVERSE)
#define hwloc_topology_diff_apply HWLOC_NAME(topology_diff_apply)
#define hwloc_topology_diff_destroy HWLOC_NAME(topology_diff_destroy)
#define hwloc_topology_diff_load_xml HWLOC_NAME(topology_diff_load_xml)
#define hwloc_topology_diff_export_xml HWLOC_NAME(topology_diff_export_xml)
#define hwloc_topology_diff_load_xmlbuffer HWLOC_NAME(topology_diff_load_xmlbuffer)
#define hwloc_topology_diff_export_xmlbuffer HWLOC_NAME(topology_diff_export_xmlbuffer)
/* shmem.h */
#define hwloc_shmem_topology_get_length HWLOC_NAME(shmem_topology_get_length)
#define hwloc_shmem_topology_write HWLOC_NAME(shmem_topology_write)
#define hwloc_shmem_topology_adopt HWLOC_NAME(shmem_topology_adopt)
/* glibc-sched.h */
#define hwloc_cpuset_to_glibc_sched_affinity HWLOC_NAME(cpuset_to_glibc_sched_affinity)
#define hwloc_cpuset_from_glibc_sched_affinity HWLOC_NAME(cpuset_from_glibc_sched_affinity)
/* linux-libnuma.h */
#define hwloc_cpuset_to_linux_libnuma_ulongs HWLOC_NAME(cpuset_to_linux_libnuma_ulongs)
#define hwloc_nodeset_to_linux_libnuma_ulongs HWLOC_NAME(nodeset_to_linux_libnuma_ulongs)
#define hwloc_cpuset_from_linux_libnuma_ulongs HWLOC_NAME(cpuset_from_linux_libnuma_ulongs)
#define hwloc_nodeset_from_linux_libnuma_ulongs HWLOC_NAME(nodeset_from_linux_libnuma_ulongs)
#define hwloc_cpuset_to_linux_libnuma_bitmask HWLOC_NAME(cpuset_to_linux_libnuma_bitmask)
#define hwloc_nodeset_to_linux_libnuma_bitmask HWLOC_NAME(nodeset_to_linux_libnuma_bitmask)
#define hwloc_cpuset_from_linux_libnuma_bitmask HWLOC_NAME(cpuset_from_linux_libnuma_bitmask)
#define hwloc_nodeset_from_linux_libnuma_bitmask HWLOC_NAME(nodeset_from_linux_libnuma_bitmask)
/* linux.h */
#define hwloc_linux_set_tid_cpubind HWLOC_NAME(linux_set_tid_cpubind)
#define hwloc_linux_get_tid_cpubind HWLOC_NAME(linux_get_tid_cpubind)
#define hwloc_linux_get_tid_last_cpu_location HWLOC_NAME(linux_get_tid_last_cpu_location)
#define hwloc_linux_read_path_as_cpumask HWLOC_NAME(linux_read_file_cpumask)
/* windows.h */
#define hwloc_windows_get_nr_processor_groups HWLOC_NAME(windows_get_nr_processor_groups)
#define hwloc_windows_get_processor_group_cpuset HWLOC_NAME(windows_get_processor_group_cpuset)
/* openfabrics-verbs.h */
#define hwloc_ibv_get_device_cpuset HWLOC_NAME(ibv_get_device_cpuset)
#define hwloc_ibv_get_device_osdev HWLOC_NAME(ibv_get_device_osdev)
#define hwloc_ibv_get_device_osdev_by_name HWLOC_NAME(ibv_get_device_osdev_by_name)
/* opencl.h */
#define hwloc_cl_device_topology_amd HWLOC_NAME(cl_device_topology_amd)
#define hwloc_opencl_get_device_pci_busid HWLOC_NAME(opencl_get_device_pci_ids)
#define hwloc_opencl_get_device_cpuset HWLOC_NAME(opencl_get_device_cpuset)
#define hwloc_opencl_get_device_osdev HWLOC_NAME(opencl_get_device_osdev)
#define hwloc_opencl_get_device_osdev_by_index HWLOC_NAME(opencl_get_device_osdev_by_index)
/* cuda.h */
#define hwloc_cuda_get_device_pci_ids HWLOC_NAME(cuda_get_device_pci_ids)
#define hwloc_cuda_get_device_cpuset HWLOC_NAME(cuda_get_device_cpuset)
#define hwloc_cuda_get_device_pcidev HWLOC_NAME(cuda_get_device_pcidev)
#define hwloc_cuda_get_device_osdev HWLOC_NAME(cuda_get_device_osdev)
#define hwloc_cuda_get_device_osdev_by_index HWLOC_NAME(cuda_get_device_osdev_by_index)
/* cudart.h */
#define hwloc_cudart_get_device_pci_ids HWLOC_NAME(cudart_get_device_pci_ids)
#define hwloc_cudart_get_device_cpuset HWLOC_NAME(cudart_get_device_cpuset)
#define hwloc_cudart_get_device_pcidev HWLOC_NAME(cudart_get_device_pcidev)
#define hwloc_cudart_get_device_osdev_by_index HWLOC_NAME(cudart_get_device_osdev_by_index)
/* nvml.h */
#define hwloc_nvml_get_device_cpuset HWLOC_NAME(nvml_get_device_cpuset)
#define hwloc_nvml_get_device_osdev HWLOC_NAME(nvml_get_device_osdev)
#define hwloc_nvml_get_device_osdev_by_index HWLOC_NAME(nvml_get_device_osdev_by_index)
/* rsmi.h */
#define hwloc_rsmi_get_device_cpuset HWLOC_NAME(rsmi_get_device_cpuset)
#define hwloc_rsmi_get_device_osdev HWLOC_NAME(rsmi_get_device_osdev)
#define hwloc_rsmi_get_device_osdev_by_index HWLOC_NAME(rsmi_get_device_osdev_by_index)
/* levelzero.h */
#define hwloc_levelzero_get_device_cpuset HWLOC_NAME(levelzero_get_device_cpuset)
#define hwloc_levelzero_get_device_osdev HWLOC_NAME(levelzero_get_device_osdev)
/* gl.h */
#define hwloc_gl_get_display_osdev_by_port_device HWLOC_NAME(gl_get_display_osdev_by_port_device)
#define hwloc_gl_get_display_osdev_by_name HWLOC_NAME(gl_get_display_osdev_by_name)
#define hwloc_gl_get_display_by_osdev HWLOC_NAME(gl_get_display_by_osdev)
/* hwloc/plugins.h */
#define hwloc_disc_phase_e HWLOC_NAME(disc_phase_e)
#define HWLOC_DISC_PHASE_GLOBAL HWLOC_NAME_CAPS(DISC_PHASE_GLOBAL)
#define HWLOC_DISC_PHASE_CPU HWLOC_NAME_CAPS(DISC_PHASE_CPU)
#define HWLOC_DISC_PHASE_MEMORY HWLOC_NAME_CAPS(DISC_PHASE_MEMORY)
#define HWLOC_DISC_PHASE_PCI HWLOC_NAME_CAPS(DISC_PHASE_PCI)
#define HWLOC_DISC_PHASE_IO HWLOC_NAME_CAPS(DISC_PHASE_IO)
#define HWLOC_DISC_PHASE_MISC HWLOC_NAME_CAPS(DISC_PHASE_MISC)
#define HWLOC_DISC_PHASE_ANNOTATE HWLOC_NAME_CAPS(DISC_PHASE_ANNOTATE)
#define HWLOC_DISC_PHASE_TWEAK HWLOC_NAME_CAPS(DISC_PHASE_TWEAK)
#define hwloc_disc_phase_t HWLOC_NAME(disc_phase_t)
#define hwloc_disc_component HWLOC_NAME(disc_component)
#define hwloc_disc_status_flag_e HWLOC_NAME(disc_status_flag_e)
#define HWLOC_DISC_STATUS_FLAG_GOT_ALLOWED_RESOURCES HWLOC_NAME_CAPS(DISC_STATUS_FLAG_GOT_ALLOWED_RESOURCES)
#define hwloc_disc_status HWLOC_NAME(disc_status)
#define hwloc_backend HWLOC_NAME(backend)
#define hwloc_backend_alloc HWLOC_NAME(backend_alloc)
#define hwloc_backend_enable HWLOC_NAME(backend_enable)
#define hwloc_component_type_e HWLOC_NAME(component_type_e)
#define HWLOC_COMPONENT_TYPE_DISC HWLOC_NAME_CAPS(COMPONENT_TYPE_DISC)
#define HWLOC_COMPONENT_TYPE_XML HWLOC_NAME_CAPS(COMPONENT_TYPE_XML)
#define hwloc_component_type_t HWLOC_NAME(component_type_t)
#define hwloc_component HWLOC_NAME(component)
#define hwloc_plugin_check_namespace HWLOC_NAME(plugin_check_namespace)
#define hwloc_hide_errors HWLOC_NAME(hide_errors)
#define hwloc__insert_object_by_cpuset HWLOC_NAME(_insert_object_by_cpuset)
#define hwloc_insert_object_by_parent HWLOC_NAME(insert_object_by_parent)
#define hwloc_alloc_setup_object HWLOC_NAME(alloc_setup_object)
#define hwloc_obj_add_children_sets HWLOC_NAME(add_children_sets)
#define hwloc_topology_reconnect HWLOC_NAME(topology_reconnect)
#define hwloc_filter_check_pcidev_subtype_important HWLOC_NAME(filter_check_pcidev_subtype_important)
#define hwloc_filter_check_osdev_subtype_important HWLOC_NAME(filter_check_osdev_subtype_important)
#define hwloc_filter_check_keep_object_type HWLOC_NAME(filter_check_keep_object_type)
#define hwloc_filter_check_keep_object HWLOC_NAME(filter_check_keep_object)
#define hwloc_pcidisc_find_cap HWLOC_NAME(pcidisc_find_cap)
#define hwloc_pcidisc_find_linkspeed HWLOC_NAME(pcidisc_find_linkspeed)
#define hwloc_pcidisc_check_bridge_type HWLOC_NAME(pcidisc_check_bridge_type)
#define hwloc_pcidisc_find_bridge_buses HWLOC_NAME(pcidisc_find_bridge_buses)
#define hwloc_pcidisc_tree_insert_by_busid HWLOC_NAME(pcidisc_tree_insert_by_busid)
#define hwloc_pcidisc_tree_attach HWLOC_NAME(pcidisc_tree_attach)
#define hwloc_pci_find_by_busid HWLOC_NAME(pcidisc_find_by_busid)
#define hwloc_pci_find_parent_by_busid HWLOC_NAME(pcidisc_find_busid_parent)
#define hwloc_backend_distances_add_handle_t HWLOC_NAME(backend_distances_add_handle_t)
#define hwloc_backend_distances_add_create HWLOC_NAME(backend_distances_add_create)
#define hwloc_backend_distances_add_values HWLOC_NAME(backend_distances_add_values)
#define hwloc_backend_distances_add_commit HWLOC_NAME(backend_distances_add_commit)
/* hwloc/deprecated.h */
#define hwloc_distances_add HWLOC_NAME(distances_add)
#define hwloc_topology_insert_misc_object_by_parent HWLOC_NAME(topology_insert_misc_object_by_parent)
#define hwloc_obj_cpuset_snprintf HWLOC_NAME(obj_cpuset_snprintf)
#define hwloc_obj_type_sscanf HWLOC_NAME(obj_type_sscanf)
#define hwloc_set_membind_nodeset HWLOC_NAME(set_membind_nodeset)
#define hwloc_get_membind_nodeset HWLOC_NAME(get_membind_nodeset)
#define hwloc_set_proc_membind_nodeset HWLOC_NAME(set_proc_membind_nodeset)
#define hwloc_get_proc_membind_nodeset HWLOC_NAME(get_proc_membind_nodeset)
#define hwloc_set_area_membind_nodeset HWLOC_NAME(set_area_membind_nodeset)
#define hwloc_get_area_membind_nodeset HWLOC_NAME(get_area_membind_nodeset)
#define hwloc_alloc_membind_nodeset HWLOC_NAME(alloc_membind_nodeset)
#define hwloc_cpuset_to_nodeset_strict HWLOC_NAME(cpuset_to_nodeset_strict)
#define hwloc_cpuset_from_nodeset_strict HWLOC_NAME(cpuset_from_nodeset_strict)
/* private/debug.h */
#define hwloc_debug_enabled HWLOC_NAME(debug_enabled)
#define hwloc_debug HWLOC_NAME(debug)
/* private/misc.h */
#ifndef HWLOC_HAVE_CORRECT_SNPRINTF
#define hwloc_snprintf HWLOC_NAME(snprintf)
#endif
#define hwloc_ffsl_manual HWLOC_NAME(ffsl_manual)
#define hwloc_ffs32 HWLOC_NAME(ffs32)
#define hwloc_ffsl_from_ffs32 HWLOC_NAME(ffsl_from_ffs32)
#define hwloc_flsl_manual HWLOC_NAME(flsl_manual)
#define hwloc_fls32 HWLOC_NAME(fls32)
#define hwloc_flsl_from_fls32 HWLOC_NAME(flsl_from_fls32)
#define hwloc_weight_long HWLOC_NAME(weight_long)
#define hwloc_strncasecmp HWLOC_NAME(strncasecmp)
#define hwloc_bitmap_compare_inclusion HWLOC_NAME(bitmap_compare_inclusion)
#define hwloc_pci_class_string HWLOC_NAME(pci_class_string)
#define hwloc_linux_pci_link_speed_from_string HWLOC_NAME(linux_pci_link_speed_from_string)
#define hwloc_cache_type_by_depth_type HWLOC_NAME(cache_type_by_depth_type)
#define hwloc__obj_type_is_normal HWLOC_NAME(_obj_type_is_normal)
#define hwloc__obj_type_is_memory HWLOC_NAME(_obj_type_is_memory)
#define hwloc__obj_type_is_io HWLOC_NAME(_obj_type_is_io)
#define hwloc__obj_type_is_special HWLOC_NAME(_obj_type_is_special)
#define hwloc__obj_type_is_cache HWLOC_NAME(_obj_type_is_cache)
#define hwloc__obj_type_is_dcache HWLOC_NAME(_obj_type_is_dcache)
#define hwloc__obj_type_is_icache HWLOC_NAME(_obj_type_is_icache)
/* private/cpuid-x86.h */
#define hwloc_have_x86_cpuid HWLOC_NAME(have_x86_cpuid)
#define hwloc_x86_cpuid HWLOC_NAME(x86_cpuid)
/* private/xml.h */
#define hwloc__xml_verbose HWLOC_NAME(_xml_verbose)
#define hwloc__xml_import_state_s HWLOC_NAME(_xml_import_state_s)
#define hwloc__xml_import_state_t HWLOC_NAME(_xml_import_state_t)
#define hwloc__xml_import_diff HWLOC_NAME(_xml_import_diff)
#define hwloc_xml_backend_data_s HWLOC_NAME(xml_backend_data_s)
#define hwloc__xml_export_state_s HWLOC_NAME(_xml_export_state_s)
#define hwloc__xml_export_state_t HWLOC_NAME(_xml_export_state_t)
#define hwloc__xml_export_data_s HWLOC_NAME(_xml_export_data_s)
#define hwloc__xml_export_topology HWLOC_NAME(_xml_export_topology)
#define hwloc__xml_export_diff HWLOC_NAME(_xml_export_diff)
#define hwloc_xml_callbacks HWLOC_NAME(xml_callbacks)
#define hwloc_xml_component HWLOC_NAME(xml_component)
#define hwloc_xml_callbacks_register HWLOC_NAME(xml_callbacks_register)
#define hwloc_xml_callbacks_reset HWLOC_NAME(xml_callbacks_reset)
#define hwloc__xml_imported_v1distances_s HWLOC_NAME(_xml_imported_v1distances_s)
/* private/components.h */
#define hwloc_disc_component_force_enable HWLOC_NAME(disc_component_force_enable)
#define hwloc_disc_components_enable_others HWLOC_NAME(disc_components_instantiate_others)
#define hwloc_backends_is_thissystem HWLOC_NAME(backends_is_thissystem)
#define hwloc_backends_find_callbacks HWLOC_NAME(backends_find_callbacks)
#define hwloc_topology_components_init HWLOC_NAME(topology_components_init)
#define hwloc_backends_disable_all HWLOC_NAME(backends_disable_all)
#define hwloc_topology_components_fini HWLOC_NAME(topology_components_fini)
#define hwloc_components_init HWLOC_NAME(components_init)
#define hwloc_components_fini HWLOC_NAME(components_fini)
/* private/internal-private.h */
#define hwloc_xml_component HWLOC_NAME(xml_component)
#define hwloc_synthetic_component HWLOC_NAME(synthetic_component)
#define hwloc_aix_component HWLOC_NAME(aix_component)
#define hwloc_bgq_component HWLOC_NAME(bgq_component)
#define hwloc_darwin_component HWLOC_NAME(darwin_component)
#define hwloc_freebsd_component HWLOC_NAME(freebsd_component)
#define hwloc_hpux_component HWLOC_NAME(hpux_component)
#define hwloc_linux_component HWLOC_NAME(linux_component)
#define hwloc_netbsd_component HWLOC_NAME(netbsd_component)
#define hwloc_noos_component HWLOC_NAME(noos_component)
#define hwloc_solaris_component HWLOC_NAME(solaris_component)
#define hwloc_windows_component HWLOC_NAME(windows_component)
#define hwloc_x86_component HWLOC_NAME(x86_component)
#define hwloc_cuda_component HWLOC_NAME(cuda_component)
#define hwloc_gl_component HWLOC_NAME(gl_component)
#define hwloc_levelzero_component HWLOC_NAME(levelzero_component)
#define hwloc_nvml_component HWLOC_NAME(nvml_component)
#define hwloc_rsmi_component HWLOC_NAME(rsmi_component)
#define hwloc_opencl_component HWLOC_NAME(opencl_component)
#define hwloc_pci_component HWLOC_NAME(pci_component)
#define hwloc_xml_libxml_component HWLOC_NAME(xml_libxml_component)
#define hwloc_xml_nolibxml_component HWLOC_NAME(xml_nolibxml_component)
/* private/private.h */
#define hwloc_internal_location_s HWLOC_NAME(internal_location_s)
#define hwloc_special_level_s HWLOC_NAME(special_level_s)
#define hwloc_pci_forced_locality_s HWLOC_NAME(pci_forced_locality_s)
#define hwloc_pci_locality_s HWLOC_NAME(pci_locality_s)
#define hwloc_topology_forced_component_s HWLOC_NAME(topology_forced_component)
#define hwloc_alloc_root_sets HWLOC_NAME(alloc_root_sets)
#define hwloc_setup_pu_level HWLOC_NAME(setup_pu_level)
#define hwloc_get_sysctlbyname HWLOC_NAME(get_sysctlbyname)
#define hwloc_get_sysctl HWLOC_NAME(get_sysctl)
#define hwloc_fallback_nbprocessors HWLOC_NAME(fallback_nbprocessors)
#define hwloc_fallback_memsize HWLOC_NAME(fallback_memsize)
#define hwloc__object_cpusets_compare_first HWLOC_NAME(_object_cpusets_compare_first)
#define hwloc__reorder_children HWLOC_NAME(_reorder_children)
#define hwloc_topology_setup_defaults HWLOC_NAME(topology_setup_defaults)
#define hwloc_topology_clear HWLOC_NAME(topology_clear)
#define hwloc__attach_memory_object HWLOC_NAME(insert_memory_object)
#define hwloc_get_obj_by_type_and_gp_index HWLOC_NAME(get_obj_by_type_and_gp_index)
#define hwloc_pci_discovery_init HWLOC_NAME(pci_discovery_init)
#define hwloc_pci_discovery_prepare HWLOC_NAME(pci_discovery_prepare)
#define hwloc_pci_discovery_exit HWLOC_NAME(pci_discovery_exit)
#define hwloc_find_insert_io_parent_by_complete_cpuset HWLOC_NAME(hwloc_find_insert_io_parent_by_complete_cpuset)
#define hwloc__add_info HWLOC_NAME(_add_info)
#define hwloc__add_info_nodup HWLOC_NAME(_add_info_nodup)
#define hwloc__move_infos HWLOC_NAME(_move_infos)
#define hwloc__free_infos HWLOC_NAME(_free_infos)
#define hwloc__tma_dup_infos HWLOC_NAME(_tma_dup_infos)
#define hwloc_binding_hooks HWLOC_NAME(binding_hooks)
#define hwloc_set_native_binding_hooks HWLOC_NAME(set_native_binding_hooks)
#define hwloc_set_binding_hooks HWLOC_NAME(set_binding_hooks)
#define hwloc_set_linuxfs_hooks HWLOC_NAME(set_linuxfs_hooks)
#define hwloc_set_bgq_hooks HWLOC_NAME(set_bgq_hooks)
#define hwloc_set_solaris_hooks HWLOC_NAME(set_solaris_hooks)
#define hwloc_set_aix_hooks HWLOC_NAME(set_aix_hooks)
#define hwloc_set_windows_hooks HWLOC_NAME(set_windows_hooks)
#define hwloc_set_darwin_hooks HWLOC_NAME(set_darwin_hooks)
#define hwloc_set_freebsd_hooks HWLOC_NAME(set_freebsd_hooks)
#define hwloc_set_netbsd_hooks HWLOC_NAME(set_netbsd_hooks)
#define hwloc_set_hpux_hooks HWLOC_NAME(set_hpux_hooks)
#define hwloc_look_hardwired_fujitsu_k HWLOC_NAME(look_hardwired_fujitsu_k)
#define hwloc_look_hardwired_fujitsu_fx10 HWLOC_NAME(look_hardwired_fujitsu_fx10)
#define hwloc_look_hardwired_fujitsu_fx100 HWLOC_NAME(look_hardwired_fujitsu_fx100)
#define hwloc_add_uname_info HWLOC_NAME(add_uname_info)
#define hwloc_free_unlinked_object HWLOC_NAME(free_unlinked_object)
#define hwloc_free_object_and_children HWLOC_NAME(free_object_and_children)
#define hwloc_free_object_siblings_and_children HWLOC_NAME(free_object_siblings_and_children)
#define hwloc_alloc_heap HWLOC_NAME(alloc_heap)
#define hwloc_alloc_mmap HWLOC_NAME(alloc_mmap)
#define hwloc_free_heap HWLOC_NAME(free_heap)
#define hwloc_free_mmap HWLOC_NAME(free_mmap)
#define hwloc_alloc_or_fail HWLOC_NAME(alloc_or_fail)
#define hwloc_internal_distances_s HWLOC_NAME(internal_distances_s)
#define hwloc_internal_distances_init HWLOC_NAME(internal_distances_init)
#define hwloc_internal_distances_prepare HWLOC_NAME(internal_distances_prepare)
#define hwloc_internal_distances_dup HWLOC_NAME(internal_distances_dup)
#define hwloc_internal_distances_refresh HWLOC_NAME(internal_distances_refresh)
#define hwloc_internal_distances_destroy HWLOC_NAME(internal_distances_destroy)
#define hwloc_internal_distances_add HWLOC_NAME(internal_distances_add)
#define hwloc_internal_distances_add_by_index HWLOC_NAME(internal_distances_add_by_index)
#define hwloc_internal_distances_invalidate_cached_objs HWLOC_NAME(hwloc_internal_distances_invalidate_cached_objs)
#define hwloc_internal_memattr_s HWLOC_NAME(internal_memattr_s)
#define hwloc_internal_memattr_target_s HWLOC_NAME(internal_memattr_target_s)
#define hwloc_internal_memattr_initiator_s HWLOC_NAME(internal_memattr_initiator_s)
#define hwloc_internal_memattrs_init HWLOC_NAME(internal_memattrs_init)
#define hwloc_internal_memattrs_prepare HWLOC_NAME(internal_memattrs_prepare)
#define hwloc_internal_memattrs_dup HWLOC_NAME(internal_memattrs_dup)
#define hwloc_internal_memattrs_destroy HWLOC_NAME(internal_memattrs_destroy)
#define hwloc_internal_memattrs_need_refresh HWLOC_NAME(internal_memattrs_need_refresh)
#define hwloc_internal_memattrs_refresh HWLOC_NAME(internal_memattrs_refresh)
#define hwloc_internal_cpukind_s HWLOC_NAME(internal_cpukind_s)
#define hwloc_internal_cpukinds_init HWLOC_NAME(internal_cpukinds_init)
#define hwloc_internal_cpukinds_destroy HWLOC_NAME(internal_cpukinds_destroy)
#define hwloc_internal_cpukinds_dup HWLOC_NAME(internal_cpukinds_dup)
#define hwloc_internal_cpukinds_register HWLOC_NAME(internal_cpukinds_register)
#define hwloc_internal_cpukinds_rank HWLOC_NAME(internal_cpukinds_rank)
#define hwloc_internal_cpukinds_restrict HWLOC_NAME(internal_cpukinds_restrict)
#define hwloc_encode_to_base64 HWLOC_NAME(encode_to_base64)
#define hwloc_decode_from_base64 HWLOC_NAME(decode_from_base64)
#define hwloc_progname HWLOC_NAME(progname)
#define hwloc__topology_disadopt HWLOC_NAME(_topology_disadopt)
#define hwloc__topology_dup HWLOC_NAME(_topology_dup)
#define hwloc_tma HWLOC_NAME(tma)
#define hwloc_tma_malloc HWLOC_NAME(tma_malloc)
#define hwloc_tma_calloc HWLOC_NAME(tma_calloc)
#define hwloc_tma_strdup HWLOC_NAME(tma_strdup)
#define hwloc_bitmap_tma_dup HWLOC_NAME(bitmap_tma_dup)
/* private/solaris-chiptype.h */
#define hwloc_solaris_chip_info_s HWLOC_NAME(solaris_chip_info_s)
#define hwloc_solaris_get_chip_info HWLOC_NAME(solaris_get_chip_info)
#endif /* HWLOC_SYM_TRANSFORM */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_RENAME_H */

View file

@ -1,203 +0,0 @@
/*
* Copyright © 2012-2021 Inria. All rights reserved.
* Copyright (c) 2020, Advanced Micro Devices, Inc. All rights reserved.
* Written by Advanced Micro Devices,
* See COPYING in top-level directory.
*/
/** \file
* \brief Macros to help interaction between hwloc and the ROCm SMI Management Library.
*
* Applications that use both hwloc and the ROCm SMI Management Library may want to
* include this file so as to get topology information for AMD GPU devices.
*/
#ifndef HWLOC_RSMI_H
#define HWLOC_RSMI_H
#include "hwloc.h"
#include "hwloc/autogen/config.h"
#include "hwloc/helper.h"
#ifdef HWLOC_LINUX_SYS
#include "hwloc/linux.h"
#endif
#include <rocm_smi/rocm_smi.h>
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup hwlocality_rsmi Interoperability with the ROCm SMI Management Library
*
* This interface offers ways to retrieve topology information about
* devices managed by the ROCm SMI Management Library.
*
* @{
*/
/** \brief Get the CPU set of logical processors that are physically
* close to AMD GPU device whose index is \p dv_ind.
*
* Store in \p set the CPU-set describing the locality of the AMD GPU device
* whose index is \p dv_ind.
*
* Topology \p topology and device \p dv_ind must match the local machine.
* I/O devices detection and the ROCm SMI component are not needed in the
* topology.
*
* The function only returns the locality of the device.
* If more information about the device is needed, OS objects should
* be used instead, see hwloc_rsmi_get_device_osdev()
* and hwloc_rsmi_get_device_osdev_by_index().
*
* This function is currently only implemented in a meaningful way for
* Linux; other systems will simply get a full cpuset.
*/
static __hwloc_inline int
hwloc_rsmi_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
uint32_t dv_ind, hwloc_cpuset_t set)
{
#ifdef HWLOC_LINUX_SYS
/* If we're on Linux, use the sysfs mechanism to get the local cpus */
#define HWLOC_RSMI_DEVICE_SYSFS_PATH_MAX 128
char path[HWLOC_RSMI_DEVICE_SYSFS_PATH_MAX];
rsmi_status_t ret;
uint64_t bdfid = 0;
unsigned domain, device, bus;
if (!hwloc_topology_is_thissystem(topology)) {
errno = EINVAL;
return -1;
}
ret = rsmi_dev_pci_id_get(dv_ind, &bdfid);
if (RSMI_STATUS_SUCCESS != ret) {
errno = EINVAL;
return -1;
}
domain = (bdfid>>32) & 0xffffffff;
bus = ((bdfid & 0xffff)>>8) & 0xff;
device = ((bdfid & 0xff)>>3) & 0x1f;
sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.0/local_cpus", domain, bus, device);
if (hwloc_linux_read_path_as_cpumask(path, set) < 0
|| hwloc_bitmap_iszero(set))
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
#else
/* Non-Linux systems simply get a full cpuset */
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
#endif
return 0;
}
/** \brief Get the hwloc OS device object corresponding to the
* AMD GPU device whose index is \p dv_ind.
*
* \return The hwloc OS device object describing the AMD GPU device whose
* index is \p dv_ind.
* \return \c NULL if none could be found.
*
* The topology \p topology does not necessarily have to match the current
* machine. For instance the topology may be an XML import of a remote host.
* I/O devices detection and the ROCm SMI component must be enabled in the
* topology.
*
* \note The corresponding PCI device object can be obtained by looking
* at the OS device parent object (unless PCI devices are filtered out).
*/
static __hwloc_inline hwloc_obj_t
hwloc_rsmi_get_device_osdev_by_index(hwloc_topology_t topology, uint32_t dv_ind)
{
hwloc_obj_t osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
if (HWLOC_OBJ_OSDEV_GPU == osdev->attr->osdev.type
&& osdev->name
&& !strncmp("rsmi", osdev->name, 4)
&& atoi(osdev->name + 4) == (int) dv_ind)
return osdev;
}
return NULL;
}
/** \brief Get the hwloc OS device object corresponding to AMD GPU device,
* whose index is \p dv_ind.
*
* \return The hwloc OS device object that describes the given
* AMD GPU, whose index is \p dv_ind.
* \return \c NULL if none could be found.
*
* Topology \p topology and device \p dv_ind must match the local machine.
* I/O devices detection and the ROCm SMI component must be enabled in the
* topology. If not, the locality of the object may still be found using
* hwloc_rsmi_get_device_cpuset().
*
* \note The corresponding hwloc PCI device may be found by looking
* at the result parent pointer (unless PCI devices are filtered out).
*/
static __hwloc_inline hwloc_obj_t
hwloc_rsmi_get_device_osdev(hwloc_topology_t topology, uint32_t dv_ind)
{
hwloc_obj_t osdev;
rsmi_status_t ret;
uint64_t bdfid = 0;
unsigned domain, device, bus, func;
uint64_t id;
char uuid[64];
if (!hwloc_topology_is_thissystem(topology)) {
errno = EINVAL;
return NULL;
}
ret = rsmi_dev_pci_id_get(dv_ind, &bdfid);
if (RSMI_STATUS_SUCCESS != ret) {
errno = EINVAL;
return NULL;
}
domain = (bdfid>>32) & 0xffffffff;
bus = ((bdfid & 0xffff)>>8) & 0xff;
device = ((bdfid & 0xff)>>3) & 0x1f;
func = bdfid & 0x7;
ret = rsmi_dev_unique_id_get(dv_ind, &id);
if (RSMI_STATUS_SUCCESS != ret)
uuid[0] = '\0';
else
sprintf(uuid, "%lx", id);
osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
hwloc_obj_t pcidev = osdev->parent;
const char *info;
if (strncmp(osdev->name, "rsmi", 4))
continue;
if (pcidev
&& pcidev->type == HWLOC_OBJ_PCI_DEVICE
&& pcidev->attr->pcidev.domain == domain
&& pcidev->attr->pcidev.bus == bus
&& pcidev->attr->pcidev.dev == device
&& pcidev->attr->pcidev.func == func)
return osdev;
info = hwloc_obj_get_info_by_name(osdev, "AMDUUID");
if (info && !strcmp(info, uuid))
return osdev;
}
return NULL;
}
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_RSMI_H */

View file

@ -1,137 +0,0 @@
/*
* Copyright © 2013-2018 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
/** \file
* \brief Sharing topologies between processes
*/
#ifndef HWLOC_SHMEM_H
#define HWLOC_SHMEM_H
#include "hwloc.h"
#ifdef __cplusplus
extern "C" {
#elif 0
}
#endif
/** \defgroup hwlocality_shmem Sharing topologies between processes
*
* These functions are used to share a topology between processes by
* duplicating it into a file-backed shared-memory buffer.
*
* The master process must first get the required shared-memory size
* for storing this topology with hwloc_shmem_topology_get_length().
*
* Then it must find a virtual memory area of that size that is available
* in all processes (identical virtual addresses in all processes).
* On Linux, this can be done by comparing holes found in /proc/\<pid\>/maps
* for each process.
*
* Once found, it must open a destination file for storing the buffer,
* and pass it to hwloc_shmem_topology_write() together with
* virtual memory address and length obtained above.
*
* Other processes may then adopt this shared topology by opening the
* same file and passing it to hwloc_shmem_topology_adopt() with the
* exact same virtual memory address and length.
*
* @{
*/
/** \brief Get the required shared memory length for storing a topology.
*
* This length (in bytes) must be used in hwloc_shmem_topology_write()
* and hwloc_shmem_topology_adopt() later.
*
* \note Flags \p flags are currently unused, must be 0.
*/
HWLOC_DECLSPEC int hwloc_shmem_topology_get_length(hwloc_topology_t topology,
size_t *lengthp,
unsigned long flags);
/** \brief Duplicate a topology to a shared memory file.
*
* Temporarily map a file in virtual memory and duplicate the
* topology \p topology by allocating duplicates in there.
*
* The segment of the file pointed by descriptor \p fd,
* starting at offset \p fileoffset, and of length \p length (in bytes),
* will be temporarily mapped at virtual address \p mmap_address
* during the duplication.
*
* The mapping length \p length must have been previously obtained with
* hwloc_shmem_topology_get_length()
* and the topology must not have been modified in the meantime.
*
* \note Flags \p flags are currently unused, must be 0.
*
* \note The object userdata pointer is duplicated but the pointed buffer
* is not. However the caller may also allocate it manually in shared memory
* to share it as well.
*
* \return -1 with errno set to EBUSY if the virtual memory mapping defined
* by \p mmap_address and \p length isn't available in the process.
* \return -1 with errno set to EINVAL if \p fileoffset, \p mmap_address
* or \p length aren't page-aligned.
*/
HWLOC_DECLSPEC int hwloc_shmem_topology_write(hwloc_topology_t topology,
int fd, hwloc_uint64_t fileoffset,
void *mmap_address, size_t length,
unsigned long flags);
/** \brief Adopt a shared memory topology stored in a file.
*
* Map a file in virtual memory and adopt the topology that was previously
* stored there with hwloc_shmem_topology_write().
*
* The returned adopted topology in \p topologyp can be used just like any
* topology. And it must be destroyed with hwloc_topology_destroy() as usual.
*
* However the topology is read-only.
* For instance, it cannot be modified with hwloc_topology_restrict()
* and object userdata pointers cannot be changed.
*
* The segment of the file pointed by descriptor \p fd,
* starting at offset \p fileoffset, and of length \p length (in bytes),
* will be mapped at virtual address \p mmap_address.
*
* The file pointed by descriptor \p fd, the offset \p fileoffset,
* the requested mapping virtual address \p mmap_address and the length \p length
* must be identical to what was given to hwloc_shmem_topology_write() earlier.
*
* \note Flags \p flags are currently unused, must be 0.
*
* \note The object userdata pointer should not be used unless the process
* that created the shared topology also placed userdata-pointed buffers
* in shared memory.
*
* \note This function takes care of calling hwloc_topology_abi_check().
*
* \return -1 with errno set to EBUSY if the virtual memory mapping defined
* by \p mmap_address and \p length isn't available in the process.
*
* \return -1 with errno set to EINVAL if \p fileoffset, \p mmap_address
* or \p length aren't page-aligned, or do not match what was given to
* hwloc_shmem_topology_write() earlier.
*
* \return -1 with errno set to EINVAL if the layout of the topology structure
* is different between the writer process and the adopter process.
*/
HWLOC_DECLSPEC int hwloc_shmem_topology_adopt(hwloc_topology_t *topologyp,
int fd, hwloc_uint64_t fileoffset,
void *mmap_address, size_t length,
unsigned long flags);
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_SHMEM_H */

View file

@ -1,76 +0,0 @@
/*
* Copyright © 2021 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
/** \file
* \brief Macros to help interaction between hwloc and Windows.
*
* Applications that use hwloc on Windows may want to include this file
* for Windows specific hwloc features.
*/
#ifndef HWLOC_WINDOWS_H
#define HWLOC_WINDOWS_H
#include "hwloc.h"
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup hwlocality_windows Windows-specific helpers
*
* These functions query Windows processor groups.
* These groups partition the operating system into virtual sets
* of up to 64 neighbor PUs.
* Threads and processes may only be bound inside a single group.
* Although Windows processor groups may be exposed in the hwloc
* hierarchy as hwloc Groups, they are also often merged into
* existing hwloc objects such as NUMA nodes or Packages.
* This API provides explicit information about Windows processor
* groups so that applications know whether binding to a large
* set of PUs may fail because it spans over multiple Windows
* processor groups.
*
* @{
*/
/** \brief Get the number of Windows processor groups
*
* \p flags must be 0 for now.
*
* \return at least \c 1 on success.
* \return -1 on error, for instance if the topology does not match
* the current system (e.g. loaded from another machine through XML).
*/
HWLOC_DECLSPEC int hwloc_windows_get_nr_processor_groups(hwloc_topology_t topology, unsigned long flags);
/** \brief Get the CPU-set of a Windows processor group.
*
* Get the set of PU included in the processor group specified
* by \p pg_index.
* \p pg_index must be between \c 0 and the value returned
* by hwloc_windows_get_nr_processor_groups() minus 1.
*
* \p flags must be 0 for now.
*
* \return \c 0 on success.
* \return \c -1 on error, for instance if \p pg_index is invalid,
* or if the topology does not match the current system (e.g. loaded
* from another machine through XML).
*/
HWLOC_DECLSPEC int hwloc_windows_get_processor_group_cpuset(hwloc_topology_t topology, unsigned pg_index, hwloc_cpuset_t cpuset, unsigned long flags);
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HWLOC_WINDOWS_H */

View file

@ -1,672 +0,0 @@
/*
* Copyright © 2009, 2011, 2012 CNRS. All rights reserved.
* Copyright © 2009-2021 Inria. All rights reserved.
* Copyright © 2009, 2011, 2012, 2015 Université Bordeaux. All rights reserved.
* Copyright © 2009-2020 Cisco Systems, Inc. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#ifndef HWLOC_CONFIGURE_H
#define HWLOC_CONFIGURE_H
#define DECLSPEC_EXPORTS
#define HWLOC_HAVE_MSVC_CPUIDEX 1
/* Define to 1 if the system has the type `CACHE_DESCRIPTOR'. */
#define HAVE_CACHE_DESCRIPTOR 0
/* Define to 1 if the system has the type `CACHE_RELATIONSHIP'. */
#define HAVE_CACHE_RELATIONSHIP 0
/* Define to 1 if you have the `clz' function. */
/* #undef HAVE_CLZ */
/* Define to 1 if you have the `clzl' function. */
/* #undef HAVE_CLZL */
/* Define to 1 if you have the <CL/cl_ext.h> header file. */
/* #undef HAVE_CL_CL_EXT_H */
/* Define to 1 if you have the `cpuset_setaffinity' function. */
/* #undef HAVE_CPUSET_SETAFFINITY */
/* Define to 1 if you have the `cpuset_setid' function. */
/* #undef HAVE_CPUSET_SETID */
/* Define to 1 if we have -lcuda */
/* #undef HAVE_CUDA */
/* Define to 1 if you have the <cuda.h> header file. */
/* #undef HAVE_CUDA_H */
/* Define to 1 if you have the <cuda_runtime_api.h> header file. */
/* #undef HAVE_CUDA_RUNTIME_API_H */
/* Define to 1 if you have the declaration of `CL_DEVICE_TOPOLOGY_AMD', and to
0 if you don't. */
/* #undef HAVE_DECL_CL_DEVICE_TOPOLOGY_AMD */
/* Define to 1 if you have the declaration of `CTL_HW', and to 0 if you don't.
*/
/* #undef HAVE_DECL_CTL_HW */
/* Define to 1 if you have the declaration of `fabsf', and to 0 if you don't.
*/
#define HAVE_DECL_FABSF 1
/* Define to 1 if you have the declaration of `modff', and to 0 if you don't.
*/
#define HAVE_DECL_MODFF 1
/* Define to 1 if you have the declaration of `HW_NCPU', and to 0 if you
don't. */
/* #undef HAVE_DECL_HW_NCPU */
/* Define to 1 if you have the declaration of
`nvmlDeviceGetMaxPcieLinkGeneration', and to 0 if you don't. */
/* #undef HAVE_DECL_NVMLDEVICEGETMAXPCIELINKGENERATION */
/* Define to 1 if you have the declaration of `pthread_getaffinity_np', and to
0 if you don't. */
#define HAVE_DECL_PTHREAD_GETAFFINITY_NP 0
/* Define to 1 if you have the declaration of `pthread_setaffinity_np', and to
0 if you don't. */
#define HAVE_DECL_PTHREAD_SETAFFINITY_NP 0
/* Define to 1 if you have the declaration of `strtoull', and to 0 if you
don't. */
#define HAVE_DECL_STRTOULL 0
/* Define to 1 if you have the declaration of `strcasecmp', and to 0 if you
don't. */
/* #undef HWLOC_HAVE_DECL_STRCASECMP */
/* Define to 1 if you have the declaration of `snprintf', and to 0 if you
don't. */
#define HAVE_DECL_SNPRINTF 0
/* Define to 1 if you have the declaration of `_strdup', and to 0 if you
don't. */
#define HAVE_DECL__STRDUP 1
/* Define to 1 if you have the declaration of `_putenv', and to 0 if you
don't. */
#define HAVE_DECL__PUTENV 1
/* Define to 1 if you have the declaration of `_SC_LARGE_PAGESIZE', and to 0
if you don't. */
#define HAVE_DECL__SC_LARGE_PAGESIZE 0
/* Define to 1 if you have the declaration of `_SC_NPROCESSORS_CONF', and to 0
if you don't. */
#define HAVE_DECL__SC_NPROCESSORS_CONF 0
/* Define to 1 if you have the declaration of `_SC_NPROCESSORS_ONLN', and to 0
if you don't. */
#define HAVE_DECL__SC_NPROCESSORS_ONLN 0
/* Define to 1 if you have the declaration of `_SC_NPROC_CONF', and to 0 if
you don't. */
#define HAVE_DECL__SC_NPROC_CONF 0
/* Define to 1 if you have the declaration of `_SC_NPROC_ONLN', and to 0 if
you don't. */
#define HAVE_DECL__SC_NPROC_ONLN 0
/* Define to 1 if you have the declaration of `_SC_PAGESIZE', and to 0 if you
don't. */
#define HAVE_DECL__SC_PAGESIZE 0
/* Define to 1 if you have the declaration of `_SC_PAGE_SIZE', and to 0 if you
don't. */
#define HAVE_DECL__SC_PAGE_SIZE 0
/* Define to 1 if you have the <dirent.h> header file. */
/* #define HAVE_DIRENT_H 1 */
#undef HAVE_DIRENT_H
/* Define to 1 if you have the <dlfcn.h> header file. */
/* #undef HAVE_DLFCN_H */
/* Define to 1 if you have the `ffs' function. */
/* #undef HAVE_FFS */
/* Define to 1 if you have the `ffsl' function. */
/* #undef HAVE_FFSL */
/* Define to 1 if you have the `fls' function. */
/* #undef HAVE_FLS */
/* Define to 1 if you have the `flsl' function. */
/* #undef HAVE_FLSL */
/* Define to 1 if you have the `getpagesize' function. */
#define HAVE_GETPAGESIZE 1
/* Define to 1 if the system has the type `GROUP_AFFINITY'. */
#define HAVE_GROUP_AFFINITY 1
/* Define to 1 if the system has the type `GROUP_RELATIONSHIP'. */
#define HAVE_GROUP_RELATIONSHIP 1
/* Define to 1 if you have the `host_info' function. */
/* #undef HAVE_HOST_INFO */
/* Define to 1 if you have the <infiniband/verbs.h> header file. */
/* #undef HAVE_INFINIBAND_VERBS_H */
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if the system has the type `KAFFINITY'. */
#define HAVE_KAFFINITY 1
/* Define to 1 if you have the <kstat.h> header file. */
/* #undef HAVE_KSTAT_H */
/* Define to 1 if you have the <langinfo.h> header file. */
/* #undef HAVE_LANGINFO_H */
/* Define to 1 if we have -lgdi32 */
#define HAVE_LIBGDI32 1
/* Define to 1 if we have -libverbs */
/* #undef HAVE_LIBIBVERBS */
/* Define to 1 if we have -lkstat */
/* #undef HAVE_LIBKSTAT */
/* Define to 1 if we have -llgrp */
/* #undef HAVE_LIBLGRP */
/* Define to 1 if you have the <locale.h> header file. */
#define HAVE_LOCALE_H 1
/* Define to 1 if the system has the type `LOGICAL_PROCESSOR_RELATIONSHIP'. */
#define HAVE_LOGICAL_PROCESSOR_RELATIONSHIP 1
/* Define to 1 if you have the <mach/mach_host.h> header file. */
/* #undef HAVE_MACH_MACH_HOST_H */
/* Define to 1 if you have the <mach/mach_init.h> header file. */
/* #undef HAVE_MACH_MACH_INIT_H */
/* Define to 1 if you have the <malloc.h> header file. */
#define HAVE_MALLOC_H 1
/* Define to 1 if you have the `memalign' function. */
/* #undef HAVE_MEMALIGN */
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the `nl_langinfo' function. */
/* #undef HAVE_NL_LANGINFO */
/* Define to 1 if you have the <numaif.h> header file. */
/* #undef HAVE_NUMAIF_H */
/* Define to 1 if the system has the type `NUMA_NODE_RELATIONSHIP'. */
#define HAVE_NUMA_NODE_RELATIONSHIP 1
/* Define to 1 if you have the <NVCtrl/NVCtrl.h> header file. */
/* #undef HAVE_NVCTRL_NVCTRL_H */
/* Define to 1 if you have the <nvml.h> header file. */
/* #undef HAVE_NVML_H */
/* Define to 1 if you have the `openat' function. */
/* #undef HAVE_OPENAT */
/* Define to 1 if you have the <picl.h> header file. */
/* #undef HAVE_PICL_H */
/* Define to 1 if you have the `posix_memalign' function. */
/* #undef HAVE_POSIX_MEMALIGN */
/* Define to 1 if the system has the type `PROCESSOR_CACHE_TYPE'. */
#define HAVE_PROCESSOR_CACHE_TYPE 1
/* Define to 1 if the system has the type `PROCESSOR_GROUP_INFO'. */
#define HAVE_PROCESSOR_GROUP_INFO 1
/* Define to 1 if the system has the type `PROCESSOR_RELATIONSHIP'. */
#define HAVE_PROCESSOR_RELATIONSHIP 1
/* Define to 1 if the system has the type `PSAPI_WORKING_SET_EX_BLOCK'. */
/* #undef HAVE_PSAPI_WORKING_SET_EX_BLOCK */
/* Define to 1 if the system has the type `PSAPI_WORKING_SET_EX_INFORMATION'.
*/
/* #undef HAVE_PSAPI_WORKING_SET_EX_INFORMATION */
/* Define to 1 if the system has the type `PROCESSOR_NUMBER'. */
#define HAVE_PROCESSOR_NUMBER 1
/* Define to 1 if you have the <pthread_np.h> header file. */
/* #undef HAVE_PTHREAD_NP_H */
/* Define to 1 if the system has the type `pthread_t'. */
/* #undef HAVE_PTHREAD_T */
#undef HAVE_PTHREAD_T
/* Define to 1 if you have the `putwc' function. */
#define HAVE_PUTWC 1
/* Define to 1 if the system has the type `RelationProcessorPackage'. */
/* #undef HAVE_RELATIONPROCESSORPACKAGE */
/* Define to 1 if you have the `setlocale' function. */
#define HAVE_SETLOCALE 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the `strftime' function. */
#define HAVE_STRFTIME 1
/* Define to 1 if you have the <strings.h> header file. */
/* #define HAVE_STRINGS_H 1*/
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the `strncasecmp' function. */
#define HAVE_STRNCASECMP 1
/* Define to '1' if sysctl is present and usable */
/* #undef HAVE_SYSCTL */
/* Define to '1' if sysctlbyname is present and usable */
/* #undef HAVE_SYSCTLBYNAME */
/* Define to 1 if the system has the type
`SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX'. */
#define HAVE_SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX 1
/* Define to 1 if you have the <sys/cpuset.h> header file. */
/* #undef HAVE_SYS_CPUSET_H */
/* Define to 1 if you have the <sys/lgrp_user.h> header file. */
/* #undef HAVE_SYS_LGRP_USER_H */
/* Define to 1 if you have the <sys/mman.h> header file. */
/* #undef HAVE_SYS_MMAN_H */
/* Define to 1 if you have the <sys/param.h> header file. */
/* #define HAVE_SYS_PARAM_H 1 */
#undef HAVE_SYS_PARAM_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/sysctl.h> header file. */
/* #undef HAVE_SYS_SYSCTL_H */
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <sys/utsname.h> header file. */
/* #undef HAVE_SYS_UTSNAME_H */
/* Define to 1 if you have the `uname' function. */
/* #undef HAVE_UNAME */
/* Define to 1 if you have the <unistd.h> header file. */
/* #define HAVE_UNISTD_H 1 */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the `uselocale' function. */
/* #undef HAVE_USELOCALE */
/* Define to 1 if the system has the type `wchar_t'. */
#define HAVE_WCHAR_T 1
/* Define to 1 if you have the <X11/keysym.h> header file. */
/* #undef HAVE_X11_KEYSYM_H */
/* Define to 1 if you have the <X11/Xlib.h> header file. */
/* #undef HAVE_X11_XLIB_H */
/* Define to 1 if you have the <X11/Xutil.h> header file. */
/* #undef HAVE_X11_XUTIL_H */
/* Define to 1 if you have the <xlocale.h> header file. */
/* #undef HAVE_XLOCALE_H */
/* Define to 1 on AIX */
/* #undef HWLOC_AIX_SYS */
/* Define to 1 on BlueGene/Q */
/* #undef HWLOC_BGQ_SYS */
/* Whether C compiler supports symbol visibility or not */
#define HWLOC_C_HAVE_VISIBILITY 0
/* Define to 1 on Darwin */
/* #undef HWLOC_DARWIN_SYS */
/* Whether we are in debugging mode or not */
/* #undef HWLOC_DEBUG */
/* Define to 1 on *FREEBSD */
/* #undef HWLOC_FREEBSD_SYS */
/* Whether your compiler has __attribute__ or not */
/* #define HWLOC_HAVE_ATTRIBUTE 1 */
#undef HWLOC_HAVE_ATTRIBUTE
/* Whether your compiler has __attribute__ aligned or not */
/* #define HWLOC_HAVE_ATTRIBUTE_ALIGNED 1 */
/* Whether your compiler has __attribute__ always_inline or not */
/* #define HWLOC_HAVE_ATTRIBUTE_ALWAYS_INLINE 1 */
/* Whether your compiler has __attribute__ cold or not */
/* #define HWLOC_HAVE_ATTRIBUTE_COLD 1 */
/* Whether your compiler has __attribute__ const or not */
/* #define HWLOC_HAVE_ATTRIBUTE_CONST 1 */
/* Whether your compiler has __attribute__ deprecated or not */
/* #define HWLOC_HAVE_ATTRIBUTE_DEPRECATED 1 */
/* Whether your compiler has __attribute__ format or not */
/* #define HWLOC_HAVE_ATTRIBUTE_FORMAT 1 */
/* Whether your compiler has __attribute__ hot or not */
/* #define HWLOC_HAVE_ATTRIBUTE_HOT 1 */
/* Whether your compiler has __attribute__ malloc or not */
/* #define HWLOC_HAVE_ATTRIBUTE_MALLOC 1 */
/* Whether your compiler has __attribute__ may_alias or not */
/* #define HWLOC_HAVE_ATTRIBUTE_MAY_ALIAS 1 */
/* Whether your compiler has __attribute__ nonnull or not */
/* #define HWLOC_HAVE_ATTRIBUTE_NONNULL 1 */
/* Whether your compiler has __attribute__ noreturn or not */
/* #define HWLOC_HAVE_ATTRIBUTE_NORETURN 1 */
/* Whether your compiler has __attribute__ no_instrument_function or not */
/* #define HWLOC_HAVE_ATTRIBUTE_NO_INSTRUMENT_FUNCTION 1 */
/* Whether your compiler has __attribute__ packed or not */
/* #define HWLOC_HAVE_ATTRIBUTE_PACKED 1 */
/* Whether your compiler has __attribute__ pure or not */
/* #define HWLOC_HAVE_ATTRIBUTE_PURE 1 */
/* Whether your compiler has __attribute__ sentinel or not */
/* #define HWLOC_HAVE_ATTRIBUTE_SENTINEL 1 */
/* Whether your compiler has __attribute__ unused or not */
/* #define HWLOC_HAVE_ATTRIBUTE_UNUSED 1 */
/* Whether your compiler has __attribute__ warn unused result or not */
/* #define HWLOC_HAVE_ATTRIBUTE_WARN_UNUSED_RESULT 1 */
/* Whether your compiler has __attribute__ weak alias or not */
/* #define HWLOC_HAVE_ATTRIBUTE_WEAK_ALIAS 1 */
/* Define to 1 if your `ffs' function is known to be broken. */
/* #undef HWLOC_HAVE_BROKEN_FFS */
/* Define to 1 if you have the `cairo' library. */
/* #undef HWLOC_HAVE_CAIRO */
/* Define to 1 if you have the `clz' function. */
/* #undef HWLOC_HAVE_CLZ */
/* Define to 1 if you have the `clzl' function. */
/* #undef HWLOC_HAVE_CLZL */
/* Define to 1 if you have cpuid */
/* #undef HWLOC_HAVE_CPUID */
/* Define to 1 if the CPU_SET macro works */
/* #undef HWLOC_HAVE_CPU_SET */
/* Define to 1 if the CPU_SET_S macro works */
/* #undef HWLOC_HAVE_CPU_SET_S */
/* Define to 1 if you have the `cudart' SDK. */
/* #undef HWLOC_HAVE_CUDART */
/* Define to 1 if function `clz' is declared by system headers */
/* #undef HWLOC_HAVE_DECL_CLZ */
/* Define to 1 if function `clzl' is declared by system headers */
/* #undef HWLOC_HAVE_DECL_CLZL */
/* Define to 1 if function `ffs' is declared by system headers */
/* #undef HWLOC_HAVE_DECL_FFS */
/* Define to 1 if function `ffsl' is declared by system headers */
/* #undef HWLOC_HAVE_DECL_FFSL */
/* Define to 1 if function `fls' is declared by system headers */
/* #undef HWLOC_HAVE_DECL_FLS */
/* Define to 1 if function `flsl' is declared by system headers */
/* #undef HWLOC_HAVE_DECL_FLSL */
/* Define to 1 if you have the `ffs' function. */
/* #undef HWLOC_HAVE_FFS */
/* Define to 1 if you have the `ffsl' function. */
/* #undef HWLOC_HAVE_FFSL */
/* Define to 1 if you have the `fls' function. */
/* #undef HWLOC_HAVE_FLS */
/* Define to 1 if you have the `flsl' function. */
/* #undef HWLOC_HAVE_FLSL */
/* Define to 1 if you have the GL module components. */
/* #undef HWLOC_HAVE_GL */
/* Define to 1 if you have a library providing the termcap interface */
/* #undef HWLOC_HAVE_LIBTERMCAP */
/* Define to 1 if you have the `libxml2' library. */
/* #undef HWLOC_HAVE_LIBXML2 */
/* Define to 1 if building the Linux PCI component */
/* #undef HWLOC_HAVE_LINUXPCI */
/* Define to 1 if you have the `NVML' library. */
/* #undef HWLOC_HAVE_NVML */
/* Define to 1 if glibc provides the old prototype (without length) of
sched_setaffinity() */
/* #undef HWLOC_HAVE_OLD_SCHED_SETAFFINITY */
/* Define to 1 if you have the `OpenCL' library. */
/* #undef HWLOC_HAVE_OPENCL */
/* Define to 1 if the hwloc library should support dynamically-loaded plugins
*/
/* #undef HWLOC_HAVE_PLUGINS */
/* `Define to 1 if you have pthread_getthrds_np' */
/* #undef HWLOC_HAVE_PTHREAD_GETTHRDS_NP */
/* Define to 1 if pthread mutexes are available */
/* #undef HWLOC_HAVE_PTHREAD_MUTEX */
/* Define to 1 if glibc provides a prototype of sched_setaffinity() */
#define HWLOC_HAVE_SCHED_SETAFFINITY 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HWLOC_HAVE_STDINT_H 1
/* Define to 1 if you have the `windows.h' header. */
#define HWLOC_HAVE_WINDOWS_H 1
/* Define to 1 if X11 headers including Xutil.h and keysym.h are available. */
/* #undef HWLOC_HAVE_X11_KEYSYM */
/* Define to 1 if function `syscall' is available */
/* #undef HWLOC_HAVE_SYSCALL */
/* Define to 1 on HP-UX */
/* #undef HWLOC_HPUX_SYS */
/* Define to 1 on Linux */
/* #undef HWLOC_LINUX_SYS */
/* Define to 1 on *NETBSD */
/* #undef HWLOC_NETBSD_SYS */
/* The size of `unsigned int', as computed by sizeof */
#define HWLOC_SIZEOF_UNSIGNED_INT 4
/* The size of `unsigned long', as computed by sizeof */
#define HWLOC_SIZEOF_UNSIGNED_LONG 4
/* Define to 1 on Solaris */
/* #undef HWLOC_SOLARIS_SYS */
/* The hwloc symbol prefix */
#define HWLOC_SYM_PREFIX hwloc_
/* The hwloc symbol prefix in all caps */
#define HWLOC_SYM_PREFIX_CAPS HWLOC_
/* Whether we need to re-define all the hwloc public symbols or not */
#define HWLOC_SYM_TRANSFORM 0
/* Define to 1 on unsupported systems */
/* #undef HWLOC_UNSUPPORTED_SYS */
/* Define to 1 if ncurses works, preferred over curses */
/* #undef HWLOC_USE_NCURSES */
/* Define to 1 on WINDOWS */
#define HWLOC_WIN_SYS 1
/* Define to 1 on x86_32 */
/* #undef HWLOC_X86_32_ARCH */
/* Define to 1 on x86_64 */
#define HWLOC_X86_64_ARCH 1
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#define LT_OBJDIR ".libs/"
/* Name of package */
#define PACKAGE "hwloc"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "https://www.open-mpi.org/projects/hwloc/"
/* Define to the full name of this package. */
#define PACKAGE_NAME "hwloc"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "hwloc"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "hwloc"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION HWLOC_VERSION
/* The size of `unsigned int', as computed by sizeof. */
#define SIZEOF_UNSIGNED_INT 4
/* The size of `unsigned long', as computed by sizeof. */
#define SIZEOF_UNSIGNED_LONG 4
/* The size of `void *', as computed by sizeof. */
#define SIZEOF_VOID_P 8
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Enable extensions on HP-UX. */
#ifndef _HPUX_SOURCE
# define _HPUX_SOURCE 1
#endif
/* Enable extensions on AIX 3, Interix. */
/*
#ifndef _ALL_SOURCE
# define _ALL_SOURCE 1
#endif
*/
/* Enable GNU extensions on systems that have them. */
/*
#ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
#endif
*/
/* Enable threading extensions on Solaris. */
/*
#ifndef _POSIX_PTHREAD_SEMANTICS
# define _POSIX_PTHREAD_SEMANTICS 1
#endif
*/
/* Enable extensions on HP NonStop. */
/*
#ifndef _TANDEM_SOURCE
# define _TANDEM_SOURCE 1
#endif
*/
/* Enable general extensions on Solaris. */
/*
#ifndef __EXTENSIONS__
# define __EXTENSIONS__ 1
#endif
*/
/* Version number of package */
#define VERSION HWLOC_VERSION
/* Define to 1 if the X Window System is missing or not being used. */
#define X_DISPLAY_MISSING 1
/* Define to 1 if on MINIX. */
/* #undef _MINIX */
/* Define to 2 if the system does not provide POSIX.1 features except with
this defined. */
/* #undef _POSIX_1_SOURCE */
/* Define to 1 if you need to in order for `stat' and other things to work. */
/* #undef _POSIX_SOURCE */
/* Define this to the process ID type */
#define hwloc_pid_t HANDLE
/* Define this to either strncasecmp or strncmp */
#define hwloc_strncasecmp strncasecmp
/* Define this to the thread ID type */
#define hwloc_thread_t HANDLE
/* Define to 1 if you have the declaration of `GetModuleFileName', and to 0 if
you don't. */
#define HAVE_DECL_GETMODULEFILENAME 1
#endif /* HWLOC_CONFIGURE_H */

View file

@ -1,45 +0,0 @@
/*
* Copyright © 2012-2019 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
#ifdef HWLOC_INSIDE_PLUGIN
/*
* these declarations are internal only, they are not available to plugins
* (many functions below are internal static symbols).
*/
#error This file should not be used in plugins
#endif
#ifndef PRIVATE_COMPONENTS_H
#define PRIVATE_COMPONENTS_H 1
#include "hwloc/plugins.h"
struct hwloc_topology;
extern int hwloc_disc_component_force_enable(struct hwloc_topology *topology,
int envvar_forced, /* 1 if forced through envvar, 0 if forced through API */
const char *name,
const void *data1, const void *data2, const void *data3);
extern void hwloc_disc_components_enable_others(struct hwloc_topology *topology);
/* Compute the topology is_thissystem flag and find some callbacks based on enabled backends */
extern void hwloc_backends_is_thissystem(struct hwloc_topology *topology);
extern void hwloc_backends_find_callbacks(struct hwloc_topology *topology);
/* Initialize the lists of components and backends used by a topology */
extern void hwloc_topology_components_init(struct hwloc_topology *topology);
/* Disable and destroy all backends used by a topology */
extern void hwloc_backends_disable_all(struct hwloc_topology *topology);
/* Cleanup the lists of components used by a topology */
extern void hwloc_topology_components_fini(struct hwloc_topology *topology);
/* Used by the core to setup/destroy the list of components */
extern void hwloc_components_init(void); /* increases components refcount, should be called exactly once per topology (during init) */
extern void hwloc_components_fini(void); /* decreases components refcount, should be called exactly once per topology (during destroy) */
#endif /* PRIVATE_COMPONENTS_H */

View file

@ -1,86 +0,0 @@
/*
* Copyright © 2010-2012, 2014 Université Bordeaux
* Copyright © 2010 Cisco Systems, Inc. All rights reserved.
* Copyright © 2014 Inria. All rights reserved.
*
* See COPYING in top-level directory.
*/
/* Internals for x86's cpuid. */
#ifndef HWLOC_PRIVATE_CPUID_X86_H
#define HWLOC_PRIVATE_CPUID_X86_H
#if (defined HWLOC_X86_32_ARCH) && (!defined HWLOC_HAVE_MSVC_CPUIDEX)
static __hwloc_inline int hwloc_have_x86_cpuid(void)
{
int ret;
unsigned tmp, tmp2;
__asm__(
"mov $0,%0\n\t" /* Not supported a priori */
"pushfl \n\t" /* Save flags */
"pushfl \n\t" \
"pop %1 \n\t" /* Get flags */ \
#define TRY_TOGGLE \
"xor $0x00200000,%1\n\t" /* Try to toggle ID */ \
"mov %1,%2\n\t" /* Save expected value */ \
"push %1 \n\t" \
"popfl \n\t" /* Try to toggle */ \
"pushfl \n\t" \
"pop %1 \n\t" \
"cmp %1,%2\n\t" /* Compare with expected value */ \
"jnz 0f\n\t" /* Unexpected, failure */ \
TRY_TOGGLE /* Try to set/clear */
TRY_TOGGLE /* Try to clear/set */
"mov $1,%0\n\t" /* Passed the test! */
"0: \n\t"
"popfl \n\t" /* Restore flags */
: "=r" (ret), "=&r" (tmp), "=&r" (tmp2));
return ret;
}
#endif /* !defined HWLOC_X86_32_ARCH && !defined HWLOC_HAVE_MSVC_CPUIDEX*/
#if (defined HWLOC_X86_64_ARCH) || (defined HWLOC_HAVE_MSVC_CPUIDEX)
static __hwloc_inline int hwloc_have_x86_cpuid(void) { return 1; }
#endif /* HWLOC_X86_64_ARCH */
static __hwloc_inline void hwloc_x86_cpuid(unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx)
{
#ifdef HWLOC_HAVE_MSVC_CPUIDEX
int regs[4];
__cpuidex(regs, *eax, *ecx);
*eax = regs[0];
*ebx = regs[1];
*ecx = regs[2];
*edx = regs[3];
#else /* HWLOC_HAVE_MSVC_CPUIDEX */
/* Note: gcc might want to use bx or the stack for %1 addressing, so we can't
* use them :/ */
#ifdef HWLOC_X86_64_ARCH
hwloc_uint64_t sav_rbx;
__asm__(
"mov %%rbx,%2\n\t"
"cpuid\n\t"
"xchg %2,%%rbx\n\t"
"movl %k2,%1\n\t"
: "+a" (*eax), "=m" (*ebx), "=&r"(sav_rbx),
"+c" (*ecx), "=&d" (*edx));
#elif defined(HWLOC_X86_32_ARCH)
__asm__(
"mov %%ebx,%1\n\t"
"cpuid\n\t"
"xchg %%ebx,%1\n\t"
: "+a" (*eax), "=&SD" (*ebx), "+c" (*ecx), "=&d" (*edx));
#else
#error unknown architecture
#endif
#endif /* HWLOC_HAVE_MSVC_CPUIDEX */
}
#endif /* HWLOC_PRIVATE_X86_CPUID_H */

View file

@ -1,95 +0,0 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2020 Inria. All rights reserved.
* Copyright © 2009, 2011 Université Bordeaux
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
/* The configuration file */
#ifndef HWLOC_DEBUG_H
#define HWLOC_DEBUG_H
#include "private/autogen/config.h"
#include "private/misc.h"
#ifdef HWLOC_DEBUG
#include <stdarg.h>
#include <stdio.h>
#endif
#ifdef ANDROID
extern void JNIDebug(char *text);
#endif
/* Compile-time assertion */
#define HWLOC_BUILD_ASSERT(condition) ((void)sizeof(char[1 - 2*!(condition)]))
#ifdef HWLOC_DEBUG
static __hwloc_inline int hwloc_debug_enabled(void)
{
static int checked = 0;
static int enabled = 1;
if (!checked) {
const char *env = getenv("HWLOC_DEBUG_VERBOSE");
if (env)
enabled = atoi(env);
if (enabled)
fprintf(stderr, "hwloc verbose debug enabled, may be disabled with HWLOC_DEBUG_VERBOSE=0 in the environment.\n");
checked = 1;
}
return enabled;
}
#endif
static __hwloc_inline void hwloc_debug(const char *s __hwloc_attribute_unused, ...) __hwloc_attribute_format(printf, 1, 2);
static __hwloc_inline void hwloc_debug(const char *s __hwloc_attribute_unused, ...)
{
#ifdef HWLOC_DEBUG
if (hwloc_debug_enabled()) {
#ifdef ANDROID
char buffer[256];
#endif
va_list ap;
va_start(ap, s);
#ifdef ANDROID
vsprintf(buffer, s, ap);
JNIDebug(buffer);
#else
vfprintf(stderr, s, ap);
#endif
va_end(ap);
}
#endif
}
#ifdef HWLOC_DEBUG
#define hwloc_debug_bitmap(fmt, bitmap) do { \
if (hwloc_debug_enabled()) { \
char *s; \
hwloc_bitmap_asprintf(&s, bitmap); \
hwloc_debug(fmt, s); \
free(s); \
} } while (0)
#define hwloc_debug_1arg_bitmap(fmt, arg1, bitmap) do { \
if (hwloc_debug_enabled()) { \
char *s; \
hwloc_bitmap_asprintf(&s, bitmap); \
hwloc_debug(fmt, arg1, s); \
free(s); \
} } while (0)
#define hwloc_debug_2args_bitmap(fmt, arg1, arg2, bitmap) do { \
if (hwloc_debug_enabled()) { \
char *s; \
hwloc_bitmap_asprintf(&s, bitmap); \
hwloc_debug(fmt, arg1, arg2, s); \
free(s); \
} } while (0)
#else
#define hwloc_debug_bitmap(s, bitmap) do { } while(0)
#define hwloc_debug_1arg_bitmap(s, arg1, bitmap) do { } while(0)
#define hwloc_debug_2args_bitmap(s, arg1, arg2, bitmap) do { } while(0)
#endif
#endif /* HWLOC_DEBUG_H */

View file

@ -1,42 +0,0 @@
/*
* Copyright © 2018-2020 Inria. All rights reserved.
*
* See COPYING in top-level directory.
*/
/* List of components defined inside hwloc */
#ifndef PRIVATE_INTERNAL_COMPONENTS_H
#define PRIVATE_INTERNAL_COMPONENTS_H
/* global discovery */
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_xml_component;
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_synthetic_component;
/* CPU discovery */
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_aix_component;
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_bgq_component;
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_darwin_component;
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_freebsd_component;
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_hpux_component;
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_linux_component;
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_netbsd_component;
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_noos_component;
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_solaris_component;
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_windows_component;
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_x86_component;
/* I/O discovery */
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_cuda_component;
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_gl_component;
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_nvml_component;
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_rsmi_component;
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_levelzero_component;
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_opencl_component;
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_pci_component;
/* XML backend */
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_xml_nolibxml_component;
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_xml_libxml_component;
#endif /* PRIVATE_INTERNAL_COMPONENTS_H */

View file

@ -1,576 +0,0 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2019 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
/* Misc macros and inlines. */
#ifndef HWLOC_PRIVATE_MISC_H
#define HWLOC_PRIVATE_MISC_H
#include "hwloc/autogen/config.h"
#include "private/autogen/config.h"
#include "hwloc.h"
#ifdef HWLOC_HAVE_DECL_STRNCASECMP
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#else
#ifdef HAVE_CTYPE_H
#include <ctype.h>
#endif
#endif
#define HWLOC_BITS_PER_LONG (HWLOC_SIZEOF_UNSIGNED_LONG * 8)
#define HWLOC_BITS_PER_INT (HWLOC_SIZEOF_UNSIGNED_INT * 8)
#if (HWLOC_BITS_PER_LONG != 32) && (HWLOC_BITS_PER_LONG != 64)
#error "unknown size for unsigned long."
#endif
#if (HWLOC_BITS_PER_INT != 16) && (HWLOC_BITS_PER_INT != 32) && (HWLOC_BITS_PER_INT != 64)
#error "unknown size for unsigned int."
#endif
/* internal-use-only value for when we don't know the type or don't have any value */
#define HWLOC_OBJ_TYPE_NONE ((hwloc_obj_type_t) -1)
/**
* ffsl helpers.
*/
#if defined(HWLOC_HAVE_BROKEN_FFS)
/* System has a broken ffs().
* We must check the before __GNUC__ or HWLOC_HAVE_FFSL
*/
# define HWLOC_NO_FFS
#elif defined(__GNUC__)
# if (__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))
/* Starting from 3.4, gcc has a long variant. */
# define hwloc_ffsl(x) __builtin_ffsl(x)
# else
# define hwloc_ffs(x) __builtin_ffs(x)
# define HWLOC_NEED_FFSL
# endif
#elif defined(HWLOC_HAVE_FFSL)
# ifndef HWLOC_HAVE_DECL_FFSL
extern int ffsl(long) __hwloc_attribute_const;
# endif
# define hwloc_ffsl(x) ffsl(x)
#elif defined(HWLOC_HAVE_FFS)
# ifndef HWLOC_HAVE_DECL_FFS
extern int ffs(int) __hwloc_attribute_const;
# endif
# define hwloc_ffs(x) ffs(x)
# define HWLOC_NEED_FFSL
#else /* no ffs implementation */
# define HWLOC_NO_FFS
#endif
#ifdef HWLOC_NO_FFS
/* no ffs or it is known to be broken */
static __hwloc_inline int
hwloc_ffsl_manual(unsigned long x) __hwloc_attribute_const;
static __hwloc_inline int
hwloc_ffsl_manual(unsigned long x)
{
int i;
if (!x)
return 0;
i = 1;
#if HWLOC_BITS_PER_LONG >= 64
if (!(x & 0xfffffffful)) {
x >>= 32;
i += 32;
}
#endif
if (!(x & 0xffffu)) {
x >>= 16;
i += 16;
}
if (!(x & 0xff)) {
x >>= 8;
i += 8;
}
if (!(x & 0xf)) {
x >>= 4;
i += 4;
}
if (!(x & 0x3)) {
x >>= 2;
i += 2;
}
if (!(x & 0x1)) {
x >>= 1;
i += 1;
}
return i;
}
/* always define hwloc_ffsl as a macro, to avoid renaming breakage */
#define hwloc_ffsl hwloc_ffsl_manual
#elif defined(HWLOC_NEED_FFSL)
/* We only have an int ffs(int) implementation, build a long one. */
/* First make it 32 bits if it was only 16. */
static __hwloc_inline int
hwloc_ffs32(unsigned long x) __hwloc_attribute_const;
static __hwloc_inline int
hwloc_ffs32(unsigned long x)
{
#if HWLOC_BITS_PER_INT == 16
int low_ffs, hi_ffs;
low_ffs = hwloc_ffs(x & 0xfffful);
if (low_ffs)
return low_ffs;
hi_ffs = hwloc_ffs(x >> 16);
if (hi_ffs)
return hi_ffs + 16;
return 0;
#else
return hwloc_ffs(x);
#endif
}
/* Then make it 64 bit if longs are. */
static __hwloc_inline int
hwloc_ffsl_from_ffs32(unsigned long x) __hwloc_attribute_const;
static __hwloc_inline int
hwloc_ffsl_from_ffs32(unsigned long x)
{
#if HWLOC_BITS_PER_LONG == 64
int low_ffs, hi_ffs;
low_ffs = hwloc_ffs32(x & 0xfffffffful);
if (low_ffs)
return low_ffs;
hi_ffs = hwloc_ffs32(x >> 32);
if (hi_ffs)
return hi_ffs + 32;
return 0;
#else
return hwloc_ffs32(x);
#endif
}
/* always define hwloc_ffsl as a macro, to avoid renaming breakage */
#define hwloc_ffsl hwloc_ffsl_from_ffs32
#endif
/**
* flsl helpers.
*/
#ifdef __GNUC_____
# if (__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))
# define hwloc_flsl(x) ((x) ? (8*sizeof(long) - __builtin_clzl(x)) : 0)
# else
# define hwloc_fls(x) ((x) ? (8*sizeof(int) - __builtin_clz(x)) : 0)
# define HWLOC_NEED_FLSL
# endif
#elif defined(HWLOC_HAVE_FLSL)
# ifndef HWLOC_HAVE_DECL_FLSL
extern int flsl(long) __hwloc_attribute_const;
# endif
# define hwloc_flsl(x) flsl(x)
#elif defined(HWLOC_HAVE_CLZL)
# ifndef HWLOC_HAVE_DECL_CLZL
extern int clzl(long) __hwloc_attribute_const;
# endif
# define hwloc_flsl(x) ((x) ? (8*sizeof(long) - clzl(x)) : 0)
#elif defined(HWLOC_HAVE_FLS)
# ifndef HWLOC_HAVE_DECL_FLS
extern int fls(int) __hwloc_attribute_const;
# endif
# define hwloc_fls(x) fls(x)
# define HWLOC_NEED_FLSL
#elif defined(HWLOC_HAVE_CLZ)
# ifndef HWLOC_HAVE_DECL_CLZ
extern int clz(int) __hwloc_attribute_const;
# endif
# define hwloc_fls(x) ((x) ? (8*sizeof(int) - clz(x)) : 0)
# define HWLOC_NEED_FLSL
#else /* no fls implementation */
static __hwloc_inline int
hwloc_flsl_manual(unsigned long x) __hwloc_attribute_const;
static __hwloc_inline int
hwloc_flsl_manual(unsigned long x)
{
int i = 0;
if (!x)
return 0;
i = 1;
#if HWLOC_BITS_PER_LONG >= 64
if ((x & 0xffffffff00000000ul)) {
x >>= 32;
i += 32;
}
#endif
if ((x & 0xffff0000u)) {
x >>= 16;
i += 16;
}
if ((x & 0xff00)) {
x >>= 8;
i += 8;
}
if ((x & 0xf0)) {
x >>= 4;
i += 4;
}
if ((x & 0xc)) {
x >>= 2;
i += 2;
}
if ((x & 0x2)) {
x >>= 1;
i += 1;
}
return i;
}
/* always define hwloc_flsl as a macro, to avoid renaming breakage */
#define hwloc_flsl hwloc_flsl_manual
#endif
#ifdef HWLOC_NEED_FLSL
/* We only have an int fls(int) implementation, build a long one. */
/* First make it 32 bits if it was only 16. */
static __hwloc_inline int
hwloc_fls32(unsigned long x) __hwloc_attribute_const;
static __hwloc_inline int
hwloc_fls32(unsigned long x)
{
#if HWLOC_BITS_PER_INT == 16
int low_fls, hi_fls;
hi_fls = hwloc_fls(x >> 16);
if (hi_fls)
return hi_fls + 16;
low_fls = hwloc_fls(x & 0xfffful);
if (low_fls)
return low_fls;
return 0;
#else
return hwloc_fls(x);
#endif
}
/* Then make it 64 bit if longs are. */
static __hwloc_inline int
hwloc_flsl_from_fls32(unsigned long x) __hwloc_attribute_const;
static __hwloc_inline int
hwloc_flsl_from_fls32(unsigned long x)
{
#if HWLOC_BITS_PER_LONG == 64
int low_fls, hi_fls;
hi_fls = hwloc_fls32(x >> 32);
if (hi_fls)
return hi_fls + 32;
low_fls = hwloc_fls32(x & 0xfffffffful);
if (low_fls)
return low_fls;
return 0;
#else
return hwloc_fls32(x);
#endif
}
/* always define hwloc_flsl as a macro, to avoid renaming breakage */
#define hwloc_flsl hwloc_flsl_from_fls32
#endif
static __hwloc_inline int
hwloc_weight_long(unsigned long w) __hwloc_attribute_const;
static __hwloc_inline int
hwloc_weight_long(unsigned long w)
{
#if HWLOC_BITS_PER_LONG == 32
#if (__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__) >= 4)
return __builtin_popcount(w);
#else
unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
#endif
#else /* HWLOC_BITS_PER_LONG == 32 */
#if (__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__) >= 4)
return __builtin_popcountll(w);
#else
unsigned long res;
res = (w & 0x5555555555555555ul) + ((w >> 1) & 0x5555555555555555ul);
res = (res & 0x3333333333333333ul) + ((res >> 2) & 0x3333333333333333ul);
res = (res & 0x0F0F0F0F0F0F0F0Ful) + ((res >> 4) & 0x0F0F0F0F0F0F0F0Ful);
res = (res & 0x00FF00FF00FF00FFul) + ((res >> 8) & 0x00FF00FF00FF00FFul);
res = (res & 0x0000FFFF0000FFFFul) + ((res >> 16) & 0x0000FFFF0000FFFFul);
return (res & 0x00000000FFFFFFFFul) + ((res >> 32) & 0x00000000FFFFFFFFul);
#endif
#endif /* HWLOC_BITS_PER_LONG == 64 */
}
#if !HAVE_DECL_STRTOULL && defined(HAVE_STRTOULL)
unsigned long long int strtoull(const char *nptr, char **endptr, int base);
#endif
static __hwloc_inline int hwloc_strncasecmp(const char *s1, const char *s2, size_t n)
{
#ifdef HWLOC_HAVE_DECL_STRNCASECMP
return strncasecmp(s1, s2, n);
#else
while (n) {
char c1 = tolower(*s1), c2 = tolower(*s2);
if (!c1 || !c2 || c1 != c2)
return c1-c2;
n--; s1++; s2++;
}
return 0;
#endif
}
static __hwloc_inline hwloc_obj_type_t hwloc_cache_type_by_depth_type(unsigned depth, hwloc_obj_cache_type_t type)
{
if (type == HWLOC_OBJ_CACHE_INSTRUCTION) {
if (depth >= 1 && depth <= 3)
return HWLOC_OBJ_L1ICACHE + depth-1;
else
return HWLOC_OBJ_TYPE_NONE;
} else {
if (depth >= 1 && depth <= 5)
return HWLOC_OBJ_L1CACHE + depth-1;
else
return HWLOC_OBJ_TYPE_NONE;
}
}
#define HWLOC_BITMAP_EQUAL 0 /* Bitmaps are equal */
#define HWLOC_BITMAP_INCLUDED 1 /* First bitmap included in second */
#define HWLOC_BITMAP_CONTAINS 2 /* First bitmap contains second */
#define HWLOC_BITMAP_INTERSECTS 3 /* Bitmaps intersect without any inclusion */
#define HWLOC_BITMAP_DIFFERENT 4 /* Bitmaps do not intersect */
/* Compare bitmaps \p bitmap1 and \p bitmap2 from an inclusion point of view. */
HWLOC_DECLSPEC int hwloc_bitmap_compare_inclusion(hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) __hwloc_attribute_pure;
/* Return a stringified PCI class. */
HWLOC_DECLSPEC extern const char * hwloc_pci_class_string(unsigned short class_id);
/* Parse a PCI link speed (GT/s) string from Linux sysfs */
#ifdef HWLOC_LINUX_SYS
#include <stdlib.h> /* for atof() */
static __hwloc_inline float
hwloc_linux_pci_link_speed_from_string(const char *string)
{
/* don't parse Gen1 with atof() since it expects a localized string
* while the kernel sysfs files aren't.
*/
if (!strncmp(string, "2.5 ", 4))
/* "2.5 GT/s" is Gen1 with 8/10 encoding */
return 2.5 * .8;
/* also hardwire Gen2 since it also has a specific encoding */
if (!strncmp(string, "5 ", 2))
/* "5 GT/s" is Gen2 with 8/10 encoding */
return 5 * .8;
/* handle Gen3+ in a generic way */
return atof(string) * 128./130; /* Gen3+ encoding is 128/130 */
}
#endif
/* Traverse children of a parent */
#define for_each_child(child, parent) for(child = parent->first_child; child; child = child->next_sibling)
#define for_each_memory_child(child, parent) for(child = parent->memory_first_child; child; child = child->next_sibling)
#define for_each_io_child(child, parent) for(child = parent->io_first_child; child; child = child->next_sibling)
#define for_each_misc_child(child, parent) for(child = parent->misc_first_child; child; child = child->next_sibling)
/* Any object attached to normal children */
static __hwloc_inline int hwloc__obj_type_is_normal (hwloc_obj_type_t type)
{
/* type contiguity is asserted in topology_check() */
return type <= HWLOC_OBJ_GROUP || type == HWLOC_OBJ_DIE;
}
/* Any object attached to memory children, currently NUMA nodes or Memory-side caches */
static __hwloc_inline int hwloc__obj_type_is_memory (hwloc_obj_type_t type)
{
/* type contiguity is asserted in topology_check() */
return type == HWLOC_OBJ_NUMANODE || type == HWLOC_OBJ_MEMCACHE;
}
/* I/O or Misc object, without cpusets or nodesets. */
static __hwloc_inline int hwloc__obj_type_is_special (hwloc_obj_type_t type)
{
/* type contiguity is asserted in topology_check() */
return type >= HWLOC_OBJ_BRIDGE && type <= HWLOC_OBJ_MISC;
}
/* Any object attached to io children */
static __hwloc_inline int hwloc__obj_type_is_io (hwloc_obj_type_t type)
{
/* type contiguity is asserted in topology_check() */
return type >= HWLOC_OBJ_BRIDGE && type <= HWLOC_OBJ_OS_DEVICE;
}
/* Any CPU caches (not Memory-side caches) */
static __hwloc_inline int
hwloc__obj_type_is_cache(hwloc_obj_type_t type)
{
/* type contiguity is asserted in topology_check() */
return (type >= HWLOC_OBJ_L1CACHE && type <= HWLOC_OBJ_L3ICACHE);
}
static __hwloc_inline int
hwloc__obj_type_is_dcache(hwloc_obj_type_t type)
{
/* type contiguity is asserted in topology_check() */
return (type >= HWLOC_OBJ_L1CACHE && type <= HWLOC_OBJ_L5CACHE);
}
/** \brief Check whether an object is a Instruction Cache. */
static __hwloc_inline int
hwloc__obj_type_is_icache(hwloc_obj_type_t type)
{
/* type contiguity is asserted in topology_check() */
return (type >= HWLOC_OBJ_L1ICACHE && type <= HWLOC_OBJ_L3ICACHE);
}
#ifdef HAVE_USELOCALE
#include "locale.h"
#ifdef HAVE_XLOCALE_H
#include "xlocale.h"
#endif
#define hwloc_localeswitch_declare locale_t __old_locale = (locale_t)0, __new_locale
#define hwloc_localeswitch_init() do { \
__new_locale = newlocale(LC_ALL_MASK, "C", (locale_t)0); \
if (__new_locale != (locale_t)0) \
__old_locale = uselocale(__new_locale); \
} while (0)
#define hwloc_localeswitch_fini() do { \
if (__new_locale != (locale_t)0) { \
uselocale(__old_locale); \
freelocale(__new_locale); \
} \
} while(0)
#else /* HAVE_USELOCALE */
#if HWLOC_HAVE_ATTRIBUTE_UNUSED
#define hwloc_localeswitch_declare int __dummy_nolocale __hwloc_attribute_unused
#define hwloc_localeswitch_init()
#else
#define hwloc_localeswitch_declare int __dummy_nolocale
#define hwloc_localeswitch_init() (void)__dummy_nolocale
#endif
#define hwloc_localeswitch_fini()
#endif /* HAVE_USELOCALE */
#if !HAVE_DECL_FABSF
#define fabsf(f) fabs((double)(f))
#endif
#if !HAVE_DECL_MODFF
#define modff(x,iptr) (float)modf((double)x,(double *)iptr)
#endif
#if HAVE_DECL__SC_PAGE_SIZE
#define hwloc_getpagesize() sysconf(_SC_PAGE_SIZE)
#elif HAVE_DECL__SC_PAGESIZE
#define hwloc_getpagesize() sysconf(_SC_PAGESIZE)
#elif defined HAVE_GETPAGESIZE
#define hwloc_getpagesize() getpagesize()
#else
#undef hwloc_getpagesize
#endif
#if HWLOC_HAVE_ATTRIBUTE_FORMAT
# define __hwloc_attribute_format(type, str, arg) __attribute__((__format__(type, str, arg)))
#else
# define __hwloc_attribute_format(type, str, arg)
#endif
#define hwloc_memory_size_printf_value(_size, _verbose) \
((_size) < (10ULL<<20) || (_verbose) ? (((_size)>>9)+1)>>1 : (_size) < (10ULL<<30) ? (((_size)>>19)+1)>>1 : (_size) < (10ULL<<40) ? (((_size)>>29)+1)>>1 : (((_size)>>39)+1)>>1)
#define hwloc_memory_size_printf_unit(_size, _verbose) \
((_size) < (10ULL<<20) || (_verbose) ? "KB" : (_size) < (10ULL<<30) ? "MB" : (_size) < (10ULL<<40) ? "GB" : "TB")
#ifdef HWLOC_WIN_SYS
# ifndef HAVE_SSIZE_T
typedef SSIZE_T ssize_t;
# endif
# if !HAVE_DECL_STRTOULL && !defined(HAVE_STRTOULL)
# define strtoull _strtoui64
# endif
# ifndef S_ISREG
# define S_ISREG(m) ((m) & S_IFREG)
# endif
# ifndef S_ISDIR
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
# endif
# ifndef S_IRWXU
# define S_IRWXU 00700
# endif
# ifndef HWLOC_HAVE_DECL_STRCASECMP
# define strcasecmp _stricmp
# endif
# if !HAVE_DECL_SNPRINTF
# define snprintf _snprintf
# endif
# if HAVE_DECL__STRDUP
# define strdup _strdup
# endif
# if HAVE_DECL__PUTENV
# define putenv _putenv
# endif
#endif
#endif /* HWLOC_PRIVATE_MISC_H */

View file

@ -1,578 +0,0 @@
/*
* Copyright © 2014 Cisco Systems, Inc. All rights reserved.
* Copyright © 2013-2014 University of Wisconsin-La Crosse.
* All rights reserved.
* Copyright © 2015-2017 Inria. All rights reserved.
*
* $COPYRIGHT$
*
* Additional copyrights may follow
* See COPYING in top-level directory.
*
* $HEADER$
*/
#ifndef _NETLOC_PRIVATE_H_
#define _NETLOC_PRIVATE_H_
#include <hwloc.h>
#include <netloc.h>
#include <netloc/uthash.h>
#include <netloc/utarray.h>
#include <private/autogen/config.h>
#define NETLOCFILE_VERSION 1
#ifdef NETLOC_SCOTCH
#include <stdint.h>
#include <scotch.h>
#define NETLOC_int SCOTCH_Num
#else
#define NETLOC_int int
#endif
/*
* "Import" a few things from hwloc
*/
#define __netloc_attribute_unused __hwloc_attribute_unused
#define __netloc_attribute_malloc __hwloc_attribute_malloc
#define __netloc_attribute_const __hwloc_attribute_const
#define __netloc_attribute_pure __hwloc_attribute_pure
#define __netloc_attribute_deprecated __hwloc_attribute_deprecated
#define __netloc_attribute_may_alias __hwloc_attribute_may_alias
#define NETLOC_DECLSPEC HWLOC_DECLSPEC
/**********************************************************************
* Types
**********************************************************************/
/**
* Definitions for Comparators
* \sa These are the return values from the following functions:
* netloc_network_compare, netloc_dt_edge_t_compare, netloc_dt_node_t_compare
*/
typedef enum {
NETLOC_CMP_SAME = 0, /**< Compared as the Same */
NETLOC_CMP_SIMILAR = -1, /**< Compared as Similar, but not the Same */
NETLOC_CMP_DIFF = -2 /**< Compared as Different */
} netloc_compare_type_t;
/**
* Enumerated type for the various types of supported networks
*/
typedef enum {
NETLOC_NETWORK_TYPE_ETHERNET = 1, /**< Ethernet network */
NETLOC_NETWORK_TYPE_INFINIBAND = 2, /**< InfiniBand network */
NETLOC_NETWORK_TYPE_INVALID = 3 /**< Invalid network */
} netloc_network_type_t;
/**
* Enumerated type for the various types of supported topologies
*/
typedef enum {
NETLOC_TOPOLOGY_TYPE_INVALID = -1, /**< Invalid */
NETLOC_TOPOLOGY_TYPE_TREE = 1, /**< Tree */
} netloc_topology_type_t;
/**
* Enumerated type for the various types of nodes
*/
typedef enum {
NETLOC_NODE_TYPE_HOST = 0, /**< Host (a.k.a., network addressable endpoint - e.g., MAC Address) node */
NETLOC_NODE_TYPE_SWITCH = 1, /**< Switch node */
NETLOC_NODE_TYPE_INVALID = 2 /**< Invalid node */
} netloc_node_type_t;
typedef enum {
NETLOC_ARCH_TREE = 0, /* Fat tree */
} netloc_arch_type_t;
/* Pre declarations to avoid inter dependency problems */
/** \cond IGNORE */
struct netloc_topology_t;
typedef struct netloc_topology_t netloc_topology_t;
struct netloc_node_t;
typedef struct netloc_node_t netloc_node_t;
struct netloc_edge_t;
typedef struct netloc_edge_t netloc_edge_t;
struct netloc_physical_link_t;
typedef struct netloc_physical_link_t netloc_physical_link_t;
struct netloc_path_t;
typedef struct netloc_path_t netloc_path_t;
struct netloc_arch_tree_t;
typedef struct netloc_arch_tree_t netloc_arch_tree_t;
struct netloc_arch_node_t;
typedef struct netloc_arch_node_t netloc_arch_node_t;
struct netloc_arch_node_slot_t;
typedef struct netloc_arch_node_slot_t netloc_arch_node_slot_t;
struct netloc_arch_t;
typedef struct netloc_arch_t netloc_arch_t;
/** \endcond */
/**
* \struct netloc_topology_t
* \brief Netloc Topology Context
*
* An opaque data structure used to reference a network topology.
*
* \note Must be initialized with \ref netloc_topology_construct()
*/
struct netloc_topology_t {
/** Topology path */
char *topopath;
/** Subnet ID */
char *subnet_id;
/** Node List */
netloc_node_t *nodes; /* Hash table of nodes by physical_id */
netloc_node_t *nodesByHostname; /* Hash table of nodes by hostname */
netloc_physical_link_t *physical_links; /* Hash table with physcial links */
/** Partition List */
UT_array *partitions;
/** Hwloc topology List */
char *hwlocpath;
UT_array *topos;
hwloc_topology_t *hwloc_topos;
/** Type of the graph */
netloc_topology_type_t type;
};
/**
* \brief Netloc Node Type
*
* Represents the concept of a node (a.k.a., vertex, endpoint) within a network
* graph. This could be a server or a network switch. The \ref node_type parameter
* will distinguish the exact type of node this represents in the graph.
*/
struct netloc_node_t {
UT_hash_handle hh; /* makes this structure hashable with physical_id */
UT_hash_handle hh2; /* makes this structure hashable with hostname */
/** Physical ID of the node */
char physical_id[20];
/** Logical ID of the node (if any) */
int logical_id;
/** Type of the node */
netloc_node_type_t type;
/* Pointer to physical_links */
UT_array *physical_links;
/** Description information from discovery (if any) */
char *description;
/**
* Application-given private data pointer.
* Initialized to NULL, and not used by the netloc library.
*/
void * userdata;
/** Outgoing edges from this node */
netloc_edge_t *edges;
UT_array *subnodes; /* the group of nodes for the virtual nodes */
netloc_path_t *paths;
char *hostname;
UT_array *partitions; /* index in the list from the topology */
hwloc_topology_t hwlocTopo;
int hwlocTopoIdx;
};
/**
* \brief Netloc Edge Type
*
* Represents the concept of a directed edge within a network graph.
*
* \note We do not point to the netloc_node_t structure directly to
* simplify the representation, and allow the information to more easily
* be entered into the data store without circular references.
* \todo JJH Is the note above still true?
*/
struct netloc_edge_t {
UT_hash_handle hh; /* makes this structure hashable */
netloc_node_t *dest;
int id;
/** Pointers to the parent node */
netloc_node_t *node;
/* Pointer to physical_links */
UT_array *physical_links;
/** total gbits of the links */
float total_gbits;
UT_array *partitions; /* index in the list from the topology */
UT_array *subnode_edges; /* for edges going to virtual nodes */
struct netloc_edge_t *other_way;
/**
* Application-given private data pointer.
* Initialized to NULL, and not used by the netloc library.
*/
void * userdata;
};
struct netloc_physical_link_t {
UT_hash_handle hh; /* makes this structure hashable */
int id; // TODO long long
netloc_node_t *src;
netloc_node_t *dest;
int ports[2];
char *width;
char *speed;
netloc_edge_t *edge;
int other_way_id;
struct netloc_physical_link_t *other_way;
UT_array *partitions; /* index in the list from the topology */
/** gbits of the link from speed and width */
float gbits;
/** Description information from discovery (if any) */
char *description;
};
struct netloc_path_t {
UT_hash_handle hh; /* makes this structure hashable */
char dest_id[20];
UT_array *links;
};
/**********************************************************************
* Architecture structures
**********************************************************************/
struct netloc_arch_tree_t {
NETLOC_int num_levels;
NETLOC_int *degrees;
NETLOC_int *cost;
};
struct netloc_arch_node_t {
UT_hash_handle hh; /* makes this structure hashable */
char *name; /* Hash key */
netloc_node_t *node; /* Corresponding node */
int idx_in_topo; /* idx with ghost hosts to have complete topo */
int num_slots; /* it is not the real number of slots but the maximum slot idx */
int *slot_idx; /* corresponding idx in slot_tree */
int *slot_os_idx; /* corresponding os index for each leaf in tree */
netloc_arch_tree_t *slot_tree; /* Tree built from hwloc */
int num_current_slots; /* Number of PUs */
NETLOC_int *current_slots; /* indices in the complete tree */
int *slot_ranks; /* corresponding MPI rank for each leaf in tree */
};
struct netloc_arch_node_slot_t {
netloc_arch_node_t *node;
int slot;
};
struct netloc_arch_t {
netloc_topology_t *topology;
int has_slots; /* if slots are included in the architecture */
netloc_arch_type_t type;
union {
netloc_arch_tree_t *node_tree;
netloc_arch_tree_t *global_tree;
} arch;
netloc_arch_node_t *nodes_by_name;
netloc_arch_node_slot_t *node_slot_by_idx; /* node_slot by index in complete topo */
NETLOC_int num_current_hosts; /* if has_slots, host is a slot, else host is a node */
NETLOC_int *current_hosts; /* indices in the complete topology */
};
/**********************************************************************
* Topology Functions
**********************************************************************/
/**
* Allocate a topology handle.
*
* User is responsible for calling \ref netloc_detach on the topology handle.
* The network parameter information is deep copied into the topology handle, so the
* user may destruct the network handle after calling this function and/or reuse
* the network handle.
*
* \returns NETLOC_SUCCESS on success
* \returns NETLOC_ERROR upon an error.
*/
netloc_topology_t *netloc_topology_construct(char *path);
/**
* Destruct a topology handle
*
* \param topology A valid pointer to a \ref netloc_topology_t handle created
* from a prior call to \ref netloc_topology_construct.
*
* \returns NETLOC_SUCCESS on success
* \returns NETLOC_ERROR upon an error.
*/
int netloc_topology_destruct(netloc_topology_t *topology);
int netloc_topology_find_partition_idx(netloc_topology_t *topology, char *partition_name);
int netloc_topology_read_hwloc(netloc_topology_t *topology, int num_nodes,
netloc_node_t **node_list);
#define netloc_topology_iter_partitions(topology,partition) \
for ((partition) = (char **)utarray_front(topology->partitions); \
(partition) != NULL; \
(partition) = (char **)utarray_next(topology->partitions, partition))
#define netloc_topology_iter_hwloctopos(topology,hwloctopo) \
for ((hwloctopo) = (char **)utarray_front(topology->topos); \
(hwloctopo) != NULL; \
(hwloctopo) = (char **)utarray_next(topology->topos, hwloctopo))
#define netloc_topology_find_node(topology,node_id,node) \
HASH_FIND_STR(topology->nodes, node_id, node)
#define netloc_topology_iter_nodes(topology,node,_tmp) \
HASH_ITER(hh, topology->nodes, node, _tmp)
#define netloc_topology_num_nodes(topology) \
HASH_COUNT(topology->nodes)
/*************************************************/
/**
* Constructor for netloc_node_t
*
* User is responsible for calling the destructor on the handle.
*
* Returns
* A newly allocated pointer to the network information.
*/
netloc_node_t *netloc_node_construct(void);
/**
* Destructor for netloc_node_t
*
* \param node A valid node handle
*
* Returns
* NETLOC_SUCCESS on success
* NETLOC_ERROR on error
*/
int netloc_node_destruct(netloc_node_t *node);
char *netloc_node_pretty_print(netloc_node_t* node);
#define netloc_node_get_num_subnodes(node) \
utarray_len((node)->subnodes)
#define netloc_node_get_subnode(node,i) \
(*(netloc_node_t **)utarray_eltptr((node)->subnodes, (i)))
#define netloc_node_get_num_edges(node) \
utarray_len((node)->edges)
#define netloc_node_get_edge(node,i) \
(*(netloc_edge_t **)utarray_eltptr((node)->edges, (i)))
#define netloc_node_iter_edges(node,edge,_tmp) \
HASH_ITER(hh, node->edges, edge, _tmp)
#define netloc_node_iter_paths(node,path,_tmp) \
HASH_ITER(hh, node->paths, path, _tmp)
#define netloc_node_is_host(node) \
(node->type == NETLOC_NODE_TYPE_HOST)
#define netloc_node_is_switch(node) \
(node->type == NETLOC_NODE_TYPE_SWITCH)
#define netloc_node_iter_paths(node, path,_tmp) \
HASH_ITER(hh, node->paths, path, _tmp)
int netloc_node_is_in_partition(netloc_node_t *node, int partition);
/*************************************************/
/**
* Constructor for netloc_edge_t
*
* User is responsible for calling the destructor on the handle.
*
* Returns
* A newly allocated pointer to the edge information.
*/
netloc_edge_t *netloc_edge_construct(void);
/**
* Destructor for netloc_edge_t
*
* \param edge A valid edge handle
*
* Returns
* NETLOC_SUCCESS on success
* NETLOC_ERROR on error
*/
int netloc_edge_destruct(netloc_edge_t *edge);
char * netloc_edge_pretty_print(netloc_edge_t* edge);
void netloc_edge_reset_uid(void);
int netloc_edge_is_in_partition(netloc_edge_t *edge, int partition);
#define netloc_edge_get_num_links(edge) \
utarray_len((edge)->physical_links)
#define netloc_edge_get_link(edge,i) \
(*(netloc_physical_link_t **)utarray_eltptr((edge)->physical_links, (i)))
#define netloc_edge_get_num_subedges(edge) \
utarray_len((edge)->subnode_edges)
#define netloc_edge_get_subedge(edge,i) \
(*(netloc_edge_t **)utarray_eltptr((edge)->subnode_edges, (i)))
/*************************************************/
/**
* Constructor for netloc_physical_link_t
*
* User is responsible for calling the destructor on the handle.
*
* Returns
* A newly allocated pointer to the physical link information.
*/
netloc_physical_link_t * netloc_physical_link_construct(void);
/**
* Destructor for netloc_physical_link_t
*
* Returns
* NETLOC_SUCCESS on success
* NETLOC_ERROR on error
*/
int netloc_physical_link_destruct(netloc_physical_link_t *link);
char * netloc_link_pretty_print(netloc_physical_link_t* link);
/*************************************************/
netloc_path_t *netloc_path_construct(void);
int netloc_path_destruct(netloc_path_t *path);
/**********************************************************************
* Architecture functions
**********************************************************************/
netloc_arch_t * netloc_arch_construct(void);
int netloc_arch_destruct(netloc_arch_t *arch);
int netloc_arch_build(netloc_arch_t *arch, int add_slots);
int netloc_arch_set_current_resources(netloc_arch_t *arch);
int netloc_arch_set_global_resources(netloc_arch_t *arch);
int netloc_arch_node_get_hwloc_info(netloc_arch_node_t *arch);
void netloc_arch_tree_complete(netloc_arch_tree_t *tree, UT_array **down_degrees_by_level,
int num_hosts, int **parch_idx);
NETLOC_int netloc_arch_tree_num_leaves(netloc_arch_tree_t *tree);
/**********************************************************************
* Access functions of various elements of the topology
**********************************************************************/
#define netloc_get_num_partitions(object) \
utarray_len((object)->partitions)
#define netloc_get_partition(object,i) \
(*(int *)utarray_eltptr((object)->partitions, (i)))
#define netloc_path_iter_links(path,link) \
for ((link) = (netloc_physical_link_t **)utarray_front(path->links); \
(link) != NULL; \
(link) = (netloc_physical_link_t **)utarray_next(path->links, link))
/**********************************************************************
* Misc functions
**********************************************************************/
/**
* Decode the network type
*
* \param net_type A valid member of the \ref netloc_network_type_t type
*
* \returns NULL if the type is invalid
* \returns A string for that \ref netloc_network_type_t type
*/
static inline const char * netloc_network_type_decode(netloc_network_type_t net_type) {
if( NETLOC_NETWORK_TYPE_ETHERNET == net_type ) {
return "ETH";
}
else if( NETLOC_NETWORK_TYPE_INFINIBAND == net_type ) {
return "IB";
}
else {
return NULL;
}
}
/**
* Decode the node type
*
* \param node_type A valid member of the \ref netloc_node_type_t type
*
* \returns NULL if the type is invalid
* \returns A string for that \ref netloc_node_type_t type
*/
static inline const char * netloc_node_type_decode(netloc_node_type_t node_type) {
if( NETLOC_NODE_TYPE_SWITCH == node_type ) {
return "SW";
}
else if( NETLOC_NODE_TYPE_HOST == node_type ) {
return "CA";
}
else {
return NULL;
}
}
ssize_t netloc_line_get(char **lineptr, size_t *n, FILE *stream);
char *netloc_line_get_next_token(char **string, char c);
int netloc_build_comm_mat(char *filename, int *pn, double ***pmat);
#define STRDUP_IF_NOT_NULL(str) (NULL == str ? NULL : strdup(str))
#define STR_EMPTY_IF_NULL(str) (NULL == str ? "" : str)
#endif // _NETLOC_PRIVATE_H_

View file

@ -1,535 +0,0 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2021 Inria. All rights reserved.
* Copyright © 2009-2012, 2020 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
*
* See COPYING in top-level directory.
*/
/* Internal types and helpers. */
#ifdef HWLOC_INSIDE_PLUGIN
/*
* these declarations are internal only, they are not available to plugins
* (many functions below are internal static symbols).
*/
#error This file should not be used in plugins
#endif
#ifndef HWLOC_PRIVATE_H
#define HWLOC_PRIVATE_H
#include "private/autogen/config.h"
#include "hwloc.h"
#include "hwloc/bitmap.h"
#include "private/components.h"
#include "private/misc.h"
#include <sys/types.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#ifdef HAVE_SYS_UTSNAME_H
#include <sys/utsname.h>
#endif
#include <string.h>
#define HWLOC_TOPOLOGY_ABI 0x20400 /* version of the layout of struct topology */
struct hwloc_internal_location_s {
enum hwloc_location_type_e type;
union {
struct {
hwloc_obj_t obj; /* cached between refreshes */
uint64_t gp_index;
hwloc_obj_type_t type;
} object; /* if type == HWLOC_LOCATION_TYPE_OBJECT */
hwloc_cpuset_t cpuset; /* if type == HWLOC_LOCATION_TYPE_CPUSET */
} location;
};
/*****************************************************
* WARNING:
* changes below in this structure (and its children)
* should cause a bump of HWLOC_TOPOLOGY_ABI.
*****************************************************/
struct hwloc_topology {
unsigned topology_abi;
unsigned nb_levels; /* Number of horizontal levels */
unsigned nb_levels_allocated; /* Number of levels allocated and zeroed in level_nbobjects and levels below */
unsigned *level_nbobjects; /* Number of objects on each horizontal level */
struct hwloc_obj ***levels; /* Direct access to levels, levels[l = 0 .. nblevels-1][0..level_nbobjects[l]] */
unsigned long flags;
int type_depth[HWLOC_OBJ_TYPE_MAX];
enum hwloc_type_filter_e type_filter[HWLOC_OBJ_TYPE_MAX];
int is_thissystem;
int is_loaded;
int modified; /* >0 if objects were added/removed recently, which means a reconnect is needed */
hwloc_pid_t pid; /* Process ID the topology is view from, 0 for self */
void *userdata;
uint64_t next_gp_index;
void *adopted_shmem_addr;
size_t adopted_shmem_length;
#define HWLOC_NR_SLEVELS 6
#define HWLOC_SLEVEL_NUMANODE 0
#define HWLOC_SLEVEL_BRIDGE 1
#define HWLOC_SLEVEL_PCIDEV 2
#define HWLOC_SLEVEL_OSDEV 3
#define HWLOC_SLEVEL_MISC 4
#define HWLOC_SLEVEL_MEMCACHE 5
/* order must match negative depth, it's asserted in setup_defaults() */
#define HWLOC_SLEVEL_FROM_DEPTH(x) (HWLOC_TYPE_DEPTH_NUMANODE-(x))
#define HWLOC_SLEVEL_TO_DEPTH(x) (HWLOC_TYPE_DEPTH_NUMANODE-(x))
struct hwloc_special_level_s {
unsigned nbobjs;
struct hwloc_obj **objs;
struct hwloc_obj *first, *last; /* Temporarily used while listing object before building the objs array */
} slevels[HWLOC_NR_SLEVELS];
hwloc_bitmap_t allowed_cpuset;
hwloc_bitmap_t allowed_nodeset;
struct hwloc_binding_hooks {
/* These are actually rather OS hooks since some of them are not about binding */
int (*set_thisproc_cpubind)(hwloc_topology_t topology, hwloc_const_cpuset_t set, int flags);
int (*get_thisproc_cpubind)(hwloc_topology_t topology, hwloc_cpuset_t set, int flags);
int (*set_thisthread_cpubind)(hwloc_topology_t topology, hwloc_const_cpuset_t set, int flags);
int (*get_thisthread_cpubind)(hwloc_topology_t topology, hwloc_cpuset_t set, int flags);
int (*set_proc_cpubind)(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_cpuset_t set, int flags);
int (*get_proc_cpubind)(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_cpuset_t set, int flags);
#ifdef hwloc_thread_t
int (*set_thread_cpubind)(hwloc_topology_t topology, hwloc_thread_t tid, hwloc_const_cpuset_t set, int flags);
int (*get_thread_cpubind)(hwloc_topology_t topology, hwloc_thread_t tid, hwloc_cpuset_t set, int flags);
#endif
int (*get_thisproc_last_cpu_location)(hwloc_topology_t topology, hwloc_cpuset_t set, int flags);
int (*get_thisthread_last_cpu_location)(hwloc_topology_t topology, hwloc_cpuset_t set, int flags);
int (*get_proc_last_cpu_location)(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_cpuset_t set, int flags);
int (*set_thisproc_membind)(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags);
int (*get_thisproc_membind)(hwloc_topology_t topology, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags);
int (*set_thisthread_membind)(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags);
int (*get_thisthread_membind)(hwloc_topology_t topology, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags);
int (*set_proc_membind)(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags);
int (*get_proc_membind)(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags);
int (*set_area_membind)(hwloc_topology_t topology, const void *addr, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags);
int (*get_area_membind)(hwloc_topology_t topology, const void *addr, size_t len, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags);
int (*get_area_memlocation)(hwloc_topology_t topology, const void *addr, size_t len, hwloc_nodeset_t nodeset, int flags);
/* This has to return the same kind of pointer as alloc_membind, so that free_membind can be used on it */
void *(*alloc)(hwloc_topology_t topology, size_t len);
/* alloc_membind has to always succeed if !(flags & HWLOC_MEMBIND_STRICT).
* see hwloc_alloc_or_fail which is convenient for that. */
void *(*alloc_membind)(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags);
int (*free_membind)(hwloc_topology_t topology, void *addr, size_t len);
int (*get_allowed_resources)(hwloc_topology_t topology);
} binding_hooks;
struct hwloc_topology_support support;
void (*userdata_export_cb)(void *reserved, struct hwloc_topology *topology, struct hwloc_obj *obj);
void (*userdata_import_cb)(struct hwloc_topology *topology, struct hwloc_obj *obj, const char *name, const void *buffer, size_t length);
int userdata_not_decoded;
struct hwloc_internal_distances_s {
char *name; /* FIXME: needs an API to set it from user */
unsigned id; /* to match the container id field of public distances structure
* not exported to XML, regenerated during _add()
*/
/* if all objects have the same type, different_types is NULL and unique_type is valid.
* otherwise unique_type is HWLOC_OBJ_TYPE_NONE and different_types contains individual objects types.
*/
hwloc_obj_type_t unique_type;
hwloc_obj_type_t *different_types;
/* add union hwloc_obj_attr_u if we ever support groups */
unsigned nbobjs;
uint64_t *indexes; /* array of OS or GP indexes before we can convert them into objs.
* OS indexes for distances covering only PUs or only NUMAnodes.
*/
#define HWLOC_DIST_TYPE_USE_OS_INDEX(_type) ((_type) == HWLOC_OBJ_PU || (_type == HWLOC_OBJ_NUMANODE))
uint64_t *values; /* distance matrices, ordered according to the above indexes/objs array.
* distance from i to j is stored in slot i*nbnodes+j.
*/
unsigned long kind;
#define HWLOC_INTERNAL_DIST_FLAG_OBJS_VALID (1U<<0) /* if the objs array is valid below */
#define HWLOC_INTERNAL_DIST_FLAG_NOT_COMMITTED (1U<<1) /* if the distances isn't in the list yet */
unsigned iflags;
/* objects are currently stored in physical_index order */
hwloc_obj_t *objs; /* array of objects */
struct hwloc_internal_distances_s *prev, *next;
} *first_dist, *last_dist;
unsigned next_dist_id;
/* memory attributes */
unsigned nr_memattrs;
struct hwloc_internal_memattr_s {
/* memattr info */
char *name; /* TODO unit is implicit, in the documentation of standard attributes, or in the name? */
unsigned long flags;
#define HWLOC_IMATTR_FLAG_STATIC_NAME (1U<<0) /* no need to free name */
#define HWLOC_IMATTR_FLAG_CACHE_VALID (1U<<1) /* target and initiator are valid */
#define HWLOC_IMATTR_FLAG_CONVENIENCE (1U<<2) /* convenience attribute reporting values from non-memattr attributes (R/O and no actual targets stored) */
unsigned iflags;
/* array of values */
unsigned nr_targets;
struct hwloc_internal_memattr_target_s {
/* target object */
hwloc_obj_t obj; /* cached between refreshes */
hwloc_obj_type_t type;
unsigned os_index; /* only used temporarily during discovery when there's no obj/gp_index yet */
hwloc_uint64_t gp_index;
/* value if there are no initiator for this attr */
hwloc_uint64_t noinitiator_value;
/* initiators otherwise */
unsigned nr_initiators;
struct hwloc_internal_memattr_initiator_s {
struct hwloc_internal_location_s initiator;
hwloc_uint64_t value;
} *initiators;
} *targets;
} *memattrs;
/* hybridcpus */
unsigned nr_cpukinds;
unsigned nr_cpukinds_allocated;
struct hwloc_internal_cpukind_s {
hwloc_cpuset_t cpuset;
#define HWLOC_CPUKIND_EFFICIENCY_UNKNOWN -1
int efficiency;
int forced_efficiency; /* returned by the hardware or OS if any */
hwloc_uint64_t ranking_value; /* internal value for ranking */
unsigned nr_infos;
struct hwloc_info_s *infos;
} *cpukinds;
int grouping;
int grouping_verbose;
unsigned grouping_nbaccuracies;
float grouping_accuracies[5];
unsigned grouping_next_subkind;
/* list of enabled backends. */
struct hwloc_backend * backends;
struct hwloc_backend * get_pci_busid_cpuset_backend; /* first backend that provides get_pci_busid_cpuset() callback */
unsigned backend_phases;
unsigned backend_excluded_phases;
/* memory allocator for topology objects */
struct hwloc_tma * tma;
/*****************************************************
* WARNING:
* changes above in this structure (and its children)
* should cause a bump of HWLOC_TOPOLOGY_ABI.
*****************************************************/
/*
* temporary variables during discovery
*/
/* machine-wide memory.
* temporarily stored there by OSes that only provide this without NUMA information,
* and actually used later by the core.
*/
struct hwloc_numanode_attr_s machine_memory;
/* pci stuff */
int pci_has_forced_locality;
unsigned pci_forced_locality_nr;
struct hwloc_pci_forced_locality_s {
unsigned domain;
unsigned bus_first, bus_last;
hwloc_bitmap_t cpuset;
} * pci_forced_locality;
/* component blacklisting */
unsigned nr_blacklisted_components;
struct hwloc_topology_forced_component_s {
struct hwloc_disc_component *component;
unsigned phases;
} *blacklisted_components;
/* FIXME: keep until topo destroy and reuse for finding specific buses */
struct hwloc_pci_locality_s {
unsigned domain;
unsigned bus_min;
unsigned bus_max;
hwloc_bitmap_t cpuset;
hwloc_obj_t parent;
struct hwloc_pci_locality_s *prev, *next;
} *first_pci_locality, *last_pci_locality;
};
extern void hwloc_alloc_root_sets(hwloc_obj_t root);
extern void hwloc_setup_pu_level(struct hwloc_topology *topology, unsigned nb_pus);
extern int hwloc_get_sysctlbyname(const char *name, int64_t *n);
extern int hwloc_get_sysctl(int name[], unsigned namelen, int64_t *n);
/* returns the number of CPU from the OS (only valid if thissystem) */
#define HWLOC_FALLBACK_NBPROCESSORS_INCLUDE_OFFLINE 1 /* by default we try to get only the online CPUs */
extern int hwloc_fallback_nbprocessors(unsigned flags);
/* returns the memory size from the OS (only valid if thissystem) */
extern int64_t hwloc_fallback_memsize(void);
extern int hwloc__object_cpusets_compare_first(hwloc_obj_t obj1, hwloc_obj_t obj2);
extern void hwloc__reorder_children(hwloc_obj_t parent);
extern void hwloc_topology_setup_defaults(struct hwloc_topology *topology);
extern void hwloc_topology_clear(struct hwloc_topology *topology);
/* insert memory object as memory child of normal parent */
extern struct hwloc_obj * hwloc__attach_memory_object(struct hwloc_topology *topology, hwloc_obj_t parent,
hwloc_obj_t obj, const char *reason);
extern hwloc_obj_t hwloc_get_obj_by_type_and_gp_index(hwloc_topology_t topology, hwloc_obj_type_t type, uint64_t gp_index);
extern void hwloc_pci_discovery_init(struct hwloc_topology *topology);
extern void hwloc_pci_discovery_prepare(struct hwloc_topology *topology);
extern void hwloc_pci_discovery_exit(struct hwloc_topology *topology);
/* Look for an object matching complete cpuset exactly, or insert one.
* Return NULL on failure.
* Return a good fallback (object above) on failure to insert.
*/
extern hwloc_obj_t hwloc_find_insert_io_parent_by_complete_cpuset(struct hwloc_topology *topology, hwloc_cpuset_t cpuset);
extern int hwloc__add_info(struct hwloc_info_s **infosp, unsigned *countp, const char *name, const char *value);
extern int hwloc__add_info_nodup(struct hwloc_info_s **infosp, unsigned *countp, const char *name, const char *value, int replace);
extern int hwloc__move_infos(struct hwloc_info_s **dst_infosp, unsigned *dst_countp, struct hwloc_info_s **src_infosp, unsigned *src_countp);
extern int hwloc__tma_dup_infos(struct hwloc_tma *tma, struct hwloc_info_s **dst_infosp, unsigned *dst_countp, struct hwloc_info_s *src_infos, unsigned src_count);
extern void hwloc__free_infos(struct hwloc_info_s *infos, unsigned count);
/* set native OS binding hooks */
extern void hwloc_set_native_binding_hooks(struct hwloc_binding_hooks *hooks, struct hwloc_topology_support *support);
/* set either native OS binding hooks (if thissystem), or dummy ones */
extern void hwloc_set_binding_hooks(struct hwloc_topology *topology);
#if defined(HWLOC_LINUX_SYS)
extern void hwloc_set_linuxfs_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support);
#endif /* HWLOC_LINUX_SYS */
#if defined(HWLOC_BGQ_SYS)
extern void hwloc_set_bgq_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support);
#endif /* HWLOC_BGQ_SYS */
#ifdef HWLOC_SOLARIS_SYS
extern void hwloc_set_solaris_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support);
#endif /* HWLOC_SOLARIS_SYS */
#ifdef HWLOC_AIX_SYS
extern void hwloc_set_aix_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support);
#endif /* HWLOC_AIX_SYS */
#ifdef HWLOC_WIN_SYS
extern void hwloc_set_windows_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support);
#endif /* HWLOC_WIN_SYS */
#ifdef HWLOC_DARWIN_SYS
extern void hwloc_set_darwin_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support);
#endif /* HWLOC_DARWIN_SYS */
#ifdef HWLOC_FREEBSD_SYS
extern void hwloc_set_freebsd_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support);
#endif /* HWLOC_FREEBSD_SYS */
#ifdef HWLOC_NETBSD_SYS
extern void hwloc_set_netbsd_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support);
#endif /* HWLOC_NETBSD_SYS */
#ifdef HWLOC_HPUX_SYS
extern void hwloc_set_hpux_hooks(struct hwloc_binding_hooks *binding_hooks, struct hwloc_topology_support *support);
#endif /* HWLOC_HPUX_SYS */
extern int hwloc_look_hardwired_fujitsu_k(struct hwloc_topology *topology);
extern int hwloc_look_hardwired_fujitsu_fx10(struct hwloc_topology *topology);
extern int hwloc_look_hardwired_fujitsu_fx100(struct hwloc_topology *topology);
/* Insert uname-specific names/values in the object infos array.
* If cached_uname isn't NULL, it is used as a struct utsname instead of recalling uname.
* Any field that starts with \0 is ignored.
*/
extern void hwloc_add_uname_info(struct hwloc_topology *topology, void *cached_uname);
/* Free obj and its attributes assuming it's not linked to a parent and doesn't have any child */
extern void hwloc_free_unlinked_object(hwloc_obj_t obj);
/* Free obj and its children, assuming it's not linked to a parent */
extern void hwloc_free_object_and_children(hwloc_obj_t obj);
/* Free obj, its next siblings, and their children, assuming they're not linked to a parent */
extern void hwloc_free_object_siblings_and_children(hwloc_obj_t obj);
/* This can be used for the alloc field to get allocated data that can be freed by free() */
void *hwloc_alloc_heap(hwloc_topology_t topology, size_t len);
/* This can be used for the alloc field to get allocated data that can be freed by munmap() */
void *hwloc_alloc_mmap(hwloc_topology_t topology, size_t len);
/* This can be used for the free_membind field to free data using free() */
int hwloc_free_heap(hwloc_topology_t topology, void *addr, size_t len);
/* This can be used for the free_membind field to free data using munmap() */
int hwloc_free_mmap(hwloc_topology_t topology, void *addr, size_t len);
/* Allocates unbound memory or fail, depending on whether STRICT is requested
* or not */
static __hwloc_inline void *
hwloc_alloc_or_fail(hwloc_topology_t topology, size_t len, int flags)
{
if (flags & HWLOC_MEMBIND_STRICT)
return NULL;
return hwloc_alloc(topology, len);
}
extern void hwloc_internal_distances_init(hwloc_topology_t topology);
extern void hwloc_internal_distances_prepare(hwloc_topology_t topology);
extern void hwloc_internal_distances_destroy(hwloc_topology_t topology);
extern int hwloc_internal_distances_dup(hwloc_topology_t new, hwloc_topology_t old);
extern void hwloc_internal_distances_refresh(hwloc_topology_t topology);
extern void hwloc_internal_distances_invalidate_cached_objs(hwloc_topology_t topology);
/* these distances_add() functions are higher-level than those in hwloc/plugins.h
* but they may change in the future, hence they are not exported to plugins.
*/
extern int hwloc_internal_distances_add_by_index(hwloc_topology_t topology, const char *name, hwloc_obj_type_t unique_type, hwloc_obj_type_t *different_types, unsigned nbobjs, uint64_t *indexes, uint64_t *values, unsigned long kind, unsigned long flags);
extern int hwloc_internal_distances_add(hwloc_topology_t topology, const char *name, unsigned nbobjs, hwloc_obj_t *objs, uint64_t *values, unsigned long kind, unsigned long flags);
extern void hwloc_internal_memattrs_init(hwloc_topology_t topology);
extern void hwloc_internal_memattrs_prepare(hwloc_topology_t topology);
extern void hwloc_internal_memattrs_destroy(hwloc_topology_t topology);
extern void hwloc_internal_memattrs_need_refresh(hwloc_topology_t topology);
extern void hwloc_internal_memattrs_refresh(hwloc_topology_t topology);
extern int hwloc_internal_memattrs_dup(hwloc_topology_t new, hwloc_topology_t old);
extern int hwloc_internal_memattr_set_value(hwloc_topology_t topology, hwloc_memattr_id_t id, hwloc_obj_type_t target_type, hwloc_uint64_t target_gp_index, unsigned target_os_index, struct hwloc_internal_location_s *initiator, hwloc_uint64_t value);
extern void hwloc_internal_cpukinds_init(hwloc_topology_t topology);
extern int hwloc_internal_cpukinds_rank(hwloc_topology_t topology);
extern void hwloc_internal_cpukinds_destroy(hwloc_topology_t topology);
extern int hwloc_internal_cpukinds_dup(hwloc_topology_t new, hwloc_topology_t old);
#define HWLOC_CPUKINDS_REGISTER_FLAG_OVERWRITE_FORCED_EFFICIENCY (1<<0)
extern int hwloc_internal_cpukinds_register(hwloc_topology_t topology, hwloc_cpuset_t cpuset, int forced_efficiency, const struct hwloc_info_s *infos, unsigned nr_infos, unsigned long flags);
extern void hwloc_internal_cpukinds_restrict(hwloc_topology_t topology);
/* encode src buffer into target buffer.
* targsize must be at least 4*((srclength+2)/3)+1.
* target will be 0-terminated.
*/
extern int hwloc_encode_to_base64(const char *src, size_t srclength, char *target, size_t targsize);
/* decode src buffer into target buffer.
* src is 0-terminated.
* targsize must be at least srclength*3/4+1 (srclength not including \0)
* but only srclength*3/4 characters will be meaningful
* (the next one may be partially written during decoding, but it should be ignored).
*/
extern int hwloc_decode_from_base64(char const *src, char *target, size_t targsize);
/* On some systems, snprintf returns the size of written data, not the actually
* required size. Sometimes it returns -1 on truncation too.
* And sometimes it doesn't like NULL output buffers.
* http://www.gnu.org/software/gnulib/manual/html_node/snprintf.html
*
* hwloc_snprintf behaves properly, but it's a bit overkill on the vast majority
* of platforms, so don't enable it unless really needed.
*/
#ifdef HWLOC_HAVE_CORRECT_SNPRINTF
#define hwloc_snprintf snprintf
#else
extern int hwloc_snprintf(char *str, size_t size, const char *format, ...) __hwloc_attribute_format(printf, 3, 4);
#endif
/* Return the name of the currently running program, if supported.
* If not NULL, must be freed by the caller.
*/
extern char * hwloc_progname(struct hwloc_topology *topology);
/* obj->attr->group.kind internal values.
* the core will keep the smallest ones when merging two groups,
* that's why user-given kinds are first.
*/
/* first, user-given groups, should remain as long as possible */
#define HWLOC_GROUP_KIND_USER 0 /* user-given, user may use subkind too */
#define HWLOC_GROUP_KIND_SYNTHETIC 10 /* subkind is group depth within synthetic description */
/* then, hardware-specific groups */
#define HWLOC_GROUP_KIND_INTEL_KNL_SUBNUMA_CLUSTER 100 /* no subkind */
#define HWLOC_GROUP_KIND_INTEL_EXTTOPOENUM_UNKNOWN 101 /* subkind is unknown level */
#define HWLOC_GROUP_KIND_INTEL_MODULE 102 /* no subkind */
#define HWLOC_GROUP_KIND_INTEL_TILE 103 /* no subkind */
#define HWLOC_GROUP_KIND_INTEL_DIE 104 /* no subkind */
#define HWLOC_GROUP_KIND_S390_BOOK 110 /* subkind 0 is book, subkind 1 is drawer (group of books) */
#define HWLOC_GROUP_KIND_AMD_COMPUTE_UNIT 120 /* no subkind */
/* then, OS-specific groups */
#define HWLOC_GROUP_KIND_SOLARIS_PG_HW_PERF 200 /* subkind is group width */
#define HWLOC_GROUP_KIND_AIX_SDL_UNKNOWN 210 /* subkind is SDL level */
#define HWLOC_GROUP_KIND_WINDOWS_PROCESSOR_GROUP 220 /* no subkind */
#define HWLOC_GROUP_KIND_WINDOWS_RELATIONSHIP_UNKNOWN 221 /* no subkind */
#define HWLOC_GROUP_KIND_LINUX_CLUSTER 222 /* no subkind */
/* distance groups */
#define HWLOC_GROUP_KIND_DISTANCE 900 /* subkind is round of adding these groups during distance based grouping */
/* finally, hwloc-specific groups required to insert something else, should disappear as soon as possible */
#define HWLOC_GROUP_KIND_IO 1000 /* no subkind */
#define HWLOC_GROUP_KIND_MEMORY 1001 /* no subkind */
/* memory allocator for topology objects */
struct hwloc_tma {
void * (*malloc)(struct hwloc_tma *, size_t);
void *data;
int dontfree; /* when set, free() or realloc() cannot be used, and tma->malloc() cannot fail */
};
static __hwloc_inline void *
hwloc_tma_malloc(struct hwloc_tma *tma,
size_t size)
{
if (tma) {
return tma->malloc(tma, size);
} else {
return malloc(size);
}
}
static __hwloc_inline void *
hwloc_tma_calloc(struct hwloc_tma *tma,
size_t size)
{
char *ptr = hwloc_tma_malloc(tma, size);
if (ptr)
memset(ptr, 0, size);
return ptr;
}
static __hwloc_inline char *
hwloc_tma_strdup(struct hwloc_tma *tma,
const char *src)
{
size_t len = strlen(src);
char *ptr = hwloc_tma_malloc(tma, len+1);
if (ptr)
memcpy(ptr, src, len+1);
return ptr;
}
/* bitmap allocator to be used inside hwloc */
extern hwloc_bitmap_t hwloc_bitmap_tma_dup(struct hwloc_tma *tma, hwloc_const_bitmap_t old);
extern int hwloc__topology_dup(hwloc_topology_t *newp, hwloc_topology_t old, struct hwloc_tma *tma);
extern void hwloc__topology_disadopt(hwloc_topology_t topology);
#endif /* HWLOC_PRIVATE_H */

View file

@ -1,43 +0,0 @@
/*
* Copyright © 2009-2010 Oracle and/or its affiliates. All rights reserved.
*
* Copyright © 2017 Inria. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#ifdef HWLOC_INSIDE_PLUGIN
/*
* these declarations are internal only, they are not available to plugins
* (functions below are internal static symbols).
*/
#error This file should not be used in plugins
#endif
#ifndef HWLOC_PRIVATE_SOLARIS_CHIPTYPE_H
#define HWLOC_PRIVATE_SOLARIS_CHIPTYPE_H
struct hwloc_solaris_chip_info_s {
char *model;
char *type;
/* L1i, L1d, L2, L3 */
#define HWLOC_SOLARIS_CHIP_INFO_L1I 0
#define HWLOC_SOLARIS_CHIP_INFO_L1D 1
#define HWLOC_SOLARIS_CHIP_INFO_L2I 2
#define HWLOC_SOLARIS_CHIP_INFO_L2D 3
#define HWLOC_SOLARIS_CHIP_INFO_L3 4
long cache_size[5]; /* cleared to -1 if we don't want of that cache */
unsigned cache_linesize[5];
unsigned cache_associativity[5];
int l2_unified;
};
/* fills the structure with 0 on error */
extern void hwloc_solaris_get_chip_info(struct hwloc_solaris_chip_info_s *info);
#endif /* HWLOC_PRIVATE_SOLARIS_CHIPTYPE_H */

View file

@ -1,21 +0,0 @@
/*
* Copyright © 2009 Université Bordeaux
* Copyright © 2020 Inria. All rights reserved.
*
* See COPYING in top-level directory.
*/
#ifndef HWLOC_PRIVATE_WINDOWS_H
#define HWLOC_PRIVATE_WINDOWS_H
#ifdef __GNUC__
#define _ANONYMOUS_UNION __extension__
#define _ANONYMOUS_STRUCT __extension__
#else
#define _ANONYMOUS_UNION
#define _ANONYMOUS_STRUCT
#endif /* __GNUC__ */
#define DUMMYUNIONNAME
#define DUMMYSTRUCTNAME
#endif /* HWLOC_PRIVATE_WINDOWS_H */

View file

@ -1,107 +0,0 @@
/*
* Copyright © 2009-2017 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
#ifndef PRIVATE_XML_H
#define PRIVATE_XML_H 1
#include "hwloc.h"
#include <sys/types.h>
HWLOC_DECLSPEC int hwloc__xml_verbose(void);
/**************
* XML import *
**************/
typedef struct hwloc__xml_import_state_s {
struct hwloc__xml_import_state_s *parent;
/* globals shared because the entire stack of states during import */
struct hwloc_xml_backend_data_s *global;
/* opaque data used to store backend-specific data.
* statically allocated to allow stack-allocation by the common code without knowing actual backend needs.
*/
char data[32];
} * hwloc__xml_import_state_t;
struct hwloc__xml_imported_v1distances_s {
unsigned long kind;
unsigned nbobjs;
float *floats;
struct hwloc__xml_imported_v1distances_s *prev, *next;
};
HWLOC_DECLSPEC int hwloc__xml_import_diff(hwloc__xml_import_state_t state, hwloc_topology_diff_t *firstdiffp);
struct hwloc_xml_backend_data_s {
/* xml backend parameters */
int (*look_init)(struct hwloc_xml_backend_data_s *bdata, struct hwloc__xml_import_state_s *state);
void (*look_done)(struct hwloc_xml_backend_data_s *bdata, int result);
void (*backend_exit)(struct hwloc_xml_backend_data_s *bdata);
int (*next_attr)(struct hwloc__xml_import_state_s * state, char **namep, char **valuep);
int (*find_child)(struct hwloc__xml_import_state_s * state, struct hwloc__xml_import_state_s * childstate, char **tagp);
int (*close_tag)(struct hwloc__xml_import_state_s * state); /* look for an explicit closing tag </name> */
void (*close_child)(struct hwloc__xml_import_state_s * state);
int (*get_content)(struct hwloc__xml_import_state_s * state, const char **beginp, size_t expected_length); /* return 0 on empty content (and sets beginp to empty string), 1 on actual content, -1 on error or unexpected content length */
void (*close_content)(struct hwloc__xml_import_state_s * state);
char * msgprefix;
void *data; /* libxml2 doc, or nolibxml buffer */
unsigned version_major, version_minor;
unsigned nbnumanodes;
hwloc_obj_t first_numanode, last_numanode; /* temporary cousin-list for handling v1distances */
struct hwloc__xml_imported_v1distances_s *first_v1dist, *last_v1dist;
};
/**************
* XML export *
**************/
typedef struct hwloc__xml_export_state_s {
struct hwloc__xml_export_state_s *parent;
void (*new_child)(struct hwloc__xml_export_state_s *parentstate, struct hwloc__xml_export_state_s *state, const char *name);
void (*new_prop)(struct hwloc__xml_export_state_s *state, const char *name, const char *value);
void (*add_content)(struct hwloc__xml_export_state_s *state, const char *buffer, size_t length);
void (*end_object)(struct hwloc__xml_export_state_s *state, const char *name);
struct hwloc__xml_export_data_s {
hwloc_obj_t v1_memory_group; /* if we need to insert intermediate group above memory children when exporting to v1 */
} *global;
/* opaque data used to store backend-specific data.
* statically allocated to allow stack-allocation by the common code without knowing actual backend needs.
*/
char data[40];
} * hwloc__xml_export_state_t;
HWLOC_DECLSPEC void hwloc__xml_export_topology(hwloc__xml_export_state_t parentstate, hwloc_topology_t topology, unsigned long flags);
HWLOC_DECLSPEC void hwloc__xml_export_diff(hwloc__xml_export_state_t parentstate, hwloc_topology_diff_t diff);
/******************
* XML components *
******************/
struct hwloc_xml_callbacks {
int (*backend_init)(struct hwloc_xml_backend_data_s *bdata, const char *xmlpath, const char *xmlbuffer, int xmlbuflen);
int (*export_file)(struct hwloc_topology *topology, struct hwloc__xml_export_data_s *edata, const char *filename, unsigned long flags);
int (*export_buffer)(struct hwloc_topology *topology, struct hwloc__xml_export_data_s *edata, char **xmlbuffer, int *buflen, unsigned long flags);
void (*free_buffer)(void *xmlbuffer);
int (*import_diff)(struct hwloc__xml_import_state_s *state, const char *xmlpath, const char *xmlbuffer, int xmlbuflen, hwloc_topology_diff_t *diff, char **refnamep);
int (*export_diff_file)(union hwloc_topology_diff_u *diff, const char *refname, const char *filename);
int (*export_diff_buffer)(union hwloc_topology_diff_u *diff, const char *refname, char **xmlbuffer, int *buflen);
};
struct hwloc_xml_component {
struct hwloc_xml_callbacks *nolibxml_callbacks;
struct hwloc_xml_callbacks *libxml_callbacks;
};
HWLOC_DECLSPEC void hwloc_xml_callbacks_register(struct hwloc_xml_component *component);
HWLOC_DECLSPEC void hwloc_xml_callbacks_reset(void);
#endif /* PRIVATE_XML_H */

View file

@ -1,309 +0,0 @@
/*
* Copyright © 2012-2018 Inria. All rights reserved.
* See COPYING in top-level directory.
*
* Modifications after import:
* - removed all #if
* - updated prototypes
* - updated #include
*/
/* include hwloc's config before anything else
* so that extensions and features are properly enabled
*/
#include "private/private.h"
/* $OpenBSD: base64.c,v 1.5 2006/10/21 09:55:03 otto Exp $ */
/*
* Copyright (c) 1996 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
/*
* Portions Copyright (c) 1995 by International Business Machines, Inc.
*
* International Business Machines, Inc. (hereinafter called IBM) grants
* permission under its copyrights to use, copy, modify, and distribute this
* Software with or without fee, provided that the above copyright notice and
* all paragraphs of this notice appear in all copies, and that the name of IBM
* not be used in connection with the marketing of any product incorporating
* the Software or modifications thereof, without specific, written prior
* permission.
*
* To the extent it has a right to do so, IBM grants an immunity from suit
* under its patents, if any, for the use, sale or manufacture of products to
* the extent that such products are used for performing Domain Name System
* dynamic updates in TCP/IP networks by means of the Software. No immunity is
* granted for any product per se or for any other function of any product.
*
* THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
* DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
* IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
*/
/* OPENBSD ORIGINAL: lib/libc/net/base64.c */
static const char Base64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const char Pad64 = '=';
/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
The following encoding technique is taken from RFC 1521 by Borenstein
and Freed. It is reproduced here in a slightly edited form for
convenience.
A 65-character subset of US-ASCII is used, enabling 6 bits to be
represented per printable character. (The extra 65th character, "=",
is used to signify a special processing function.)
The encoding process represents 24-bit groups of input bits as output
strings of 4 encoded characters. Proceeding from left to right, a
24-bit input group is formed by concatenating 3 8-bit input groups.
These 24 bits are then treated as 4 concatenated 6-bit groups, each
of which is translated into a single digit in the base64 alphabet.
Each 6-bit group is used as an index into an array of 64 printable
characters. The character referenced by the index is placed in the
output string.
Table 1: The Base64 Alphabet
Value Encoding Value Encoding Value Encoding Value Encoding
0 A 17 R 34 i 51 z
1 B 18 S 35 j 52 0
2 C 19 T 36 k 53 1
3 D 20 U 37 l 54 2
4 E 21 V 38 m 55 3
5 F 22 W 39 n 56 4
6 G 23 X 40 o 57 5
7 H 24 Y 41 p 58 6
8 I 25 Z 42 q 59 7
9 J 26 a 43 r 60 8
10 K 27 b 44 s 61 9
11 L 28 c 45 t 62 +
12 M 29 d 46 u 63 /
13 N 30 e 47 v
14 O 31 f 48 w (pad) =
15 P 32 g 49 x
16 Q 33 h 50 y
Special processing is performed if fewer than 24 bits are available
at the end of the data being encoded. A full encoding quantum is
always completed at the end of a quantity. When fewer than 24 input
bits are available in an input group, zero bits are added (on the
right) to form an integral number of 6-bit groups. Padding at the
end of the data is performed using the '=' character.
Since all base64 input is an integral number of octets, only the
-------------------------------------------------
following cases can arise:
(1) the final quantum of encoding input is an integral
multiple of 24 bits; here, the final unit of encoded
output will be an integral multiple of 4 characters
with no "=" padding,
(2) the final quantum of encoding input is exactly 8 bits;
here, the final unit of encoded output will be two
characters followed by two "=" padding characters, or
(3) the final quantum of encoding input is exactly 16 bits;
here, the final unit of encoded output will be three
characters followed by one "=" padding character.
*/
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int
hwloc_encode_to_base64(const char *src, size_t srclength, char *target, size_t targsize)
{
size_t datalength = 0;
unsigned char input[3];
unsigned char output[4];
unsigned int i;
while (2 < srclength) {
input[0] = *src++;
input[1] = *src++;
input[2] = *src++;
srclength -= 3;
output[0] = input[0] >> 2;
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
output[3] = input[2] & 0x3f;
if (datalength + 4 > targsize)
return (-1);
target[datalength++] = Base64[output[0]];
target[datalength++] = Base64[output[1]];
target[datalength++] = Base64[output[2]];
target[datalength++] = Base64[output[3]];
}
/* Now we worry about padding. */
if (0 != srclength) {
/* Get what's left. */
input[0] = input[1] = input[2] = '\0';
for (i = 0; i < srclength; i++)
input[i] = *src++;
output[0] = input[0] >> 2;
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
if (datalength + 4 > targsize)
return (-1);
target[datalength++] = Base64[output[0]];
target[datalength++] = Base64[output[1]];
if (srclength == 1)
target[datalength++] = Pad64;
else
target[datalength++] = Base64[output[2]];
target[datalength++] = Pad64;
}
if (datalength >= targsize)
return (-1);
target[datalength] = '\0'; /* Returned value doesn't count \0. */
return (int)(datalength);
}
/* skips all whitespace anywhere.
converts characters, four at a time, starting at (or after)
src from base - 64 numbers into three 8 bit bytes in the target area.
it returns the number of data bytes stored at the target, or -1 on error.
*/
int
hwloc_decode_from_base64(char const *src, char *target, size_t targsize)
{
unsigned int tarindex, state;
int ch;
char *pos;
state = 0;
tarindex = 0;
while ((ch = *src++) != '\0') {
if (isspace(ch)) /* Skip whitespace anywhere. */
continue;
if (ch == Pad64)
break;
pos = strchr(Base64, ch);
if (pos == 0) /* A non-base64 character. */
return (-1);
switch (state) {
case 0:
if (target) {
if (tarindex >= targsize)
return (-1);
target[tarindex] = (char)(pos - Base64) << 2;
}
state = 1;
break;
case 1:
if (target) {
if (tarindex + 1 >= targsize)
return (-1);
target[tarindex] |= (pos - Base64) >> 4;
target[tarindex+1] = ((pos - Base64) & 0x0f)
<< 4 ;
}
tarindex++;
state = 2;
break;
case 2:
if (target) {
if (tarindex + 1 >= targsize)
return (-1);
target[tarindex] |= (pos - Base64) >> 2;
target[tarindex+1] = ((pos - Base64) & 0x03)
<< 6;
}
tarindex++;
state = 3;
break;
case 3:
if (target) {
if (tarindex >= targsize)
return (-1);
target[tarindex] |= (pos - Base64);
}
tarindex++;
state = 0;
break;
}
}
/*
* We are done decoding Base-64 chars. Let's see if we ended
* on a byte boundary, and/or with erroneous trailing characters.
*/
if (ch == Pad64) { /* We got a pad char. */
ch = *src++; /* Skip it, get next. */
switch (state) {
case 0: /* Invalid = in first position */
case 1: /* Invalid = in second position */
return (-1);
case 2: /* Valid, means one byte of info */
/* Skip any number of spaces. */
for (; ch != '\0'; ch = *src++)
if (!isspace(ch))
break;
/* Make sure there is another trailing = sign. */
if (ch != Pad64)
return (-1);
ch = *src++; /* Skip the = */
/* Fall through to "single trailing =" case. */
/* FALLTHROUGH */
case 3: /* Valid, means two bytes of info */
/*
* We know this char is an =. Is there anything but
* whitespace after it?
*/
for (; ch != '\0'; ch = *src++)
if (!isspace(ch))
return (-1);
/*
* Now make sure for cases 2 and 3 that the "extra"
* bits that slopped past the last full byte were
* zeros. If we don't check them, they become a
* subliminal channel.
*/
if (target && target[tarindex] != 0)
return (-1);
}
} else {
/*
* We ended by seeing the end of the string. Make sure we
* have no partial bytes lying around.
*/
if (state != 0)
return (-1);
}
return (tarindex);
}

View file

@ -1,926 +0,0 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2020 Inria. All rights reserved.
* Copyright © 2009-2010, 2012 Université Bordeaux
* Copyright © 2011-2015 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
#include "private/autogen/config.h"
#include "hwloc.h"
#include "private/private.h"
#include "hwloc/helper.h"
#ifdef HAVE_SYS_MMAN_H
# include <sys/mman.h>
#endif
/* <malloc.h> is only needed if we don't have posix_memalign() */
#if defined(hwloc_getpagesize) && !defined(HAVE_POSIX_MEMALIGN) && defined(HAVE_MEMALIGN) && defined(HAVE_MALLOC_H)
#include <malloc.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <stdlib.h>
#include <errno.h>
/* TODO: HWLOC_GNU_SYS,
*
* We could use glibc's sched_setaffinity generically when it is available
*
* Darwin and OpenBSD don't seem to have binding facilities.
*/
#define HWLOC_CPUBIND_ALLFLAGS (HWLOC_CPUBIND_PROCESS|HWLOC_CPUBIND_THREAD|HWLOC_CPUBIND_STRICT|HWLOC_CPUBIND_NOMEMBIND)
static hwloc_const_bitmap_t
hwloc_fix_cpubind(hwloc_topology_t topology, hwloc_const_bitmap_t set)
{
hwloc_const_bitmap_t topology_set = hwloc_topology_get_topology_cpuset(topology);
hwloc_const_bitmap_t complete_set = hwloc_topology_get_complete_cpuset(topology);
if (hwloc_bitmap_iszero(set)) {
errno = EINVAL;
return NULL;
}
if (!hwloc_bitmap_isincluded(set, complete_set)) {
errno = EINVAL;
return NULL;
}
if (hwloc_bitmap_isincluded(topology_set, set))
set = complete_set;
return set;
}
int
hwloc_set_cpubind(hwloc_topology_t topology, hwloc_const_bitmap_t set, int flags)
{
if (flags & ~HWLOC_CPUBIND_ALLFLAGS) {
errno = EINVAL;
return -1;
}
set = hwloc_fix_cpubind(topology, set);
if (!set)
return -1;
if (flags & HWLOC_CPUBIND_PROCESS) {
if (topology->binding_hooks.set_thisproc_cpubind)
return topology->binding_hooks.set_thisproc_cpubind(topology, set, flags);
} else if (flags & HWLOC_CPUBIND_THREAD) {
if (topology->binding_hooks.set_thisthread_cpubind)
return topology->binding_hooks.set_thisthread_cpubind(topology, set, flags);
} else {
if (topology->binding_hooks.set_thisproc_cpubind) {
int err = topology->binding_hooks.set_thisproc_cpubind(topology, set, flags);
if (err >= 0 || errno != ENOSYS)
return err;
/* ENOSYS, fallback */
}
if (topology->binding_hooks.set_thisthread_cpubind)
return topology->binding_hooks.set_thisthread_cpubind(topology, set, flags);
}
errno = ENOSYS;
return -1;
}
int
hwloc_get_cpubind(hwloc_topology_t topology, hwloc_bitmap_t set, int flags)
{
if (flags & ~HWLOC_CPUBIND_ALLFLAGS) {
errno = EINVAL;
return -1;
}
if (flags & HWLOC_CPUBIND_PROCESS) {
if (topology->binding_hooks.get_thisproc_cpubind)
return topology->binding_hooks.get_thisproc_cpubind(topology, set, flags);
} else if (flags & HWLOC_CPUBIND_THREAD) {
if (topology->binding_hooks.get_thisthread_cpubind)
return topology->binding_hooks.get_thisthread_cpubind(topology, set, flags);
} else {
if (topology->binding_hooks.get_thisproc_cpubind) {
int err = topology->binding_hooks.get_thisproc_cpubind(topology, set, flags);
if (err >= 0 || errno != ENOSYS)
return err;
/* ENOSYS, fallback */
}
if (topology->binding_hooks.get_thisthread_cpubind)
return topology->binding_hooks.get_thisthread_cpubind(topology, set, flags);
}
errno = ENOSYS;
return -1;
}
int
hwloc_set_proc_cpubind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_bitmap_t set, int flags)
{
if (flags & ~HWLOC_CPUBIND_ALLFLAGS) {
errno = EINVAL;
return -1;
}
set = hwloc_fix_cpubind(topology, set);
if (!set)
return -1;
if (topology->binding_hooks.set_proc_cpubind)
return topology->binding_hooks.set_proc_cpubind(topology, pid, set, flags);
errno = ENOSYS;
return -1;
}
int
hwloc_get_proc_cpubind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_bitmap_t set, int flags)
{
if (flags & ~HWLOC_CPUBIND_ALLFLAGS) {
errno = EINVAL;
return -1;
}
if (topology->binding_hooks.get_proc_cpubind)
return topology->binding_hooks.get_proc_cpubind(topology, pid, set, flags);
errno = ENOSYS;
return -1;
}
#ifdef hwloc_thread_t
int
hwloc_set_thread_cpubind(hwloc_topology_t topology, hwloc_thread_t tid, hwloc_const_bitmap_t set, int flags)
{
if (flags & ~HWLOC_CPUBIND_ALLFLAGS) {
errno = EINVAL;
return -1;
}
set = hwloc_fix_cpubind(topology, set);
if (!set)
return -1;
if (topology->binding_hooks.set_thread_cpubind)
return topology->binding_hooks.set_thread_cpubind(topology, tid, set, flags);
errno = ENOSYS;
return -1;
}
int
hwloc_get_thread_cpubind(hwloc_topology_t topology, hwloc_thread_t tid, hwloc_bitmap_t set, int flags)
{
if (flags & ~HWLOC_CPUBIND_ALLFLAGS) {
errno = EINVAL;
return -1;
}
if (topology->binding_hooks.get_thread_cpubind)
return topology->binding_hooks.get_thread_cpubind(topology, tid, set, flags);
errno = ENOSYS;
return -1;
}
#endif
int
hwloc_get_last_cpu_location(hwloc_topology_t topology, hwloc_bitmap_t set, int flags)
{
if (flags & ~HWLOC_CPUBIND_ALLFLAGS) {
errno = EINVAL;
return -1;
}
if (flags & HWLOC_CPUBIND_PROCESS) {
if (topology->binding_hooks.get_thisproc_last_cpu_location)
return topology->binding_hooks.get_thisproc_last_cpu_location(topology, set, flags);
} else if (flags & HWLOC_CPUBIND_THREAD) {
if (topology->binding_hooks.get_thisthread_last_cpu_location)
return topology->binding_hooks.get_thisthread_last_cpu_location(topology, set, flags);
} else {
if (topology->binding_hooks.get_thisproc_last_cpu_location) {
int err = topology->binding_hooks.get_thisproc_last_cpu_location(topology, set, flags);
if (err >= 0 || errno != ENOSYS)
return err;
/* ENOSYS, fallback */
}
if (topology->binding_hooks.get_thisthread_last_cpu_location)
return topology->binding_hooks.get_thisthread_last_cpu_location(topology, set, flags);
}
errno = ENOSYS;
return -1;
}
int
hwloc_get_proc_last_cpu_location(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_bitmap_t set, int flags)
{
if (flags & ~HWLOC_CPUBIND_ALLFLAGS) {
errno = EINVAL;
return -1;
}
if (topology->binding_hooks.get_proc_last_cpu_location)
return topology->binding_hooks.get_proc_last_cpu_location(topology, pid, set, flags);
errno = ENOSYS;
return -1;
}
#define HWLOC_MEMBIND_ALLFLAGS (HWLOC_MEMBIND_PROCESS|HWLOC_MEMBIND_THREAD|HWLOC_MEMBIND_STRICT|HWLOC_MEMBIND_MIGRATE|HWLOC_MEMBIND_NOCPUBIND|HWLOC_MEMBIND_BYNODESET)
static hwloc_const_nodeset_t
hwloc_fix_membind(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset)
{
hwloc_const_bitmap_t topology_nodeset = hwloc_topology_get_topology_nodeset(topology);
hwloc_const_bitmap_t complete_nodeset = hwloc_topology_get_complete_nodeset(topology);
if (hwloc_bitmap_iszero(nodeset)) {
errno = EINVAL;
return NULL;
}
if (!hwloc_bitmap_isincluded(nodeset, complete_nodeset)) {
errno = EINVAL;
return NULL;
}
if (hwloc_bitmap_isincluded(topology_nodeset, nodeset))
return complete_nodeset;
return nodeset;
}
static int
hwloc_fix_membind_cpuset(hwloc_topology_t topology, hwloc_nodeset_t nodeset, hwloc_const_cpuset_t cpuset)
{
hwloc_const_bitmap_t topology_set = hwloc_topology_get_topology_cpuset(topology);
hwloc_const_bitmap_t complete_set = hwloc_topology_get_complete_cpuset(topology);
hwloc_const_bitmap_t complete_nodeset = hwloc_topology_get_complete_nodeset(topology);
if (hwloc_bitmap_iszero(cpuset)) {
errno = EINVAL;
return -1;
}
if (!hwloc_bitmap_isincluded(cpuset, complete_set)) {
errno = EINVAL;
return -1;
}
if (hwloc_bitmap_isincluded(topology_set, cpuset)) {
hwloc_bitmap_copy(nodeset, complete_nodeset);
return 0;
}
hwloc_cpuset_to_nodeset(topology, cpuset, nodeset);
return 0;
}
static __hwloc_inline int hwloc__check_membind_policy(hwloc_membind_policy_t policy)
{
if (policy == HWLOC_MEMBIND_DEFAULT
|| policy == HWLOC_MEMBIND_FIRSTTOUCH
|| policy == HWLOC_MEMBIND_BIND
|| policy == HWLOC_MEMBIND_INTERLEAVE
|| policy == HWLOC_MEMBIND_NEXTTOUCH)
return 0;
return -1;
}
static int
hwloc_set_membind_by_nodeset(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
{
if ((flags & ~HWLOC_MEMBIND_ALLFLAGS) || hwloc__check_membind_policy(policy) < 0) {
errno = EINVAL;
return -1;
}
nodeset = hwloc_fix_membind(topology, nodeset);
if (!nodeset)
return -1;
if (flags & HWLOC_MEMBIND_PROCESS) {
if (topology->binding_hooks.set_thisproc_membind)
return topology->binding_hooks.set_thisproc_membind(topology, nodeset, policy, flags);
} else if (flags & HWLOC_MEMBIND_THREAD) {
if (topology->binding_hooks.set_thisthread_membind)
return topology->binding_hooks.set_thisthread_membind(topology, nodeset, policy, flags);
} else {
if (topology->binding_hooks.set_thisproc_membind) {
int err = topology->binding_hooks.set_thisproc_membind(topology, nodeset, policy, flags);
if (err >= 0 || errno != ENOSYS)
return err;
/* ENOSYS, fallback */
}
if (topology->binding_hooks.set_thisthread_membind)
return topology->binding_hooks.set_thisthread_membind(topology, nodeset, policy, flags);
}
errno = ENOSYS;
return -1;
}
int
hwloc_set_membind(hwloc_topology_t topology, hwloc_const_bitmap_t set, hwloc_membind_policy_t policy, int flags)
{
int ret;
if (flags & HWLOC_MEMBIND_BYNODESET) {
ret = hwloc_set_membind_by_nodeset(topology, set, policy, flags);
} else {
hwloc_nodeset_t nodeset = hwloc_bitmap_alloc();
if (hwloc_fix_membind_cpuset(topology, nodeset, set))
ret = -1;
else
ret = hwloc_set_membind_by_nodeset(topology, nodeset, policy, flags);
hwloc_bitmap_free(nodeset);
}
return ret;
}
static int
hwloc_get_membind_by_nodeset(hwloc_topology_t topology, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags)
{
if (flags & ~HWLOC_MEMBIND_ALLFLAGS) {
errno = EINVAL;
return -1;
}
if (flags & HWLOC_MEMBIND_PROCESS) {
if (topology->binding_hooks.get_thisproc_membind)
return topology->binding_hooks.get_thisproc_membind(topology, nodeset, policy, flags);
} else if (flags & HWLOC_MEMBIND_THREAD) {
if (topology->binding_hooks.get_thisthread_membind)
return topology->binding_hooks.get_thisthread_membind(topology, nodeset, policy, flags);
} else {
if (topology->binding_hooks.get_thisproc_membind) {
int err = topology->binding_hooks.get_thisproc_membind(topology, nodeset, policy, flags);
if (err >= 0 || errno != ENOSYS)
return err;
/* ENOSYS, fallback */
}
if (topology->binding_hooks.get_thisthread_membind)
return topology->binding_hooks.get_thisthread_membind(topology, nodeset, policy, flags);
}
errno = ENOSYS;
return -1;
}
int
hwloc_get_membind(hwloc_topology_t topology, hwloc_bitmap_t set, hwloc_membind_policy_t * policy, int flags)
{
int ret;
if (flags & HWLOC_MEMBIND_BYNODESET) {
ret = hwloc_get_membind_by_nodeset(topology, set, policy, flags);
} else {
hwloc_nodeset_t nodeset = hwloc_bitmap_alloc();
ret = hwloc_get_membind_by_nodeset(topology, nodeset, policy, flags);
if (!ret)
hwloc_cpuset_from_nodeset(topology, set, nodeset);
hwloc_bitmap_free(nodeset);
}
return ret;
}
static int
hwloc_set_proc_membind_by_nodeset(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
{
if ((flags & ~HWLOC_MEMBIND_ALLFLAGS) || hwloc__check_membind_policy(policy) < 0) {
errno = EINVAL;
return -1;
}
nodeset = hwloc_fix_membind(topology, nodeset);
if (!nodeset)
return -1;
if (topology->binding_hooks.set_proc_membind)
return topology->binding_hooks.set_proc_membind(topology, pid, nodeset, policy, flags);
errno = ENOSYS;
return -1;
}
int
hwloc_set_proc_membind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_bitmap_t set, hwloc_membind_policy_t policy, int flags)
{
int ret;
if (flags & HWLOC_MEMBIND_BYNODESET) {
ret = hwloc_set_proc_membind_by_nodeset(topology, pid, set, policy, flags);
} else {
hwloc_nodeset_t nodeset = hwloc_bitmap_alloc();
if (hwloc_fix_membind_cpuset(topology, nodeset, set))
ret = -1;
else
ret = hwloc_set_proc_membind_by_nodeset(topology, pid, nodeset, policy, flags);
hwloc_bitmap_free(nodeset);
}
return ret;
}
static int
hwloc_get_proc_membind_by_nodeset(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags)
{
if (flags & ~HWLOC_MEMBIND_ALLFLAGS) {
errno = EINVAL;
return -1;
}
if (topology->binding_hooks.get_proc_membind)
return topology->binding_hooks.get_proc_membind(topology, pid, nodeset, policy, flags);
errno = ENOSYS;
return -1;
}
int
hwloc_get_proc_membind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_bitmap_t set, hwloc_membind_policy_t * policy, int flags)
{
int ret;
if (flags & HWLOC_MEMBIND_BYNODESET) {
ret = hwloc_get_proc_membind_by_nodeset(topology, pid, set, policy, flags);
} else {
hwloc_nodeset_t nodeset = hwloc_bitmap_alloc();
ret = hwloc_get_proc_membind_by_nodeset(topology, pid, nodeset, policy, flags);
if (!ret)
hwloc_cpuset_from_nodeset(topology, set, nodeset);
hwloc_bitmap_free(nodeset);
}
return ret;
}
static int
hwloc_set_area_membind_by_nodeset(hwloc_topology_t topology, const void *addr, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
{
if ((flags & ~HWLOC_MEMBIND_ALLFLAGS) || hwloc__check_membind_policy(policy) < 0) {
errno = EINVAL;
return -1;
}
if (!len)
/* nothing to do */
return 0;
nodeset = hwloc_fix_membind(topology, nodeset);
if (!nodeset)
return -1;
if (topology->binding_hooks.set_area_membind)
return topology->binding_hooks.set_area_membind(topology, addr, len, nodeset, policy, flags);
errno = ENOSYS;
return -1;
}
int
hwloc_set_area_membind(hwloc_topology_t topology, const void *addr, size_t len, hwloc_const_bitmap_t set, hwloc_membind_policy_t policy, int flags)
{
int ret;
if (flags & HWLOC_MEMBIND_BYNODESET) {
ret = hwloc_set_area_membind_by_nodeset(topology, addr, len, set, policy, flags);
} else {
hwloc_nodeset_t nodeset = hwloc_bitmap_alloc();
if (hwloc_fix_membind_cpuset(topology, nodeset, set))
ret = -1;
else
ret = hwloc_set_area_membind_by_nodeset(topology, addr, len, nodeset, policy, flags);
hwloc_bitmap_free(nodeset);
}
return ret;
}
static int
hwloc_get_area_membind_by_nodeset(hwloc_topology_t topology, const void *addr, size_t len, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags)
{
if (flags & ~HWLOC_MEMBIND_ALLFLAGS) {
errno = EINVAL;
return -1;
}
if (!len) {
/* nothing to query */
errno = EINVAL;
return -1;
}
if (topology->binding_hooks.get_area_membind)
return topology->binding_hooks.get_area_membind(topology, addr, len, nodeset, policy, flags);
errno = ENOSYS;
return -1;
}
int
hwloc_get_area_membind(hwloc_topology_t topology, const void *addr, size_t len, hwloc_bitmap_t set, hwloc_membind_policy_t * policy, int flags)
{
int ret;
if (flags & HWLOC_MEMBIND_BYNODESET) {
ret = hwloc_get_area_membind_by_nodeset(topology, addr, len, set, policy, flags);
} else {
hwloc_nodeset_t nodeset = hwloc_bitmap_alloc();
ret = hwloc_get_area_membind_by_nodeset(topology, addr, len, nodeset, policy, flags);
if (!ret)
hwloc_cpuset_from_nodeset(topology, set, nodeset);
hwloc_bitmap_free(nodeset);
}
return ret;
}
static int
hwloc_get_area_memlocation_by_nodeset(hwloc_topology_t topology, const void *addr, size_t len, hwloc_nodeset_t nodeset, int flags)
{
if (flags & ~HWLOC_MEMBIND_ALLFLAGS) {
errno = EINVAL;
return -1;
}
if (!len)
/* nothing to do */
return 0;
if (topology->binding_hooks.get_area_memlocation)
return topology->binding_hooks.get_area_memlocation(topology, addr, len, nodeset, flags);
errno = ENOSYS;
return -1;
}
int
hwloc_get_area_memlocation(hwloc_topology_t topology, const void *addr, size_t len, hwloc_cpuset_t set, int flags)
{
int ret;
if (flags & HWLOC_MEMBIND_BYNODESET) {
ret = hwloc_get_area_memlocation_by_nodeset(topology, addr, len, set, flags);
} else {
hwloc_nodeset_t nodeset = hwloc_bitmap_alloc();
ret = hwloc_get_area_memlocation_by_nodeset(topology, addr, len, nodeset, flags);
if (!ret)
hwloc_cpuset_from_nodeset(topology, set, nodeset);
hwloc_bitmap_free(nodeset);
}
return ret;
}
void *
hwloc_alloc_heap(hwloc_topology_t topology __hwloc_attribute_unused, size_t len)
{
void *p = NULL;
#if defined(hwloc_getpagesize) && defined(HAVE_POSIX_MEMALIGN)
errno = posix_memalign(&p, hwloc_getpagesize(), len);
if (errno)
p = NULL;
#elif defined(hwloc_getpagesize) && defined(HAVE_MEMALIGN)
p = memalign(hwloc_getpagesize(), len);
#else
p = malloc(len);
#endif
return p;
}
#ifdef MAP_ANONYMOUS
void *
hwloc_alloc_mmap(hwloc_topology_t topology __hwloc_attribute_unused, size_t len)
{
void * buffer = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
return buffer == MAP_FAILED ? NULL : buffer;
}
#endif
int
hwloc_free_heap(hwloc_topology_t topology __hwloc_attribute_unused, void *addr, size_t len __hwloc_attribute_unused)
{
free(addr);
return 0;
}
#ifdef MAP_ANONYMOUS
int
hwloc_free_mmap(hwloc_topology_t topology __hwloc_attribute_unused, void *addr, size_t len)
{
if (!addr)
return 0;
return munmap(addr, len);
}
#endif
void *
hwloc_alloc(hwloc_topology_t topology, size_t len)
{
if (topology->binding_hooks.alloc)
return topology->binding_hooks.alloc(topology, len);
return hwloc_alloc_heap(topology, len);
}
static void *
hwloc_alloc_membind_by_nodeset(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
{
void *p;
if ((flags & ~HWLOC_MEMBIND_ALLFLAGS) || hwloc__check_membind_policy(policy) < 0) {
errno = EINVAL;
return NULL;
}
nodeset = hwloc_fix_membind(topology, nodeset);
if (!nodeset)
goto fallback;
if (flags & HWLOC_MEMBIND_MIGRATE) {
errno = EINVAL;
goto fallback;
}
if (topology->binding_hooks.alloc_membind)
return topology->binding_hooks.alloc_membind(topology, len, nodeset, policy, flags);
else if (topology->binding_hooks.set_area_membind) {
p = hwloc_alloc(topology, len);
if (!p)
return NULL;
if (topology->binding_hooks.set_area_membind(topology, p, len, nodeset, policy, flags) && flags & HWLOC_MEMBIND_STRICT) {
int error = errno;
free(p);
errno = error;
return NULL;
}
return p;
} else {
errno = ENOSYS;
}
fallback:
if (flags & HWLOC_MEMBIND_STRICT)
/* Report error */
return NULL;
/* Never mind, allocate anyway */
return hwloc_alloc(topology, len);
}
void *
hwloc_alloc_membind(hwloc_topology_t topology, size_t len, hwloc_const_bitmap_t set, hwloc_membind_policy_t policy, int flags)
{
void *ret;
if (flags & HWLOC_MEMBIND_BYNODESET) {
ret = hwloc_alloc_membind_by_nodeset(topology, len, set, policy, flags);
} else {
hwloc_nodeset_t nodeset = hwloc_bitmap_alloc();
if (hwloc_fix_membind_cpuset(topology, nodeset, set)) {
if (flags & HWLOC_MEMBIND_STRICT)
ret = NULL;
else
ret = hwloc_alloc(topology, len);
} else
ret = hwloc_alloc_membind_by_nodeset(topology, len, nodeset, policy, flags);
hwloc_bitmap_free(nodeset);
}
return ret;
}
int
hwloc_free(hwloc_topology_t topology, void *addr, size_t len)
{
if (topology->binding_hooks.free_membind)
return topology->binding_hooks.free_membind(topology, addr, len);
return hwloc_free_heap(topology, addr, len);
}
/*
* Empty binding hooks always returning success
*/
static int dontset_return_complete_cpuset(hwloc_topology_t topology, hwloc_cpuset_t set)
{
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
return 0;
}
static int dontset_thisthread_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
{
return 0;
}
static int dontget_thisthread_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_bitmap_t set, int flags __hwloc_attribute_unused)
{
return dontset_return_complete_cpuset(topology, set);
}
static int dontset_thisproc_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
{
return 0;
}
static int dontget_thisproc_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_bitmap_t set, int flags __hwloc_attribute_unused)
{
return dontset_return_complete_cpuset(topology, set);
}
static int dontset_proc_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_pid_t pid __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
{
return 0;
}
static int dontget_proc_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_pid_t pid __hwloc_attribute_unused, hwloc_bitmap_t cpuset, int flags __hwloc_attribute_unused)
{
return dontset_return_complete_cpuset(topology, cpuset);
}
#ifdef hwloc_thread_t
static int dontset_thread_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_thread_t tid __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
{
return 0;
}
static int dontget_thread_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_thread_t tid __hwloc_attribute_unused, hwloc_bitmap_t cpuset, int flags __hwloc_attribute_unused)
{
return dontset_return_complete_cpuset(topology, cpuset);
}
#endif
static int dontset_return_complete_nodeset(hwloc_topology_t topology, hwloc_nodeset_t set, hwloc_membind_policy_t *policy)
{
hwloc_bitmap_copy(set, hwloc_topology_get_complete_nodeset(topology));
*policy = HWLOC_MEMBIND_MIXED;
return 0;
}
static int dontset_thisproc_membind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, hwloc_membind_policy_t policy __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
{
return 0;
}
static int dontget_thisproc_membind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_bitmap_t set, hwloc_membind_policy_t * policy, int flags __hwloc_attribute_unused)
{
return dontset_return_complete_nodeset(topology, set, policy);
}
static int dontset_thisthread_membind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, hwloc_membind_policy_t policy __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
{
return 0;
}
static int dontget_thisthread_membind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_bitmap_t set, hwloc_membind_policy_t * policy, int flags __hwloc_attribute_unused)
{
return dontset_return_complete_nodeset(topology, set, policy);
}
static int dontset_proc_membind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_pid_t pid __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, hwloc_membind_policy_t policy __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
{
return 0;
}
static int dontget_proc_membind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_pid_t pid __hwloc_attribute_unused, hwloc_bitmap_t set, hwloc_membind_policy_t * policy, int flags __hwloc_attribute_unused)
{
return dontset_return_complete_nodeset(topology, set, policy);
}
static int dontset_area_membind(hwloc_topology_t topology __hwloc_attribute_unused, const void *addr __hwloc_attribute_unused, size_t size __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, hwloc_membind_policy_t policy __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
{
return 0;
}
static int dontget_area_membind(hwloc_topology_t topology __hwloc_attribute_unused, const void *addr __hwloc_attribute_unused, size_t size __hwloc_attribute_unused, hwloc_bitmap_t set, hwloc_membind_policy_t * policy, int flags __hwloc_attribute_unused)
{
return dontset_return_complete_nodeset(topology, set, policy);
}
static int dontget_area_memlocation(hwloc_topology_t topology __hwloc_attribute_unused, const void *addr __hwloc_attribute_unused, size_t size __hwloc_attribute_unused, hwloc_bitmap_t set, int flags __hwloc_attribute_unused)
{
hwloc_membind_policy_t policy;
return dontset_return_complete_nodeset(topology, set, &policy);
}
static void * dontalloc_membind(hwloc_topology_t topology __hwloc_attribute_unused, size_t size __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, hwloc_membind_policy_t policy __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
{
return malloc(size);
}
static int dontfree_membind(hwloc_topology_t topology __hwloc_attribute_unused, void *addr __hwloc_attribute_unused, size_t size __hwloc_attribute_unused)
{
free(addr);
return 0;
}
static void hwloc_set_dummy_hooks(struct hwloc_binding_hooks *hooks,
struct hwloc_topology_support *support __hwloc_attribute_unused)
{
hooks->set_thisproc_cpubind = dontset_thisproc_cpubind;
hooks->get_thisproc_cpubind = dontget_thisproc_cpubind;
hooks->set_thisthread_cpubind = dontset_thisthread_cpubind;
hooks->get_thisthread_cpubind = dontget_thisthread_cpubind;
hooks->set_proc_cpubind = dontset_proc_cpubind;
hooks->get_proc_cpubind = dontget_proc_cpubind;
#ifdef hwloc_thread_t
hooks->set_thread_cpubind = dontset_thread_cpubind;
hooks->get_thread_cpubind = dontget_thread_cpubind;
#endif
hooks->get_thisproc_last_cpu_location = dontget_thisproc_cpubind; /* cpubind instead of last_cpu_location is ok */
hooks->get_thisthread_last_cpu_location = dontget_thisthread_cpubind; /* cpubind instead of last_cpu_location is ok */
hooks->get_proc_last_cpu_location = dontget_proc_cpubind; /* cpubind instead of last_cpu_location is ok */
/* TODO: get_thread_last_cpu_location */
hooks->set_thisproc_membind = dontset_thisproc_membind;
hooks->get_thisproc_membind = dontget_thisproc_membind;
hooks->set_thisthread_membind = dontset_thisthread_membind;
hooks->get_thisthread_membind = dontget_thisthread_membind;
hooks->set_proc_membind = dontset_proc_membind;
hooks->get_proc_membind = dontget_proc_membind;
hooks->set_area_membind = dontset_area_membind;
hooks->get_area_membind = dontget_area_membind;
hooks->get_area_memlocation = dontget_area_memlocation;
hooks->alloc_membind = dontalloc_membind;
hooks->free_membind = dontfree_membind;
}
void
hwloc_set_native_binding_hooks(struct hwloc_binding_hooks *hooks, struct hwloc_topology_support *support)
{
# ifdef HWLOC_LINUX_SYS
hwloc_set_linuxfs_hooks(hooks, support);
# endif /* HWLOC_LINUX_SYS */
# ifdef HWLOC_BGQ_SYS
hwloc_set_bgq_hooks(hooks, support);
# endif /* HWLOC_BGQ_SYS */
# ifdef HWLOC_AIX_SYS
hwloc_set_aix_hooks(hooks, support);
# endif /* HWLOC_AIX_SYS */
# ifdef HWLOC_SOLARIS_SYS
hwloc_set_solaris_hooks(hooks, support);
# endif /* HWLOC_SOLARIS_SYS */
# ifdef HWLOC_WIN_SYS
hwloc_set_windows_hooks(hooks, support);
# endif /* HWLOC_WIN_SYS */
# ifdef HWLOC_DARWIN_SYS
hwloc_set_darwin_hooks(hooks, support);
# endif /* HWLOC_DARWIN_SYS */
# ifdef HWLOC_FREEBSD_SYS
hwloc_set_freebsd_hooks(hooks, support);
# endif /* HWLOC_FREEBSD_SYS */
# ifdef HWLOC_NETBSD_SYS
hwloc_set_netbsd_hooks(hooks, support);
# endif /* HWLOC_NETBSD_SYS */
# ifdef HWLOC_HPUX_SYS
hwloc_set_hpux_hooks(hooks, support);
# endif /* HWLOC_HPUX_SYS */
}
/* If the represented system is actually not this system, use dummy binding hooks. */
void
hwloc_set_binding_hooks(struct hwloc_topology *topology)
{
if (topology->is_thissystem) {
hwloc_set_native_binding_hooks(&topology->binding_hooks, &topology->support);
/* every hook not set above will return ENOSYS */
} else {
/* not this system, use dummy binding hooks that do nothing (but don't return ENOSYS) */
hwloc_set_dummy_hooks(&topology->binding_hooks, &topology->support);
/* Linux has some hooks that also work in this case, but they are not strictly needed yet. */
}
/* if not is_thissystem, set_cpubind is fake
* and get_cpubind returns the whole system cpuset,
* so don't report that set/get_cpubind as supported
*/
if (topology->is_thissystem) {
#define DO(which,kind) \
if (topology->binding_hooks.kind) \
topology->support.which##bind->kind = 1;
DO(cpu,set_thisproc_cpubind);
DO(cpu,get_thisproc_cpubind);
DO(cpu,set_proc_cpubind);
DO(cpu,get_proc_cpubind);
DO(cpu,set_thisthread_cpubind);
DO(cpu,get_thisthread_cpubind);
#ifdef hwloc_thread_t
DO(cpu,set_thread_cpubind);
DO(cpu,get_thread_cpubind);
#endif
DO(cpu,get_thisproc_last_cpu_location);
DO(cpu,get_proc_last_cpu_location);
DO(cpu,get_thisthread_last_cpu_location);
DO(mem,set_thisproc_membind);
DO(mem,get_thisproc_membind);
DO(mem,set_thisthread_membind);
DO(mem,get_thisthread_membind);
DO(mem,set_proc_membind);
DO(mem,get_proc_membind);
DO(mem,set_area_membind);
DO(mem,get_area_membind);
DO(mem,get_area_memlocation);
DO(mem,alloc_membind);
#undef DO
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,661 +0,0 @@
/*
* Copyright © 2020-2021 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
#include "private/autogen/config.h"
#include "hwloc.h"
#include "private/private.h"
#include "private/debug.h"
/*****************
* Basics
*/
void
hwloc_internal_cpukinds_init(struct hwloc_topology *topology)
{
topology->cpukinds = NULL;
topology->nr_cpukinds = 0;
topology->nr_cpukinds_allocated = 0;
}
void
hwloc_internal_cpukinds_destroy(struct hwloc_topology *topology)
{
unsigned i;
for(i=0; i<topology->nr_cpukinds; i++) {
struct hwloc_internal_cpukind_s *kind = &topology->cpukinds[i];
hwloc_bitmap_free(kind->cpuset);
hwloc__free_infos(kind->infos, kind->nr_infos);
}
free(topology->cpukinds);
topology->cpukinds = NULL;
topology->nr_cpukinds = 0;
}
int
hwloc_internal_cpukinds_dup(hwloc_topology_t new, hwloc_topology_t old)
{
struct hwloc_tma *tma = new->tma;
struct hwloc_internal_cpukind_s *kinds;
unsigned i;
if (!old->nr_cpukinds)
return 0;
kinds = hwloc_tma_malloc(tma, old->nr_cpukinds * sizeof(*kinds));
if (!kinds)
return -1;
new->cpukinds = kinds;
new->nr_cpukinds = old->nr_cpukinds;
memcpy(kinds, old->cpukinds, old->nr_cpukinds * sizeof(*kinds));
for(i=0;i<old->nr_cpukinds; i++) {
kinds[i].cpuset = hwloc_bitmap_tma_dup(tma, old->cpukinds[i].cpuset);
if (!kinds[i].cpuset) {
new->nr_cpukinds = i;
goto failed;
}
if (hwloc__tma_dup_infos(tma,
&kinds[i].infos, &kinds[i].nr_infos,
old->cpukinds[i].infos, old->cpukinds[i].nr_infos) < 0) {
assert(!tma || !tma->dontfree); /* this tma cannot fail to allocate */
hwloc_bitmap_free(kinds[i].cpuset);
new->nr_cpukinds = i;
goto failed;
}
}
return 0;
failed:
hwloc_internal_cpukinds_destroy(new);
return -1;
}
void
hwloc_internal_cpukinds_restrict(hwloc_topology_t topology)
{
unsigned i;
int removed = 0;
for(i=0; i<topology->nr_cpukinds; i++) {
struct hwloc_internal_cpukind_s *kind = &topology->cpukinds[i];
hwloc_bitmap_and(kind->cpuset, kind->cpuset, hwloc_get_root_obj(topology)->cpuset);
if (hwloc_bitmap_iszero(kind->cpuset)) {
hwloc_bitmap_free(kind->cpuset);
hwloc__free_infos(kind->infos, kind->nr_infos);
memmove(kind, kind+1, (topology->nr_cpukinds - i - 1)*sizeof(*kind));
i--;
topology->nr_cpukinds--;
removed = 1;
}
}
if (removed)
hwloc_internal_cpukinds_rank(topology);
}
/********************
* Registering
*/
static __hwloc_inline int
hwloc__cpukind_check_duplicate_info(struct hwloc_internal_cpukind_s *kind,
const char *name, const char *value)
{
unsigned i;
for(i=0; i<kind->nr_infos; i++)
if (!strcmp(kind->infos[i].name, name)
&& !strcmp(kind->infos[i].value, value))
return 1;
return 0;
}
static __hwloc_inline void
hwloc__cpukind_add_infos(struct hwloc_internal_cpukind_s *kind,
const struct hwloc_info_s *infos, unsigned nr_infos)
{
unsigned i;
for(i=0; i<nr_infos; i++) {
if (hwloc__cpukind_check_duplicate_info(kind, infos[i].name, infos[i].value))
continue;
hwloc__add_info(&kind->infos, &kind->nr_infos, infos[i].name, infos[i].value);
}
}
int
hwloc_internal_cpukinds_register(hwloc_topology_t topology, hwloc_cpuset_t cpuset,
int forced_efficiency,
const struct hwloc_info_s *infos, unsigned nr_infos,
unsigned long flags)
{
struct hwloc_internal_cpukind_s *kinds;
unsigned i, max, bits, oldnr, newnr;
if (hwloc_bitmap_iszero(cpuset)) {
hwloc_bitmap_free(cpuset);
errno = EINVAL;
return -1;
}
if (flags & ~HWLOC_CPUKINDS_REGISTER_FLAG_OVERWRITE_FORCED_EFFICIENCY) {
errno = EINVAL;
return -1;
}
/* TODO: for now, only windows provides a forced efficiency.
* if another backend ever provides a conflicting value, the first backend value will be kept.
* (user-provided values are not an issue, they are meant to overwrite)
*/
/* If we have N kinds currently, we may need 2N+1 kinds after inserting the new one:
* - each existing kind may get split into which PUs are in the new kind and which aren't.
* - some PUs might not have been in any kind yet.
*/
max = 2 * topology->nr_cpukinds + 1;
/* Allocate the power-of-two above 2N+1. */
bits = hwloc_flsl(max-1) + 1;
max = 1U<<bits;
/* Allocate 8 minimum to avoid multiple reallocs */
if (max < 8)
max = 8;
/* Create or enlarge the array of kinds if needed */
kinds = topology->cpukinds;
if (max > topology->nr_cpukinds_allocated) {
kinds = realloc(kinds, max * sizeof(*kinds));
if (!kinds) {
hwloc_bitmap_free(cpuset);
return -1;
}
memset(&kinds[topology->nr_cpukinds_allocated], 0, (max - topology->nr_cpukinds_allocated) * sizeof(*kinds));
topology->nr_cpukinds_allocated = max;
topology->cpukinds = kinds;
}
newnr = oldnr = topology->nr_cpukinds;
for(i=0; i<oldnr; i++) {
int res = hwloc_bitmap_compare_inclusion(cpuset, kinds[i].cpuset);
if (res == HWLOC_BITMAP_INTERSECTS || res == HWLOC_BITMAP_INCLUDED) {
/* new kind with intersection of cpusets and union of infos */
kinds[newnr].cpuset = hwloc_bitmap_alloc();
kinds[newnr].efficiency = HWLOC_CPUKIND_EFFICIENCY_UNKNOWN;
kinds[newnr].forced_efficiency = forced_efficiency;
hwloc_bitmap_and(kinds[newnr].cpuset, cpuset, kinds[i].cpuset);
hwloc__cpukind_add_infos(&kinds[newnr], kinds[i].infos, kinds[i].nr_infos);
hwloc__cpukind_add_infos(&kinds[newnr], infos, nr_infos);
/* remove cpuset PUs from the existing kind that we just split */
hwloc_bitmap_andnot(kinds[i].cpuset, kinds[i].cpuset, kinds[newnr].cpuset);
/* clear cpuset PUs that were taken care of */
hwloc_bitmap_andnot(cpuset, cpuset, kinds[newnr].cpuset);
newnr++;
} else if (res == HWLOC_BITMAP_CONTAINS
|| res == HWLOC_BITMAP_EQUAL) {
/* append new info to existing smaller (or equal) kind */
hwloc__cpukind_add_infos(&kinds[i], infos, nr_infos);
if ((flags & HWLOC_CPUKINDS_REGISTER_FLAG_OVERWRITE_FORCED_EFFICIENCY)
|| kinds[i].forced_efficiency == HWLOC_CPUKIND_EFFICIENCY_UNKNOWN)
kinds[i].forced_efficiency = forced_efficiency;
/* clear cpuset PUs that were taken care of */
hwloc_bitmap_andnot(cpuset, cpuset, kinds[i].cpuset);
} else {
assert(res == HWLOC_BITMAP_DIFFERENT);
/* nothing to do */
}
/* don't compare with anything else if already empty */
if (hwloc_bitmap_iszero(cpuset))
break;
}
/* add a final kind with remaining PUs if any */
if (!hwloc_bitmap_iszero(cpuset)) {
kinds[newnr].cpuset = cpuset;
kinds[newnr].efficiency = HWLOC_CPUKIND_EFFICIENCY_UNKNOWN;
kinds[newnr].forced_efficiency = forced_efficiency;
hwloc__cpukind_add_infos(&kinds[newnr], infos, nr_infos);
newnr++;
} else {
hwloc_bitmap_free(cpuset);
}
topology->nr_cpukinds = newnr;
return 0;
}
int
hwloc_cpukinds_register(hwloc_topology_t topology, hwloc_cpuset_t _cpuset,
int forced_efficiency,
unsigned nr_infos, struct hwloc_info_s *infos,
unsigned long flags)
{
hwloc_bitmap_t cpuset;
int err;
if (flags) {
errno = EINVAL;
return -1;
}
if (!_cpuset || hwloc_bitmap_iszero(_cpuset)) {
errno = EINVAL;
return -1;
}
cpuset = hwloc_bitmap_dup(_cpuset);
if (!cpuset)
return -1;
if (forced_efficiency < 0)
forced_efficiency = HWLOC_CPUKIND_EFFICIENCY_UNKNOWN;
err = hwloc_internal_cpukinds_register(topology, cpuset, forced_efficiency, infos, nr_infos, HWLOC_CPUKINDS_REGISTER_FLAG_OVERWRITE_FORCED_EFFICIENCY);
if (err < 0)
return err;
hwloc_internal_cpukinds_rank(topology);
return 0;
}
/*********************
* Ranking
*/
static int
hwloc__cpukinds_check_duplicate_rankings(struct hwloc_topology *topology)
{
unsigned i,j;
for(i=0; i<topology->nr_cpukinds; i++)
for(j=i+1; j<topology->nr_cpukinds; j++)
if (topology->cpukinds[i].ranking_value == topology->cpukinds[j].ranking_value)
/* if any duplicate, fail */
return -1;
return 0;
}
static int
hwloc__cpukinds_try_rank_by_forced_efficiency(struct hwloc_topology *topology)
{
unsigned i;
hwloc_debug("Trying to rank cpukinds by forced efficiency...\n");
for(i=0; i<topology->nr_cpukinds; i++) {
if (topology->cpukinds[i].forced_efficiency == HWLOC_CPUKIND_EFFICIENCY_UNKNOWN)
/* if any unknown, fail */
return -1;
topology->cpukinds[i].ranking_value = topology->cpukinds[i].forced_efficiency;
}
return hwloc__cpukinds_check_duplicate_rankings(topology);
}
struct hwloc_cpukinds_info_summary {
int have_max_freq;
int have_base_freq;
int have_intel_core_type;
struct hwloc_cpukind_info_summary {
unsigned intel_core_type; /* 1 for atom, 2 for core */
unsigned max_freq, base_freq; /* MHz, hence < 100000 */
} * summaries;
};
static void
hwloc__cpukinds_summarize_info(struct hwloc_topology *topology,
struct hwloc_cpukinds_info_summary *summary)
{
unsigned i, j;
summary->have_max_freq = 1;
summary->have_base_freq = 1;
summary->have_intel_core_type = 1;
for(i=0; i<topology->nr_cpukinds; i++) {
struct hwloc_internal_cpukind_s *kind = &topology->cpukinds[i];
for(j=0; j<kind->nr_infos; j++) {
struct hwloc_info_s *info = &kind->infos[j];
if (!strcmp(info->name, "FrequencyMaxMHz")) {
summary->summaries[i].max_freq = atoi(info->value);
} else if (!strcmp(info->name, "FrequencyBaseMHz")) {
summary->summaries[i].base_freq = atoi(info->value);
} else if (!strcmp(info->name, "CoreType")) {
if (!strcmp(info->value, "IntelAtom"))
summary->summaries[i].intel_core_type = 1;
else if (!strcmp(info->value, "IntelCore"))
summary->summaries[i].intel_core_type = 2;
}
}
hwloc_debug("cpukind #%u has intel_core_type %u max_freq %u base_freq %u\n",
i, summary->summaries[i].intel_core_type,
summary->summaries[i].max_freq, summary->summaries[i].base_freq);
if (!summary->summaries[i].base_freq)
summary->have_base_freq = 0;
if (!summary->summaries[i].max_freq)
summary->have_max_freq = 0;
if (!summary->summaries[i].intel_core_type)
summary->have_intel_core_type = 0;
}
}
enum hwloc_cpukinds_ranking {
HWLOC_CPUKINDS_RANKING_DEFAULT, /* forced + frequency on ARM, forced + coretype_frequency otherwise */
HWLOC_CPUKINDS_RANKING_NO_FORCED_EFFICIENCY, /* default without forced */
HWLOC_CPUKINDS_RANKING_FORCED_EFFICIENCY,
HWLOC_CPUKINDS_RANKING_CORETYPE_FREQUENCY, /* either coretype or frequency or both */
HWLOC_CPUKINDS_RANKING_CORETYPE_FREQUENCY_STRICT, /* both coretype and frequency are required */
HWLOC_CPUKINDS_RANKING_CORETYPE,
HWLOC_CPUKINDS_RANKING_FREQUENCY,
HWLOC_CPUKINDS_RANKING_FREQUENCY_MAX,
HWLOC_CPUKINDS_RANKING_FREQUENCY_BASE,
HWLOC_CPUKINDS_RANKING_NONE
};
static int
hwloc__cpukinds_try_rank_by_info(struct hwloc_topology *topology,
enum hwloc_cpukinds_ranking heuristics,
struct hwloc_cpukinds_info_summary *summary)
{
unsigned i;
if (HWLOC_CPUKINDS_RANKING_CORETYPE_FREQUENCY_STRICT == heuristics) {
hwloc_debug("Trying to rank cpukinds by coretype+frequency_strict...\n");
/* we need intel_core_type AND (base or max freq) for all kinds */
if (!summary->have_intel_core_type
|| (!summary->have_max_freq && !summary->have_base_freq))
return -1;
/* rank first by coretype (Core>>Atom) then by frequency, base if available, max otherwise */
for(i=0; i<topology->nr_cpukinds; i++) {
struct hwloc_internal_cpukind_s *kind = &topology->cpukinds[i];
if (summary->have_base_freq)
kind->ranking_value = (summary->summaries[i].intel_core_type << 20) + summary->summaries[i].base_freq;
else
kind->ranking_value = (summary->summaries[i].intel_core_type << 20) + summary->summaries[i].max_freq;
}
} else if (HWLOC_CPUKINDS_RANKING_CORETYPE_FREQUENCY == heuristics) {
hwloc_debug("Trying to rank cpukinds by coretype+frequency...\n");
/* we need intel_core_type OR (base or max freq) for all kinds */
if (!summary->have_intel_core_type
&& (!summary->have_max_freq && !summary->have_base_freq))
return -1;
/* rank first by coretype (Core>>Atom) then by frequency, base if available, max otherwise */
for(i=0; i<topology->nr_cpukinds; i++) {
struct hwloc_internal_cpukind_s *kind = &topology->cpukinds[i];
if (summary->have_base_freq)
kind->ranking_value = (summary->summaries[i].intel_core_type << 20) + summary->summaries[i].base_freq;
else
kind->ranking_value = (summary->summaries[i].intel_core_type << 20) + summary->summaries[i].max_freq;
}
} else if (HWLOC_CPUKINDS_RANKING_CORETYPE == heuristics) {
hwloc_debug("Trying to rank cpukinds by coretype...\n");
/* we need intel_core_type */
if (!summary->have_intel_core_type)
return -1;
/* rank by coretype (Core>>Atom) */
for(i=0; i<topology->nr_cpukinds; i++) {
struct hwloc_internal_cpukind_s *kind = &topology->cpukinds[i];
kind->ranking_value = (summary->summaries[i].intel_core_type << 20);
}
} else if (HWLOC_CPUKINDS_RANKING_FREQUENCY == heuristics) {
hwloc_debug("Trying to rank cpukinds by frequency...\n");
/* we need base or max freq for all kinds */
if (!summary->have_max_freq && !summary->have_base_freq)
return -1;
/* rank first by frequency, base if available, max otherwise */
for(i=0; i<topology->nr_cpukinds; i++) {
struct hwloc_internal_cpukind_s *kind = &topology->cpukinds[i];
if (summary->have_base_freq)
kind->ranking_value = summary->summaries[i].base_freq;
else
kind->ranking_value = summary->summaries[i].max_freq;
}
} else if (HWLOC_CPUKINDS_RANKING_FREQUENCY_MAX == heuristics) {
hwloc_debug("Trying to rank cpukinds by frequency max...\n");
/* we need max freq for all kinds */
if (!summary->have_max_freq)
return -1;
/* rank first by frequency, base if available, max otherwise */
for(i=0; i<topology->nr_cpukinds; i++) {
struct hwloc_internal_cpukind_s *kind = &topology->cpukinds[i];
kind->ranking_value = summary->summaries[i].max_freq;
}
} else if (HWLOC_CPUKINDS_RANKING_FREQUENCY_BASE == heuristics) {
hwloc_debug("Trying to rank cpukinds by frequency base...\n");
/* we need max freq for all kinds */
if (!summary->have_base_freq)
return -1;
/* rank first by frequency, base if available, max otherwise */
for(i=0; i<topology->nr_cpukinds; i++) {
struct hwloc_internal_cpukind_s *kind = &topology->cpukinds[i];
kind->ranking_value = summary->summaries[i].base_freq;
}
} else assert(0);
return hwloc__cpukinds_check_duplicate_rankings(topology);
}
static int hwloc__cpukinds_compare_ranking_values(const void *_a, const void *_b)
{
const struct hwloc_internal_cpukind_s *a = _a;
const struct hwloc_internal_cpukind_s *b = _b;
uint64_t arv = a->ranking_value;
uint64_t brv = b->ranking_value;
return arv < brv ? -1 : arv > brv ? 1 : 0;
}
/* this function requires ranking values to be unique */
static void
hwloc__cpukinds_finalize_ranking(struct hwloc_topology *topology)
{
unsigned i;
/* sort */
qsort(topology->cpukinds, topology->nr_cpukinds, sizeof(*topology->cpukinds), hwloc__cpukinds_compare_ranking_values);
/* define our own efficiency between 0 and N-1 */
for(i=0; i<topology->nr_cpukinds; i++)
topology->cpukinds[i].efficiency = i;
}
int
hwloc_internal_cpukinds_rank(struct hwloc_topology *topology)
{
enum hwloc_cpukinds_ranking heuristics;
char *env;
unsigned i;
int err;
if (!topology->nr_cpukinds)
return 0;
if (topology->nr_cpukinds == 1) {
topology->cpukinds[0].efficiency = 0;
return 0;
}
heuristics = HWLOC_CPUKINDS_RANKING_DEFAULT;
env = getenv("HWLOC_CPUKINDS_RANKING");
if (env) {
if (!strcmp(env, "default"))
heuristics = HWLOC_CPUKINDS_RANKING_DEFAULT;
else if (!strcmp(env, "none"))
heuristics = HWLOC_CPUKINDS_RANKING_NONE;
else if (!strcmp(env, "coretype+frequency"))
heuristics = HWLOC_CPUKINDS_RANKING_CORETYPE_FREQUENCY;
else if (!strcmp(env, "coretype+frequency_strict"))
heuristics = HWLOC_CPUKINDS_RANKING_CORETYPE_FREQUENCY_STRICT;
else if (!strcmp(env, "coretype"))
heuristics = HWLOC_CPUKINDS_RANKING_CORETYPE;
else if (!strcmp(env, "frequency"))
heuristics = HWLOC_CPUKINDS_RANKING_FREQUENCY;
else if (!strcmp(env, "frequency_max"))
heuristics = HWLOC_CPUKINDS_RANKING_FREQUENCY_MAX;
else if (!strcmp(env, "frequency_base"))
heuristics = HWLOC_CPUKINDS_RANKING_FREQUENCY_BASE;
else if (!strcmp(env, "forced_efficiency"))
heuristics = HWLOC_CPUKINDS_RANKING_FORCED_EFFICIENCY;
else if (!strcmp(env, "no_forced_efficiency"))
heuristics = HWLOC_CPUKINDS_RANKING_NO_FORCED_EFFICIENCY;
else if (hwloc_hide_errors() < 2)
fprintf(stderr, "hwloc: Failed to recognize HWLOC_CPUKINDS_RANKING value %s\n", env);
}
if (heuristics == HWLOC_CPUKINDS_RANKING_DEFAULT
|| heuristics == HWLOC_CPUKINDS_RANKING_NO_FORCED_EFFICIENCY) {
/* default is forced_efficiency first */
struct hwloc_cpukinds_info_summary summary;
if (heuristics == HWLOC_CPUKINDS_RANKING_DEFAULT)
hwloc_debug("Using default ranking strategy...\n");
else
hwloc_debug("Using custom ranking strategy from HWLOC_CPUKINDS_RANKING=%s\n", env);
if (heuristics != HWLOC_CPUKINDS_RANKING_NO_FORCED_EFFICIENCY) {
err = hwloc__cpukinds_try_rank_by_forced_efficiency(topology);
if (!err)
goto ready;
}
summary.summaries = calloc(topology->nr_cpukinds, sizeof(*summary.summaries));
if (!summary.summaries)
goto failed;
hwloc__cpukinds_summarize_info(topology, &summary);
err = hwloc__cpukinds_try_rank_by_info(topology, HWLOC_CPUKINDS_RANKING_CORETYPE_FREQUENCY, &summary);
free(summary.summaries);
if (!err)
goto ready;
} else if (heuristics == HWLOC_CPUKINDS_RANKING_FORCED_EFFICIENCY) {
hwloc_debug("Using custom ranking strategy from HWLOC_CPUKINDS_RANKING=%s\n", env);
err = hwloc__cpukinds_try_rank_by_forced_efficiency(topology);
if (!err)
goto ready;
} else if (heuristics != HWLOC_CPUKINDS_RANKING_NONE) {
/* custom heuristics */
struct hwloc_cpukinds_info_summary summary;
hwloc_debug("Using custom ranking strategy from HWLOC_CPUKINDS_RANKING=%s\n", env);
summary.summaries = calloc(topology->nr_cpukinds, sizeof(*summary.summaries));
if (!summary.summaries)
goto failed;
hwloc__cpukinds_summarize_info(topology, &summary);
err = hwloc__cpukinds_try_rank_by_info(topology, heuristics, &summary);
free(summary.summaries);
if (!err)
goto ready;
}
failed:
/* failed to rank, clear efficiencies */
for(i=0; i<topology->nr_cpukinds; i++)
topology->cpukinds[i].efficiency = HWLOC_CPUKIND_EFFICIENCY_UNKNOWN;
hwloc_debug("Failed to rank cpukinds.\n\n");
return 0;
ready:
for(i=0; i<topology->nr_cpukinds; i++)
hwloc_debug("cpukind #%u got ranking value %llu\n", i, (unsigned long long) topology->cpukinds[i].ranking_value);
hwloc__cpukinds_finalize_ranking(topology);
#ifdef HWLOC_DEBUG
for(i=0; i<topology->nr_cpukinds; i++)
assert(topology->cpukinds[i].efficiency == (int) i);
#endif
hwloc_debug("\n");
return 0;
}
/*****************
* Consulting
*/
int
hwloc_cpukinds_get_nr(hwloc_topology_t topology, unsigned long flags)
{
if (flags) {
errno = EINVAL;
return -1;
}
return topology->nr_cpukinds;
}
int
hwloc_cpukinds_get_info(hwloc_topology_t topology,
unsigned id,
hwloc_bitmap_t cpuset,
int *efficiencyp,
unsigned *nr_infosp, struct hwloc_info_s **infosp,
unsigned long flags)
{
struct hwloc_internal_cpukind_s *kind;
if (flags) {
errno = EINVAL;
return -1;
}
if (id >= topology->nr_cpukinds) {
errno = ENOENT;
return -1;
}
kind = &topology->cpukinds[id];
if (cpuset)
hwloc_bitmap_copy(cpuset, kind->cpuset);
if (efficiencyp)
*efficiencyp = kind->efficiency;
if (nr_infosp && infosp) {
*nr_infosp = kind->nr_infos;
*infosp = kind->infos;
}
return 0;
}
int
hwloc_cpukinds_get_by_cpuset(hwloc_topology_t topology,
hwloc_const_bitmap_t cpuset,
unsigned long flags)
{
unsigned id;
if (flags) {
errno = EINVAL;
return -1;
}
if (!cpuset || hwloc_bitmap_iszero(cpuset)) {
errno = EINVAL;
return -1;
}
for(id=0; id<topology->nr_cpukinds; id++) {
struct hwloc_internal_cpukind_s *kind = &topology->cpukinds[id];
int res = hwloc_bitmap_compare_inclusion(cpuset, kind->cpuset);
if (res == HWLOC_BITMAP_EQUAL || res == HWLOC_BITMAP_INCLUDED) {
return (int) id;
} else if (res == HWLOC_BITMAP_INTERSECTS || res == HWLOC_BITMAP_CONTAINS) {
errno = EXDEV;
return -1;
}
}
errno = ENOENT;
return -1;
}

View file

@ -1,540 +0,0 @@
/*
* Copyright © 2013-2020 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
#include "private/autogen/config.h"
#include "private/private.h"
#include "private/misc.h"
int hwloc_topology_diff_destroy(hwloc_topology_diff_t diff)
{
hwloc_topology_diff_t next;
while (diff) {
next = diff->generic.next;
switch (diff->generic.type) {
default:
break;
case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR:
switch (diff->obj_attr.diff.generic.type) {
default:
break;
case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_NAME:
case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_INFO:
free(diff->obj_attr.diff.string.name);
free(diff->obj_attr.diff.string.oldvalue);
free(diff->obj_attr.diff.string.newvalue);
break;
}
break;
}
free(diff);
diff = next;
}
return 0;
}
/************************
* Computing diffs
*/
static void hwloc_append_diff(hwloc_topology_diff_t newdiff,
hwloc_topology_diff_t *firstdiffp,
hwloc_topology_diff_t *lastdiffp)
{
if (*firstdiffp)
(*lastdiffp)->generic.next = newdiff;
else
*firstdiffp = newdiff;
*lastdiffp = newdiff;
newdiff->generic.next = NULL;
}
static int hwloc_append_diff_too_complex(hwloc_obj_t obj1,
hwloc_topology_diff_t *firstdiffp,
hwloc_topology_diff_t *lastdiffp)
{
hwloc_topology_diff_t newdiff;
newdiff = malloc(sizeof(*newdiff));
if (!newdiff)
return -1;
newdiff->too_complex.type = HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX;
newdiff->too_complex.obj_depth = obj1->depth;
newdiff->too_complex.obj_index = obj1->logical_index;
hwloc_append_diff(newdiff, firstdiffp, lastdiffp);
return 0;
}
static int hwloc_append_diff_obj_attr_string(hwloc_obj_t obj,
hwloc_topology_diff_obj_attr_type_t type,
const char *name,
const char *oldvalue,
const char *newvalue,
hwloc_topology_diff_t *firstdiffp,
hwloc_topology_diff_t *lastdiffp)
{
hwloc_topology_diff_t newdiff;
newdiff = malloc(sizeof(*newdiff));
if (!newdiff)
return -1;
newdiff->obj_attr.type = HWLOC_TOPOLOGY_DIFF_OBJ_ATTR;
newdiff->obj_attr.obj_depth = obj->depth;
newdiff->obj_attr.obj_index = obj->logical_index;
newdiff->obj_attr.diff.string.type = type;
newdiff->obj_attr.diff.string.name = name ? strdup(name) : NULL;
newdiff->obj_attr.diff.string.oldvalue = oldvalue ? strdup(oldvalue) : NULL;
newdiff->obj_attr.diff.string.newvalue = newvalue ? strdup(newvalue) : NULL;
hwloc_append_diff(newdiff, firstdiffp, lastdiffp);
return 0;
}
static int hwloc_append_diff_obj_attr_uint64(hwloc_obj_t obj,
hwloc_topology_diff_obj_attr_type_t type,
hwloc_uint64_t idx,
hwloc_uint64_t oldvalue,
hwloc_uint64_t newvalue,
hwloc_topology_diff_t *firstdiffp,
hwloc_topology_diff_t *lastdiffp)
{
hwloc_topology_diff_t newdiff;
newdiff = malloc(sizeof(*newdiff));
if (!newdiff)
return -1;
newdiff->obj_attr.type = HWLOC_TOPOLOGY_DIFF_OBJ_ATTR;
newdiff->obj_attr.obj_depth = obj->depth;
newdiff->obj_attr.obj_index = obj->logical_index;
newdiff->obj_attr.diff.uint64.type = type;
newdiff->obj_attr.diff.uint64.index = idx;
newdiff->obj_attr.diff.uint64.oldvalue = oldvalue;
newdiff->obj_attr.diff.uint64.newvalue = newvalue;
hwloc_append_diff(newdiff, firstdiffp, lastdiffp);
return 0;
}
static int
hwloc_diff_trees(hwloc_topology_t topo1, hwloc_obj_t obj1,
hwloc_topology_t topo2, hwloc_obj_t obj2,
unsigned flags,
hwloc_topology_diff_t *firstdiffp, hwloc_topology_diff_t *lastdiffp)
{
unsigned i;
int err;
hwloc_obj_t child1, child2;
if (obj1->depth != obj2->depth)
goto out_too_complex;
if (obj1->type != obj2->type)
goto out_too_complex;
if ((!obj1->subtype) != (!obj2->subtype)
|| (obj1->subtype && strcmp(obj1->subtype, obj2->subtype)))
goto out_too_complex;
if (obj1->os_index != obj2->os_index)
/* we could allow different os_index for non-PU non-NUMAnode objects
* but it's likely useless anyway */
goto out_too_complex;
#define _SETS_DIFFERENT(_set1, _set2) \
( ( !(_set1) != !(_set2) ) \
|| ( (_set1) && !hwloc_bitmap_isequal(_set1, _set2) ) )
#define SETS_DIFFERENT(_set, _obj1, _obj2) _SETS_DIFFERENT((_obj1)->_set, (_obj2)->_set)
if (SETS_DIFFERENT(cpuset, obj1, obj2)
|| SETS_DIFFERENT(complete_cpuset, obj1, obj2)
|| SETS_DIFFERENT(nodeset, obj1, obj2)
|| SETS_DIFFERENT(complete_nodeset, obj1, obj2))
goto out_too_complex;
/* no need to check logical_index, sibling_rank, symmetric_subtree,
* the parents did it */
/* gp_index don't have to be strictly identical */
if ((!obj1->name) != (!obj2->name)
|| (obj1->name && strcmp(obj1->name, obj2->name))) {
err = hwloc_append_diff_obj_attr_string(obj1,
HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_NAME,
NULL,
obj1->name,
obj2->name,
firstdiffp, lastdiffp);
if (err < 0)
return err;
}
/* type-specific attrs */
switch (obj1->type) {
default:
break;
case HWLOC_OBJ_NUMANODE:
if (obj1->attr->numanode.local_memory != obj2->attr->numanode.local_memory) {
err = hwloc_append_diff_obj_attr_uint64(obj1,
HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_SIZE,
0,
obj1->attr->numanode.local_memory,
obj2->attr->numanode.local_memory,
firstdiffp, lastdiffp);
if (err < 0)
return err;
}
/* ignore memory page_types */
break;
case HWLOC_OBJ_L1CACHE:
case HWLOC_OBJ_L2CACHE:
case HWLOC_OBJ_L3CACHE:
case HWLOC_OBJ_L4CACHE:
case HWLOC_OBJ_L5CACHE:
case HWLOC_OBJ_L1ICACHE:
case HWLOC_OBJ_L2ICACHE:
case HWLOC_OBJ_L3ICACHE:
if (memcmp(obj1->attr, obj2->attr, sizeof(obj1->attr->cache)))
goto out_too_complex;
break;
case HWLOC_OBJ_GROUP:
if (memcmp(obj1->attr, obj2->attr, sizeof(obj1->attr->group)))
goto out_too_complex;
break;
case HWLOC_OBJ_PCI_DEVICE:
if (memcmp(obj1->attr, obj2->attr, sizeof(obj1->attr->pcidev)))
goto out_too_complex;
break;
case HWLOC_OBJ_BRIDGE:
if (memcmp(obj1->attr, obj2->attr, sizeof(obj1->attr->bridge)))
goto out_too_complex;
break;
case HWLOC_OBJ_OS_DEVICE:
if (memcmp(obj1->attr, obj2->attr, sizeof(obj1->attr->osdev)))
goto out_too_complex;
break;
}
/* infos */
if (obj1->infos_count != obj2->infos_count)
goto out_too_complex;
for(i=0; i<obj1->infos_count; i++) {
struct hwloc_info_s *info1 = &obj1->infos[i], *info2 = &obj2->infos[i];
if (strcmp(info1->name, info2->name))
goto out_too_complex;
if (strcmp(obj1->infos[i].value, obj2->infos[i].value)) {
err = hwloc_append_diff_obj_attr_string(obj1,
HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_INFO,
info1->name,
info1->value,
info2->value,
firstdiffp, lastdiffp);
if (err < 0)
return err;
}
}
/* ignore userdata */
/* children */
for(child1 = obj1->first_child, child2 = obj2->first_child;
child1 != NULL && child2 != NULL;
child1 = child1->next_sibling, child2 = child2->next_sibling) {
err = hwloc_diff_trees(topo1, child1,
topo2, child2,
flags,
firstdiffp, lastdiffp);
if (err < 0)
return err;
}
if (child1 || child2)
goto out_too_complex;
/* memory children */
for(child1 = obj1->memory_first_child, child2 = obj2->memory_first_child;
child1 != NULL && child2 != NULL;
child1 = child1->next_sibling, child2 = child2->next_sibling) {
err = hwloc_diff_trees(topo1, child1,
topo2, child2,
flags,
firstdiffp, lastdiffp);
if (err < 0)
return err;
}
if (child1 || child2)
goto out_too_complex;
/* I/O children */
for(child1 = obj1->io_first_child, child2 = obj2->io_first_child;
child1 != NULL && child2 != NULL;
child1 = child1->next_sibling, child2 = child2->next_sibling) {
err = hwloc_diff_trees(topo1, child1,
topo2, child2,
flags,
firstdiffp, lastdiffp);
if (err < 0)
return err;
}
if (child1 || child2)
goto out_too_complex;
/* misc children */
for(child1 = obj1->misc_first_child, child2 = obj2->misc_first_child;
child1 != NULL && child2 != NULL;
child1 = child1->next_sibling, child2 = child2->next_sibling) {
err = hwloc_diff_trees(topo1, child1,
topo2, child2,
flags,
firstdiffp, lastdiffp);
if (err < 0)
return err;
}
if (child1 || child2)
goto out_too_complex;
return 0;
out_too_complex:
hwloc_append_diff_too_complex(obj1, firstdiffp, lastdiffp);
return 0;
}
int hwloc_topology_diff_build(hwloc_topology_t topo1,
hwloc_topology_t topo2,
unsigned long flags,
hwloc_topology_diff_t *diffp)
{
hwloc_topology_diff_t lastdiff, tmpdiff;
struct hwloc_internal_distances_s *dist1, *dist2;
unsigned i;
int err;
if (!topo1->is_loaded || !topo2->is_loaded) {
errno = EINVAL;
return -1;
}
if (flags != 0) {
errno = EINVAL;
return -1;
}
*diffp = NULL;
err = hwloc_diff_trees(topo1, hwloc_get_root_obj(topo1),
topo2, hwloc_get_root_obj(topo2),
flags,
diffp, &lastdiff);
if (!err) {
tmpdiff = *diffp;
while (tmpdiff) {
if (tmpdiff->generic.type == HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX) {
err = 1;
break;
}
tmpdiff = tmpdiff->generic.next;
}
}
if (!err) {
if (SETS_DIFFERENT(allowed_cpuset, topo1, topo2)
|| SETS_DIFFERENT(allowed_nodeset, topo1, topo2))
goto roottoocomplex;
}
if (!err) {
/* distances */
hwloc_internal_distances_refresh(topo1);
hwloc_internal_distances_refresh(topo2);
dist1 = topo1->first_dist;
dist2 = topo2->first_dist;
while (dist1 || dist2) {
if (!!dist1 != !!dist2)
goto roottoocomplex;
if (dist1->unique_type != dist2->unique_type
|| dist1->different_types || dist2->different_types /* too lazy to support this case */
|| dist1->nbobjs != dist2->nbobjs
|| dist1->kind != dist2->kind
|| memcmp(dist1->values, dist2->values, dist1->nbobjs * dist1->nbobjs * sizeof(*dist1->values)))
goto roottoocomplex;
for(i=0; i<dist1->nbobjs; i++)
/* gp_index isn't enforced above. so compare logical_index instead, which is enforced. requires distances refresh() above */
if (dist1->objs[i]->logical_index != dist2->objs[i]->logical_index)
goto roottoocomplex;
dist1 = dist1->next;
dist2 = dist2->next;
}
}
if (!err) {
/* memattrs */
hwloc_internal_memattrs_refresh(topo1);
hwloc_internal_memattrs_refresh(topo2);
if (topo1->nr_memattrs != topo2->nr_memattrs)
goto roottoocomplex;
for(i=0; i<topo1->nr_memattrs; i++) {
struct hwloc_internal_memattr_s *imattr1 = &topo1->memattrs[i], *imattr2 = &topo2->memattrs[i];
unsigned j;
if (strcmp(imattr1->name, imattr2->name)
|| imattr1->flags != imattr2->flags
|| imattr1->nr_targets != imattr2->nr_targets)
goto roottoocomplex;
if (i == HWLOC_MEMATTR_ID_CAPACITY
|| i == HWLOC_MEMATTR_ID_LOCALITY)
/* no need to check virtual attributes, there were refreshed from other topology attributes, checked above */
continue;
for(j=0; j<imattr1->nr_targets; j++) {
struct hwloc_internal_memattr_target_s *imtg1 = &imattr1->targets[j], *imtg2 = &imattr2->targets[j];
if (imtg1->type != imtg2->type)
goto roottoocomplex;
if (imtg1->obj->logical_index != imtg2->obj->logical_index)
goto roottoocomplex;
if (imattr1->flags & HWLOC_MEMATTR_FLAG_NEED_INITIATOR) {
unsigned k;
for(k=0; k<imtg1->nr_initiators; k++) {
struct hwloc_internal_memattr_initiator_s *imi1 = &imtg1->initiators[k], *imi2 = &imtg2->initiators[k];
if (imi1->value != imi2->value
|| imi1->initiator.type != imi2->initiator.type)
goto roottoocomplex;
if (imi1->initiator.type == HWLOC_LOCATION_TYPE_CPUSET) {
if (!hwloc_bitmap_isequal(imi1->initiator.location.cpuset, imi2->initiator.location.cpuset))
goto roottoocomplex;
} else if (imi1->initiator.type == HWLOC_LOCATION_TYPE_OBJECT) {
if (imi1->initiator.location.object.type != imi2->initiator.location.object.type)
goto roottoocomplex;
if (imi1->initiator.location.object.obj->logical_index != imi2->initiator.location.object.obj->logical_index)
goto roottoocomplex;
} else {
assert(0);
}
}
} else {
if (imtg1->noinitiator_value != imtg2->noinitiator_value)
goto roottoocomplex;
}
}
}
}
return err;
roottoocomplex:
hwloc_append_diff_too_complex(hwloc_get_root_obj(topo1), diffp, &lastdiff);
return 1;
}
/********************
* Applying diffs
*/
static int
hwloc_apply_diff_one(hwloc_topology_t topology,
hwloc_topology_diff_t diff,
unsigned long flags)
{
int reverse = !!(flags & HWLOC_TOPOLOGY_DIFF_APPLY_REVERSE);
switch (diff->generic.type) {
case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR: {
struct hwloc_topology_diff_obj_attr_s *obj_attr = &diff->obj_attr;
hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, obj_attr->obj_depth, obj_attr->obj_index);
if (!obj)
return -1;
switch (obj_attr->diff.generic.type) {
case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_SIZE: {
hwloc_obj_t tmpobj;
hwloc_uint64_t oldvalue = reverse ? obj_attr->diff.uint64.newvalue : obj_attr->diff.uint64.oldvalue;
hwloc_uint64_t newvalue = reverse ? obj_attr->diff.uint64.oldvalue : obj_attr->diff.uint64.newvalue;
hwloc_uint64_t valuediff = newvalue - oldvalue;
if (obj->type != HWLOC_OBJ_NUMANODE)
return -1;
if (obj->attr->numanode.local_memory != oldvalue)
return -1;
obj->attr->numanode.local_memory = newvalue;
tmpobj = obj;
while (tmpobj) {
tmpobj->total_memory += valuediff;
tmpobj = tmpobj->parent;
}
break;
}
case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_NAME: {
const char *oldvalue = reverse ? obj_attr->diff.string.newvalue : obj_attr->diff.string.oldvalue;
const char *newvalue = reverse ? obj_attr->diff.string.oldvalue : obj_attr->diff.string.newvalue;
if (!obj->name || strcmp(obj->name, oldvalue))
return -1;
free(obj->name);
obj->name = strdup(newvalue);
break;
}
case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_INFO: {
const char *name = obj_attr->diff.string.name;
const char *oldvalue = reverse ? obj_attr->diff.string.newvalue : obj_attr->diff.string.oldvalue;
const char *newvalue = reverse ? obj_attr->diff.string.oldvalue : obj_attr->diff.string.newvalue;
unsigned i;
int found = 0;
for(i=0; i<obj->infos_count; i++) {
struct hwloc_info_s *info = &obj->infos[i];
if (!strcmp(info->name, name)
&& !strcmp(info->value, oldvalue)) {
free(info->value);
info->value = strdup(newvalue);
found = 1;
break;
}
}
if (!found)
return -1;
break;
}
default:
return -1;
}
break;
}
default:
return -1;
}
return 0;
}
int hwloc_topology_diff_apply(hwloc_topology_t topology,
hwloc_topology_diff_t diff,
unsigned long flags)
{
hwloc_topology_diff_t tmpdiff, tmpdiff2;
int err, nr;
if (!topology->is_loaded) {
errno = EINVAL;
return -1;
}
if (topology->adopted_shmem_addr) {
errno = EPERM;
return -1;
}
if (flags & ~HWLOC_TOPOLOGY_DIFF_APPLY_REVERSE) {
errno = EINVAL;
return -1;
}
tmpdiff = diff;
nr = 0;
while (tmpdiff) {
nr++;
err = hwloc_apply_diff_one(topology, tmpdiff, flags);
if (err < 0)
goto cancel;
tmpdiff = tmpdiff->generic.next;
}
return 0;
cancel:
tmpdiff2 = tmpdiff;
tmpdiff = diff;
while (tmpdiff != tmpdiff2) {
hwloc_apply_diff_one(topology, tmpdiff, flags ^ HWLOC_TOPOLOGY_DIFF_APPLY_REVERSE);
tmpdiff = tmpdiff->generic.next;
}
errno = EINVAL;
return -nr; /* return the index (starting at 1) of the first element that couldn't be applied */
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,153 +0,0 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2020 Inria. All rights reserved.
* Copyright © 2009-2010 Université Bordeaux
* Copyright © 2009-2018 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
#include "private/autogen/config.h"
#include "private/private.h"
#include "private/misc.h"
#include <stdarg.h>
#ifdef HAVE_SYS_UTSNAME_H
#include <sys/utsname.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#ifdef HAVE_PROGRAM_INVOCATION_NAME
#include <errno.h>
extern char *program_invocation_name;
#endif
#ifdef HAVE___PROGNAME
extern char *__progname;
#endif
#ifndef HWLOC_HAVE_CORRECT_SNPRINTF
int hwloc_snprintf(char *str, size_t size, const char *format, ...)
{
int ret;
va_list ap;
static char bin;
size_t fakesize;
char *fakestr;
/* Some systems crash on str == NULL */
if (!size) {
str = &bin;
size = 1;
}
va_start(ap, format);
ret = vsnprintf(str, size, format, ap);
va_end(ap);
if (ret >= 0 && (size_t) ret != size-1)
return ret;
/* vsnprintf returned size-1 or -1. That could be a system which reports the
* written data and not the actually required room. Try increasing buffer
* size to get the latter. */
fakesize = size;
fakestr = NULL;
do {
fakesize *= 2;
free(fakestr);
fakestr = malloc(fakesize);
if (NULL == fakestr)
return -1;
va_start(ap, format);
errno = 0;
ret = vsnprintf(fakestr, fakesize, format, ap);
va_end(ap);
} while ((size_t) ret == fakesize-1 || (ret < 0 && (!errno || errno == ERANGE)));
if (ret >= 0 && size) {
if (size > (size_t) ret+1)
size = ret+1;
memcpy(str, fakestr, size-1);
str[size-1] = 0;
}
free(fakestr);
return ret;
}
#endif
void hwloc_add_uname_info(struct hwloc_topology *topology __hwloc_attribute_unused,
void *cached_uname __hwloc_attribute_unused)
{
#ifdef HAVE_UNAME
struct utsname _utsname, *utsname;
if (hwloc_obj_get_info_by_name(topology->levels[0][0], "OSName"))
/* don't annotate twice */
return;
if (cached_uname)
utsname = (struct utsname *) cached_uname;
else {
utsname = &_utsname;
if (uname(utsname) < 0)
return;
}
if (*utsname->sysname)
hwloc_obj_add_info(topology->levels[0][0], "OSName", utsname->sysname);
if (*utsname->release)
hwloc_obj_add_info(topology->levels[0][0], "OSRelease", utsname->release);
if (*utsname->version)
hwloc_obj_add_info(topology->levels[0][0], "OSVersion", utsname->version);
if (*utsname->nodename)
hwloc_obj_add_info(topology->levels[0][0], "HostName", utsname->nodename);
if (*utsname->machine)
hwloc_obj_add_info(topology->levels[0][0], "Architecture", utsname->machine);
#endif /* HAVE_UNAME */
}
char *
hwloc_progname(struct hwloc_topology *topology __hwloc_attribute_unused)
{
#if (defined HAVE_DECL_GETMODULEFILENAME) && HAVE_DECL_GETMODULEFILENAME
char name[256], *local_basename;
unsigned res = GetModuleFileName(NULL, name, sizeof(name));
if (res == sizeof(name) || !res)
return NULL;
local_basename = strrchr(name, '\\');
if (!local_basename)
local_basename = name;
else
local_basename++;
return strdup(local_basename);
#else /* !HAVE_GETMODULEFILENAME */
const char *name, *local_basename;
#if HAVE_DECL_GETPROGNAME
name = getprogname(); /* FreeBSD, NetBSD, some Solaris */
#elif HAVE_DECL_GETEXECNAME
name = getexecname(); /* Solaris */
#elif defined HAVE_PROGRAM_INVOCATION_NAME
name = program_invocation_name; /* Glibc. BGQ CNK. */
/* could use program_invocation_short_name directly, but we have the code to remove the path below anyway */
#elif defined HAVE___PROGNAME
name = __progname; /* fallback for most unix, used for OpenBSD */
#else
/* TODO: _NSGetExecutablePath(path, &size) on Darwin */
/* TODO: AIX, HPUX */
name = NULL;
#endif
if (!name)
return NULL;
local_basename = strrchr(name, '/');
if (!local_basename)
local_basename = name;
else
local_basename++;
return strdup(local_basename);
#endif /* !HAVE_GETMODULEFILENAME */
}

File diff suppressed because it is too large Load diff

View file

@ -1,300 +0,0 @@
/*
* Copyright © 2017-2020 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
#include "private/autogen/config.h"
#include "hwloc.h"
#include "hwloc/shmem.h"
#include "private/private.h"
#ifndef HWLOC_WIN_SYS
#include <sys/mman.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <assert.h>
#define HWLOC_SHMEM_HEADER_VERSION 1
struct hwloc_shmem_header {
uint32_t header_version; /* sanity check */
uint32_t header_length; /* where the actual topology starts in the file/mapping */
uint64_t mmap_address; /* virtual address to pass to mmap */
uint64_t mmap_length; /* length to pass to mmap (includes the header) */
};
#define HWLOC_SHMEM_MALLOC_ALIGN 8UL
static void *
tma_shmem_malloc(struct hwloc_tma * tma,
size_t length)
{
void *current = tma->data;
tma->data = (char*)tma->data + ((length + HWLOC_SHMEM_MALLOC_ALIGN - 1) & ~(HWLOC_SHMEM_MALLOC_ALIGN - 1));
return current;
}
static void *
tma_get_length_malloc(struct hwloc_tma * tma,
size_t length)
{
size_t *tma_length = tma->data;
*tma_length += (length + HWLOC_SHMEM_MALLOC_ALIGN - 1) & ~(HWLOC_SHMEM_MALLOC_ALIGN - 1);
return malloc(length);
}
int
hwloc_shmem_topology_get_length(hwloc_topology_t topology,
size_t *lengthp,
unsigned long flags)
{
hwloc_topology_t new;
struct hwloc_tma tma;
size_t length = 0;
unsigned long pagesize = hwloc_getpagesize(); /* round-up to full page for mmap() */
int err;
if (flags) {
errno = EINVAL;
return -1;
}
tma.malloc = tma_get_length_malloc;
tma.dontfree = 0;
tma.data = &length;
err = hwloc__topology_dup(&new, topology, &tma);
if (err < 0)
return err;
hwloc_topology_destroy(new);
*lengthp = (sizeof(struct hwloc_shmem_header) + length + pagesize - 1) & ~(pagesize - 1);
return 0;
}
int
hwloc_shmem_topology_write(hwloc_topology_t topology,
int fd, hwloc_uint64_t fileoffset,
void *mmap_address, size_t length,
unsigned long flags)
{
hwloc_topology_t new;
struct hwloc_tma tma;
struct hwloc_shmem_header header;
void *mmap_res;
int err;
if (flags) {
errno = EINVAL;
return -1;
}
/* refresh old topology distances so that we don't uselessly duplicate invalid distances
* without being able to free() them.
*/
hwloc_internal_distances_refresh(topology);
hwloc_internal_memattrs_refresh(topology);
header.header_version = HWLOC_SHMEM_HEADER_VERSION;
header.header_length = sizeof(header);
header.mmap_address = (uintptr_t) mmap_address;
header.mmap_length = length;
err = lseek(fd, fileoffset, SEEK_SET);
if (err < 0)
return -1;
err = write(fd, &header, sizeof(header));
if (err != sizeof(header))
return -1;
err = ftruncate(fd, fileoffset + length);
if (err < 0)
return -1;
mmap_res = mmap(mmap_address, length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, fileoffset);
if (mmap_res == MAP_FAILED)
return -1;
if (mmap_res != mmap_address) {
munmap(mmap_res, length);
errno = EBUSY;
return -1;
}
tma.malloc = tma_shmem_malloc;
tma.dontfree = 1;
tma.data = (char *)mmap_res + sizeof(header);
err = hwloc__topology_dup(&new, topology, &tma);
if (err < 0)
return err;
assert((char*)new == (char*)mmap_address + sizeof(header));
assert((char *)mmap_res <= (char *)mmap_address + length);
/* now refresh the new distances/memattrs so that adopters can use them without refreshing the R/O shmem mapping */
hwloc_internal_distances_refresh(new);
hwloc_internal_memattrs_refresh(topology);
/* topology is saved, release resources now */
munmap(mmap_address, length);
hwloc_components_fini();
return 0;
}
int
hwloc_shmem_topology_adopt(hwloc_topology_t *topologyp,
int fd, hwloc_uint64_t fileoffset,
void *mmap_address, size_t length,
unsigned long flags)
{
hwloc_topology_t new, old;
struct hwloc_shmem_header header;
void *mmap_res;
int err;
if (flags) {
errno = EINVAL;
return -1;
}
err = lseek(fd, fileoffset, SEEK_SET);
if (err < 0)
return -1;
err = read(fd, &header, sizeof(header));
if (err != sizeof(header))
return -1;
if (header.header_version != HWLOC_SHMEM_HEADER_VERSION
|| header.header_length != sizeof(header)
|| header.mmap_address != (uintptr_t) mmap_address
|| header.mmap_length != length) {
errno = EINVAL;
return -1;
}
mmap_res = mmap(mmap_address, length, PROT_READ, MAP_SHARED, fd, fileoffset);
if (mmap_res == MAP_FAILED)
return -1;
if (mmap_res != mmap_address) {
errno = EBUSY;
goto out_with_mmap;
}
old = (hwloc_topology_t)((char*)mmap_address + sizeof(header));
if (hwloc_topology_abi_check(old) < 0) {
errno = EINVAL;
goto out_with_mmap;
}
/* enforced by dup() inside shmem_topology_write() */
assert(old->is_loaded);
assert(old->backends == NULL);
assert(old->get_pci_busid_cpuset_backend == NULL);
hwloc_components_init();
/* duplicate the topology object so that we ca change use local binding_hooks
* (those are likely not mapped at the same location in both processes).
*/
new = malloc(sizeof(struct hwloc_topology));
if (!new)
goto out_with_components;
memcpy(new, old, sizeof(*old));
new->tma = NULL;
new->adopted_shmem_addr = mmap_address;
new->adopted_shmem_length = length;
new->topology_abi = HWLOC_TOPOLOGY_ABI;
/* setting binding hooks will touch support arrays, so duplicate them too.
* could avoid that by requesting a R/W mmap
*/
new->support.discovery = malloc(sizeof(*new->support.discovery));
new->support.cpubind = malloc(sizeof(*new->support.cpubind));
new->support.membind = malloc(sizeof(*new->support.membind));
new->support.misc = malloc(sizeof(*new->support.misc));
if (!new->support.discovery || !new->support.cpubind || !new->support.membind || !new->support.misc)
goto out_with_support;
memcpy(new->support.discovery, old->support.discovery, sizeof(*new->support.discovery));
memcpy(new->support.cpubind, old->support.cpubind, sizeof(*new->support.cpubind));
memcpy(new->support.membind, old->support.membind, sizeof(*new->support.membind));
memcpy(new->support.misc, old->support.misc, sizeof(*new->support.misc));
hwloc_set_binding_hooks(new);
/* clear userdata callbacks pointing to the writer process' functions */
new->userdata_export_cb = NULL;
new->userdata_import_cb = NULL;
#ifndef HWLOC_DEBUG
if (getenv("HWLOC_DEBUG_CHECK"))
#endif
hwloc_topology_check(new);
*topologyp = new;
return 0;
out_with_support:
free(new->support.discovery);
free(new->support.cpubind);
free(new->support.membind);
free(new->support.misc);
free(new);
out_with_components:
hwloc_components_fini();
out_with_mmap:
munmap(mmap_res, length);
return -1;
}
void
hwloc__topology_disadopt(hwloc_topology_t topology)
{
hwloc_components_fini();
munmap(topology->adopted_shmem_addr, topology->adopted_shmem_length);
free(topology->support.discovery);
free(topology->support.cpubind);
free(topology->support.membind);
free(topology->support.misc);
free(topology);
}
#else /* HWLOC_WIN_SYS */
int
hwloc_shmem_topology_get_length(hwloc_topology_t topology __hwloc_attribute_unused,
size_t *lengthp __hwloc_attribute_unused,
unsigned long flags __hwloc_attribute_unused)
{
errno = ENOSYS;
return -1;
}
int
hwloc_shmem_topology_write(hwloc_topology_t topology __hwloc_attribute_unused,
int fd __hwloc_attribute_unused, hwloc_uint64_t fileoffset __hwloc_attribute_unused,
void *mmap_address __hwloc_attribute_unused, size_t length __hwloc_attribute_unused,
unsigned long flags __hwloc_attribute_unused)
{
errno = ENOSYS;
return -1;
}
int
hwloc_shmem_topology_adopt(hwloc_topology_t *topologyp __hwloc_attribute_unused,
int fd __hwloc_attribute_unused, hwloc_uint64_t fileoffset __hwloc_attribute_unused,
void *mmap_address __hwloc_attribute_unused, size_t length __hwloc_attribute_unused,
unsigned long flags __hwloc_attribute_unused)
{
errno = ENOSYS;
return -1;
}
void
hwloc__topology_disadopt(hwloc_topology_t topology __hwloc_attribute_unused)
{
}
#endif /* HWLOC_WIN_SYS */

View file

@ -1,15 +0,0 @@
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_noos_component;
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_xml_component;
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_synthetic_component;
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_xml_nolibxml_component;
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_windows_component;
HWLOC_DECLSPEC extern const struct hwloc_component hwloc_x86_component;
static const struct hwloc_component * hwloc_static_components[] = {
&hwloc_noos_component,
&hwloc_xml_component,
&hwloc_synthetic_component,
&hwloc_xml_nolibxml_component,
&hwloc_windows_component,
&hwloc_x86_component,
NULL
};

View file

@ -1,80 +0,0 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2019 Inria. All rights reserved.
* Copyright © 2009-2012, 2020 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
#include "private/autogen/config.h"
#include "hwloc.h"
#include "private/private.h"
static int
hwloc_look_noos(struct hwloc_backend *backend, struct hwloc_disc_status *dstatus)
{
/*
* This backend uses the underlying OS.
* However we don't enforce topology->is_thissystem so that
* we may still force use this backend when debugging with !thissystem.
*/
struct hwloc_topology *topology = backend->topology;
int64_t memsize;
assert(dstatus->phase == HWLOC_DISC_PHASE_CPU);
if (!topology->levels[0][0]->cpuset) {
int nbprocs;
/* Nobody (even the x86 backend) created objects yet, setup basic objects */
nbprocs = hwloc_fallback_nbprocessors(0);
if (nbprocs >= 1)
topology->support.discovery->pu = 1;
else
nbprocs = 1;
hwloc_alloc_root_sets(topology->levels[0][0]);
hwloc_setup_pu_level(topology, nbprocs);
}
memsize = hwloc_fallback_memsize();
if (memsize > 0)
topology->machine_memory.local_memory = memsize;;
hwloc_add_uname_info(topology, NULL);
return 0;
}
static struct hwloc_backend *
hwloc_noos_component_instantiate(struct hwloc_topology *topology,
struct hwloc_disc_component *component,
unsigned excluded_phases __hwloc_attribute_unused,
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
struct hwloc_backend *backend;
backend = hwloc_backend_alloc(topology, component);
if (!backend)
return NULL;
backend->discover = hwloc_look_noos;
return backend;
}
static struct hwloc_disc_component hwloc_noos_disc_component = {
"no_os",
HWLOC_DISC_PHASE_CPU,
HWLOC_DISC_PHASE_GLOBAL,
hwloc_noos_component_instantiate,
40, /* lower than native OS component, higher than globals */
1,
NULL
};
const struct hwloc_component hwloc_noos_component = {
HWLOC_COMPONENT_ABI,
NULL, NULL,
HWLOC_COMPONENT_TYPE_DISC,
0,
&hwloc_noos_disc_component
};

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,907 +0,0 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2020 Inria. All rights reserved.
* Copyright © 2009-2011 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
#include "private/autogen/config.h"
#include "hwloc.h"
#include "hwloc/plugins.h"
#include "private/private.h"
#include "private/misc.h"
#include "private/xml.h"
#include "private/debug.h"
#include <string.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
/*******************
* Import routines *
*******************/
struct hwloc__nolibxml_backend_data_s {
size_t buflen; /* size of both buffer, set during backend_init() */
char *buffer; /* allocated and filled during backend_init() */
};
typedef struct hwloc__nolibxml_import_state_data_s {
char *tagbuffer; /* buffer containing the next tag */
char *attrbuffer; /* buffer containing the next attribute of the current node */
const char *tagname; /* tag name of the current node */
int closed; /* set if the current node is auto-closing */
} __hwloc_attribute_may_alias * hwloc__nolibxml_import_state_data_t;
static char *
hwloc__nolibxml_import_ignore_spaces(char *buffer)
{
return buffer + strspn(buffer, " \t\n");
}
static int
hwloc__nolibxml_import_next_attr(hwloc__xml_import_state_t state, char **namep, char **valuep)
{
hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
size_t namelen;
size_t len, escaped;
char *buffer, *value, *end;
if (!nstate->attrbuffer)
return -1;
/* find the beginning of an attribute */
buffer = hwloc__nolibxml_import_ignore_spaces(nstate->attrbuffer);
namelen = strspn(buffer, "abcdefghijklmnopqrstuvwxyz_");
if (buffer[namelen] != '=' || buffer[namelen+1] != '\"')
return -1;
buffer[namelen] = '\0';
*namep = buffer;
/* find the beginning of its value, and unescape it */
*valuep = value = buffer+namelen+2;
len = 0; escaped = 0;
while (value[len+escaped] != '\"') {
if (value[len+escaped] == '&') {
if (!strncmp(&value[1+len+escaped], "#10;", 4)) {
escaped += 4;
value[len] = '\n';
} else if (!strncmp(&value[1+len+escaped], "#13;", 4)) {
escaped += 4;
value[len] = '\r';
} else if (!strncmp(&value[1+len+escaped], "#9;", 3)) {
escaped += 3;
value[len] = '\t';
} else if (!strncmp(&value[1+len+escaped], "quot;", 5)) {
escaped += 5;
value[len] = '\"';
} else if (!strncmp(&value[1+len+escaped], "lt;", 3)) {
escaped += 3;
value[len] = '<';
} else if (!strncmp(&value[1+len+escaped], "gt;", 3)) {
escaped += 3;
value[len] = '>';
} else if (!strncmp(&value[1+len+escaped], "amp;", 4)) {
escaped += 4;
value[len] = '&';
} else {
return -1;
}
} else {
value[len] = value[len+escaped];
}
len++;
if (value[len+escaped] == '\0')
return -1;
}
value[len] = '\0';
/* find next attribute */
end = &value[len+escaped+1]; /* skip the ending " */
nstate->attrbuffer = hwloc__nolibxml_import_ignore_spaces(end);
return 0;
}
static int
hwloc__nolibxml_import_find_child(hwloc__xml_import_state_t state,
hwloc__xml_import_state_t childstate,
char **tagp)
{
hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
hwloc__nolibxml_import_state_data_t nchildstate = (void*) childstate->data;
char *buffer = nstate->tagbuffer;
char *end;
char *tag;
size_t namelen;
childstate->parent = state;
childstate->global = state->global;
/* auto-closed tags have no children */
if (nstate->closed)
return 0;
/* find the beginning of the tag */
buffer = hwloc__nolibxml_import_ignore_spaces(buffer);
if (buffer[0] != '<')
return -1;
buffer++;
/* if closing tag, return nothing and do not advance */
if (buffer[0] == '/')
return 0;
/* normal tag */
nchildstate->tagname = tag = buffer;
/* find the end, mark it and return it */
end = strchr(buffer, '>');
if (!end)
return -1;
end[0] = '\0';
nchildstate->tagbuffer = end+1;
/* handle auto-closing tags */
if (end[-1] == '/') {
nchildstate->closed = 1;
end[-1] = '\0';
} else
nchildstate->closed = 0;
/* find attributes */
namelen = strspn(buffer, "abcdefghijklmnopqrstuvwxyz1234567890_");
if (buffer[namelen] == '\0') {
/* no attributes */
nchildstate->attrbuffer = NULL;
*tagp = tag;
return 1;
}
if (buffer[namelen] != ' ')
return -1;
/* found a space, likely starting attributes */
buffer[namelen] = '\0';
nchildstate->attrbuffer = buffer+namelen+1;
*tagp = tag;
return 1;
}
static int
hwloc__nolibxml_import_close_tag(hwloc__xml_import_state_t state)
{
hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
char *buffer = nstate->tagbuffer;
char *end;
/* auto-closed tags need nothing */
if (nstate->closed)
return 0;
/* find the beginning of the tag */
buffer = hwloc__nolibxml_import_ignore_spaces(buffer);
if (buffer[0] != '<')
return -1;
buffer++;
/* find the end, mark it and return it to the parent */
end = strchr(buffer, '>');
if (!end)
return -1;
end[0] = '\0';
nstate->tagbuffer = end+1;
/* if closing tag, return nothing */
if (buffer[0] != '/' || strcmp(buffer+1, nstate->tagname) )
return -1;
return 0;
}
static void
hwloc__nolibxml_import_close_child(hwloc__xml_import_state_t state)
{
hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
hwloc__nolibxml_import_state_data_t nparent = (void*) state->parent->data;
nparent->tagbuffer = nstate->tagbuffer;
}
static int
hwloc__nolibxml_import_get_content(hwloc__xml_import_state_t state,
const char **beginp, size_t expected_length)
{
hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
char *buffer = nstate->tagbuffer;
size_t length;
char *end;
/* auto-closed tags have no content */
if (nstate->closed) {
if (expected_length)
return -1;
*beginp = "";
return 0;
}
/* find the next tag, where the content ends */
end = strchr(buffer, '<');
if (!end)
return -1;
length = (size_t) (end-buffer);
if (length != expected_length)
return -1;
nstate->tagbuffer = end;
*end = '\0'; /* mark as 0-terminated for now */
*beginp = buffer;
return 1;
}
static void
hwloc__nolibxml_import_close_content(hwloc__xml_import_state_t state)
{
/* put back the '<' that we overwrote to 0-terminate the content */
hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
if (!nstate->closed)
*nstate->tagbuffer = '<';
}
static int
hwloc_nolibxml_look_init(struct hwloc_xml_backend_data_s *bdata,
struct hwloc__xml_import_state_s *state)
{
hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
struct hwloc__nolibxml_backend_data_s *nbdata = bdata->data;
unsigned major, minor;
char *end;
char *buffer = nbdata->buffer;
const char *tagname;
HWLOC_BUILD_ASSERT(sizeof(*nstate) <= sizeof(state->data));
/* skip headers */
while (!strncmp(buffer, "<?xml ", 6) || !strncmp(buffer, "<!DOCTYPE ", 10)) {
buffer = strchr(buffer, '\n');
if (!buffer)
goto failed;
buffer++;
}
/* find topology tag */
if (sscanf(buffer, "<topology version=\"%u.%u\">", &major, &minor) == 2) {
bdata->version_major = major;
bdata->version_minor = minor;
end = strchr(buffer, '>') + 1;
tagname = "topology";
} else if (!strncmp(buffer, "<topology>", 10)) {
bdata->version_major = 1;
bdata->version_minor = 0;
end = buffer + 10;
tagname = "topology";
} else if (!strncmp(buffer, "<root>", 6)) {
bdata->version_major = 0;
bdata->version_minor = 9;
end = buffer + 6;
tagname = "root";
} else
goto failed;
state->global->next_attr = hwloc__nolibxml_import_next_attr;
state->global->find_child = hwloc__nolibxml_import_find_child;
state->global->close_tag = hwloc__nolibxml_import_close_tag;
state->global->close_child = hwloc__nolibxml_import_close_child;
state->global->get_content = hwloc__nolibxml_import_get_content;
state->global->close_content = hwloc__nolibxml_import_close_content;
state->parent = NULL;
nstate->closed = 0;
nstate->tagbuffer = end;
nstate->tagname = tagname;
nstate->attrbuffer = NULL;
return 0; /* success */
failed:
return -1; /* failed */
}
/* can be called at the end of the import (to cleanup things early),
* or by backend_exit() if load failed for other reasons.
*/
static void
hwloc_nolibxml_free_buffers(struct hwloc_xml_backend_data_s *bdata)
{
struct hwloc__nolibxml_backend_data_s *nbdata = bdata->data;
if (nbdata->buffer) {
free(nbdata->buffer);
nbdata->buffer = NULL;
}
}
static void
hwloc_nolibxml_look_done(struct hwloc_xml_backend_data_s *bdata, int result)
{
hwloc_nolibxml_free_buffers(bdata);
if (result < 0 && hwloc__xml_verbose())
fprintf(stderr, "Failed to parse XML input with the minimalistic parser. If it was not\n"
"generated by hwloc, try enabling full XML support with libxml2.\n");
}
/********************
* Backend routines *
********************/
static void
hwloc_nolibxml_backend_exit(struct hwloc_xml_backend_data_s *bdata)
{
struct hwloc__nolibxml_backend_data_s *nbdata = bdata->data;
hwloc_nolibxml_free_buffers(bdata);
free(nbdata);
}
static int
hwloc_nolibxml_read_file(const char *xmlpath, char **bufferp, size_t *buflenp)
{
FILE * file;
size_t buflen, offset, readlen;
struct stat statbuf;
char *buffer, *tmp;
size_t ret;
if (!strcmp(xmlpath, "-"))
xmlpath = "/dev/stdin";
file = fopen(xmlpath, "r");
if (!file)
goto out;
/* find the required buffer size for regular files, or use 4k when unknown, we'll realloc later if needed */
buflen = 4096;
if (!stat(xmlpath, &statbuf))
if (S_ISREG(statbuf.st_mode))
buflen = statbuf.st_size+1; /* one additional byte so that the first fread() gets EOF too */
buffer = malloc(buflen+1); /* one more byte for the ending \0 */
if (!buffer)
goto out_with_file;
offset = 0; readlen = buflen;
while (1) {
ret = fread(buffer+offset, 1, readlen, file);
offset += ret;
buffer[offset] = 0;
if (ret != readlen)
break;
buflen *= 2;
tmp = realloc(buffer, buflen+1);
if (!tmp)
goto out_with_buffer;
buffer = tmp;
readlen = buflen/2;
}
fclose(file);
*bufferp = buffer;
*buflenp = offset+1;
return 0;
out_with_buffer:
free(buffer);
out_with_file:
fclose(file);
out:
return -1;
}
static int
hwloc_nolibxml_backend_init(struct hwloc_xml_backend_data_s *bdata,
const char *xmlpath, const char *xmlbuffer, int xmlbuflen)
{
struct hwloc__nolibxml_backend_data_s *nbdata = malloc(sizeof(*nbdata));
if (!nbdata)
goto out;
bdata->data = nbdata;
if (xmlbuffer) {
nbdata->buffer = malloc(xmlbuflen+1);
if (!nbdata->buffer)
goto out_with_nbdata;
nbdata->buflen = xmlbuflen+1;
memcpy(nbdata->buffer, xmlbuffer, xmlbuflen);
nbdata->buffer[xmlbuflen] = '\0';
} else {
int err = hwloc_nolibxml_read_file(xmlpath, &nbdata->buffer, &nbdata->buflen);
if (err < 0)
goto out_with_nbdata;
}
bdata->look_init = hwloc_nolibxml_look_init;
bdata->look_done = hwloc_nolibxml_look_done;
bdata->backend_exit = hwloc_nolibxml_backend_exit;
return 0;
out_with_nbdata:
free(nbdata);
out:
return -1;
}
static int
hwloc_nolibxml_import_diff(struct hwloc__xml_import_state_s *state,
const char *xmlpath, const char *xmlbuffer, int xmlbuflen,
hwloc_topology_diff_t *firstdiffp, char **refnamep)
{
hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
struct hwloc__xml_import_state_s childstate;
char *refname = NULL;
char *buffer, *tmp, *tag;
size_t buflen;
int ret;
HWLOC_BUILD_ASSERT(sizeof(*nstate) <= sizeof(state->data));
if (xmlbuffer) {
buffer = malloc(xmlbuflen);
if (!buffer)
goto out;
memcpy(buffer, xmlbuffer, xmlbuflen);
buflen = xmlbuflen;
} else {
ret = hwloc_nolibxml_read_file(xmlpath, &buffer, &buflen);
if (ret < 0)
goto out;
}
/* skip headers */
tmp = buffer;
while (!strncmp(tmp, "<?xml ", 6) || !strncmp(tmp, "<!DOCTYPE ", 10)) {
tmp = strchr(tmp, '\n');
if (!tmp)
goto out_with_buffer;
tmp++;
}
state->global->next_attr = hwloc__nolibxml_import_next_attr;
state->global->find_child = hwloc__nolibxml_import_find_child;
state->global->close_tag = hwloc__nolibxml_import_close_tag;
state->global->close_child = hwloc__nolibxml_import_close_child;
state->global->get_content = hwloc__nolibxml_import_get_content;
state->global->close_content = hwloc__nolibxml_import_close_content;
state->parent = NULL;
nstate->closed = 0;
nstate->tagbuffer = tmp;
nstate->tagname = NULL;
nstate->attrbuffer = NULL;
/* find root */
ret = hwloc__nolibxml_import_find_child(state, &childstate, &tag);
if (ret < 0)
goto out_with_buffer;
if (!tag || strcmp(tag, "topologydiff"))
goto out_with_buffer;
while (1) {
char *attrname, *attrvalue;
if (hwloc__nolibxml_import_next_attr(&childstate, &attrname, &attrvalue) < 0)
break;
if (!strcmp(attrname, "refname")) {
free(refname);
refname = strdup(attrvalue);
} else
goto out_with_buffer;
}
ret = hwloc__xml_import_diff(&childstate, firstdiffp);
if (refnamep && !ret)
*refnamep = refname;
else
free(refname);
free(buffer);
return ret;
out_with_buffer:
free(buffer);
free(refname);
out:
return -1;
}
/*******************
* Export routines *
*******************/
typedef struct hwloc__nolibxml_export_state_data_s {
char *buffer; /* (moving) buffer where to write */
size_t written; /* how many bytes were written (or would have be written if not truncated) */
size_t remaining; /* how many bytes are still available in the buffer */
unsigned indent; /* indentation level for the next line */
unsigned nr_children;
unsigned has_content;
} __hwloc_attribute_may_alias * hwloc__nolibxml_export_state_data_t;
static void
hwloc__nolibxml_export_update_buffer(hwloc__nolibxml_export_state_data_t ndata, int res)
{
if (res >= 0) {
ndata->written += res;
if (res >= (int) ndata->remaining)
res = ndata->remaining>0 ? (int)ndata->remaining-1 : 0;
ndata->buffer += res;
ndata->remaining -= res;
}
}
static char *
hwloc__nolibxml_export_escape_string(const char *src)
{
size_t fulllen, sublen;
char *escaped, *dst;
fulllen = strlen(src);
sublen = strcspn(src, "\n\r\t\"<>&");
if (sublen == fulllen)
return NULL; /* nothing to escape */
escaped = malloc(fulllen*6+1); /* escaped chars are replaced by at most 6 char */
dst = escaped;
memcpy(dst, src, sublen);
src += sublen;
dst += sublen;
while (*src) {
int replen;
switch (*src) {
case '\n': strcpy(dst, "&#10;"); replen=5; break;
case '\r': strcpy(dst, "&#13;"); replen=5; break;
case '\t': strcpy(dst, "&#9;"); replen=4; break;
case '\"': strcpy(dst, "&quot;"); replen=6; break;
case '<': strcpy(dst, "&lt;"); replen=4; break;
case '>': strcpy(dst, "&gt;"); replen=4; break;
case '&': strcpy(dst, "&amp;"); replen=5; break;
default: replen=0; break;
}
dst+=replen; src++;
sublen = strcspn(src, "\n\r\t\"<>&");
memcpy(dst, src, sublen);
src += sublen;
dst += sublen;
}
*dst = 0;
return escaped;
}
static void
hwloc__nolibxml_export_new_child(hwloc__xml_export_state_t parentstate,
hwloc__xml_export_state_t state,
const char *name)
{
hwloc__nolibxml_export_state_data_t npdata = (void *) parentstate->data;
hwloc__nolibxml_export_state_data_t ndata = (void *) state->data;
int res;
assert(!npdata->has_content);
if (!npdata->nr_children) {
res = hwloc_snprintf(npdata->buffer, npdata->remaining, ">\n");
hwloc__nolibxml_export_update_buffer(npdata, res);
}
npdata->nr_children++;
state->parent = parentstate;
state->new_child = parentstate->new_child;
state->new_prop = parentstate->new_prop;
state->add_content = parentstate->add_content;
state->end_object = parentstate->end_object;
state->global = parentstate->global;
ndata->buffer = npdata->buffer;
ndata->written = npdata->written;
ndata->remaining = npdata->remaining;
ndata->indent = npdata->indent + 2;
ndata->nr_children = 0;
ndata->has_content = 0;
res = hwloc_snprintf(ndata->buffer, ndata->remaining, "%*s<%s", (int) npdata->indent, "", name);
hwloc__nolibxml_export_update_buffer(ndata, res);
}
static void
hwloc__nolibxml_export_new_prop(hwloc__xml_export_state_t state, const char *name, const char *value)
{
hwloc__nolibxml_export_state_data_t ndata = (void *) state->data;
char *escaped = hwloc__nolibxml_export_escape_string(value);
int res = hwloc_snprintf(ndata->buffer, ndata->remaining, " %s=\"%s\"", name, escaped ? (const char *) escaped : value);
hwloc__nolibxml_export_update_buffer(ndata, res);
free(escaped);
}
static void
hwloc__nolibxml_export_end_object(hwloc__xml_export_state_t state, const char *name)
{
hwloc__nolibxml_export_state_data_t ndata = (void *) state->data;
hwloc__nolibxml_export_state_data_t npdata = (void *) state->parent->data;
int res;
assert (!(ndata->has_content && ndata->nr_children));
if (ndata->has_content) {
res = hwloc_snprintf(ndata->buffer, ndata->remaining, "</%s>\n", name);
} else if (ndata->nr_children) {
res = hwloc_snprintf(ndata->buffer, ndata->remaining, "%*s</%s>\n", (int) npdata->indent, "", name);
} else {
res = hwloc_snprintf(ndata->buffer, ndata->remaining, "/>\n");
}
hwloc__nolibxml_export_update_buffer(ndata, res);
npdata->buffer = ndata->buffer;
npdata->written = ndata->written;
npdata->remaining = ndata->remaining;
}
static void
hwloc__nolibxml_export_add_content(hwloc__xml_export_state_t state, const char *buffer, size_t length __hwloc_attribute_unused)
{
hwloc__nolibxml_export_state_data_t ndata = (void *) state->data;
int res;
assert(!ndata->nr_children);
if (!ndata->has_content) {
res = hwloc_snprintf(ndata->buffer, ndata->remaining, ">");
hwloc__nolibxml_export_update_buffer(ndata, res);
}
ndata->has_content = 1;
res = hwloc_snprintf(ndata->buffer, ndata->remaining, "%s", buffer);
hwloc__nolibxml_export_update_buffer(ndata, res);
}
static size_t
hwloc___nolibxml_prepare_export(hwloc_topology_t topology, struct hwloc__xml_export_data_s *edata,
char *xmlbuffer, int buflen, unsigned long flags)
{
struct hwloc__xml_export_state_s state, childstate;
hwloc__nolibxml_export_state_data_t ndata = (void *) &state.data;
int v1export = flags & HWLOC_TOPOLOGY_EXPORT_XML_FLAG_V1;
int res;
HWLOC_BUILD_ASSERT(sizeof(*ndata) <= sizeof(state.data));
state.new_child = hwloc__nolibxml_export_new_child;
state.new_prop = hwloc__nolibxml_export_new_prop;
state.add_content = hwloc__nolibxml_export_add_content;
state.end_object = hwloc__nolibxml_export_end_object;
state.global = edata;
ndata->indent = 0;
ndata->written = 0;
ndata->buffer = xmlbuffer;
ndata->remaining = buflen;
ndata->nr_children = 1; /* don't close a non-existing previous tag when opening the topology tag */
ndata->has_content = 0;
res = hwloc_snprintf(ndata->buffer, ndata->remaining,
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<!DOCTYPE topology SYSTEM \"%s\">\n", v1export ? "hwloc.dtd" : "hwloc2.dtd");
hwloc__nolibxml_export_update_buffer(ndata, res);
hwloc__nolibxml_export_new_child(&state, &childstate, "topology");
if (!(flags & HWLOC_TOPOLOGY_EXPORT_XML_FLAG_V1))
hwloc__nolibxml_export_new_prop(&childstate, "version", "2.0");
hwloc__xml_export_topology (&childstate, topology, flags);
hwloc__nolibxml_export_end_object(&childstate, "topology");
return ndata->written+1; /* ending \0 */
}
static int
hwloc_nolibxml_export_buffer(hwloc_topology_t topology, struct hwloc__xml_export_data_s *edata,
char **bufferp, int *buflenp, unsigned long flags)
{
char *buffer;
size_t bufferlen, res;
bufferlen = 16384; /* random guess for large enough default */
buffer = malloc(bufferlen);
if (!buffer)
return -1;
res = hwloc___nolibxml_prepare_export(topology, edata, buffer, (int)bufferlen, flags);
if (res > bufferlen) {
char *tmp = realloc(buffer, res);
if (!tmp) {
free(buffer);
return -1;
}
buffer = tmp;
hwloc___nolibxml_prepare_export(topology, edata, buffer, (int)res, flags);
}
*bufferp = buffer;
*buflenp = (int)res;
return 0;
}
static int
hwloc_nolibxml_export_file(hwloc_topology_t topology, struct hwloc__xml_export_data_s *edata,
const char *filename, unsigned long flags)
{
FILE *file;
char *buffer;
int bufferlen;
int ret;
ret = hwloc_nolibxml_export_buffer(topology, edata, &buffer, &bufferlen, flags);
if (ret < 0)
return -1;
if (!strcmp(filename, "-")) {
file = stdout;
} else {
file = fopen(filename, "w");
if (!file) {
free(buffer);
return -1;
}
}
ret = (int)fwrite(buffer, 1, bufferlen-1 /* don't write the ending \0 */, file);
if (ret == bufferlen-1) {
ret = 0;
} else {
errno = ferror(file);
ret = -1;
}
free(buffer);
if (file != stdout)
fclose(file);
return ret;
}
static size_t
hwloc___nolibxml_prepare_export_diff(hwloc_topology_diff_t diff, const char *refname, char *xmlbuffer, int buflen)
{
struct hwloc__xml_export_state_s state, childstate;
hwloc__nolibxml_export_state_data_t ndata = (void *) &state.data;
int res;
HWLOC_BUILD_ASSERT(sizeof(*ndata) <= sizeof(state.data));
state.new_child = hwloc__nolibxml_export_new_child;
state.new_prop = hwloc__nolibxml_export_new_prop;
state.add_content = hwloc__nolibxml_export_add_content;
state.end_object = hwloc__nolibxml_export_end_object;
state.global = NULL;
ndata->indent = 0;
ndata->written = 0;
ndata->buffer = xmlbuffer;
ndata->remaining = buflen;
ndata->nr_children = 1; /* don't close a non-existing previous tag when opening the topology tag */
ndata->has_content = 0;
res = hwloc_snprintf(ndata->buffer, ndata->remaining,
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<!DOCTYPE topologydiff SYSTEM \"hwloc2-diff.dtd\">\n");
hwloc__nolibxml_export_update_buffer(ndata, res);
hwloc__nolibxml_export_new_child(&state, &childstate, "topologydiff");
if (refname)
hwloc__nolibxml_export_new_prop(&childstate, "refname", refname);
hwloc__xml_export_diff (&childstate, diff);
hwloc__nolibxml_export_end_object(&childstate, "topologydiff");
return ndata->written+1;
}
static int
hwloc_nolibxml_export_diff_buffer(hwloc_topology_diff_t diff, const char *refname, char **bufferp, int *buflenp)
{
char *buffer;
size_t bufferlen, res;
bufferlen = 16384; /* random guess for large enough default */
buffer = malloc(bufferlen);
if (!buffer)
return -1;
res = hwloc___nolibxml_prepare_export_diff(diff, refname, buffer, (int)bufferlen);
if (res > bufferlen) {
char *tmp = realloc(buffer, res);
if (!tmp) {
free(buffer);
return -1;
}
buffer = tmp;
hwloc___nolibxml_prepare_export_diff(diff, refname, buffer, (int)res);
}
*bufferp = buffer;
*buflenp = (int)res;
return 0;
}
static int
hwloc_nolibxml_export_diff_file(hwloc_topology_diff_t diff, const char *refname, const char *filename)
{
FILE *file;
char *buffer;
int bufferlen;
int ret;
ret = hwloc_nolibxml_export_diff_buffer(diff, refname, &buffer, &bufferlen);
if (ret < 0)
return -1;
if (!strcmp(filename, "-")) {
file = stdout;
} else {
file = fopen(filename, "w");
if (!file) {
free(buffer);
return -1;
}
}
ret = (int)fwrite(buffer, 1, bufferlen-1 /* don't write the ending \0 */, file);
if (ret == bufferlen-1) {
ret = 0;
} else {
errno = ferror(file);
ret = -1;
}
free(buffer);
if (file != stdout)
fclose(file);
return ret;
}
static void
hwloc_nolibxml_free_buffer(void *xmlbuffer)
{
free(xmlbuffer);
}
/*************
* Callbacks *
*************/
static struct hwloc_xml_callbacks hwloc_xml_nolibxml_callbacks = {
hwloc_nolibxml_backend_init,
hwloc_nolibxml_export_file,
hwloc_nolibxml_export_buffer,
hwloc_nolibxml_free_buffer,
hwloc_nolibxml_import_diff,
hwloc_nolibxml_export_diff_file,
hwloc_nolibxml_export_diff_buffer
};
static struct hwloc_xml_component hwloc_nolibxml_xml_component = {
&hwloc_xml_nolibxml_callbacks,
NULL
};
const struct hwloc_component hwloc_xml_nolibxml_component = {
HWLOC_COMPONENT_ABI,
NULL, NULL,
HWLOC_COMPONENT_TYPE_XML,
0,
&hwloc_nolibxml_xml_component
};

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,837 +0,0 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2021 Inria. All rights reserved.
* Copyright © 2009-2010, 2020 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
*/
#include "private/autogen/config.h"
#include "hwloc.h"
#include "private/private.h"
#include "private/misc.h"
#include "private/debug.h"
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif /* HAVE_STRINGS_H */
int
hwloc_get_type_depth (struct hwloc_topology *topology, hwloc_obj_type_t type)
{
HWLOC_BUILD_ASSERT(HWLOC_OBJ_TYPE_MIN == 0);
if ((unsigned) type >= HWLOC_OBJ_TYPE_MAX)
return HWLOC_TYPE_DEPTH_UNKNOWN;
else
return topology->type_depth[type];
}
hwloc_obj_type_t
hwloc_get_depth_type (hwloc_topology_t topology, int depth)
{
if ((unsigned)depth >= topology->nb_levels)
switch (depth) {
case HWLOC_TYPE_DEPTH_NUMANODE:
return HWLOC_OBJ_NUMANODE;
case HWLOC_TYPE_DEPTH_BRIDGE:
return HWLOC_OBJ_BRIDGE;
case HWLOC_TYPE_DEPTH_PCI_DEVICE:
return HWLOC_OBJ_PCI_DEVICE;
case HWLOC_TYPE_DEPTH_OS_DEVICE:
return HWLOC_OBJ_OS_DEVICE;
case HWLOC_TYPE_DEPTH_MISC:
return HWLOC_OBJ_MISC;
case HWLOC_TYPE_DEPTH_MEMCACHE:
return HWLOC_OBJ_MEMCACHE;
default:
return HWLOC_OBJ_TYPE_NONE;
}
return topology->levels[depth][0]->type;
}
int
hwloc_get_memory_parents_depth (hwloc_topology_t topology)
{
int depth = HWLOC_TYPE_DEPTH_UNKNOWN;
/* memory leaves are always NUMA nodes for now, no need to check parents of other memory types */
hwloc_obj_t numa = hwloc_get_obj_by_depth(topology, HWLOC_TYPE_DEPTH_NUMANODE, 0);
assert(numa);
while (numa) {
hwloc_obj_t parent = numa->parent;
/* walk-up the memory hierarchy */
while (hwloc__obj_type_is_memory(parent->type))
parent = parent->parent;
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
depth = parent->depth;
else if (depth != parent->depth)
return HWLOC_TYPE_DEPTH_MULTIPLE;
numa = numa->next_cousin;
}
assert(depth >= 0);
return depth;
}
unsigned
hwloc_get_nbobjs_by_depth (struct hwloc_topology *topology, int depth)
{
if ((unsigned)depth >= topology->nb_levels) {
unsigned l = HWLOC_SLEVEL_FROM_DEPTH(depth);
if (l < HWLOC_NR_SLEVELS)
return topology->slevels[l].nbobjs;
else
return 0;
}
return topology->level_nbobjects[depth];
}
struct hwloc_obj *
hwloc_get_obj_by_depth (struct hwloc_topology *topology, int depth, unsigned idx)
{
if ((unsigned)depth >= topology->nb_levels) {
unsigned l = HWLOC_SLEVEL_FROM_DEPTH(depth);
if (l < HWLOC_NR_SLEVELS)
return idx < topology->slevels[l].nbobjs ? topology->slevels[l].objs[idx] : NULL;
else
return NULL;
}
if (idx >= topology->level_nbobjects[depth])
return NULL;
return topology->levels[depth][idx];
}
int
hwloc_obj_type_is_normal(hwloc_obj_type_t type)
{
return hwloc__obj_type_is_normal(type);
}
int
hwloc_obj_type_is_memory(hwloc_obj_type_t type)
{
return hwloc__obj_type_is_memory(type);
}
int
hwloc_obj_type_is_io(hwloc_obj_type_t type)
{
return hwloc__obj_type_is_io(type);
}
int
hwloc_obj_type_is_cache(hwloc_obj_type_t type)
{
return hwloc__obj_type_is_cache(type);
}
int
hwloc_obj_type_is_dcache(hwloc_obj_type_t type)
{
return hwloc__obj_type_is_dcache(type);
}
int
hwloc_obj_type_is_icache(hwloc_obj_type_t type)
{
return hwloc__obj_type_is_icache(type);
}
static hwloc_obj_t hwloc_get_obj_by_depth_and_gp_index(hwloc_topology_t topology, unsigned depth, uint64_t gp_index)
{
hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, depth, 0);
while (obj) {
if (obj->gp_index == gp_index)
return obj;
obj = obj->next_cousin;
}
return NULL;
}
hwloc_obj_t hwloc_get_obj_by_type_and_gp_index(hwloc_topology_t topology, hwloc_obj_type_t type, uint64_t gp_index)
{
int depth = hwloc_get_type_depth(topology, type);
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
return NULL;
if (depth == HWLOC_TYPE_DEPTH_MULTIPLE) {
for(depth=1 /* no multiple machine levels */;
(unsigned) depth < topology->nb_levels-1 /* no multiple PU levels */;
depth++) {
if (hwloc_get_depth_type(topology, depth) == type) {
hwloc_obj_t obj = hwloc_get_obj_by_depth_and_gp_index(topology, depth, gp_index);
if (obj)
return obj;
}
}
return NULL;
}
return hwloc_get_obj_by_depth_and_gp_index(topology, depth, gp_index);
}
unsigned hwloc_get_closest_objs (struct hwloc_topology *topology, struct hwloc_obj *src, struct hwloc_obj **objs, unsigned max)
{
struct hwloc_obj *parent, *nextparent, **src_objs;
unsigned i,src_nbobjects;
unsigned stored = 0;
if (!src->cpuset)
return 0;
src_nbobjects = topology->level_nbobjects[src->depth];
src_objs = topology->levels[src->depth];
parent = src;
while (stored < max) {
while (1) {
nextparent = parent->parent;
if (!nextparent)
goto out;
if (!hwloc_bitmap_isequal(parent->cpuset, nextparent->cpuset))
break;
parent = nextparent;
}
/* traverse src's objects and find those that are in nextparent and were not in parent */
for(i=0; i<src_nbobjects; i++) {
if (hwloc_bitmap_isincluded(src_objs[i]->cpuset, nextparent->cpuset)
&& !hwloc_bitmap_isincluded(src_objs[i]->cpuset, parent->cpuset)) {
objs[stored++] = src_objs[i];
if (stored == max)
goto out;
}
}
parent = nextparent;
}
out:
return stored;
}
static int
hwloc__get_largest_objs_inside_cpuset (struct hwloc_obj *current, hwloc_const_bitmap_t set,
struct hwloc_obj ***res, int *max)
{
int gotten = 0;
unsigned i;
/* the caller must ensure this */
if (*max <= 0)
return 0;
if (hwloc_bitmap_isequal(current->cpuset, set)) {
**res = current;
(*res)++;
(*max)--;
return 1;
}
for (i=0; i<current->arity; i++) {
hwloc_bitmap_t subset;
int ret;
/* split out the cpuset part corresponding to this child and see if there's anything to do */
if (!hwloc_bitmap_intersects(set,current->children[i]->cpuset))
continue;
subset = hwloc_bitmap_dup(set);
hwloc_bitmap_and(subset, subset, current->children[i]->cpuset);
ret = hwloc__get_largest_objs_inside_cpuset (current->children[i], subset, res, max);
gotten += ret;
hwloc_bitmap_free(subset);
/* if no more room to store remaining objects, return what we got so far */
if (!*max)
break;
}
return gotten;
}
int
hwloc_get_largest_objs_inside_cpuset (struct hwloc_topology *topology, hwloc_const_bitmap_t set,
struct hwloc_obj **objs, int max)
{
struct hwloc_obj *current = topology->levels[0][0];
if (!hwloc_bitmap_isincluded(set, current->cpuset))
return -1;
if (max <= 0)
return 0;
return hwloc__get_largest_objs_inside_cpuset (current, set, &objs, &max);
}
const char *
hwloc_obj_type_string (hwloc_obj_type_t obj)
{
switch (obj)
{
case HWLOC_OBJ_MACHINE: return "Machine";
case HWLOC_OBJ_MISC: return "Misc";
case HWLOC_OBJ_GROUP: return "Group";
case HWLOC_OBJ_MEMCACHE: return "MemCache";
case HWLOC_OBJ_NUMANODE: return "NUMANode";
case HWLOC_OBJ_PACKAGE: return "Package";
case HWLOC_OBJ_DIE: return "Die";
case HWLOC_OBJ_L1CACHE: return "L1Cache";
case HWLOC_OBJ_L2CACHE: return "L2Cache";
case HWLOC_OBJ_L3CACHE: return "L3Cache";
case HWLOC_OBJ_L4CACHE: return "L4Cache";
case HWLOC_OBJ_L5CACHE: return "L5Cache";
case HWLOC_OBJ_L1ICACHE: return "L1iCache";
case HWLOC_OBJ_L2ICACHE: return "L2iCache";
case HWLOC_OBJ_L3ICACHE: return "L3iCache";
case HWLOC_OBJ_CORE: return "Core";
case HWLOC_OBJ_BRIDGE: return "Bridge";
case HWLOC_OBJ_PCI_DEVICE: return "PCIDev";
case HWLOC_OBJ_OS_DEVICE: return "OSDev";
case HWLOC_OBJ_PU: return "PU";
default: return "Unknown";
}
}
/* Check if string matches the given type at least on minmatch chars.
* On success, return the address of where matching stop, either pointing to \0 or to a suffix (digits, colon, etc)
* On error, return NULL;
*/
static __hwloc_inline const char *
hwloc__type_match(const char *string,
const char *type, /* type must be lowercase */
size_t minmatch)
{
const char *s, *t;
unsigned i;
for(i=0, s=string, t=type; ; i++, s++, t++) {
if (!*s) {
/* string ends before type */
if (i<minmatch)
return NULL;
else
return s;
}
if (*s != *t && *s != *t + 'A' - 'a') {
/* string is different */
if ((*s >= 'a' && *s <= 'z') || (*s >= 'A' && *s <= 'Z') || *s == '-')
/* valid character that doesn't match */
return NULL;
/* invalid character, we reached the end of the type namein string, stop matching here */
if (i<minmatch)
return NULL;
else
return s;
}
}
return NULL;
}
int
hwloc_type_sscanf(const char *string, hwloc_obj_type_t *typep,
union hwloc_obj_attr_u *attrp, size_t attrsize)
{
hwloc_obj_type_t type = (hwloc_obj_type_t) -1;
unsigned depthattr = (unsigned) -1;
hwloc_obj_cache_type_t cachetypeattr = (hwloc_obj_cache_type_t) -1; /* unspecified */
hwloc_obj_bridge_type_t ubtype = (hwloc_obj_bridge_type_t) -1;
hwloc_obj_osdev_type_t ostype = (hwloc_obj_osdev_type_t) -1;
char *end;
/* Never match the ending \0 since we want to match things like core:2 too.
* We'll only compare the beginning substring only made of letters and dash.
*/
/* types without a custom depth */
/* osdev subtype first to avoid conflicts coproc/core etc */
if (hwloc__type_match(string, "osdev", 2)) {
type = HWLOC_OBJ_OS_DEVICE;
} else if (hwloc__type_match(string, "block", 4)) {
type = HWLOC_OBJ_OS_DEVICE;
ostype = HWLOC_OBJ_OSDEV_BLOCK;
} else if (hwloc__type_match(string, "network", 3)) {
type = HWLOC_OBJ_OS_DEVICE;
ostype = HWLOC_OBJ_OSDEV_NETWORK;
} else if (hwloc__type_match(string, "openfabrics", 7)) {
type = HWLOC_OBJ_OS_DEVICE;
ostype = HWLOC_OBJ_OSDEV_OPENFABRICS;
} else if (hwloc__type_match(string, "dma", 3)) {
type = HWLOC_OBJ_OS_DEVICE;
ostype = HWLOC_OBJ_OSDEV_DMA;
} else if (hwloc__type_match(string, "gpu", 3)) {
type = HWLOC_OBJ_OS_DEVICE;
ostype = HWLOC_OBJ_OSDEV_GPU;
} else if (hwloc__type_match(string, "coproc", 5)
|| hwloc__type_match(string, "co-processor", 6)) {
type = HWLOC_OBJ_OS_DEVICE;
ostype = HWLOC_OBJ_OSDEV_COPROC;
} else if (hwloc__type_match(string, "machine", 2)) {
type = HWLOC_OBJ_MACHINE;
} else if (hwloc__type_match(string, "numanode", 2)
|| hwloc__type_match(string, "node", 2)) { /* for convenience */
type = HWLOC_OBJ_NUMANODE;
} else if (hwloc__type_match(string, "memcache", 5)
|| hwloc__type_match(string, "memory-side cache", 8)) {
type = HWLOC_OBJ_MEMCACHE;
} else if (hwloc__type_match(string, "package", 2)
|| hwloc__type_match(string, "socket", 2)) { /* backward compat with v1.10 */
type = HWLOC_OBJ_PACKAGE;
} else if (hwloc__type_match(string, "die", 2)) {
type = HWLOC_OBJ_DIE;
} else if (hwloc__type_match(string, "core", 2)) {
type = HWLOC_OBJ_CORE;
} else if (hwloc__type_match(string, "pu", 2)) {
type = HWLOC_OBJ_PU;
} else if (hwloc__type_match(string, "misc", 4)) {
type = HWLOC_OBJ_MISC;
} else if (hwloc__type_match(string, "bridge", 4)) {
type = HWLOC_OBJ_BRIDGE;
} else if (hwloc__type_match(string, "hostbridge", 6)) {
type = HWLOC_OBJ_BRIDGE;
ubtype = HWLOC_OBJ_BRIDGE_HOST;
} else if (hwloc__type_match(string, "pcibridge", 5)) {
type = HWLOC_OBJ_BRIDGE;
ubtype = HWLOC_OBJ_BRIDGE_PCI;
/* if downstream_type can ever be non-PCI, we'll have to make strings more precise,
* or relax the hwloc_type_sscanf test */
} else if (hwloc__type_match(string, "pcidev", 3)) {
type = HWLOC_OBJ_PCI_DEVICE;
/* types with depthattr */
} else if ((string[0] == 'l' || string[0] == 'L') && string[1] >= '0' && string[1] <= '9') {
char *suffix;
depthattr = strtol(string+1, &end, 10);
if (*end == 'i' || *end == 'I') {
if (depthattr >= 1 && depthattr <= 3) {
type = HWLOC_OBJ_L1ICACHE + depthattr-1;
cachetypeattr = HWLOC_OBJ_CACHE_INSTRUCTION;
suffix = end+1;
} else
return -1;
} else {
if (depthattr >= 1 && depthattr <= 5) {
type = HWLOC_OBJ_L1CACHE + depthattr-1;
if (*end == 'd' || *end == 'D') {
cachetypeattr = HWLOC_OBJ_CACHE_DATA;
suffix = end+1;
} else if (*end == 'u' || *end == 'U') {
cachetypeattr = HWLOC_OBJ_CACHE_UNIFIED;
suffix = end+1;
} else {
cachetypeattr = HWLOC_OBJ_CACHE_UNIFIED;
suffix = end;
}
} else
return -1;
}
/* check whether the optional suffix matches "cache" */
if (!hwloc__type_match(suffix, "cache", 0))
return -1;
} else if ((end = (char *) hwloc__type_match(string, "group", 2)) != NULL) {
type = HWLOC_OBJ_GROUP;
if (*end >= '0' && *end <= '9') {
depthattr = strtol(end, &end, 10);
}
} else
return -1;
*typep = type;
if (attrp) {
if (hwloc__obj_type_is_cache(type) && attrsize >= sizeof(attrp->cache)) {
attrp->cache.depth = depthattr;
attrp->cache.type = cachetypeattr;
} else if (type == HWLOC_OBJ_GROUP && attrsize >= sizeof(attrp->group)) {
attrp->group.depth = depthattr;
} else if (type == HWLOC_OBJ_BRIDGE && attrsize >= sizeof(attrp->bridge)) {
attrp->bridge.upstream_type = ubtype;
attrp->bridge.downstream_type = HWLOC_OBJ_BRIDGE_PCI;
/* if downstream_type can ever be non-PCI, we'll have to make strings more precise,
* or relax the hwloc_type_sscanf test */
} else if (type == HWLOC_OBJ_OS_DEVICE && attrsize >= sizeof(attrp->osdev)) {
attrp->osdev.type = ostype;
}
}
return 0;
}
int
hwloc_type_sscanf_as_depth(const char *string, hwloc_obj_type_t *typep,
hwloc_topology_t topology, int *depthp)
{
union hwloc_obj_attr_u attr;
hwloc_obj_type_t type;
int depth;
int err;
err = hwloc_type_sscanf(string, &type, &attr, sizeof(attr));
if (err < 0)
return err;
depth = hwloc_get_type_depth(topology, type);
if (type == HWLOC_OBJ_GROUP
&& depth == HWLOC_TYPE_DEPTH_MULTIPLE
&& attr.group.depth != (unsigned)-1) {
unsigned l;
depth = HWLOC_TYPE_DEPTH_UNKNOWN;
for(l=0; l<topology->nb_levels; l++) {
if (topology->levels[l][0]->type == HWLOC_OBJ_GROUP
&& topology->levels[l][0]->attr->group.depth == attr.group.depth) {
depth = (int)l;
break;
}
}
}
if (typep)
*typep = type;
*depthp = depth;
return 0;
}
static const char* hwloc_obj_cache_type_letter(hwloc_obj_cache_type_t type)
{
switch (type) {
case HWLOC_OBJ_CACHE_UNIFIED: return "";
case HWLOC_OBJ_CACHE_DATA: return "d";
case HWLOC_OBJ_CACHE_INSTRUCTION: return "i";
default: return "unknown";
}
}
int
hwloc_obj_type_snprintf(char * __hwloc_restrict string, size_t size, hwloc_obj_t obj, int verbose)
{
hwloc_obj_type_t type = obj->type;
switch (type) {
case HWLOC_OBJ_MISC:
case HWLOC_OBJ_MACHINE:
case HWLOC_OBJ_NUMANODE:
case HWLOC_OBJ_MEMCACHE:
case HWLOC_OBJ_PACKAGE:
case HWLOC_OBJ_DIE:
case HWLOC_OBJ_CORE:
case HWLOC_OBJ_PU:
return hwloc_snprintf(string, size, "%s", hwloc_obj_type_string(type));
case HWLOC_OBJ_L1CACHE:
case HWLOC_OBJ_L2CACHE:
case HWLOC_OBJ_L3CACHE:
case HWLOC_OBJ_L4CACHE:
case HWLOC_OBJ_L5CACHE:
case HWLOC_OBJ_L1ICACHE:
case HWLOC_OBJ_L2ICACHE:
case HWLOC_OBJ_L3ICACHE:
return hwloc_snprintf(string, size, "L%u%s%s", obj->attr->cache.depth,
hwloc_obj_cache_type_letter(obj->attr->cache.type),
verbose ? "Cache" : "");
case HWLOC_OBJ_GROUP:
if (obj->attr->group.depth != (unsigned) -1)
return hwloc_snprintf(string, size, "%s%u", hwloc_obj_type_string(type), obj->attr->group.depth);
else
return hwloc_snprintf(string, size, "%s", hwloc_obj_type_string(type));
case HWLOC_OBJ_BRIDGE:
/* if downstream_type can ever be non-PCI, we'll have to make strings more precise,
* or relax the hwloc_type_sscanf test */
assert(obj->attr->bridge.downstream_type == HWLOC_OBJ_BRIDGE_PCI);
return hwloc_snprintf(string, size, obj->attr->bridge.upstream_type == HWLOC_OBJ_BRIDGE_PCI ? "PCIBridge" : "HostBridge");
case HWLOC_OBJ_PCI_DEVICE:
return hwloc_snprintf(string, size, "PCI");
case HWLOC_OBJ_OS_DEVICE:
switch (obj->attr->osdev.type) {
case HWLOC_OBJ_OSDEV_BLOCK: return hwloc_snprintf(string, size, "Block");
case HWLOC_OBJ_OSDEV_NETWORK: return hwloc_snprintf(string, size, verbose ? "Network" : "Net");
case HWLOC_OBJ_OSDEV_OPENFABRICS: return hwloc_snprintf(string, size, "OpenFabrics");
case HWLOC_OBJ_OSDEV_DMA: return hwloc_snprintf(string, size, "DMA");
case HWLOC_OBJ_OSDEV_GPU: return hwloc_snprintf(string, size, "GPU");
case HWLOC_OBJ_OSDEV_COPROC: return hwloc_snprintf(string, size, verbose ? "Co-Processor" : "CoProc");
default:
if (size > 0)
*string = '\0';
return 0;
}
break;
default:
if (size > 0)
*string = '\0';
return 0;
}
}
int
hwloc_obj_attr_snprintf(char * __hwloc_restrict string, size_t size, hwloc_obj_t obj, const char * separator, int verbose)
{
const char *prefix = "";
char *tmp = string;
ssize_t tmplen = size;
int ret = 0;
int res;
/* make sure we output at least an empty string */
if (size)
*string = '\0';
/* print memory attributes */
res = 0;
if (verbose) {
if (obj->type == HWLOC_OBJ_NUMANODE && obj->attr->numanode.local_memory)
res = hwloc_snprintf(tmp, tmplen, "%slocal=%lu%s%stotal=%lu%s",
prefix,
(unsigned long) hwloc_memory_size_printf_value(obj->attr->numanode.local_memory, verbose),
hwloc_memory_size_printf_unit(obj->attr->numanode.local_memory, verbose),
separator,
(unsigned long) hwloc_memory_size_printf_value(obj->total_memory, verbose),
hwloc_memory_size_printf_unit(obj->total_memory, verbose));
else if (obj->total_memory)
res = hwloc_snprintf(tmp, tmplen, "%stotal=%lu%s",
prefix,
(unsigned long) hwloc_memory_size_printf_value(obj->total_memory, verbose),
hwloc_memory_size_printf_unit(obj->total_memory, verbose));
} else {
if (obj->type == HWLOC_OBJ_NUMANODE && obj->attr->numanode.local_memory)
res = hwloc_snprintf(tmp, tmplen, "%s%lu%s",
prefix,
(unsigned long) hwloc_memory_size_printf_value(obj->attr->numanode.local_memory, verbose),
hwloc_memory_size_printf_unit(obj->attr->numanode.local_memory, verbose));
}
if (res < 0)
return -1;
ret += res;
if (ret > 0)
prefix = separator;
if (res >= tmplen)
res = tmplen>0 ? (int)tmplen - 1 : 0;
tmp += res;
tmplen -= res;
/* printf type-specific attributes */
res = 0;
switch (obj->type) {
case HWLOC_OBJ_L1CACHE:
case HWLOC_OBJ_L2CACHE:
case HWLOC_OBJ_L3CACHE:
case HWLOC_OBJ_L4CACHE:
case HWLOC_OBJ_L5CACHE:
case HWLOC_OBJ_L1ICACHE:
case HWLOC_OBJ_L2ICACHE:
case HWLOC_OBJ_L3ICACHE:
case HWLOC_OBJ_MEMCACHE:
if (verbose) {
char assoc[32];
if (obj->attr->cache.associativity == -1)
snprintf(assoc, sizeof(assoc), "%sfully-associative", separator);
else if (obj->attr->cache.associativity == 0)
*assoc = '\0';
else
snprintf(assoc, sizeof(assoc), "%sways=%d", separator, obj->attr->cache.associativity);
res = hwloc_snprintf(tmp, tmplen, "%ssize=%lu%s%slinesize=%u%s",
prefix,
(unsigned long) hwloc_memory_size_printf_value(obj->attr->cache.size, verbose),
hwloc_memory_size_printf_unit(obj->attr->cache.size, verbose),
separator, obj->attr->cache.linesize,
assoc);
} else
res = hwloc_snprintf(tmp, tmplen, "%s%lu%s",
prefix,
(unsigned long) hwloc_memory_size_printf_value(obj->attr->cache.size, verbose),
hwloc_memory_size_printf_unit(obj->attr->cache.size, verbose));
break;
case HWLOC_OBJ_BRIDGE:
if (verbose) {
char up[128], down[64];
/* upstream is PCI or HOST */
if (obj->attr->bridge.upstream_type == HWLOC_OBJ_BRIDGE_PCI) {
char linkspeed[64]= "";
if (obj->attr->pcidev.linkspeed)
snprintf(linkspeed, sizeof(linkspeed), "%slink=%.2fGB/s", separator, obj->attr->pcidev.linkspeed);
snprintf(up, sizeof(up), "busid=%04x:%02x:%02x.%01x%sid=%04x:%04x%sclass=%04x(%s)%s",
obj->attr->pcidev.domain, obj->attr->pcidev.bus, obj->attr->pcidev.dev, obj->attr->pcidev.func, separator,
obj->attr->pcidev.vendor_id, obj->attr->pcidev.device_id, separator,
obj->attr->pcidev.class_id, hwloc_pci_class_string(obj->attr->pcidev.class_id), linkspeed);
} else
*up = '\0';
/* downstream is_PCI */
if (obj->attr->bridge.downstream_type == HWLOC_OBJ_BRIDGE_PCI) {
snprintf(down, sizeof(down), "buses=%04x:[%02x-%02x]",
obj->attr->bridge.downstream.pci.domain, obj->attr->bridge.downstream.pci.secondary_bus, obj->attr->bridge.downstream.pci.subordinate_bus);
} else
assert(0);
if (*up)
res = hwloc_snprintf(string, size, "%s%s%s", up, separator, down);
else
res = hwloc_snprintf(string, size, "%s", down);
}
break;
case HWLOC_OBJ_PCI_DEVICE:
if (verbose) {
char linkspeed[64]= "";
if (obj->attr->pcidev.linkspeed)
snprintf(linkspeed, sizeof(linkspeed), "%slink=%.2fGB/s", separator, obj->attr->pcidev.linkspeed);
res = hwloc_snprintf(string, size, "busid=%04x:%02x:%02x.%01x%sid=%04x:%04x%sclass=%04x(%s)%s",
obj->attr->pcidev.domain, obj->attr->pcidev.bus, obj->attr->pcidev.dev, obj->attr->pcidev.func, separator,
obj->attr->pcidev.vendor_id, obj->attr->pcidev.device_id, separator,
obj->attr->pcidev.class_id, hwloc_pci_class_string(obj->attr->pcidev.class_id), linkspeed);
}
break;
default:
break;
}
if (res < 0)
return -1;
ret += res;
if (ret > 0)
prefix = separator;
if (res >= tmplen)
res = tmplen>0 ? (int)tmplen - 1 : 0;
tmp += res;
tmplen -= res;
/* printf infos */
if (verbose) {
unsigned i;
for(i=0; i<obj->infos_count; i++) {
struct hwloc_info_s *info = &obj->infos[i];
const char *quote;
if (strchr(info->value, ' '))
quote = "\"";
else
quote = "";
res = hwloc_snprintf(tmp, tmplen, "%s%s=%s%s%s",
prefix,
info->name,
quote, info->value, quote);
if (res < 0)
return -1;
ret += res;
if (res >= tmplen)
res = tmplen>0 ? (int)tmplen - 1 : 0;
tmp += res;
tmplen -= res;
if (ret > 0)
prefix = separator;
}
}
return ret;
}
int hwloc_bitmap_singlify_per_core(hwloc_topology_t topology, hwloc_bitmap_t cpuset, unsigned which)
{
hwloc_obj_t core = NULL;
while ((core = hwloc_get_next_obj_covering_cpuset_by_type(topology, cpuset, HWLOC_OBJ_CORE, core)) != NULL) {
/* this core has some PUs in the cpuset, find the index-th one */
unsigned i = 0;
int pu = -1;
do {
pu = hwloc_bitmap_next(core->cpuset, pu);
if (pu == -1) {
/* no which-th PU in cpuset and core, remove the entire core */
hwloc_bitmap_andnot(cpuset, cpuset, core->cpuset);
break;
}
if (hwloc_bitmap_isset(cpuset, pu)) {
if (i == which) {
/* remove the entire core except that exact pu */
hwloc_bitmap_andnot(cpuset, cpuset, core->cpuset);
hwloc_bitmap_set(cpuset, pu);
break;
}
i++;
}
} while (1);
}
return 0;
}
hwloc_obj_t
hwloc_get_obj_with_same_locality(hwloc_topology_t topology, hwloc_obj_t src,
hwloc_obj_type_t type, const char *subtype, const char *nameprefix,
unsigned long flags)
{
if (flags) {
errno = EINVAL;
return NULL;
}
if (hwloc_obj_type_is_normal(src->type) || hwloc_obj_type_is_memory(src->type)) {
/* normal/memory type, look for normal/memory type with same sets */
hwloc_obj_t obj;
if (!hwloc_obj_type_is_normal(type) && !hwloc_obj_type_is_memory(type)) {
errno = EINVAL;
return NULL;
}
obj = NULL;
while ((obj = hwloc_get_next_obj_by_type(topology, type, obj)) != NULL) {
if (!hwloc_bitmap_isequal(src->cpuset, obj->cpuset)
|| !hwloc_bitmap_isequal(src->nodeset, obj->nodeset))
continue;
if (subtype && (!obj->subtype || strcasecmp(subtype, obj->subtype)))
continue;
if (nameprefix && (!obj->name || hwloc_strncasecmp(nameprefix, obj->name, strlen(nameprefix))))
continue;
return obj;
}
errno = ENOENT;
return NULL;
} else if (hwloc_obj_type_is_io(src->type)) {
/* I/O device, look for PCI/OS in same PCI */
hwloc_obj_t pci;
if ((src->type != HWLOC_OBJ_OS_DEVICE && src->type != HWLOC_OBJ_PCI_DEVICE)
|| (type != HWLOC_OBJ_OS_DEVICE && type != HWLOC_OBJ_PCI_DEVICE)) {
errno = EINVAL;
return NULL;
}
/* walk up to find the container */
pci = src;
while (pci->type == HWLOC_OBJ_OS_DEVICE)
pci = pci->parent;
if (type == HWLOC_OBJ_PCI_DEVICE) {
if (pci->type != HWLOC_OBJ_PCI_DEVICE) {
errno = ENOENT;
return NULL;
}
if (subtype && (!pci->subtype || strcasecmp(subtype, pci->subtype))) {
errno = ENOENT;
return NULL;
}
if (nameprefix && (!pci->name || hwloc_strncasecmp(nameprefix, pci->name, strlen(nameprefix)))) {
errno = ENOENT;
return NULL;
}
return pci;
} else {
/* find a matching osdev child */
assert(type == HWLOC_OBJ_OS_DEVICE);
/* FIXME: won't work if we ever store osdevs in osdevs */
hwloc_obj_t child;
for(child = pci->io_first_child; child; child = child->next_sibling) {
if (child->type != HWLOC_OBJ_OS_DEVICE)
/* FIXME: should never occur currently */
continue;
if (subtype && (!child->subtype || strcasecmp(subtype, child->subtype)))
continue;
if (nameprefix && (!child->name || hwloc_strncasecmp(nameprefix, child->name, strlen(nameprefix))))
continue;
return child;
}
}
errno = ENOENT;
return NULL;
} else {
/* nothing for Misc */
errno = EINVAL;
return NULL;
}
}

View file

@ -1,24 +0,0 @@
cmake_minimum_required (VERSION 2.8.12)
project (ethash C)
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Os")
set(HEADERS
data_sizes.h
endian.h
ethash.h
ethash_internal.h
fnv.h
)
set(SOURCES
ethash_internal.c
keccakf800.c
)
include_directories(../..)
add_library(ethash STATIC
${HEADERS}
${SOURCES}
)

View file

@ -1,811 +0,0 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software FoundationUUU,either version 3 of the LicenseUUU,or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be usefulU,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If notUUU,see <http://www.gnu.org/licenses/>.
*/
/** @file data_sizes.h
* @author Matthew Wampler-Doty <negacthulhu@gmail.com>
* @date 2015
*/
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
// 2048 Epochs (~20 years) worth of tabulated DAG sizes
// Generated with the following Mathematica Code:
// GetCacheSizes[n_] := Module[{
// CacheSizeBytesInit = 2^24,
// CacheGrowth = 2^17,
// HashBytes = 64,
// j = 0},
// Reap[
// While[j < n,
// Module[{i =
// Floor[(CacheSizeBytesInit + CacheGrowth * j) / HashBytes]},
// While[! PrimeQ[i], i--];
// Sow[i*HashBytes]; j++]]]][[2]][[1]]
static const uint64_t dag_sizes[2048] = {
1073739904U, 1082130304U, 1090514816U, 1098906752U, 1107293056U,
1115684224U, 1124070016U, 1132461952U, 1140849536U, 1149232768U,
1157627776U, 1166013824U, 1174404736U, 1182786944U, 1191180416U,
1199568512U, 1207958912U, 1216345216U, 1224732032U, 1233124736U,
1241513344U, 1249902464U, 1258290304U, 1266673792U, 1275067264U,
1283453312U, 1291844992U, 1300234112U, 1308619904U, 1317010048U,
1325397376U, 1333787776U, 1342176128U, 1350561664U, 1358954368U,
1367339392U, 1375731584U, 1384118144U, 1392507008U, 1400897408U,
1409284736U, 1417673344U, 1426062464U, 1434451072U, 1442839168U,
1451229056U, 1459615616U, 1468006016U, 1476394112U, 1484782976U,
1493171584U, 1501559168U, 1509948032U, 1518337664U, 1526726528U,
1535114624U, 1543503488U, 1551892096U, 1560278656U, 1568669056U,
1577056384U, 1585446272U, 1593831296U, 1602219392U, 1610610304U,
1619000192U, 1627386752U, 1635773824U, 1644164224U, 1652555648U,
1660943488U, 1669332608U, 1677721216U, 1686109312U, 1694497664U,
1702886272U, 1711274624U, 1719661184U, 1728047744U, 1736434816U,
1744829056U, 1753218944U, 1761606272U, 1769995904U, 1778382464U,
1786772864U, 1795157888U, 1803550592U, 1811937664U, 1820327552U,
1828711552U, 1837102976U, 1845488768U, 1853879936U, 1862269312U,
1870656896U, 1879048064U, 1887431552U, 1895825024U, 1904212096U,
1912601216U, 1920988544U, 1929379456U, 1937765504U, 1946156672U,
1954543232U, 1962932096U, 1971321728U, 1979707264U, 1988093056U,
1996487552U, 2004874624U, 2013262208U, 2021653888U, 2030039936U,
2038430848U, 2046819968U, 2055208576U, 2063596672U, 2071981952U,
2080373632U, 2088762752U, 2097149056U, 2105539712U, 2113928576U,
2122315136U, 2130700672U, 2139092608U, 2147483264U, 2155872128U,
2164257664U, 2172642176U, 2181035392U, 2189426048U, 2197814912U,
2206203008U, 2214587264U, 2222979712U, 2231367808U, 2239758208U,
2248145024U, 2256527744U, 2264922752U, 2273312128U, 2281701248U,
2290086272U, 2298476672U, 2306867072U, 2315251072U, 2323639168U,
2332032128U, 2340420224U, 2348808064U, 2357196416U, 2365580416U,
2373966976U, 2382363008U, 2390748544U, 2399139968U, 2407530368U,
2415918976U, 2424307328U, 2432695424U, 2441084288U, 2449472384U,
2457861248U, 2466247808U, 2474637184U, 2483026816U, 2491414144U,
2499803776U, 2508191872U, 2516582272U, 2524970368U, 2533359232U,
2541743488U, 2550134144U, 2558525056U, 2566913408U, 2575301504U,
2583686528U, 2592073856U, 2600467328U, 2608856192U, 2617240448U,
2625631616U, 2634022016U, 2642407552U, 2650796416U, 2659188352U,
2667574912U, 2675965312U, 2684352896U, 2692738688U, 2701130624U,
2709518464U, 2717907328U, 2726293376U, 2734685056U, 2743073152U,
2751462016U, 2759851648U, 2768232832U, 2776625536U, 2785017728U,
2793401984U, 2801794432U, 2810182016U, 2818571648U, 2826959488U,
2835349376U, 2843734144U, 2852121472U, 2860514432U, 2868900992U,
2877286784U, 2885676928U, 2894069632U, 2902451584U, 2910843008U,
2919234688U, 2927622784U, 2936011648U, 2944400768U, 2952789376U,
2961177728U, 2969565568U, 2977951616U, 2986338944U, 2994731392U,
3003120256U, 3011508352U, 3019895936U, 3028287104U, 3036675968U,
3045063808U, 3053452928U, 3061837696U, 3070228352U, 3078615424U,
3087003776U, 3095394944U, 3103782272U, 3112173184U, 3120562048U,
3128944768U, 3137339264U, 3145725056U, 3154109312U, 3162505088U,
3170893184U, 3179280256U, 3187669376U, 3196056704U, 3204445568U,
3212836736U, 3221224064U, 3229612928U, 3238002304U, 3246391168U,
3254778496U, 3263165824U, 3271556224U, 3279944576U, 3288332416U,
3296719232U, 3305110912U, 3313500032U, 3321887104U, 3330273152U,
3338658944U, 3347053184U, 3355440512U, 3363827072U, 3372220288U,
3380608384U, 3388997504U, 3397384576U, 3405774208U, 3414163072U,
3422551936U, 3430937984U, 3439328384U, 3447714176U, 3456104576U,
3464493952U, 3472883584U, 3481268864U, 3489655168U, 3498048896U,
3506434432U, 3514826368U, 3523213952U, 3531603584U, 3539987072U,
3548380288U, 3556763264U, 3565157248U, 3573545344U, 3581934464U,
3590324096U, 3598712704U, 3607098752U, 3615488384U, 3623877248U,
3632265856U, 3640646528U, 3649043584U, 3657430144U, 3665821568U,
3674207872U, 3682597504U, 3690984832U, 3699367808U, 3707764352U,
3716152448U, 3724541056U, 3732925568U, 3741318016U, 3749706368U,
3758091136U, 3766481536U, 3774872704U, 3783260032U, 3791650432U,
3800036224U, 3808427648U, 3816815488U, 3825204608U, 3833592704U,
3841981568U, 3850370432U, 3858755968U, 3867147904U, 3875536256U,
3883920512U, 3892313728U, 3900702592U, 3909087872U, 3917478784U,
3925868416U, 3934256512U, 3942645376U, 3951032192U, 3959422336U,
3967809152U, 3976200064U, 3984588416U, 3992974976U, 4001363584U,
4009751168U, 4018141312U, 4026530432U, 4034911616U, 4043308928U,
4051695488U, 4060084352U, 4068472448U, 4076862848U, 4085249408U,
4093640576U, 4102028416U, 4110413696U, 4118805632U, 4127194496U,
4135583104U, 4143971968U, 4152360832U, 4160746112U, 4169135744U,
4177525888U, 4185912704U, 4194303616U, 4202691968U, 4211076736U,
4219463552U, 4227855488U, 4236246656U, 4244633728U, 4253022848U,
4261412224U, 4269799808U, 4278184832U, 4286578048U, 4294962304U,
4303349632U, 4311743104U, 4320130432U, 4328521088U, 4336909184U,
4345295488U, 4353687424U, 4362073472U, 4370458496U, 4378852736U,
4387238528U, 4395630208U, 4404019072U, 4412407424U, 4420790656U,
4429182848U, 4437571456U, 4445962112U, 4454344064U, 4462738048U,
4471119232U, 4479516544U, 4487904128U, 4496289664U, 4504682368U,
4513068416U, 4521459584U, 4529846144U, 4538232704U, 4546619776U,
4555010176U, 4563402112U, 4571790208U, 4580174464U, 4588567936U,
4596957056U, 4605344896U, 4613734016U, 4622119808U, 4630511488U,
4638898816U, 4647287936U, 4655675264U, 4664065664U, 4672451968U,
4680842624U, 4689231488U, 4697620352U, 4706007424U, 4714397056U,
4722786176U, 4731173248U, 4739562368U, 4747951744U, 4756340608U,
4764727936U, 4773114496U, 4781504384U, 4789894784U, 4798283648U,
4806667648U, 4815059584U, 4823449472U, 4831835776U, 4840226176U,
4848612224U, 4857003392U, 4865391488U, 4873780096U, 4882169728U,
4890557312U, 4898946944U, 4907333248U, 4915722368U, 4924110976U,
4932499328U, 4940889728U, 4949276032U, 4957666432U, 4966054784U,
4974438016U, 4982831488U, 4991221376U, 4999607168U, 5007998848U,
5016386432U, 5024763776U, 5033164672U, 5041544576U, 5049941888U,
5058329728U, 5066717056U, 5075107456U, 5083494272U, 5091883904U,
5100273536U, 5108662144U, 5117048192U, 5125436032U, 5133827456U,
5142215296U, 5150605184U, 5158993024U, 5167382144U, 5175769472U,
5184157568U, 5192543872U, 5200936064U, 5209324928U, 5217711232U,
5226102656U, 5234490496U, 5242877312U, 5251263872U, 5259654016U,
5268040832U, 5276434304U, 5284819328U, 5293209728U, 5301598592U,
5309986688U, 5318374784U, 5326764416U, 5335151488U, 5343542144U,
5351929472U, 5360319872U, 5368706944U, 5377096576U, 5385484928U,
5393871232U, 5402263424U, 5410650496U, 5419040384U, 5427426944U,
5435816576U, 5444205952U, 5452594816U, 5460981376U, 5469367936U,
5477760896U, 5486148736U, 5494536832U, 5502925952U, 5511315328U,
5519703424U, 5528089984U, 5536481152U, 5544869504U, 5553256064U,
5561645696U, 5570032768U, 5578423936U, 5586811264U, 5595193216U,
5603585408U, 5611972736U, 5620366208U, 5628750464U, 5637143936U,
5645528192U, 5653921408U, 5662310272U, 5670694784U, 5679082624U,
5687474048U, 5695864448U, 5704251008U, 5712641408U, 5721030272U,
5729416832U, 5737806208U, 5746194304U, 5754583936U, 5762969984U,
5771358592U, 5779748224U, 5788137856U, 5796527488U, 5804911232U,
5813300608U, 5821692544U, 5830082176U, 5838468992U, 5846855552U,
5855247488U, 5863636096U, 5872024448U, 5880411008U, 5888799872U,
5897186432U, 5905576832U, 5913966976U, 5922352768U, 5930744704U,
5939132288U, 5947522432U, 5955911296U, 5964299392U, 5972688256U,
5981074304U, 5989465472U, 5997851008U, 6006241408U, 6014627968U,
6023015552U, 6031408256U, 6039796096U, 6048185216U, 6056574848U,
6064963456U, 6073351808U, 6081736064U, 6090128768U, 6098517632U,
6106906496U, 6115289216U, 6123680896U, 6132070016U, 6140459648U,
6148849024U, 6157237376U, 6165624704U, 6174009728U, 6182403712U,
6190792064U, 6199176064U, 6207569792U, 6215952256U, 6224345216U,
6232732544U, 6241124224U, 6249510272U, 6257899136U, 6266287744U,
6274676864U, 6283065728U, 6291454336U, 6299843456U, 6308232064U,
6316620928U, 6325006208U, 6333395584U, 6341784704U, 6350174848U,
6358562176U, 6366951296U, 6375337856U, 6383729536U, 6392119168U,
6400504192U, 6408895616U, 6417283456U, 6425673344U, 6434059136U,
6442444672U, 6450837376U, 6459223424U, 6467613056U, 6476004224U,
6484393088U, 6492781952U, 6501170048U, 6509555072U, 6517947008U,
6526336384U, 6534725504U, 6543112832U, 6551500672U, 6559888768U,
6568278656U, 6576662912U, 6585055616U, 6593443456U, 6601834112U,
6610219648U, 6618610304U, 6626999168U, 6635385472U, 6643777408U,
6652164224U, 6660552832U, 6668941952U, 6677330048U, 6685719424U,
6694107776U, 6702493568U, 6710882176U, 6719274112U, 6727662976U,
6736052096U, 6744437632U, 6752825984U, 6761213824U, 6769604224U,
6777993856U, 6786383488U, 6794770816U, 6803158144U, 6811549312U,
6819937664U, 6828326528U, 6836706176U, 6845101696U, 6853491328U,
6861880448U, 6870269312U, 6878655104U, 6887046272U, 6895433344U,
6903822208U, 6912212864U, 6920596864U, 6928988288U, 6937377152U,
6945764992U, 6954149248U, 6962544256U, 6970928768U, 6979317376U,
6987709312U, 6996093824U, 7004487296U, 7012875392U, 7021258624U,
7029652352U, 7038038912U, 7046427776U, 7054818944U, 7063207808U,
7071595136U, 7079980928U, 7088372608U, 7096759424U, 7105149824U,
7113536896U, 7121928064U, 7130315392U, 7138699648U, 7147092352U,
7155479168U, 7163865728U, 7172249984U, 7180648064U, 7189036672U,
7197424768U, 7205810816U, 7214196608U, 7222589824U, 7230975104U,
7239367552U, 7247755904U, 7256145536U, 7264533376U, 7272921472U,
7281308032U, 7289694848U, 7298088832U, 7306471808U, 7314864512U,
7323253888U, 7331643008U, 7340029568U, 7348419712U, 7356808832U,
7365196672U, 7373585792U, 7381973888U, 7390362752U, 7398750592U,
7407138944U, 7415528576U, 7423915648U, 7432302208U, 7440690304U,
7449080192U, 7457472128U, 7465860992U, 7474249088U, 7482635648U,
7491023744U, 7499412608U, 7507803008U, 7516192384U, 7524579968U,
7532967296U, 7541358464U, 7549745792U, 7558134656U, 7566524032U,
7574912896U, 7583300992U, 7591690112U, 7600075136U, 7608466816U,
7616854912U, 7625244544U, 7633629824U, 7642020992U, 7650410368U,
7658794112U, 7667187328U, 7675574912U, 7683961984U, 7692349568U,
7700739712U, 7709130368U, 7717519232U, 7725905536U, 7734295424U,
7742683264U, 7751069056U, 7759457408U, 7767849088U, 7776238208U,
7784626816U, 7793014912U, 7801405312U, 7809792128U, 7818179968U,
7826571136U, 7834957184U, 7843347328U, 7851732352U, 7860124544U,
7868512384U, 7876902016U, 7885287808U, 7893679744U, 7902067072U,
7910455936U, 7918844288U, 7927230848U, 7935622784U, 7944009344U,
7952400256U, 7960786048U, 7969176704U, 7977565312U, 7985953408U,
7994339968U, 8002730368U, 8011119488U, 8019508096U, 8027896192U,
8036285056U, 8044674688U, 8053062272U, 8061448832U, 8069838464U,
8078227328U, 8086616704U, 8095006592U, 8103393664U, 8111783552U,
8120171392U, 8128560256U, 8136949376U, 8145336704U, 8153726848U,
8162114944U, 8170503296U, 8178891904U, 8187280768U, 8195669632U,
8204058496U, 8212444544U, 8220834176U, 8229222272U, 8237612672U,
8246000768U, 8254389376U, 8262775168U, 8271167104U, 8279553664U,
8287944064U, 8296333184U, 8304715136U, 8313108352U, 8321497984U,
8329885568U, 8338274432U, 8346663296U, 8355052928U, 8363441536U,
8371828352U, 8380217984U, 8388606592U, 8396996224U, 8405384576U,
8413772672U, 8422161536U, 8430549376U, 8438939008U, 8447326592U,
8455715456U, 8464104832U, 8472492928U, 8480882048U, 8489270656U,
8497659776U, 8506045312U, 8514434944U, 8522823808U, 8531208832U,
8539602304U, 8547990656U, 8556378752U, 8564768384U, 8573154176U,
8581542784U, 8589933952U, 8598322816U, 8606705024U, 8615099264U,
8623487872U, 8631876992U, 8640264064U, 8648653952U, 8657040256U,
8665430656U, 8673820544U, 8682209152U, 8690592128U, 8698977152U,
8707374464U, 8715763328U, 8724151424U, 8732540032U, 8740928384U,
8749315712U, 8757704576U, 8766089344U, 8774480768U, 8782871936U,
8791260032U, 8799645824U, 8808034432U, 8816426368U, 8824812928U,
8833199488U, 8841591424U, 8849976448U, 8858366336U, 8866757248U,
8875147136U, 8883532928U, 8891923328U, 8900306816U, 8908700288U,
8917088384U, 8925478784U, 8933867392U, 8942250368U, 8950644608U,
8959032704U, 8967420544U, 8975809664U, 8984197504U, 8992584064U,
9000976256U, 9009362048U, 9017752448U, 9026141312U, 9034530688U,
9042917504U, 9051307904U, 9059694208U, 9068084864U, 9076471424U,
9084861824U, 9093250688U, 9101638528U, 9110027648U, 9118416512U,
9126803584U, 9135188096U, 9143581312U, 9151969664U, 9160356224U,
9168747136U, 9177134464U, 9185525632U, 9193910144U, 9202302848U,
9210690688U, 9219079552U, 9227465344U, 9235854464U, 9244244864U,
9252633472U, 9261021824U, 9269411456U, 9277799296U, 9286188928U,
9294574208U, 9302965888U, 9311351936U, 9319740032U, 9328131968U,
9336516736U, 9344907392U, 9353296768U, 9361685888U, 9370074752U,
9378463616U, 9386849408U, 9395239808U, 9403629184U, 9412016512U,
9420405376U, 9428795008U, 9437181568U, 9445570688U, 9453960832U,
9462346624U, 9470738048U, 9479121536U, 9487515008U, 9495903616U,
9504289664U, 9512678528U, 9521067904U, 9529456256U, 9537843584U,
9546233728U, 9554621312U, 9563011456U, 9571398784U, 9579788672U,
9588178304U, 9596567168U, 9604954496U, 9613343104U, 9621732992U,
9630121856U, 9638508416U, 9646898816U, 9655283584U, 9663675776U,
9672061312U, 9680449664U, 9688840064U, 9697230464U, 9705617536U,
9714003584U, 9722393984U, 9730772608U, 9739172224U, 9747561088U,
9755945344U, 9764338816U, 9772726144U, 9781116544U, 9789503872U,
9797892992U, 9806282624U, 9814670464U, 9823056512U, 9831439232U,
9839833984U, 9848224384U, 9856613504U, 9865000576U, 9873391232U,
9881772416U, 9890162816U, 9898556288U, 9906940544U, 9915333248U,
9923721088U, 9932108672U, 9940496512U, 9948888448U, 9957276544U,
9965666176U, 9974048384U, 9982441088U, 9990830464U, 9999219584U,
10007602816U, 10015996544U, 10024385152U, 10032774016U, 10041163648U,
10049548928U, 10057940096U, 10066329472U, 10074717824U, 10083105152U,
10091495296U, 10099878784U, 10108272256U, 10116660608U, 10125049216U,
10133437312U, 10141825664U, 10150213504U, 10158601088U, 10166991232U,
10175378816U, 10183766144U, 10192157312U, 10200545408U, 10208935552U,
10217322112U, 10225712768U, 10234099328U, 10242489472U, 10250876032U,
10259264896U, 10267656064U, 10276042624U, 10284429184U, 10292820352U,
10301209472U, 10309598848U, 10317987712U, 10326375296U, 10334763392U,
10343153536U, 10351541632U, 10359930752U, 10368318592U, 10376707456U,
10385096576U, 10393484672U, 10401867136U, 10410262144U, 10418647424U,
10427039104U, 10435425664U, 10443810176U, 10452203648U, 10460589952U,
10468982144U, 10477369472U, 10485759104U, 10494147712U, 10502533504U,
10510923392U, 10519313536U, 10527702656U, 10536091264U, 10544478592U,
10552867712U, 10561255808U, 10569642368U, 10578032768U, 10586423168U,
10594805632U, 10603200128U, 10611588992U, 10619976064U, 10628361344U,
10636754048U, 10645143424U, 10653531776U, 10661920384U, 10670307968U,
10678696832U, 10687086464U, 10695475072U, 10703863168U, 10712246144U,
10720639616U, 10729026688U, 10737414784U, 10745806208U, 10754190976U,
10762581376U, 10770971264U, 10779356288U, 10787747456U, 10796135552U,
10804525184U, 10812915584U, 10821301888U, 10829692288U, 10838078336U,
10846469248U, 10854858368U, 10863247232U, 10871631488U, 10880023424U,
10888412032U, 10896799616U, 10905188992U, 10913574016U, 10921964672U,
10930352768U, 10938742912U, 10947132544U, 10955518592U, 10963909504U,
10972298368U, 10980687488U, 10989074816U, 10997462912U, 11005851776U,
11014241152U, 11022627712U, 11031017344U, 11039403904U, 11047793024U,
11056184704U, 11064570752U, 11072960896U, 11081343872U, 11089737856U,
11098128256U, 11106514816U, 11114904448U, 11123293568U, 11131680128U,
11140065152U, 11148458368U, 11156845696U, 11165236864U, 11173624192U,
11182013824U, 11190402688U, 11198790784U, 11207179136U, 11215568768U,
11223957376U, 11232345728U, 11240734592U, 11249122688U, 11257511296U,
11265899648U, 11274285952U, 11282675584U, 11291065472U, 11299452544U,
11307842432U, 11316231296U, 11324616832U, 11333009024U, 11341395584U,
11349782656U, 11358172288U, 11366560384U, 11374950016U, 11383339648U,
11391721856U, 11400117376U, 11408504192U, 11416893568U, 11425283456U,
11433671552U, 11442061184U, 11450444672U, 11458837888U, 11467226752U,
11475611776U, 11484003968U, 11492392064U, 11500780672U, 11509169024U,
11517550976U, 11525944448U, 11534335616U, 11542724224U, 11551111808U,
11559500672U, 11567890304U, 11576277376U, 11584667008U, 11593056128U,
11601443456U, 11609830016U, 11618221952U, 11626607488U, 11634995072U,
11643387776U, 11651775104U, 11660161664U, 11668552576U, 11676940928U,
11685330304U, 11693718656U, 11702106496U, 11710496128U, 11718882688U,
11727273088U, 11735660416U, 11744050048U, 11752437376U, 11760824704U,
11769216128U, 11777604736U, 11785991296U, 11794381952U, 11802770048U,
11811157888U, 11819548544U, 11827932544U, 11836324736U, 11844713344U,
11853100928U, 11861486464U, 11869879936U, 11878268032U, 11886656896U,
11895044992U, 11903433088U, 11911822976U, 11920210816U, 11928600448U,
11936987264U, 11945375872U, 11953761152U, 11962151296U, 11970543488U,
11978928512U, 11987320448U, 11995708288U, 12004095104U, 12012486272U,
12020875136U, 12029255552U, 12037652096U, 12046039168U, 12054429568U,
12062813824U, 12071206528U, 12079594624U, 12087983744U, 12096371072U,
12104759936U, 12113147264U, 12121534592U, 12129924992U, 12138314624U,
12146703232U, 12155091584U, 12163481216U, 12171864704U, 12180255872U,
12188643968U, 12197034112U, 12205424512U, 12213811328U, 12222199424U,
12230590336U, 12238977664U, 12247365248U, 12255755392U, 12264143488U,
12272531584U, 12280920448U, 12289309568U, 12297694592U, 12306086528U,
12314475392U, 12322865024U, 12331253632U, 12339640448U, 12348029312U,
12356418944U, 12364805248U, 12373196672U, 12381580928U, 12389969024U,
12398357632U, 12406750592U, 12415138432U, 12423527552U, 12431916416U,
12440304512U, 12448692352U, 12457081216U, 12465467776U, 12473859968U,
12482245504U, 12490636672U, 12499025536U, 12507411584U, 12515801728U,
12524190592U, 12532577152U, 12540966272U, 12549354368U, 12557743232U,
12566129536U, 12574523264U, 12582911872U, 12591299456U, 12599688064U,
12608074624U, 12616463488U, 12624845696U, 12633239936U, 12641631616U,
12650019968U, 12658407296U, 12666795136U, 12675183232U, 12683574656U,
12691960192U, 12700350592U, 12708740224U, 12717128576U, 12725515904U,
12733906816U, 12742295168U, 12750680192U, 12759071872U, 12767460736U,
12775848832U, 12784236928U, 12792626816U, 12801014656U, 12809404288U,
12817789312U, 12826181504U, 12834568832U, 12842954624U, 12851345792U,
12859732352U, 12868122496U, 12876512128U, 12884901248U, 12893289088U,
12901672832U, 12910067584U, 12918455168U, 12926842496U, 12935232896U,
12943620736U, 12952009856U, 12960396928U, 12968786816U, 12977176192U,
12985563776U, 12993951104U, 13002341504U, 13010730368U, 13019115392U,
13027506304U, 13035895168U, 13044272512U, 13052673152U, 13061062528U,
13069446272U, 13077838976U, 13086227072U, 13094613632U, 13103000192U,
13111393664U, 13119782528U, 13128157568U, 13136559232U, 13144945024U,
13153329536U, 13161724288U, 13170111872U, 13178502784U, 13186884736U,
13195279744U, 13203667072U, 13212057472U, 13220445824U, 13228832128U,
13237221248U, 13245610624U, 13254000512U, 13262388352U, 13270777472U,
13279166336U, 13287553408U, 13295943296U, 13304331904U, 13312719488U,
13321108096U, 13329494656U, 13337885824U, 13346274944U, 13354663808U,
13363051136U, 13371439232U, 13379825024U, 13388210816U, 13396605056U,
13404995456U, 13413380224U, 13421771392U, 13430159744U, 13438546048U,
13446937216U, 13455326848U, 13463708288U, 13472103808U, 13480492672U,
13488875648U, 13497269888U, 13505657728U, 13514045312U, 13522435712U,
13530824576U, 13539210112U, 13547599232U, 13555989376U, 13564379008U,
13572766336U, 13581154432U, 13589544832U, 13597932928U, 13606320512U,
13614710656U, 13623097472U, 13631477632U, 13639874944U, 13648264064U,
13656652928U, 13665041792U, 13673430656U, 13681818496U, 13690207616U,
13698595712U, 13706982272U, 13715373184U, 13723762048U, 13732150144U,
13740536704U, 13748926592U, 13757316224U, 13765700992U, 13774090112U,
13782477952U, 13790869376U, 13799259008U, 13807647872U, 13816036736U,
13824425344U, 13832814208U, 13841202304U, 13849591424U, 13857978752U,
13866368896U, 13874754688U, 13883145344U, 13891533184U, 13899919232U,
13908311168U, 13916692096U, 13925085056U, 13933473152U, 13941866368U,
13950253696U, 13958643584U, 13967032192U, 13975417216U, 13983807616U,
13992197504U, 14000582272U, 14008973696U, 14017363072U, 14025752192U,
14034137984U, 14042528384U, 14050918016U, 14059301504U, 14067691648U,
14076083584U, 14084470144U, 14092852352U, 14101249664U, 14109635968U,
14118024832U, 14126407552U, 14134804352U, 14143188608U, 14151577984U,
14159968384U, 14168357248U, 14176741504U, 14185127296U, 14193521024U,
14201911424U, 14210301824U, 14218685056U, 14227067264U, 14235467392U,
14243855488U, 14252243072U, 14260630144U, 14269021568U, 14277409408U,
14285799296U, 14294187904U, 14302571392U, 14310961792U, 14319353728U,
14327738752U, 14336130944U, 14344518784U, 14352906368U, 14361296512U,
14369685376U, 14378071424U, 14386462592U, 14394848128U, 14403230848U,
14411627392U, 14420013952U, 14428402304U, 14436793472U, 14445181568U,
14453569664U, 14461959808U, 14470347904U, 14478737024U, 14487122816U,
14495511424U, 14503901824U, 14512291712U, 14520677504U, 14529064832U,
14537456768U, 14545845632U, 14554234496U, 14562618496U, 14571011456U,
14579398784U, 14587789184U, 14596172672U, 14604564608U, 14612953984U,
14621341312U, 14629724288U, 14638120832U, 14646503296U, 14654897536U,
14663284864U, 14671675264U, 14680061056U, 14688447616U, 14696835968U,
14705228416U, 14713616768U, 14722003328U, 14730392192U, 14738784128U,
14747172736U, 14755561088U, 14763947648U, 14772336512U, 14780725376U,
14789110144U, 14797499776U, 14805892736U, 14814276992U, 14822670208U,
14831056256U, 14839444352U, 14847836032U, 14856222848U, 14864612992U,
14872997504U, 14881388672U, 14889775744U, 14898165376U, 14906553472U,
14914944896U, 14923329664U, 14931721856U, 14940109696U, 14948497024U,
14956887424U, 14965276544U, 14973663616U, 14982053248U, 14990439808U,
14998830976U, 15007216768U, 15015605888U, 15023995264U, 15032385152U,
15040768384U, 15049154944U, 15057549184U, 15065939072U, 15074328448U,
15082715008U, 15091104128U, 15099493504U, 15107879296U, 15116269184U,
15124659584U, 15133042304U, 15141431936U, 15149824384U, 15158214272U,
15166602368U, 15174991232U, 15183378304U, 15191760512U, 15200154496U,
15208542592U, 15216931712U, 15225323392U, 15233708416U, 15242098048U,
15250489216U, 15258875264U, 15267265408U, 15275654528U, 15284043136U,
15292431488U, 15300819584U, 15309208192U, 15317596544U, 15325986176U,
15334374784U, 15342763648U, 15351151744U, 15359540608U, 15367929728U,
15376318336U, 15384706432U, 15393092992U, 15401481856U, 15409869952U,
15418258816U, 15426649984U, 15435037568U, 15443425664U, 15451815296U,
15460203392U, 15468589184U, 15476979328U, 15485369216U, 15493755776U,
15502146944U, 15510534272U, 15518924416U, 15527311232U, 15535699072U,
15544089472U, 15552478336U, 15560866688U, 15569254528U, 15577642624U,
15586031488U, 15594419072U, 15602809472U, 15611199104U, 15619586432U,
15627975296U, 15636364928U, 15644753792U, 15653141888U, 15661529216U,
15669918848U, 15678305152U, 15686696576U, 15695083136U, 15703474048U,
15711861632U, 15720251264U, 15728636288U, 15737027456U, 15745417088U,
15753804928U, 15762194048U, 15770582656U, 15778971008U, 15787358336U,
15795747712U, 15804132224U, 15812523392U, 15820909696U, 15829300096U,
15837691264U, 15846071936U, 15854466944U, 15862855808U, 15871244672U,
15879634816U, 15888020608U, 15896409728U, 15904799104U, 15913185152U,
15921577088U, 15929966464U, 15938354816U, 15946743424U, 15955129472U,
15963519872U, 15971907968U, 15980296064U, 15988684928U, 15997073024U,
16005460864U, 16013851264U, 16022241152U, 16030629248U, 16039012736U,
16047406976U, 16055794816U, 16064181376U, 16072571264U, 16080957824U,
16089346688U, 16097737856U, 16106125184U, 16114514816U, 16122904192U,
16131292544U, 16139678848U, 16148066944U, 16156453504U, 16164839552U,
16173236096U, 16181623424U, 16190012032U, 16198401152U, 16206790528U,
16215177344U, 16223567744U, 16231956352U, 16240344704U, 16248731008U,
16257117824U, 16265504384U, 16273898624U, 16282281856U, 16290668672U,
16299064192U, 16307449216U, 16315842176U, 16324230016U, 16332613504U,
16341006464U, 16349394304U, 16357783168U, 16366172288U, 16374561664U,
16382951296U, 16391337856U, 16399726208U, 16408116352U, 16416505472U,
16424892032U, 16433282176U, 16441668224U, 16450058624U, 16458448768U,
16466836864U, 16475224448U, 16483613056U, 16492001408U, 16500391808U,
16508779648U, 16517166976U, 16525555328U, 16533944192U, 16542330752U,
16550719616U, 16559110528U, 16567497088U, 16575888512U, 16584274816U,
16592665472U, 16601051008U, 16609442944U, 16617832064U, 16626218624U,
16634607488U, 16642996096U, 16651385728U, 16659773824U, 16668163712U,
16676552576U, 16684938112U, 16693328768U, 16701718144U, 16710095488U,
16718492288U, 16726883968U, 16735272832U, 16743661184U, 16752049792U,
16760436608U, 16768827008U, 16777214336U, 16785599104U, 16793992832U,
16802381696U, 16810768768U, 16819151744U, 16827542656U, 16835934848U,
16844323712U, 16852711552U, 16861101952U, 16869489536U, 16877876864U,
16886265728U, 16894653056U, 16903044736U, 16911431296U, 16919821696U,
16928207488U, 16936592768U, 16944987776U, 16953375616U, 16961763968U,
16970152832U, 16978540928U, 16986929536U, 16995319168U, 17003704448U,
17012096896U, 17020481152U, 17028870784U, 17037262208U, 17045649536U,
17054039936U, 17062426496U, 17070814336U, 17079205504U, 17087592064U,
17095978112U, 17104369024U, 17112759424U, 17121147776U, 17129536384U,
17137926016U, 17146314368U, 17154700928U, 17163089792U, 17171480192U,
17179864192U, 17188256896U, 17196644992U, 17205033856U, 17213423488U,
17221811072U, 17230198912U, 17238588032U, 17246976896U, 17255360384U,
17263754624U, 17272143232U, 17280530048U, 17288918912U, 17297309312U,
17305696384U, 17314085504U, 17322475136U, 17330863744U, 17339252096U,
17347640192U, 17356026496U, 17364413824U, 17372796544U, 17381190016U,
17389583488U, 17397972608U, 17406360704U, 17414748544U, 17423135872U,
17431527296U, 17439915904U, 17448303232U, 17456691584U, 17465081728U,
17473468288U, 17481857408U, 17490247552U, 17498635904U, 17507022464U,
17515409024U, 17523801728U, 17532189824U, 17540577664U, 17548966016U,
17557353344U, 17565741184U, 17574131584U, 17582519168U, 17590907008U,
17599296128U, 17607687808U, 17616076672U, 17624455808U, 17632852352U,
17641238656U, 17649630848U, 17658018944U, 17666403968U, 17674794112U,
17683178368U, 17691573376U, 17699962496U, 17708350592U, 17716739968U,
17725126528U, 17733517184U, 17741898112U, 17750293888U, 17758673024U,
17767070336U, 17775458432U, 17783848832U, 17792236928U, 17800625536U,
17809012352U, 17817402752U, 17825785984U, 17834178944U, 17842563968U,
17850955648U, 17859344512U, 17867732864U, 17876119424U, 17884511872U,
17892900224U, 17901287296U, 17909677696U, 17918058112U, 17926451072U,
17934843776U, 17943230848U, 17951609216U, 17960008576U, 17968397696U,
17976784256U, 17985175424U, 17993564032U, 18001952128U, 18010339712U,
18018728576U, 18027116672U, 18035503232U, 18043894144U, 18052283264U,
18060672128U, 18069056384U, 18077449856U, 18085837184U, 18094225792U,
18102613376U, 18111004544U, 18119388544U, 18127781248U, 18136170368U,
18144558976U, 18152947328U, 18161336192U, 18169724288U, 18178108544U,
18186498944U, 18194886784U, 18203275648U, 18211666048U, 18220048768U,
18228444544U, 18236833408U, 18245220736U
};
// Generated with the following Mathematica Code:
// GetCacheSizes[n_] := Module[{
// DataSetSizeBytesInit = 2^30,
// MixBytes = 128,
// DataSetGrowth = 2^23,
// HashBytes = 64,
// CacheMultiplier = 1024,
// j = 0},
// Reap[
// While[j < n,
// Module[{i = Floor[(DataSetSizeBytesInit + DataSetGrowth * j) / (CacheMultiplier * HashBytes)]},
// While[! PrimeQ[i], i--];
// Sow[i*HashBytes]; j++]]]][[2]][[1]]
const uint64_t cache_sizes[2048] = {
16776896U, 16907456U, 17039296U, 17170112U, 17301056U, 17432512U, 17563072U,
17693888U, 17824192U, 17955904U, 18087488U, 18218176U, 18349504U, 18481088U,
18611392U, 18742336U, 18874304U, 19004224U, 19135936U, 19267264U, 19398208U,
19529408U, 19660096U, 19791424U, 19922752U, 20053952U, 20184896U, 20315968U,
20446912U, 20576576U, 20709184U, 20840384U, 20971072U, 21102272U, 21233216U,
21364544U, 21494848U, 21626816U, 21757376U, 21887552U, 22019392U, 22151104U,
22281536U, 22412224U, 22543936U, 22675264U, 22806464U, 22935872U, 23068096U,
23198272U, 23330752U, 23459008U, 23592512U, 23723968U, 23854912U, 23986112U,
24116672U, 24247616U, 24378688U, 24509504U, 24640832U, 24772544U, 24903488U,
25034432U, 25165376U, 25296704U, 25427392U, 25558592U, 25690048U, 25820096U,
25951936U, 26081728U, 26214208U, 26345024U, 26476096U, 26606656U, 26737472U,
26869184U, 26998208U, 27131584U, 27262528U, 27393728U, 27523904U, 27655744U,
27786688U, 27917888U, 28049344U, 28179904U, 28311488U, 28441792U, 28573504U,
28700864U, 28835648U, 28966208U, 29096768U, 29228608U, 29359808U, 29490752U,
29621824U, 29752256U, 29882816U, 30014912U, 30144448U, 30273728U, 30406976U,
30538432U, 30670784U, 30799936U, 30932672U, 31063744U, 31195072U, 31325248U,
31456192U, 31588288U, 31719232U, 31850432U, 31981504U, 32110784U, 32243392U,
32372672U, 32505664U, 32636608U, 32767808U, 32897344U, 33029824U, 33160768U,
33289664U, 33423296U, 33554368U, 33683648U, 33816512U, 33947456U, 34076992U,
34208704U, 34340032U, 34471744U, 34600256U, 34734016U, 34864576U, 34993984U,
35127104U, 35258176U, 35386688U, 35518528U, 35650624U, 35782336U, 35910976U,
36044608U, 36175808U, 36305728U, 36436672U, 36568384U, 36699968U, 36830656U,
36961984U, 37093312U, 37223488U, 37355072U, 37486528U, 37617472U, 37747904U,
37879232U, 38009792U, 38141888U, 38272448U, 38403392U, 38535104U, 38660672U,
38795584U, 38925632U, 39059264U, 39190336U, 39320768U, 39452096U, 39581632U,
39713984U, 39844928U, 39974848U, 40107968U, 40238144U, 40367168U, 40500032U,
40631744U, 40762816U, 40894144U, 41023552U, 41155904U, 41286208U, 41418304U,
41547712U, 41680448U, 41811904U, 41942848U, 42073792U, 42204992U, 42334912U,
42467008U, 42597824U, 42729152U, 42860096U, 42991552U, 43122368U, 43253696U,
43382848U, 43515712U, 43646912U, 43777088U, 43907648U, 44039104U, 44170432U,
44302144U, 44433344U, 44564288U, 44694976U, 44825152U, 44956864U, 45088448U,
45219008U, 45350464U, 45481024U, 45612608U, 45744064U, 45874496U, 46006208U,
46136768U, 46267712U, 46399424U, 46529344U, 46660672U, 46791488U, 46923328U,
47053504U, 47185856U, 47316928U, 47447872U, 47579072U, 47710144U, 47839936U,
47971648U, 48103232U, 48234176U, 48365248U, 48496192U, 48627136U, 48757312U,
48889664U, 49020736U, 49149248U, 49283008U, 49413824U, 49545152U, 49675712U,
49807168U, 49938368U, 50069056U, 50200256U, 50331584U, 50462656U, 50593472U,
50724032U, 50853952U, 50986048U, 51117632U, 51248576U, 51379904U, 51510848U,
51641792U, 51773248U, 51903296U, 52035136U, 52164032U, 52297664U, 52427968U,
52557376U, 52690112U, 52821952U, 52952896U, 53081536U, 53213504U, 53344576U,
53475776U, 53608384U, 53738816U, 53870528U, 54000832U, 54131776U, 54263744U,
54394688U, 54525248U, 54655936U, 54787904U, 54918592U, 55049152U, 55181248U,
55312064U, 55442752U, 55574336U, 55705024U, 55836224U, 55967168U, 56097856U,
56228672U, 56358592U, 56490176U, 56621888U, 56753728U, 56884928U, 57015488U,
57146816U, 57278272U, 57409216U, 57540416U, 57671104U, 57802432U, 57933632U,
58064576U, 58195264U, 58326976U, 58457408U, 58588864U, 58720192U, 58849984U,
58981696U, 59113024U, 59243456U, 59375552U, 59506624U, 59637568U, 59768512U,
59897792U, 60030016U, 60161984U, 60293056U, 60423872U, 60554432U, 60683968U,
60817216U, 60948032U, 61079488U, 61209664U, 61341376U, 61471936U, 61602752U,
61733696U, 61865792U, 61996736U, 62127808U, 62259136U, 62389568U, 62520512U,
62651584U, 62781632U, 62910784U, 63045056U, 63176128U, 63307072U, 63438656U,
63569216U, 63700928U, 63831616U, 63960896U, 64093888U, 64225088U, 64355392U,
64486976U, 64617664U, 64748608U, 64879424U, 65009216U, 65142464U, 65273792U,
65402816U, 65535424U, 65666752U, 65797696U, 65927744U, 66060224U, 66191296U,
66321344U, 66453056U, 66584384U, 66715328U, 66846656U, 66977728U, 67108672U,
67239104U, 67370432U, 67501888U, 67631296U, 67763776U, 67895104U, 68026304U,
68157248U, 68287936U, 68419264U, 68548288U, 68681408U, 68811968U, 68942912U,
69074624U, 69205568U, 69337024U, 69467584U, 69599168U, 69729472U, 69861184U,
69989824U, 70122944U, 70253888U, 70385344U, 70515904U, 70647232U, 70778816U,
70907968U, 71040832U, 71171648U, 71303104U, 71432512U, 71564992U, 71695168U,
71826368U, 71958464U, 72089536U, 72219712U, 72350144U, 72482624U, 72613568U,
72744512U, 72875584U, 73006144U, 73138112U, 73268672U, 73400128U, 73530944U,
73662272U, 73793344U, 73924544U, 74055104U, 74185792U, 74316992U, 74448832U,
74579392U, 74710976U, 74841664U, 74972864U, 75102784U, 75233344U, 75364544U,
75497024U, 75627584U, 75759296U, 75890624U, 76021696U, 76152256U, 76283072U,
76414144U, 76545856U, 76676672U, 76806976U, 76937792U, 77070016U, 77200832U,
77331392U, 77462464U, 77593664U, 77725376U, 77856448U, 77987776U, 78118336U,
78249664U, 78380992U, 78511424U, 78642496U, 78773056U, 78905152U, 79033664U,
79166656U, 79297472U, 79429568U, 79560512U, 79690816U, 79822784U, 79953472U,
80084672U, 80214208U, 80346944U, 80477632U, 80608576U, 80740288U, 80870848U,
81002048U, 81133504U, 81264448U, 81395648U, 81525952U, 81657536U, 81786304U,
81919808U, 82050112U, 82181312U, 82311616U, 82443968U, 82573376U, 82705984U,
82835776U, 82967744U, 83096768U, 83230528U, 83359552U, 83491264U, 83622464U,
83753536U, 83886016U, 84015296U, 84147776U, 84277184U, 84409792U, 84540608U,
84672064U, 84803008U, 84934336U, 85065152U, 85193792U, 85326784U, 85458496U,
85589312U, 85721024U, 85851968U, 85982656U, 86112448U, 86244416U, 86370112U,
86506688U, 86637632U, 86769344U, 86900672U, 87031744U, 87162304U, 87293632U,
87424576U, 87555392U, 87687104U, 87816896U, 87947968U, 88079168U, 88211264U,
88341824U, 88473152U, 88603712U, 88735424U, 88862912U, 88996672U, 89128384U,
89259712U, 89390272U, 89521984U, 89652544U, 89783872U, 89914816U, 90045376U,
90177088U, 90307904U, 90438848U, 90569152U, 90700096U, 90832832U, 90963776U,
91093696U, 91223744U, 91356992U, 91486784U, 91618496U, 91749824U, 91880384U,
92012224U, 92143552U, 92273344U, 92405696U, 92536768U, 92666432U, 92798912U,
92926016U, 93060544U, 93192128U, 93322816U, 93453632U, 93583936U, 93715136U,
93845056U, 93977792U, 94109504U, 94240448U, 94371776U, 94501184U, 94632896U,
94764224U, 94895552U, 95023424U, 95158208U, 95287744U, 95420224U, 95550016U,
95681216U, 95811904U, 95943872U, 96075328U, 96203584U, 96337856U, 96468544U,
96599744U, 96731072U, 96860992U, 96992576U, 97124288U, 97254848U, 97385536U,
97517248U, 97647808U, 97779392U, 97910464U, 98041408U, 98172608U, 98303168U,
98434496U, 98565568U, 98696768U, 98827328U, 98958784U, 99089728U, 99220928U,
99352384U, 99482816U, 99614272U, 99745472U, 99876416U, 100007104U,
100138048U, 100267072U, 100401088U, 100529984U, 100662592U, 100791872U,
100925248U, 101056064U, 101187392U, 101317952U, 101449408U, 101580608U,
101711296U, 101841728U, 101973824U, 102104896U, 102235712U, 102366016U,
102498112U, 102628672U, 102760384U, 102890432U, 103021888U, 103153472U,
103284032U, 103415744U, 103545152U, 103677248U, 103808576U, 103939648U,
104070976U, 104201792U, 104332736U, 104462528U, 104594752U, 104725952U,
104854592U, 104988608U, 105118912U, 105247808U, 105381184U, 105511232U,
105643072U, 105774784U, 105903296U, 106037056U, 106167872U, 106298944U,
106429504U, 106561472U, 106691392U, 106822592U, 106954304U, 107085376U,
107216576U, 107346368U, 107478464U, 107609792U, 107739712U, 107872192U,
108003136U, 108131392U, 108265408U, 108396224U, 108527168U, 108657344U,
108789568U, 108920384U, 109049792U, 109182272U, 109312576U, 109444928U,
109572928U, 109706944U, 109837888U, 109969088U, 110099648U, 110230976U,
110362432U, 110492992U, 110624704U, 110755264U, 110886208U, 111017408U,
111148864U, 111279296U, 111410752U, 111541952U, 111673024U, 111803456U,
111933632U, 112066496U, 112196416U, 112328512U, 112457792U, 112590784U,
112715968U, 112852672U, 112983616U, 113114944U, 113244224U, 113376448U,
113505472U, 113639104U, 113770304U, 113901376U, 114031552U, 114163264U,
114294592U, 114425536U, 114556864U, 114687424U, 114818624U, 114948544U,
115080512U, 115212224U, 115343296U, 115473472U, 115605184U, 115736128U,
115867072U, 115997248U, 116128576U, 116260288U, 116391488U, 116522944U,
116652992U, 116784704U, 116915648U, 117046208U, 117178304U, 117308608U,
117440192U, 117569728U, 117701824U, 117833024U, 117964096U, 118094656U,
118225984U, 118357312U, 118489024U, 118617536U, 118749632U, 118882112U,
119012416U, 119144384U, 119275328U, 119406016U, 119537344U, 119668672U,
119798464U, 119928896U, 120061376U, 120192832U, 120321728U, 120454336U,
120584512U, 120716608U, 120848192U, 120979136U, 121109056U, 121241408U,
121372352U, 121502912U, 121634752U, 121764416U, 121895744U, 122027072U,
122157632U, 122289088U, 122421184U, 122550592U, 122682944U, 122813888U,
122945344U, 123075776U, 123207488U, 123338048U, 123468736U, 123600704U,
123731264U, 123861952U, 123993664U, 124124608U, 124256192U, 124386368U,
124518208U, 124649024U, 124778048U, 124911296U, 125041088U, 125173696U,
125303744U, 125432896U, 125566912U, 125696576U, 125829056U, 125958592U,
126090304U, 126221248U, 126352832U, 126483776U, 126615232U, 126746432U,
126876608U, 127008704U, 127139392U, 127270336U, 127401152U, 127532224U,
127663552U, 127794752U, 127925696U, 128055232U, 128188096U, 128319424U,
128449856U, 128581312U, 128712256U, 128843584U, 128973632U, 129103808U,
129236288U, 129365696U, 129498944U, 129629888U, 129760832U, 129892288U,
130023104U, 130154048U, 130283968U, 130416448U, 130547008U, 130678336U,
130807616U, 130939456U, 131071552U, 131202112U, 131331776U, 131464384U,
131594048U, 131727296U, 131858368U, 131987392U, 132120256U, 132250816U,
132382528U, 132513728U, 132644672U, 132774976U, 132905792U, 133038016U,
133168832U, 133299392U, 133429312U, 133562048U, 133692992U, 133823296U,
133954624U, 134086336U, 134217152U, 134348608U, 134479808U, 134607296U,
134741056U, 134872384U, 135002944U, 135134144U, 135265472U, 135396544U,
135527872U, 135659072U, 135787712U, 135921472U, 136052416U, 136182848U,
136313792U, 136444864U, 136576448U, 136707904U, 136837952U, 136970048U,
137099584U, 137232064U, 137363392U, 137494208U, 137625536U, 137755712U,
137887424U, 138018368U, 138149824U, 138280256U, 138411584U, 138539584U,
138672832U, 138804928U, 138936128U, 139066688U, 139196864U, 139328704U,
139460032U, 139590208U, 139721024U, 139852864U, 139984576U, 140115776U,
140245696U, 140376512U, 140508352U, 140640064U, 140769856U, 140902336U,
141032768U, 141162688U, 141294016U, 141426496U, 141556544U, 141687488U,
141819584U, 141949888U, 142080448U, 142212544U, 142342336U, 142474432U,
142606144U, 142736192U, 142868288U, 142997824U, 143129408U, 143258944U,
143392448U, 143523136U, 143653696U, 143785024U, 143916992U, 144045632U,
144177856U, 144309184U, 144440768U, 144570688U, 144701888U, 144832448U,
144965056U, 145096384U, 145227584U, 145358656U, 145489856U, 145620928U,
145751488U, 145883072U, 146011456U, 146144704U, 146275264U, 146407232U,
146538176U, 146668736U, 146800448U, 146931392U, 147062336U, 147193664U,
147324224U, 147455936U, 147586624U, 147717056U, 147848768U, 147979456U,
148110784U, 148242368U, 148373312U, 148503232U, 148635584U, 148766144U,
148897088U, 149028416U, 149159488U, 149290688U, 149420224U, 149551552U,
149683136U, 149814976U, 149943616U, 150076352U, 150208064U, 150338624U,
150470464U, 150600256U, 150732224U, 150862784U, 150993088U, 151125952U,
151254976U, 151388096U, 151519168U, 151649728U, 151778752U, 151911104U,
152042944U, 152174144U, 152304704U, 152435648U, 152567488U, 152698816U,
152828992U, 152960576U, 153091648U, 153222976U, 153353792U, 153484096U,
153616192U, 153747008U, 153878336U, 154008256U, 154139968U, 154270912U,
154402624U, 154533824U, 154663616U, 154795712U, 154926272U, 155057984U,
155188928U, 155319872U, 155450816U, 155580608U, 155712064U, 155843392U,
155971136U, 156106688U, 156237376U, 156367424U, 156499264U, 156630976U,
156761536U, 156892352U, 157024064U, 157155008U, 157284416U, 157415872U,
157545536U, 157677248U, 157810496U, 157938112U, 158071744U, 158203328U,
158334656U, 158464832U, 158596288U, 158727616U, 158858048U, 158988992U,
159121216U, 159252416U, 159381568U, 159513152U, 159645632U, 159776192U,
159906496U, 160038464U, 160169536U, 160300352U, 160430656U, 160563008U,
160693952U, 160822208U, 160956352U, 161086784U, 161217344U, 161349184U,
161480512U, 161611456U, 161742272U, 161873216U, 162002752U, 162135872U,
162266432U, 162397888U, 162529216U, 162660032U, 162790976U, 162922048U,
163052096U, 163184576U, 163314752U, 163446592U, 163577408U, 163707968U,
163839296U, 163969984U, 164100928U, 164233024U, 164364224U, 164494912U,
164625856U, 164756672U, 164887616U, 165019072U, 165150016U, 165280064U,
165412672U, 165543104U, 165674944U, 165805888U, 165936832U, 166067648U,
166198336U, 166330048U, 166461248U, 166591552U, 166722496U, 166854208U,
166985408U, 167116736U, 167246656U, 167378368U, 167508416U, 167641024U,
167771584U, 167903168U, 168034112U, 168164032U, 168295744U, 168427456U,
168557632U, 168688448U, 168819136U, 168951616U, 169082176U, 169213504U,
169344832U, 169475648U, 169605952U, 169738048U, 169866304U, 169999552U,
170131264U, 170262464U, 170393536U, 170524352U, 170655424U, 170782016U,
170917696U, 171048896U, 171179072U, 171310784U, 171439936U, 171573184U,
171702976U, 171835072U, 171966272U, 172097216U, 172228288U, 172359232U,
172489664U, 172621376U, 172747712U, 172883264U, 173014208U, 173144512U,
173275072U, 173407424U, 173539136U, 173669696U, 173800768U, 173931712U,
174063424U, 174193472U, 174325696U, 174455744U, 174586816U, 174718912U,
174849728U, 174977728U, 175109696U, 175242688U, 175374272U, 175504832U,
175636288U, 175765696U, 175898432U, 176028992U, 176159936U, 176291264U,
176422592U, 176552512U, 176684864U, 176815424U, 176946496U, 177076544U,
177209152U, 177340096U, 177470528U, 177600704U, 177731648U, 177864256U,
177994816U, 178126528U, 178257472U, 178387648U, 178518464U, 178650176U,
178781888U, 178912064U, 179044288U, 179174848U, 179305024U, 179436736U,
179568448U, 179698496U, 179830208U, 179960512U, 180092608U, 180223808U,
180354752U, 180485696U, 180617152U, 180748096U, 180877504U, 181009984U,
181139264U, 181272512U, 181402688U, 181532608U, 181663168U, 181795136U,
181926592U, 182057536U, 182190016U, 182320192U, 182451904U, 182582336U,
182713792U, 182843072U, 182976064U, 183107264U, 183237056U, 183368384U,
183494848U, 183631424U, 183762752U, 183893824U, 184024768U, 184154816U,
184286656U, 184417984U, 184548928U, 184680128U, 184810816U, 184941248U,
185072704U, 185203904U, 185335616U, 185465408U, 185596352U, 185727296U,
185859904U, 185989696U, 186121664U, 186252992U, 186383552U, 186514112U,
186645952U, 186777152U, 186907328U, 187037504U, 187170112U, 187301824U,
187429184U, 187562048U, 187693504U, 187825472U, 187957184U, 188087104U,
188218304U, 188349376U, 188481344U, 188609728U, 188743616U, 188874304U,
189005248U, 189136448U, 189265088U, 189396544U, 189528128U, 189660992U,
189791936U, 189923264U, 190054208U, 190182848U, 190315072U, 190447424U,
190577984U, 190709312U, 190840768U, 190971328U, 191102656U, 191233472U,
191364032U, 191495872U, 191626816U, 191758016U, 191888192U, 192020288U,
192148928U, 192282176U, 192413504U, 192542528U, 192674752U, 192805952U,
192937792U, 193068608U, 193198912U, 193330496U, 193462208U, 193592384U,
193723456U, 193854272U, 193985984U, 194116672U, 194247232U, 194379712U,
194508352U, 194641856U, 194772544U, 194900672U, 195035072U, 195166016U,
195296704U, 195428032U, 195558592U, 195690304U, 195818176U, 195952576U,
196083392U, 196214336U, 196345792U, 196476736U, 196607552U, 196739008U,
196869952U, 197000768U, 197130688U, 197262784U, 197394368U, 197523904U,
197656384U, 197787584U, 197916608U, 198049472U, 198180544U, 198310208U,
198442432U, 198573632U, 198705088U, 198834368U, 198967232U, 199097792U,
199228352U, 199360192U, 199491392U, 199621696U, 199751744U, 199883968U,
200014016U, 200146624U, 200276672U, 200408128U, 200540096U, 200671168U,
200801984U, 200933312U, 201062464U, 201194944U, 201326144U, 201457472U,
201588544U, 201719744U, 201850816U, 201981632U, 202111552U, 202244032U,
202374464U, 202505152U, 202636352U, 202767808U, 202898368U, 203030336U,
203159872U, 203292608U, 203423296U, 203553472U, 203685824U, 203816896U,
203947712U, 204078272U, 204208192U, 204341056U, 204472256U, 204603328U,
204733888U, 204864448U, 204996544U, 205125568U, 205258304U, 205388864U,
205517632U, 205650112U, 205782208U, 205913536U, 206044736U, 206176192U,
206307008U, 206434496U, 206569024U, 206700224U, 206831168U, 206961856U,
207093056U, 207223616U, 207355328U, 207486784U, 207616832U, 207749056U,
207879104U, 208010048U, 208141888U, 208273216U, 208404032U, 208534336U,
208666048U, 208796864U, 208927424U, 209059264U, 209189824U, 209321792U,
209451584U, 209582656U, 209715136U, 209845568U, 209976896U, 210106432U,
210239296U, 210370112U, 210501568U, 210630976U, 210763712U, 210894272U,
211024832U, 211156672U, 211287616U, 211418176U, 211549376U, 211679296U,
211812032U, 211942592U, 212074432U, 212204864U, 212334016U, 212467648U,
212597824U, 212727616U, 212860352U, 212991424U, 213120832U, 213253952U,
213385024U, 213515584U, 213645632U, 213777728U, 213909184U, 214040128U,
214170688U, 214302656U, 214433728U, 214564544U, 214695232U, 214826048U,
214956992U, 215089088U, 215219776U, 215350592U, 215482304U, 215613248U,
215743552U, 215874752U, 216005312U, 216137024U, 216267328U, 216399296U,
216530752U, 216661696U, 216790592U, 216923968U, 217054528U, 217183168U,
217316672U, 217448128U, 217579072U, 217709504U, 217838912U, 217972672U,
218102848U, 218233024U, 218364736U, 218496832U, 218627776U, 218759104U,
218888896U, 219021248U, 219151936U, 219281728U, 219413056U, 219545024U,
219675968U, 219807296U, 219938624U, 220069312U, 220200128U, 220331456U,
220461632U, 220592704U, 220725184U, 220855744U, 220987072U, 221117888U,
221249216U, 221378368U, 221510336U, 221642048U, 221772736U, 221904832U,
222031808U, 222166976U, 222297536U, 222428992U, 222559936U, 222690368U,
222820672U, 222953152U, 223083968U, 223213376U, 223345984U, 223476928U,
223608512U, 223738688U, 223869376U, 224001472U, 224132672U, 224262848U,
224394944U, 224524864U, 224657344U, 224788288U, 224919488U, 225050432U,
225181504U, 225312704U, 225443776U, 225574592U, 225704768U, 225834176U,
225966784U, 226097216U, 226229824U, 226360384U, 226491712U, 226623424U,
226754368U, 226885312U, 227015104U, 227147456U, 227278528U, 227409472U,
227539904U, 227669696U, 227802944U, 227932352U, 228065216U, 228196288U,
228326464U, 228457792U, 228588736U, 228720064U, 228850112U, 228981056U,
229113152U, 229243328U, 229375936U, 229505344U, 229636928U, 229769152U,
229894976U, 230030272U, 230162368U, 230292416U, 230424512U, 230553152U,
230684864U, 230816704U, 230948416U, 231079616U, 231210944U, 231342016U,
231472448U, 231603776U, 231733952U, 231866176U, 231996736U, 232127296U,
232259392U, 232388672U, 232521664U, 232652608U, 232782272U, 232914496U,
233043904U, 233175616U, 233306816U, 233438528U, 233569984U, 233699776U,
233830592U, 233962688U, 234092224U, 234221888U, 234353984U, 234485312U,
234618304U, 234749888U, 234880832U, 235011776U, 235142464U, 235274048U,
235403456U, 235535936U, 235667392U, 235797568U, 235928768U, 236057152U,
236190272U, 236322752U, 236453312U, 236583616U, 236715712U, 236846528U,
236976448U, 237108544U, 237239104U, 237371072U, 237501632U, 237630784U,
237764416U, 237895232U, 238026688U, 238157632U, 238286912U, 238419392U,
238548032U, 238681024U, 238812608U, 238941632U, 239075008U, 239206336U,
239335232U, 239466944U, 239599168U, 239730496U, 239861312U, 239992384U,
240122816U, 240254656U, 240385856U, 240516928U, 240647872U, 240779072U,
240909632U, 241040704U, 241171904U, 241302848U, 241433408U, 241565248U,
241696192U, 241825984U, 241958848U, 242088256U, 242220224U, 242352064U,
242481856U, 242611648U, 242744896U, 242876224U, 243005632U, 243138496U,
243268672U, 243400384U, 243531712U, 243662656U, 243793856U, 243924544U,
244054592U, 244187072U, 244316608U, 244448704U, 244580032U, 244710976U,
244841536U, 244972864U, 245104448U, 245233984U, 245365312U, 245497792U,
245628736U, 245759936U, 245889856U, 246021056U, 246152512U, 246284224U,
246415168U, 246545344U, 246675904U, 246808384U, 246939584U, 247070144U,
247199552U, 247331648U, 247463872U, 247593536U, 247726016U, 247857088U,
247987648U, 248116928U, 248249536U, 248380736U, 248512064U, 248643008U,
248773312U, 248901056U, 249036608U, 249167552U, 249298624U, 249429184U,
249560512U, 249692096U, 249822784U, 249954112U, 250085312U, 250215488U,
250345792U, 250478528U, 250608704U, 250739264U, 250870976U, 251002816U,
251133632U, 251263552U, 251395136U, 251523904U, 251657792U, 251789248U,
251919424U, 252051392U, 252182464U, 252313408U, 252444224U, 252575552U,
252706624U, 252836032U, 252968512U, 253099712U, 253227584U, 253361728U,
253493056U, 253623488U, 253754432U, 253885504U, 254017216U, 254148032U,
254279488U, 254410432U, 254541376U, 254672576U, 254803264U, 254933824U,
255065792U, 255196736U, 255326528U, 255458752U, 255589952U, 255721408U,
255851072U, 255983296U, 256114624U, 256244416U, 256374208U, 256507712U,
256636096U, 256768832U, 256900544U, 257031616U, 257162176U, 257294272U,
257424448U, 257555776U, 257686976U, 257818432U, 257949632U, 258079552U,
258211136U, 258342464U, 258473408U, 258603712U, 258734656U, 258867008U,
258996544U, 259127744U, 259260224U, 259391296U, 259522112U, 259651904U,
259784384U, 259915328U, 260045888U, 260175424U, 260308544U, 260438336U,
260570944U, 260700992U, 260832448U, 260963776U, 261092672U, 261226304U,
261356864U, 261487936U, 261619648U, 261750592U, 261879872U, 262011968U,
262143424U, 262274752U, 262404416U, 262537024U, 262667968U, 262799296U,
262928704U, 263061184U, 263191744U, 263322944U, 263454656U, 263585216U,
263716672U, 263847872U, 263978944U, 264108608U, 264241088U, 264371648U,
264501184U, 264632768U, 264764096U, 264895936U, 265024576U, 265158464U,
265287488U, 265418432U, 265550528U, 265681216U, 265813312U, 265943488U,
266075968U, 266206144U, 266337728U, 266468032U, 266600384U, 266731072U,
266862272U, 266993344U, 267124288U, 267255616U, 267386432U, 267516992U,
267648704U, 267777728U, 267910592U, 268040512U, 268172096U, 268302784U,
268435264U, 268566208U, 268696256U, 268828096U, 268959296U, 269090368U,
269221312U, 269352256U, 269482688U, 269614784U, 269745856U, 269876416U,
270007616U, 270139328U, 270270272U, 270401216U, 270531904U, 270663616U,
270791744U, 270924736U, 271056832U, 271186112U, 271317184U, 271449536U,
271580992U, 271711936U, 271843136U, 271973056U, 272105408U, 272236352U,
272367296U, 272498368U, 272629568U, 272759488U, 272891456U, 273022784U,
273153856U, 273284672U, 273415616U, 273547072U, 273677632U, 273808448U,
273937088U, 274071488U, 274200896U, 274332992U, 274463296U, 274595392U,
274726208U, 274857536U, 274988992U, 275118656U, 275250496U, 275382208U,
275513024U, 275643968U, 275775296U, 275906368U, 276037184U, 276167872U,
276297664U, 276429376U, 276560576U, 276692672U, 276822976U, 276955072U,
277085632U, 277216832U, 277347008U, 277478848U, 277609664U, 277740992U,
277868608U, 278002624U, 278134336U, 278265536U, 278395328U, 278526784U,
278657728U, 278789824U, 278921152U, 279052096U, 279182912U, 279313088U,
279443776U, 279576256U, 279706048U, 279838528U, 279969728U, 280099648U,
280230976U, 280361408U, 280493632U, 280622528U, 280755392U, 280887104U,
281018176U, 281147968U, 281278912U, 281411392U, 281542592U, 281673152U,
281803712U, 281935552U, 282066496U, 282197312U, 282329024U, 282458816U,
282590272U, 282720832U, 282853184U, 282983744U, 283115072U, 283246144U,
283377344U, 283508416U, 283639744U, 283770304U, 283901504U, 284032576U,
284163136U, 284294848U, 284426176U, 284556992U, 284687296U, 284819264U,
284950208U, 285081536U
};
#ifdef __cplusplus
}
#endif

Some files were not shown because too many files have changed in this diff Show more