diff --git a/.github/workflows/basic.yml b/.github/workflows/basic.yml index b5ce1e948..736f08eef 100644 --- a/.github/workflows/basic.yml +++ b/.github/workflows/basic.yml @@ -23,6 +23,8 @@ jobs: shared_library: ['OFF'] level_zero_provider: ['ON'] install_tbb: ['ON'] + disable_hwloc: ['OFF'] + link_hwloc_statically: ['OFF'] include: - os: 'ubuntu-20.04' build_type: Release @@ -69,6 +71,20 @@ jobs: shared_library: 'ON' level_zero_provider: 'ON' install_tbb: 'OFF' + - os: 'ubuntu-22.04' + build_type: Debug + compiler: {c: gcc, cxx: g++} + shared_library: 'ON' + level_zero_provider: 'ON' + install_tbb: 'ON' + disable_hwloc: 'ON' + - os: 'ubuntu-22.04' + build_type: Release + compiler: {c: gcc, cxx: g++} + shared_library: 'ON' + level_zero_provider: 'ON' + install_tbb: 'ON' + link_hwloc_statically: 'ON' runs-on: ${{matrix.os}} steps: @@ -122,6 +138,8 @@ jobs: -DUMF_BUILD_LIBUMF_POOL_JEMALLOC=ON -DUMF_BUILD_LIBUMF_POOL_DISJOINT=ON -DUMF_TESTS_FAIL_ON_SKIP=ON + -DUMF_DISABLE_HWLOC=${{matrix.disable_hwloc}} + -DUMF_LINK_HWLOC_STATICALLY=${{matrix.link_hwloc_statically}} - name: Build UMF run: cmake --build ${{env.BUILD_DIR}} -j $(nproc) @@ -144,7 +162,7 @@ jobs: --build-type ${{matrix.build_type}} --disjoint-pool --jemalloc-pool - ${{ matrix.install_tbb == 'ON' && '--proxy' || '' }} + ${{ matrix.install_tbb == 'ON' && matrix.disable_hwloc != 'ON' && matrix.link_hwloc_statically != 'ON' && '--proxy' || '' }} --umf-version ${{env.UMF_VERSION}} ${{ matrix.shared_library == 'ON' && '--shared-library' || '' }} diff --git a/.github/workflows/sanitizers.yml b/.github/workflows/sanitizers.yml index 06ad492eb..4b4b37aaf 100644 --- a/.github/workflows/sanitizers.yml +++ b/.github/workflows/sanitizers.yml @@ -72,9 +72,7 @@ jobs: working-directory: ${{env.BUILD_DIR}} run: > ${{ matrix.compiler.cxx == 'icpx' && '. /opt/intel/oneapi/setvars.sh &&' || ''}} - GTEST_FILTER="-*umfProviderTest.alloc_page64_align_0*" ctest --output-on-failure - # TO DO: fix umf-provider_os_memory test for sanitizers - # issue 581: https://github.com/oneapi-src/unified-memory-framework/issues/581 + ctest --output-on-failure windows-build: name: cl and clang-cl on Windows diff --git a/CMakeLists.txt b/CMakeLists.txt index e84a45097..2e4f7ab1b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,8 @@ cmake_minimum_required(VERSION 3.14.0 FATAL_ERROR) set(UMF_CMAKE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) list(APPEND CMAKE_MODULE_PATH "${UMF_CMAKE_SOURCE_DIR}/cmake") -include(helpers) +# Use full path of the helpers module (to omit potential conflicts with others) +include(${UMF_CMAKE_SOURCE_DIR}/cmake/helpers.cmake) # We use semver aligned version, set via git tags. We parse git output to # establih the version of UMF to be used in CMake, Win dll's, and within the @@ -47,8 +48,10 @@ option(UMF_BUILD_EXAMPLES "Build UMF examples" ON) option(UMF_BUILD_FUZZTESTS "Build UMF fuzz tests" OFF) option(UMF_BUILD_GPU_EXAMPLES "Build UMF GPU examples" OFF) option(UMF_DEVELOPER_MODE "Enable additional developer checks" OFF) -option(UMF_LINK_HWLOC_STATICALLY - "Link UMF with HWLOC library statically (Windows+Release only)" OFF) +option( + UMF_LINK_HWLOC_STATICALLY + "Link UMF with HWLOC library statically (supported for Linux, MacOS and Release build on Windows)" + OFF) option(UMF_FORMAT_CODE_STYLE "Add clang, cmake, and black -format-check and -format-apply targets" OFF) @@ -60,6 +63,10 @@ option(USE_TSAN "Enable ThreadSanitizer checks" OFF) option(USE_MSAN "Enable MemorySanitizer checks" OFF) option(USE_VALGRIND "Enable Valgrind instrumentation" OFF) option(USE_GCOV "Enable gcov support" OFF) +option( + UMF_DISABLE_HWLOC + "Disable features that requires hwloc (OS provider, memory targets, topolgy discovery)" + OFF) # set UMF_PROXY_LIB_BASED_ON_POOL to one of: SCALABLE or JEMALLOC set(KNOWN_PROXY_LIB_POOLS SCALABLE JEMALLOC) @@ -93,27 +100,42 @@ else() message(FATAL_ERROR "Unknown OS type") endif() +if(NOT DEFINED UMF_HWLOC_REPO) + set(UMF_HWLOC_REPO "https://github.com/open-mpi/hwloc.git") +endif() + +if(NOT DEFINED UMF_HWLOC_TAG) + set(UMF_HWLOC_TAG hwloc-2.10.0) +endif() + if(NOT UMF_LINK_HWLOC_STATICALLY) - pkg_check_modules(LIBHWLOC hwloc>=2.3.0) - if(NOT LIBHWLOC_FOUND) - find_package(LIBHWLOC 2.3.0 REQUIRED hwloc) + if(NOT UMF_DISABLE_HWLOC) + pkg_check_modules(LIBHWLOC hwloc>=2.3.0) + if(NOT LIBHWLOC_FOUND) + find_package(LIBHWLOC 2.3.0 REQUIRED hwloc) + endif() + + # add PATH to DLL on Windows + set(DLL_PATH_LIST + "${DLL_PATH_LIST};PATH=path_list_append:${LIBHWLOC_LIBRARY_DIRS}/../bin" + ) endif() # add PATH to DLL on Windows set(DLL_PATH_LIST "${DLL_PATH_LIST};PATH=path_list_append:${LIBHWLOC_LIBRARY_DIRS}/../bin" ) -else() - if(NOT WINDOWS) - message(FATAL_ERROR "hwloc can be statically linked only on Windows") - endif() +elseif(WINDOWS AND NOT UMF_DISABLE_HWLOC) include(FetchContent) set(HWLOC_ENABLE_TESTING OFF) set(HWLOC_SKIP_LSTOPO ON) set(HWLOC_SKIP_TOOLS ON) + + message(STATUS "Will fetch hwloc from ${UMF_HWLOC_REPO}") + FetchContent_Declare( hwloc_targ - GIT_REPOSITORY "https://github.com/open-mpi/hwloc.git" - GIT_TAG hwloc-2.10.0 + GIT_REPOSITORY ${UMF_HWLOC_REPO} + GIT_TAG ${UMF_HWLOC_TAG} SOURCE_SUBDIR contrib/windows-cmake/ FIND_PACKAGE_ARGS) FetchContent_GetProperties(hwloc_targ) @@ -126,6 +148,57 @@ else() set(LIBHWLOC_LIBRARY_DIRS ${hwloc_targ_BINARY_DIR}/Release;${hwloc_targ_BINARY_DIR}/Debug) + message(STATUS " LIBHWLOC_LIBRARIES = ${LIBHWLOC_LIBRARIES}") + message(STATUS " LIBHWLOC_INCLUDE_DIRS = ${LIBHWLOC_INCLUDE_DIRS}") + message(STATUS " LIBHWLOC_LIBRARY_DIRS = ${LIBHWLOC_LIBRARY_DIRS}") +elseif(NOT UMF_DISABLE_HWLOC) + include(FetchContent) + message(STATUS "Will fetch hwloc from ${UMF_HWLOC_REPO}") + + FetchContent_Declare( + hwloc_targ + GIT_REPOSITORY ${UMF_HWLOC_REPO} + GIT_TAG ${UMF_HWLOC_TAG}) + + FetchContent_GetProperties(hwloc_targ) + if(NOT hwloc_targ_POPULATED) + FetchContent_MakeAvailable(hwloc_targ) + endif() + + add_custom_command( + COMMAND ./autogen.sh + WORKING_DIRECTORY ${hwloc_targ_SOURCE_DIR} + OUTPUT ${hwloc_targ_SOURCE_DIR}/configure) + add_custom_command( + COMMAND + ./configure --prefix=${hwloc_targ_BINARY_DIR} --enable-static=yes + --enable-shared=no --disable-libxml2 --disable-levelzero + CFLAGS=-fPIC CXXFLAGS=-fPIC + WORKING_DIRECTORY ${hwloc_targ_SOURCE_DIR} + OUTPUT ${hwloc_targ_SOURCE_DIR}/Makefile + DEPENDS ${hwloc_targ_SOURCE_DIR}/configure) + add_custom_command( + COMMAND make + WORKING_DIRECTORY ${hwloc_targ_SOURCE_DIR} + OUTPUT ${hwloc_targ_SOURCE_DIR}/lib/libhwloc.la + DEPENDS ${hwloc_targ_SOURCE_DIR}/Makefile) + add_custom_command( + COMMAND make install + WORKING_DIRECTORY ${hwloc_targ_SOURCE_DIR} + OUTPUT ${hwloc_targ_BINARY_DIR}/lib/libhwloc.a + DEPENDS ${hwloc_targ_SOURCE_DIR}/lib/libhwloc.la) + + add_custom_target(hwloc_prod + DEPENDS ${hwloc_targ_BINARY_DIR}/lib/libhwloc.a) + add_library(hwloc INTERFACE) + target_link_libraries(hwloc + INTERFACE ${hwloc_targ_BINARY_DIR}/lib/libhwloc.a) + add_dependencies(hwloc hwloc_prod) + + set(LIBHWLOC_LIBRARY_DIRS ${hwloc_targ_BINARY_DIR}/lib) + set(LIBHWLOC_INCLUDE_DIRS ${hwloc_targ_BINARY_DIR}/include) + set(LIBHWLOC_LIBRARIES ${hwloc_targ_BINARY_DIR}/lib/libhwloc.a) + message(STATUS " LIBHWLOC_LIBRARIES = ${LIBHWLOC_LIBRARIES}") message(STATUS " LIBHWLOC_INCLUDE_DIRS = ${LIBHWLOC_INCLUDE_DIRS}") message(STATUS " LIBHWLOC_LIBRARY_DIRS = ${LIBHWLOC_LIBRARY_DIRS}") @@ -317,6 +390,18 @@ else() ) endif() +set(UMF_OPTIONAL_SYMBOLS_LINUX "") +set(UMF_OPTIONAL_SYMBOLS_WINDOWS "") + +# Conditional configuration for Level Zero provider +if(UMF_BUILD_LEVEL_ZERO_PROVIDER) + add_optional_symbol(umfLevelZeroMemoryProviderOps) +endif() + +if(NOT UMF_DISABLE_HWLOC) + add_optional_symbol(umfOsMemoryProviderOps) +endif() + add_subdirectory(src) if(UMF_BUILD_TESTS) @@ -328,20 +413,13 @@ if(UMF_BUILD_BENCHMARKS) endif() if(UMF_BUILD_EXAMPLES) - add_subdirectory(examples) -endif() - -# Conditional configuration for Level Zero provider -if(UMF_BUILD_LEVEL_ZERO_PROVIDER) - set(OPTIONAL_SYMBOLS "umfLevelZeroMemoryProviderOps") -else() - set(OPTIONAL_SYMBOLS "") + if(NOT UMF_DISABLE_HWLOC) + add_subdirectory(examples) + else() + message(WARNING "Examples cannot be build - hwloc disabled") + endif() endif() -# Configure the DEF file based on whether Level Zero provider is built -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/libumf.def.in" - "${CMAKE_CURRENT_BINARY_DIR}/src/libumf.def" @ONLY) - if(UMF_FORMAT_CODE_STYLE) find_program(CLANG_FORMAT NAMES clang-format-15 clang-format-15.0 clang-format) @@ -522,8 +600,10 @@ endif() # Configure make install/uninstall and packages # --------------------------------------------------------------------------- # install(FILES ${CMAKE_SOURCE_DIR}/LICENSE.TXT - ${CMAKE_SOURCE_DIR}/third-party-programs.txt DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/doc/${PROJECT_NAME}/") +install( + FILES ${CMAKE_SOURCE_DIR}/licensing/third-party-programs.txt + DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/doc/${PROJECT_NAME}/licensing/") install(DIRECTORY examples DESTINATION "${CMAKE_INSTALL_DOCDIR}") diff --git a/cmake/helpers.cmake b/cmake/helpers.cmake index bb9b703d8..a4f59a763 100644 --- a/cmake/helpers.cmake +++ b/cmake/helpers.cmake @@ -176,14 +176,33 @@ function(get_program_version_major_minor name ret) PARENT_SCOPE) endfunction() +# Checks compiler for given ${flag}, stores the output in C_HAS_${flag} and +# CXX_HAS_${flag} (if compiler supports C++) +function(check_compilers_flag flag) + check_c_compiler_flag("${flag}" "C_HAS_${flag}") + if(CMAKE_CXX_COMPILE_FEATURES) + check_cxx_compiler_flag("${flag}" "CXX_HAS_${flag}") + endif() +endfunction() + +function(check_add_target_compile_options target) + foreach(option ${ARGN}) + check_compilers_flag(${option}) + if(C_HAS_${option} AND CXX_HAS_${option}) + target_compile_options(${target} PRIVATE ${option}) + endif() + endforeach() +endfunction() + function(add_umf_target_compile_options name) + check_add_target_compile_options(${name} "-Wno-covered-switch-default") + if(NOT MSVC) target_compile_options( ${name} PRIVATE -fPIC -Wall -Wextra - -Werror -Wpedantic -Wempty-body -Wunused-parameter @@ -213,7 +232,6 @@ function(add_umf_target_compile_options name) /analyze /DYNAMICBASE /W4 - /WX /Gy /GS # disable warning 6326: Potential comparison of a constant @@ -399,3 +417,12 @@ macro(add_sanitizer_flag flag) set(CMAKE_REQUIRED_FLAGS ${SAVED_CMAKE_REQUIRED_FLAGS}) endmacro() + +function(add_optional_symbol symbol) + set(UMF_OPTIONAL_SYMBOLS_WINDOWS + "${UMF_OPTIONAL_SYMBOLS_WINDOWS} \n ${symbol}" + PARENT_SCOPE) + set(UMF_OPTIONAL_SYMBOLS_LINUX + "${UMF_OPTIONAL_SYMBOLS_LINUX} \n ${symbol};" + PARENT_SCOPE) +endfunction() diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index ac0b3168c..918dc2809 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -18,7 +18,7 @@ set(EXAMPLE_NAME umf_example_basic) add_umf_executable( NAME ${EXAMPLE_NAME} SRCS basic/basic.c - LIBS umf hwloc) + LIBS umf ${LIBHWLOC_LIBRARIES}) target_include_directories( ${EXAMPLE_NAME} PRIVATE ${UMF_CMAKE_SOURCE_DIR}/src/utils diff --git a/third-party-programs.txt b/licensing/third-party-programs.txt similarity index 100% rename from third-party-programs.txt rename to licensing/third-party-programs.txt diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c261ac6ed..6a1e1d475 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -61,6 +61,8 @@ set(BA_SOURCES ${BA_SOURCES} PARENT_SCOPE) +set(HWLOC_DEPENDENT_SOURCES topology.c) + set(UMF_SOURCES ${BA_SOURCES} libumf.c @@ -74,8 +76,11 @@ set(UMF_SOURCES provider/provider_tracking.c critnib/critnib.c pool/pool_proxy.c - pool/pool_scalable.c - topology.c) + pool/pool_scalable.c) + +if(NOT UMF_DISABLE_HWLOC) + set(UMF_SOURCES ${UMF_SOURCES} ${HWLOC_DEPENDENT_SOURCES}) +endif() set(UMF_SOURCES_LINUX libumf_linux.c) @@ -93,16 +98,43 @@ set(UMF_SOURCES_COMMON_LINUX_MACOSX memspaces/memspace_highest_bandwidth.c memspaces/memspace_lowest_latency.c) -set(UMF_SOURCES_LINUX ${UMF_SOURCES_LINUX} ${UMF_SOURCES_COMMON_LINUX_MACOSX} - provider/provider_os_memory_linux.c) +if(NOT UMF_DISABLE_HWLOC) + set(UMF_SOURCES_LINUX + ${UMF_SOURCES_LINUX} ${UMF_SOURCES_COMMON_LINUX_MACOSX} + provider/provider_os_memory_linux.c) + + set(UMF_SOURCES_MACOSX + ${UMF_SOURCES_MACOSX} ${UMF_SOURCES_COMMON_LINUX_MACOSX} + provider/provider_os_memory_macosx.c) + + set(UMF_SOURCES_WINDOWS + ${UMF_SOURCES_WINDOWS} provider/provider_os_memory.c + provider/provider_os_memory_windows.c) + + set(UMF_LIBS ${UMF_LIBS} ${LIBHWLOC_LIBRARIES}) + + if(NOT WINDOWS) + add_optional_symbol(umfMemspaceCreateFromNumaArray) + add_optional_symbol(umfMemspaceHighestBandwidthGet) + add_optional_symbol(umfMemspaceHighestCapacityGet) + add_optional_symbol(umfMemspaceHostAllGet) + add_optional_symbol(umfMemspaceLowestLatencyGet) + endif() +endif() + +if(WINDOWS) + message(STATUS "UMF_OPTIONAL_SYMBOLS: ${UMF_OPTIONAL_SYMBOLS_WINDOWS}") +else() + message(STATUS "UMF_OPTIONAL_SYMBOLS: ${UMF_OPTIONAL_SYMBOLS_LINUX}") +endif() -set(UMF_SOURCES_MACOSX ${UMF_SOURCES_MACOSX} ${UMF_SOURCES_COMMON_LINUX_MACOSX} - provider/provider_os_memory_macosx.c) +# Configure the DEF file based on whether Level Zero provider is built +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/libumf.def.in" + "${CMAKE_CURRENT_BINARY_DIR}/libumf.def" @ONLY) -set(UMF_SOURCES_WINDOWS ${UMF_SOURCES_WINDOWS} provider/provider_os_memory.c - provider/provider_os_memory_windows.c) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/libumf.map.in" + "${CMAKE_CURRENT_BINARY_DIR}/libumf.map" @ONLY) -set(UMF_LIBS ${UMF_LIBS} ${LIBHWLOC_LIBRARIES}) set(UMF_PRIVATE_LIBRARY_DIRS ${UMF_PRIVATE_LIBRARY_DIRS} ${LIBHWLOC_LIBRARY_DIRS}) @@ -121,12 +153,15 @@ elseif(MACOSX) endif() if(UMF_BUILD_SHARED_LIBRARY) + if(NOT UMF_DISABLE_HWLOC) + set(HWLOC_LIB hwloc) + endif() add_umf_library( NAME umf TYPE SHARED SRCS ${UMF_SOURCES} - LIBS ${UMF_LIBS} hwloc - LINUX_MAP_FILE ${CMAKE_CURRENT_SOURCE_DIR}/libumf.map + LIBS ${UMF_LIBS} ${HWLOC_LIB} + LINUX_MAP_FILE ${CMAKE_CURRENT_BINARY_DIR}/libumf.map WINDOWS_DEF_FILE ${CMAKE_CURRENT_BINARY_DIR}/libumf.def) set(UMF_COMMON_COMPILE_DEFINITIONS ${UMF_COMMON_COMPILE_DEFINITIONS} "UMF_SHARED_LIBRARY") @@ -143,6 +178,11 @@ else() LIBS ${UMF_LIBS}) endif() +if(UMF_DISABLE_HWLOC) + set(UMF_COMMON_COMPILE_DEFINITIONS ${UMF_COMMON_COMPILE_DEFINITIONS} + UMF_NO_HWLOC=1) +endif() + if(UMF_LINK_HWLOC_STATICALLY) add_dependencies(umf hwloc) endif() @@ -190,6 +230,8 @@ install(TARGETS umf EXPORT ${PROJECT_NAME}-targets) add_subdirectory(pool) -if(UMF_PROXY_LIB_ENABLED AND NOT UMF_LINK_HWLOC_STATICALLY) +if(UMF_PROXY_LIB_ENABLED + AND NOT UMF_LINK_HWLOC_STATICALLY + AND NOT UMF_DISABLE_HWLOC) add_subdirectory(proxy_lib) endif() diff --git a/src/base_alloc/base_alloc_global.c b/src/base_alloc/base_alloc_global.c index 003e43a03..b5660d440 100644 --- a/src/base_alloc/base_alloc_global.c +++ b/src/base_alloc/base_alloc_global.c @@ -195,14 +195,12 @@ void umf_ba_global_free(void *ptr) { int ac_index = size_to_idx(total_size); if (ac_index >= NUM_ALLOCATION_CLASSES) { - utils_annotate_memory_inaccessible(ptr, total_size); ba_os_free(ptr, total_size); return; } if (!BASE_ALLOC.ac[ac_index]) { // if creating ac failed, memory must have been allocated by os - utils_annotate_memory_inaccessible(ptr, total_size); ba_os_free(ptr, total_size); return; } diff --git a/src/base_alloc/base_alloc_linux.c b/src/base_alloc/base_alloc_linux.c index 8d07d5ab6..3e5456b2c 100644 --- a/src/base_alloc/base_alloc_linux.c +++ b/src/base_alloc/base_alloc_linux.c @@ -19,8 +19,13 @@ static UTIL_ONCE_FLAG Page_size_is_initialized = UTIL_ONCE_FLAG_INIT; static size_t Page_size; void *ba_os_alloc(size_t size) { - return mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, - -1, 0); + void *ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + // this should be unnecessary but pairs of mmap/munmap do not reset + // asan's user-poisoning flags, leading to invalid error reports + // Bug 81619: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81619 + utils_annotate_memory_defined(ptr, size); + return ptr; } void ba_os_free(void *ptr, size_t size) { diff --git a/src/libumf.c b/src/libumf.c index d11fa1637..1d99ab26a 100644 --- a/src/libumf.c +++ b/src/libumf.c @@ -12,8 +12,10 @@ #include "base_alloc_global.h" #include "memspace_internal.h" #include "provider_tracking.h" -#include "topology.h" #include "utils_log.h" +#if !defined(UMF_NO_HWLOC) +#include "topology.h" +#endif umf_memory_tracker_handle_t TRACKER = NULL; @@ -30,7 +32,7 @@ int umfInit(void) { void umfTearDown(void) { if (util_fetch_and_add64(&umfRefCount, -1) == 1) { -#ifndef _WIN32 +#if !defined(_WIN32) && !defined(UMF_NO_HWLOC) umfMemspaceHostAllDestroy(); umfMemspaceHighestCapacityDestroy(); umfMemspaceHighestBandwidthDestroy(); diff --git a/src/libumf.def.in b/src/libumf.def.in index 8ee99e024..aa78d0953 100644 --- a/src/libumf.def.in +++ b/src/libumf.def.in @@ -42,7 +42,6 @@ EXPORTS umfMempolicySetInterleavePartSize umfMemspaceDestroy umfOpenIPCHandle - umfOsMemoryProviderOps umfPoolAlignedMalloc umfPoolByPtr umfPoolCalloc @@ -59,4 +58,4 @@ EXPORTS umfProxyPoolOps umfPutIPCHandle umfScalablePoolOps - @OPTIONAL_SYMBOLS@ + @UMF_OPTIONAL_SYMBOLS_WINDOWS@ diff --git a/src/libumf.map b/src/libumf.map.in similarity index 87% rename from src/libumf.map rename to src/libumf.map.in index cb09cdb94..20031f16e 100644 --- a/src/libumf.map +++ b/src/libumf.map.in @@ -11,7 +11,6 @@ UMF_1.0 { umfFree; umfGetIPCHandle; umfGetLastFailedMemoryProvider; - umfLevelZeroMemoryProviderOps; umfMemoryTrackerGetAllocInfo; umfMemoryProviderAlloc; umfMemoryProviderAllocationMerge; @@ -35,14 +34,8 @@ UMF_1.0 { umfMempolicyDestroy; umfMempolicySetCustomSplitPartitions; umfMempolicySetInterleavePartSize; - umfMemspaceCreateFromNumaArray; umfMemspaceDestroy; - umfMemspaceHighestBandwidthGet; - umfMemspaceHighestCapacityGet; - umfMemspaceHostAllGet; - umfMemspaceLowestLatencyGet; umfOpenIPCHandle; - umfOsMemoryProviderOps; umfPoolAlignedMalloc; umfPoolByPtr; umfPoolCalloc; @@ -59,6 +52,7 @@ UMF_1.0 { umfProxyPoolOps; umfPutIPCHandle; umfScalablePoolOps; + @UMF_OPTIONAL_SYMBOLS_LINUX@ local: *; }; diff --git a/src/libumf.rc.in b/src/libumf.rc.in index 9d0677f6d..3915e0a10 100644 --- a/src/libumf.rc.in +++ b/src/libumf.rc.in @@ -9,7 +9,7 @@ #include "umf/base.h" #define UMF_VERNUMBERS @CMAKE_PROJECT_VERSION_MAJOR@,@CMAKE_PROJECT_VERSION_MINOR@,@CMAKE_PROJECT_VERSION_PATCH@,@UMF_VERSION_REVISION@ -#define UMF_VERSION "@UMF_VERSION@" +#define _UMF_VERSION "@UMF_VERSION@" #ifdef _DEBUG #define VERSION_DEBUG VS_FF_DEBUG @@ -50,12 +50,12 @@ BEGIN BEGIN VALUE "CompanyName", "Intel Corporation\0" VALUE "FileDescription", "Unified Memory Framework (UMF) library\0" - VALUE "FileVersion", UMF_VERSION "\0" + VALUE "FileVersion", _UMF_VERSION "\0" VALUE "LegalCopyright", "Copyright 2024, Intel Corporation. All rights reserved.\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "umf.dll\0" VALUE "ProductName", "Unified Memory Framework (UMF)\0" - VALUE "ProductVersion", UMF_VERSION "\0" + VALUE "ProductVersion", _UMF_VERSION "\0" VALUE "PrivateBuild", "\0" VALUE "SpecialBuild", "\0" END diff --git a/src/pool/pool_disjoint.cpp b/src/pool/pool_disjoint.cpp index d48d430ce..edb5fc649 100644 --- a/src/pool/pool_disjoint.cpp +++ b/src/pool/pool_disjoint.cpp @@ -31,6 +31,27 @@ #include "utils_math.h" #include "utils_sanitizers.h" +// Temporary solution for disabling memory poisoning. This is needed because +// AddressSanitizer does not support memory poisoning for GPU allocations. +// More info: https://github.com/oneapi-src/unified-memory-framework/issues/634 +#ifndef POISON_MEMORY +#define POISON_MEMORY 0 +#endif + +static inline void annotate_memory_inaccessible([[maybe_unused]] void *ptr, + [[maybe_unused]] size_t size) { +#if (POISON_MEMORY != 0) + utils_annotate_memory_inaccessible(ptr, size); +#endif +} + +static inline void annotate_memory_undefined([[maybe_unused]] void *ptr, + [[maybe_unused]] size_t size) { +#if (POISON_MEMORY != 0) + utils_annotate_memory_undefined(ptr, size); +#endif +} + typedef struct umf_disjoint_pool_shared_limits_t { size_t MaxSize; std::atomic TotalSize; @@ -400,7 +421,7 @@ static void *memoryProviderAlloc(umf_memory_provider_handle_t hProvider, if (ret != UMF_RESULT_SUCCESS) { throw MemoryProviderError{ret}; } - utils_annotate_memory_inaccessible(ptr, size); + annotate_memory_inaccessible(ptr, size); return ptr; } @@ -822,7 +843,7 @@ void *DisjointPool::AllocImpl::allocate(size_t Size, bool &FromPool) try { FromPool = false; if (Size > getParams().MaxPoolableSize) { Ptr = memoryProviderAlloc(getMemHandle(), Size); - utils_annotate_memory_undefined(Ptr, Size); + annotate_memory_undefined(Ptr, Size); return Ptr; } @@ -839,7 +860,7 @@ void *DisjointPool::AllocImpl::allocate(size_t Size, bool &FromPool) try { } VALGRIND_DO_MEMPOOL_ALLOC(this, Ptr, Size); - utils_annotate_memory_undefined(Ptr, Bucket.getSize()); + annotate_memory_undefined(Ptr, Bucket.getSize()); return Ptr; } catch (MemoryProviderError &e) { @@ -877,7 +898,7 @@ void *DisjointPool::AllocImpl::allocate(size_t Size, size_t Alignment, FromPool = false; if (AlignedSize > getParams().MaxPoolableSize) { Ptr = memoryProviderAlloc(getMemHandle(), Size, Alignment); - utils_annotate_memory_undefined(Ptr, Size); + annotate_memory_undefined(Ptr, Size); return Ptr; } @@ -894,8 +915,7 @@ void *DisjointPool::AllocImpl::allocate(size_t Size, size_t Alignment, } VALGRIND_DO_MEMPOOL_ALLOC(this, AlignPtrUp(Ptr, Alignment), Size); - utils_annotate_memory_undefined(AlignPtrUp(Ptr, Alignment), Size); - + annotate_memory_undefined(AlignPtrUp(Ptr, Alignment), Size); return AlignPtrUp(Ptr, Alignment); } catch (MemoryProviderError &e) { umf::getPoolLastStatusRef() = e.code; @@ -962,8 +982,7 @@ void DisjointPool::AllocImpl::deallocate(void *Ptr, bool &ToPool) { } VALGRIND_DO_MEMPOOL_FREE(this, Ptr); - utils_annotate_memory_inaccessible(Ptr, Bucket.getSize()); - + annotate_memory_inaccessible(Ptr, Bucket.getSize()); if (Bucket.getSize() <= Bucket.ChunkCutOff()) { Bucket.freeChunk(Ptr, Slab, ToPool); } else { diff --git a/src/provider/provider_os_memory.c b/src/provider/provider_os_memory.c index 4bec6d5fd..00251e53b 100644 --- a/src/provider/provider_os_memory.c +++ b/src/provider/provider_os_memory.c @@ -525,6 +525,14 @@ static umf_result_t os_initialize(void *params, void **provider) { goto err_destroy_bitmaps; } + if (os_provider->fd > 0) { + if (util_mutex_init(&os_provider->lock_fd) == NULL) { + LOG_ERR("initializing the file size lock failed"); + ret = UMF_RESULT_ERROR_UNKNOWN; + goto err_destroy_bitmaps; + } + } + os_provider->nodeset_str_buf = umf_ba_global_alloc(NODESET_STR_BUF_LEN); if (!os_provider->nodeset_str_buf) { LOG_INFO("allocating memory for printing NUMA nodes failed"); @@ -562,6 +570,10 @@ static void os_finalize(void *provider) { os_memory_provider_t *os_provider = provider; + if (os_provider->fd > 0) { + util_mutex_destroy_not_free(&os_provider->lock_fd); + } + critnib_delete(os_provider->fd_offset_map); free_bitmaps(os_provider); @@ -624,8 +636,9 @@ static inline void assert_is_page_aligned(uintptr_t ptr, size_t page_size) { static int os_mmap_aligned(void *hint_addr, size_t length, size_t alignment, size_t page_size, int prot, int flag, int fd, - size_t max_fd_size, void **out_addr, - size_t *fd_size) { + size_t max_fd_size, os_mutex_t *lock_fd, + void **out_addr, size_t *fd_size, + size_t *fd_offset) { assert(out_addr); size_t extended_length = length; @@ -638,19 +651,26 @@ static int os_mmap_aligned(void *hint_addr, size_t length, size_t alignment, extended_length += alignment; } - size_t fd_offset = 0; + *fd_offset = 0; if (fd > 0) { + if (util_mutex_lock(lock_fd)) { + LOG_ERR("locking file size failed"); + return -1; + } + if (*fd_size + extended_length > max_fd_size) { + util_mutex_unlock(lock_fd); LOG_ERR("cannot grow a file size beyond %zu", max_fd_size); return -1; } - fd_offset = *fd_size; + *fd_offset = *fd_size; *fd_size += extended_length; + util_mutex_unlock(lock_fd); } - void *ptr = os_mmap(hint_addr, extended_length, prot, flag, fd, fd_offset); + void *ptr = os_mmap(hint_addr, extended_length, prot, flag, fd, *fd_offset); if (ptr == NULL) { LOG_PDEBUG("memory mapping failed"); return -1; @@ -893,17 +913,17 @@ static umf_result_t os_alloc(void *provider, size_t size, size_t alignment, return UMF_RESULT_ERROR_INVALID_ARGUMENT; } - size_t fd_offset = os_provider->size_fd; // needed for critnib_insert() + size_t fd_offset; // needed for critnib_insert() void *addr = NULL; errno = 0; - ret = os_mmap_aligned(NULL, size, alignment, page_size, - os_provider->protection, os_provider->visibility, - os_provider->fd, os_provider->max_size_fd, &addr, - &os_provider->size_fd); + ret = os_mmap_aligned( + NULL, size, alignment, page_size, os_provider->protection, + os_provider->visibility, os_provider->fd, os_provider->max_size_fd, + &os_provider->lock_fd, &addr, &os_provider->size_fd, &fd_offset); if (ret) { - os_store_last_native_error(UMF_OS_RESULT_ERROR_ALLOC_FAILED, errno); - LOG_PERR("memory allocation failed"); + os_store_last_native_error(UMF_OS_RESULT_ERROR_ALLOC_FAILED, 0); + LOG_ERR("memory allocation failed"); return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC; } diff --git a/src/provider/provider_os_memory_internal.h b/src/provider/provider_os_memory_internal.h index 68750c6d1..81d729d27 100644 --- a/src/provider/provider_os_memory_internal.h +++ b/src/provider/provider_os_memory_internal.h @@ -13,6 +13,7 @@ #include "critnib.h" #include "umf_hwloc.h" #include "utils_common.h" +#include "utils_concurrency.h" #ifdef __cplusplus extern "C" { @@ -33,6 +34,8 @@ typedef struct os_memory_provider_t { int fd; // file descriptor for memory mapping size_t size_fd; // size of file used for memory mapping size_t max_size_fd; // maximum size of file used for memory mapping + os_mutex_t lock_fd; // lock for updating file size + // A critnib map storing (ptr, fd_offset + 1) pairs. We add 1 to fd_offset // in order to be able to store fd_offset equal 0, because // critnib_get() returns value or NULL, so a value cannot equal 0. diff --git a/src/provider/provider_os_memory_posix.c b/src/provider/provider_os_memory_posix.c index f7040c3f0..9308f6a18 100644 --- a/src/provider/provider_os_memory_posix.c +++ b/src/provider/provider_os_memory_posix.c @@ -16,6 +16,7 @@ #include "provider_os_memory_internal.h" #include "utils_log.h" +#include "utils_sanitizers.h" // maximum value of the off_t type #define OFF_T_MAX \ @@ -74,11 +75,20 @@ void *os_mmap(void *hint_addr, size_t length, int prot, int flag, int fd, if (ptr == MAP_FAILED) { return NULL; } - + // this should be unnecessary but pairs of mmap/munmap do not reset + // asan's user-poisoning flags, leading to invalid error reports + // Bug 81619: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81619 + utils_annotate_memory_defined(ptr, length); return ptr; } -int os_munmap(void *addr, size_t length) { return munmap(addr, length); } +int os_munmap(void *addr, size_t length) { + // this should be unnecessary but pairs of mmap/munmap do not reset + // asan's user-poisoning flags, leading to invalid error reports + // Bug 81619: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81619 + utils_annotate_memory_defined(addr, length); + return munmap(addr, length); +} size_t os_get_page_size(void) { return sysconf(_SC_PAGE_SIZE); } diff --git a/src/proxy_lib/proxy_lib.rc.in b/src/proxy_lib/proxy_lib.rc.in index 66910afc4..29c8b0482 100644 --- a/src/proxy_lib/proxy_lib.rc.in +++ b/src/proxy_lib/proxy_lib.rc.in @@ -9,7 +9,7 @@ #include "umf/base.h" #define UMF_VERNUMBERS @CMAKE_PROJECT_VERSION_MAJOR@,@CMAKE_PROJECT_VERSION_MINOR@,@CMAKE_PROJECT_VERSION_PATCH@,@UMF_VERSION_REVISION@ -#define UMF_VERSION "@UMF_VERSION@" +#define _UMF_VERSION "@UMF_VERSION@" #ifdef _DEBUG #define VERSION_DEBUG VS_FF_DEBUG @@ -50,12 +50,12 @@ BEGIN BEGIN VALUE "CompanyName", "Intel Corporation\0" VALUE "FileDescription", "Unified Memory Framework (UMF) proxy library\0" - VALUE "FileVersion", UMF_VERSION "\0" + VALUE "FileVersion", _UMF_VERSION "\0" VALUE "LegalCopyright", "Copyright 2024, Intel Corporation. All rights reserved.\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "umf_proxy.dll\0" VALUE "ProductName", "Unified Memory Framework (UMF)\0" - VALUE "ProductVersion", UMF_VERSION "\0" + VALUE "ProductVersion", _UMF_VERSION "\0" VALUE "PrivateBuild", "\0" VALUE "SpecialBuild", "\0" END diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 890ac5572..c77a6e326 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -152,26 +152,29 @@ endif() if(UMF_BUILD_LIBUMF_POOL_DISJOINT AND UMF_BUILD_LIBUMF_POOL_JEMALLOC - AND UMF_POOL_SCALABLE_ENABLED) + AND UMF_POOL_SCALABLE_ENABLED + AND (NOT UMF_DISABLE_HWLOC)) add_umf_test( NAME c_api_multi_pool SRCS c_api/multi_pool.c LIBS disjoint_pool jemalloc_pool ${JEMALLOC_LIBRARIES}) endif() -if(UMF_BUILD_LIBUMF_POOL_JEMALLOC) +if(UMF_BUILD_LIBUMF_POOL_JEMALLOC AND (NOT UMF_DISABLE_HWLOC)) add_umf_test( NAME jemalloc_pool SRCS pools/jemalloc_pool.cpp malloc_compliance_tests.cpp LIBS jemalloc_pool) endif() -if(UMF_POOL_SCALABLE_ENABLED) +if(UMF_POOL_SCALABLE_ENABLED AND (NOT UMF_DISABLE_HWLOC)) add_umf_test(NAME scalable_pool SRCS pools/scalable_pool.cpp malloc_compliance_tests.cpp) endif() -if(LINUX) # OS-specific functions are implemented only for Linux now +if(LINUX AND (NOT UMF_DISABLE_HWLOC)) # OS-specific functions are implemented + # only for + # Linux now if(PkgConfig_FOUND) pkg_check_modules(LIBNUMA numa) endif() @@ -262,7 +265,10 @@ add_umf_test( LIBS ${UMF_UTILS_FOR_TEST}) # tests for the proxy library -if(UMF_PROXY_LIB_ENABLED AND UMF_BUILD_SHARED_LIBRARY) +if(UMF_PROXY_LIB_ENABLED + AND UMF_BUILD_SHARED_LIBRARY + AND NOT UMF_DISABLE_HWLOC + AND NOT UMF_LINK_HWLOC_STATICALLY) add_umf_test( NAME proxy_lib_basic SRCS ${BA_SOURCES_FOR_TEST} test_proxy_lib.cpp @@ -313,22 +319,24 @@ function(add_umf_ipc_test) endfunction() if(LINUX) - build_umf_test( - NAME - ipc_os_prov_consumer - SRCS - ipc_os_prov_consumer.c - common/ipc_common.c - common/ipc_os_prov_common.c) - build_umf_test( - NAME - ipc_os_prov_producer - SRCS - ipc_os_prov_producer.c - common/ipc_common.c - common/ipc_os_prov_common.c) - add_umf_ipc_test(TEST ipc_os_prov_anon_fd) - add_umf_ipc_test(TEST ipc_os_prov_shm) + if(NOT UMF_DISABLE_HWLOC) + build_umf_test( + NAME + ipc_os_prov_consumer + SRCS + ipc_os_prov_consumer.c + common/ipc_common.c + common/ipc_os_prov_common.c) + build_umf_test( + NAME + ipc_os_prov_producer + SRCS + ipc_os_prov_producer.c + common/ipc_common.c + common/ipc_os_prov_common.c) + add_umf_ipc_test(TEST ipc_os_prov_anon_fd) + add_umf_ipc_test(TEST ipc_os_prov_shm) + endif() if(UMF_BUILD_GPU_TESTS AND UMF_BUILD_LEVEL_ZERO_PROVIDER) build_umf_test( NAME @@ -364,7 +372,8 @@ endif() if(LINUX AND UMF_BUILD_SHARED_LIBRARY - AND UMF_POOL_SCALABLE_ENABLED) + AND UMF_POOL_SCALABLE_ENABLED + AND NOT UMF_DISABLE_HWLOC) add_umf_test( NAME init_teardown SRCS test_init_teardown.c @@ -427,11 +436,13 @@ if(LINUX ) endif() - add_test( - NAME umf_standalone_examples - COMMAND - ${UMF_CMAKE_SOURCE_DIR}/test/test_examples.sh - ${UMF_CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ${CMAKE_INSTALL_PREFIX} - ${EXAMPLES} - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + if(NOT UMF_DISABLE_HWLOC) + add_test( + NAME umf_standalone_examples + COMMAND + ${UMF_CMAKE_SOURCE_DIR}/test/test_examples.sh + ${UMF_CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} + ${CMAKE_INSTALL_PREFIX} ${EXAMPLES} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + endif() endif() diff --git a/test/test_installation.py b/test/test_installation.py index 6acb4a0bc..49a382969 100644 --- a/test/test_installation.py +++ b/test/test_installation.py @@ -146,7 +146,8 @@ def _create_match_list(self) -> List[str]: examples.insert(0, "share/doc/umf/examples") share.extend(examples) share.append("share/doc/umf/LICENSE.TXT") - share.append("share/doc/umf/third-party-programs.txt") + share.append("share/doc/umf/licensing") + share.append("share/doc/umf/licensing/third-party-programs.txt") all_files = bin + include + lib + share if platform.system() == "Windows": pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy