Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow building and loading of TBBBind on macOS #1132

Merged
merged 2 commits into from
Aug 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 1 addition & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,6 @@ if (NOT BUILD_SHARED_LIBS)
message(WARNING "You are building oneTBB as a static library. This is highly discouraged and such configuration is not supported. Consider building a dynamic library to avoid unforeseen issues.")
endif()

# Prevent searching HWLOC by pkg-config on macOS
if (APPLE)
set(TBB_DISABLE_HWLOC_AUTOMATIC_SEARCH ON)
endif()

if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Build type" FORCE)
message(STATUS "CMAKE_BUILD_TYPE is not specified. Using default: ${CMAKE_BUILD_TYPE}")
Expand Down Expand Up @@ -244,7 +239,7 @@ else()
add_subdirectory(src/tbbmalloc_proxy)
endif()
endif()
if (APPLE OR NOT BUILD_SHARED_LIBS)
if (NOT BUILD_SHARED_LIBS)
message(STATUS "TBBBind build targets are disabled due to unsupported environment")
else()
add_subdirectory(src/tbbbind)
Expand Down
3 changes: 3 additions & 0 deletions include/oneapi/tbb/detail/_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,9 @@
#define __TBB_ARENA_BINDING 1
#endif

// Thread pinning is not available on macOS*
#define __TBB_CPUBIND_PRESENT (__TBB_ARENA_BINDING && !__APPLE__)
pavelkumbrasev marked this conversation as resolved.
Show resolved Hide resolved

#ifndef __TBB_ENQUEUE_ENFORCED_CONCURRENCY
#define __TBB_ENQUEUE_ENFORCED_CONCURRENCY 1
#endif
Expand Down
4 changes: 2 additions & 2 deletions src/tbb/arena.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -543,10 +543,10 @@ void task_arena_impl::initialize(d1::task_arena_base& ta) {
threading_control* thr_control = threading_control::register_public_reference();
arena& a = arena::create(thr_control, unsigned(ta.my_max_concurrency), ta.my_num_reserved_slots, priority_level);
ta.my_arena.store(&a, std::memory_order_release);
#if __TBB_ARENA_BINDING
#if __TBB_CPUBIND_PRESENT
pavelkumbrasev marked this conversation as resolved.
Show resolved Hide resolved
a.my_numa_binding_observer = construct_binding_observer(
static_cast<d1::task_arena*>(&ta), a.my_num_slots, ta.my_numa_id, ta.core_type(), ta.max_threads_per_core());
#endif /*__TBB_ARENA_BINDING*/
#endif /*__TBB_CPUBIND_PRESENT*/
}

void task_arena_impl::terminate(d1::task_arena_base& ta) {
Expand Down
2 changes: 1 addition & 1 deletion src/tbb/arena.h
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ struct arena_base : padded<intrusive_list_node> {

#if __TBB_ARENA_BINDING
//! Pointer to internal observer that allows to bind threads in arena to certain NUMA node.
numa_binding_observer* my_numa_binding_observer;
numa_binding_observer* my_numa_binding_observer{nullptr};
#endif /*__TBB_ARENA_BINDING*/

// Below are rarely modified members
Expand Down
12 changes: 9 additions & 3 deletions src/tbb/governor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -372,15 +372,18 @@ static void (*restore_affinity_ptr)( binding_handler* handler_ptr, int slot_num
int (*get_default_concurrency_ptr)( int numa_id, int core_type_id, int max_threads_per_core )
= dummy_get_default_concurrency;

#if _WIN32 || _WIN64 || __unix__
#if _WIN32 || _WIN64 || __unix__ || __APPLE__

// Table describing how to link the handlers.
static const dynamic_link_descriptor TbbBindLinkTable[] = {
DLD(__TBB_internal_initialize_system_topology, initialize_system_topology_ptr),
DLD(__TBB_internal_destroy_system_topology, destroy_system_topology_ptr),
#if __TBB_CPUBIND_PRESENT
DLD(__TBB_internal_allocate_binding_handler, allocate_binding_handler_ptr),
DLD(__TBB_internal_deallocate_binding_handler, deallocate_binding_handler_ptr),
DLD(__TBB_internal_apply_affinity, apply_affinity_ptr),
DLD(__TBB_internal_restore_affinity, restore_affinity_ptr),
#endif
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can it be dynamically understood that tbbbind does not have all symbols and "bind"-related symbols are just not set upon loading of tbbbind?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dynamic_link functionality guarantees that either all of requested symbols are loaded, or none of them, if something is missing. Thus, we shouldn't expect hwloc's cpubind related symbols here in the first place.

DLD(__TBB_internal_get_default_concurrency, get_default_concurrency_ptr)
};

Expand All @@ -395,6 +398,9 @@ static const unsigned LinkTableSize = sizeof(TbbBindLinkTable) / sizeof(dynamic_
#if _WIN32 || _WIN64
#define LIBRARY_EXTENSION ".dll"
#define LIBRARY_PREFIX
#elif __APPLE__
#define LIBRARY_EXTENSION __TBB_STRING(.3.dylib)
#define LIBRARY_PREFIX "lib"
#elif __unix__
#define LIBRARY_EXTENSION __TBB_STRING(.so.3)
#define LIBRARY_PREFIX "lib"
Expand Down Expand Up @@ -423,7 +429,7 @@ int core_types_count = 0;
int* core_types_indexes = nullptr;

const char* load_tbbbind_shared_object() {
#if _WIN32 || _WIN64 || __unix__
#if _WIN32 || _WIN64 || __unix__ || __APPLE__
#if _WIN32 && !_WIN64
// For 32-bit Windows applications, process affinity masks can only support up to 32 logical CPUs.
SYSTEM_INFO si;
Expand All @@ -435,7 +441,7 @@ const char* load_tbbbind_shared_object() {
return tbbbind_version;
}
}
#endif /* _WIN32 || _WIN64 || __unix__ */
#endif /* _WIN32 || _WIN64 || __unix__ || __APPLE__ */
return nullptr;
}

Expand Down
18 changes: 18 additions & 0 deletions src/tbbbind/def/mac64-tbbbind.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright (c) 2023 Intel Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

___TBB_internal_initialize_system_topology
___TBB_internal_get_default_concurrency
___TBB_internal_destroy_system_topology

7 changes: 6 additions & 1 deletion src/tbbbind/tbb_bind.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (c) 2019-2021 Intel Corporation
Copyright (c) 2019-2023 Intel Corporation

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -104,6 +104,7 @@ class system_topology {
if ( initialization_state != topology_loaded )
return;

#if __TBB_CPUBIND_PRESENT
// Getting process affinity mask
if ( intergroup_binding_allowed(groups_num) ) {
process_cpu_affinity_mask = hwloc_bitmap_dup(hwloc_topology_get_complete_cpuset (topology));
Expand All @@ -115,6 +116,10 @@ class system_topology {
assertion_hwloc_wrapper(hwloc_get_cpubind, topology, process_cpu_affinity_mask, 0);
hwloc_cpuset_to_nodeset(topology, process_cpu_affinity_mask, process_node_affinity_mask);
}
#else
process_cpu_affinity_mask = hwloc_bitmap_dup(hwloc_topology_get_complete_cpuset (topology));
process_node_affinity_mask = hwloc_bitmap_dup(hwloc_topology_get_complete_nodeset(topology));
#endif

number_of_processors_groups = groups_num;
}
Expand Down
11 changes: 10 additions & 1 deletion test/common/common_arena_constraints.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (c) 2019-2022 Intel Corporation
Copyright (c) 2019-2023 Intel Corporation

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -89,6 +89,7 @@ int get_processors_group_count() { return 1; }
#define __HWLOC_HYBRID_CPUS_INTERFACES_VALID (!_WIN32 || _WIN64)

#define __HYBRID_CPUS_TESTING __HWLOC_HYBRID_CPUS_INTERFACES_PRESENT && __HWLOC_HYBRID_CPUS_INTERFACES_VALID
#define __HWLOC_CPUBIND_PRESENT (!__APPLE__)

// Macro to check hwloc interfaces return codes
#define hwloc_require_ex(command, ...) \
Expand Down Expand Up @@ -179,12 +180,16 @@ class system_info {
#endif
hwloc_require_ex(hwloc_topology_load, topology);

#if __HWLOC_CPUBIND_PRESENT
if ( get_processors_group_count() > 1 ) {
process_cpuset = hwloc_bitmap_dup(hwloc_topology_get_complete_cpuset(topology));
} else {
process_cpuset = hwloc_bitmap_alloc();
hwloc_require_ex(hwloc_get_cpubind, topology, process_cpuset, 0);
}
#else
process_cpuset = hwloc_bitmap_dup(hwloc_topology_get_complete_cpuset(topology));
#endif

hwloc_obj_t current_numa_node = nullptr;
index_info current_node_info{};
Expand Down Expand Up @@ -349,7 +354,11 @@ class system_info {
static affinity_mask allocate_current_affinity_mask() {
affinity_mask result = hwloc_bitmap_alloc();
instance().memory_handler.insert(result);
#if __HWLOC_CPUBIND_PRESENT
hwloc_require_ex(hwloc_get_cpubind, instance().topology, result, HWLOC_CPUBIND_THREAD);
#else
hwloc_bitmap_copy(result, hwloc_topology_get_complete_cpuset(instance().topology));
#endif
REQUIRE_MESSAGE(!hwloc_bitmap_iszero(result), "Empty current affinity mask.");
return result;
}
Expand Down
6 changes: 3 additions & 3 deletions test/tbb/test_arena_constraints.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (c) 2019-2022 Intel Corporation
Copyright (c) 2019-2023 Intel Corporation

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -21,7 +21,7 @@

#include "tbb/parallel_for.h"

#if __TBB_HWLOC_VALID_ENVIRONMENT
#if __TBB_HWLOC_VALID_ENVIRONMENT && __HWLOC_CPUBIND_PRESENT
//! Test affinity and default_concurrency correctness for all available constraints.
//! \brief \ref error_guessing
TEST_CASE("Test affinity and default_concurrency correctness for all available constraints.") {
Expand Down Expand Up @@ -87,7 +87,7 @@ TEST_CASE("Test constraints propagation during arenas copy construction") {
test_constraints_affinity_and_concurrency(constraints, copied_affinity);
}
}
#endif /*__TBB_HWLOC_VALID_ENVIRONMENT*/
#endif /*__TBB_HWLOC_VALID_ENVIRONMENT && __HWLOC_CPUBIND_PRESENT */

// The test cannot be stabilized with TBB malloc under Thread Sanitizer
#if !__TBB_USE_THREAD_SANITIZER
Expand Down
Loading