### Basic ForkUnion Usage in C++ Source: https://github.com/ashvardanian/forkunion/blob/main/README.md A minimal C++ example demonstrating thread pool creation, task dispatching, and parallel execution of tasks and slices. ```cpp #include // `basic_pool_t` #include // `stderr` #include // `EXIT_SUCCESS` namespace fu = ashvardanian::fork_union; int main() { alignas(fu::default_alignment_k) fu::basic_pool_t pool; if (!pool.try_spawn(std::thread::hardware_concurrency())) { std::fprintf(stderr, "Failed to fork the threads\n"); return EXIT_FAILURE; } // Dispatch a callback to each thread in the pool pool.for_threads([&](std::size_t thread_index) noexcept { std::printf("Hello from thread # %zu (of %zu)\n", thread_index + 1, pool.threads_count()); }); // Execute 1000 tasks in parallel, expecting them to have comparable runtimes // and mostly co-locating subsequent tasks on the same thread. Analogous to: // // #pragma omp parallel for schedule(static) // for (int i = 0; i < 1000; ++i) { ... } // // You can also think about it as a shortcut for the `for_slices` + `for`. pool.for_n(1000, [](std::size_t task_index) noexcept { std::printf("Running task %zu of 1000\n", task_index + 1); }); pool.for_slices(1000, [](std::size_t first_index, std::size_t count) noexcept { std::printf("Running slice [%zu, %zu)\n", first_index, first_index + count); }); // Like `for_n`, but each thread greedily steals tasks, without waiting for // the others or expecting individual tasks to have same runtimes. Analogous to: // // #pragma omp parallel for schedule(dynamic, 1) // for (int i = 0; i < 3; ++i) { ... } pool.for_n_dynamic(3, [](std::size_t task_index) noexcept { std::printf("Running dynamic task %zu of 3\n", task_index + 1); }); return EXIT_SUCCESS; } ``` -------------------------------- ### Realistic ForkUnion Example with Error Handling in Rust Source: https://github.com/ashvardanian/forkunion/blob/main/README.md Shows a more practical Rust example with named threads, error handling, and dynamic task distribution. ```rust use std::error::Error; use fork_union as fu; fn heavy_math(_: usize) {} fn main() -> Result<(), Box> { let mut pool = fu::ThreadPool::try_spawn(4)?; let mut pool = fu::ThreadPool::try_named_spawn("heavy-math", 4)?; pool.for_n_dynamic(400, |prong| { heavy_math(prong.task_index); }); Ok(()) } ``` -------------------------------- ### Install Dependencies for NUMA and Huge Pages Source: https://github.com/ashvardanian/forkunion/blob/main/README.md Install necessary libraries for NUMA and Huge Pages on Linux systems. These optimizations can improve performance for memory-intensive applications. ```bash sudo apt-get -y install libnuma-dev libnuma1 # NUMA sudo apt-get -y install libhugetlbfs-dev libhugetlbfs-bin # Huge Pages sudo ln -s /usr/bin/ld.hugetlbfs /usr/share/libhugetlbfs/ld # Huge Pages linker ``` -------------------------------- ### Minimal ForkUnion Usage in Rust Source: https://github.com/ashvardanian/forkunion/blob/main/README.md A basic example demonstrating how to spawn a thread pool and execute a closure on each thread. ```rust use fork_union as fu; let mut pool = fu::spawn(2); pool.for_threads(|thread_index, colocation_index| { println!("Hello from thread # {} on colocation # {}", thread_index + 1, colocation_index + 1); }); ``` -------------------------------- ### Manage Rust Toolchains and Build Source: https://github.com/ashvardanian/forkunion/blob/main/README.md Install necessary Rust toolchains for the Alloc API and use `cargo miri` to catch Undefined Behavior (UB). Build with NUMA support on Linux and run release tests for speed. ```bash rustup toolchain install # for Alloc API cargo miri test # to catch UBs cargo build --features numa # for NUMA support on Linux cargo test --release # to run the tests fast cargo test --features numa --release # for NUMA tests on Linux ``` -------------------------------- ### Build C++ with Apple Clang on macOS Source: https://github.com/ashvardanian/forkunion/blob/main/README.md Install a specific version of LLVM using Homebrew. Configure CMake to use the installed clang++ compiler for building debug executables on macOS. ```bash brew install llvm@20 cmake -B build_debug -D CMAKE_BUILD_TYPE=Debug -D CMAKE_CXX_COMPILER=$(brew --prefix llvm@20)/bin/clang++ cmake --build build_debug --config Debug build_debug/fork_union_test_cpp20 ``` -------------------------------- ### Build C++ with LLVM Clang and OpenMP Source: https://github.com/ashvardanian/forkunion/blob/main/README.md Install LLVM Clang and the matching OpenMP library. Configure CMake to use clang++ as the C++ compiler for building debug executables. ```bash sudo apt-get install libomp-15-dev clang++-15 # OpenMP version must match Clang cmake -B build_debug -D CMAKE_BUILD_TYPE=Debug -D CMAKE_CXX_COMPILER=clang++-15 cmake --build build_debug --config Debug build_debug/fork_union_test_cpp20 ``` -------------------------------- ### Perform Static Analysis on C++ Code Source: https://github.com/ashvardanian/forkunion/blob/main/README.md Install static analysis tools like cppcheck and clang-tidy, then use CMake to run them. cppcheck detects bugs and undefined behavior, while clang-tidy suggests code improvements. ```bash sudo apt install cppcheck clang-tidy cmake --build build_debug --target cppcheck # detects bugs & undefined behavior cmake --build build_debug --target clang-tidy # suggest code improvements ``` -------------------------------- ### Detect Minimum Supported Rust Version (MSRV) Source: https://github.com/ashvardanian/forkunion/blob/main/README.md Install the `cargo-msrv` tool to automatically detect the Minimum Supported Rust Version (MSRV) for your project. Use the `--ignore-lockfile` flag if necessary. ```bash cargo +stable install cargo-msrv cargo msrv find --ignore-lockfile ``` -------------------------------- ### Shard Data Across NUMA Nodes with C++ Source: https://github.com/ashvardanian/forkunion/blob/main/README.md Dynamically shards incoming vectors across two NUMA nodes in a round-robin fashion using `std::vector` with a NUMA-aware allocator. Ensure `libnuma` is installed. ```cpp #include // `std::vector` #include // `std::span` #include // `linux_numa_allocator`, `numa_topology_t`, `linux_distributed_pool_t` #include // `simsimd_f32_cos`, `simsimd_distance_t` namespace fu = ashvardanian::fork_union; using floats_alloc_t = fu::linux_numa_allocator; constexpr std::size_t dimensions = 768; /// Matches most BERT-like models static std::vector first_half(floats_alloc_t(0)); static std::vector second_half(floats_alloc_t(1)); static fu::numa_topology_t numa_topology; static fu::linux_distributed_pool_t distributed_pool; /// Dynamically shards incoming vectors across 2 nodes in a round-robin fashion. void append(std::span vector) { bool put_in_second = first_half.size() > second_half.size(); if (put_in_second) second_half.insert(second_half.end(), vector.begin(), vector.end()); else first_half.insert(first_half.end(), vector.begin(), vector.end()); } ``` -------------------------------- ### Build and Run C++ Tests and Benchmarks Source: https://github.com/ashvardanian/forkunion/blob/main/README.md Use CMake to build the project with testing enabled and then run all tests or benchmarks. Ensure the build type is set to Release for performance-critical operations. ```bash cmake -B build_release -D CMAKE_BUILD_TYPE=Release -D BUILD_TESTING=ON cmake --build build_release --config Release -j ctest --test-dir build_release # run all tests build_release/fork_union_nbody # run the benchmarks ``` -------------------------------- ### Run N-body Simulation Benchmark (C++) Source: https://github.com/ashvardanian/forkunion/blob/main/README.md Execute the N-body simulation benchmark using the C++ implementation with ForkUnion static backend. Ensure the project is built first. ```bash cmake -B build_release -D CMAKE_BUILD_TYPE=Release cmake --build build_release --config Release time NBODY_COUNT=128 NBODY_ITERATIONS=1000000 NBODY_BACKEND=fork_union_static build_release/fork_union_nbody ``` -------------------------------- ### Run N-body Simulation Benchmark (C++) Source: https://github.com/ashvardanian/forkunion/blob/main/README.md Execute the N-body simulation benchmark using the C++ implementation with ForkUnion dynamic backend. Ensure the project is built first. ```bash time NBODY_COUNT=128 NBODY_ITERATIONS=1000000 NBODY_BACKEND=fork_union_dynamic build_release/fork_union_nbody ``` -------------------------------- ### Create C++17, C++20, C++23 Test Executables Source: https://github.com/ashvardanian/forkunion/blob/main/scripts/CMakeLists.txt This section iterates through C++ standards 17, 20, and 23 to create test executables. It sets the C++ standard, required settings, and output directory, then registers them as CTest tests and applies common script properties. ```cmake set(TEST_SOURCES test.cpp) set(CXX_STANDARDS 17 20 23) foreach (STD IN LISTS CXX_STANDARDS) # Derive a unique target name set(TGT fork_union_test_cpp${STD}) # Create the executable add_executable(${TGT} ${TEST_SOURCES}) set_target_properties( ${TGT} PROPERTIES CXX_STANDARD ${STD} CXX_STANDARD_REQUIRED ON CXX_EXTENSIONS OFF RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR} ) # register it as a CTest test add_test(NAME ${TGT} COMMAND ${TGT}) set_target_properties_for_fork_union_script(${TGT}) # Link against `libatomic` for Linux toolchains that might need it if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") if (UNIX AND NOT APPLE) target_link_libraries(${TGT} PRIVATE -latomic) endif () endif () endforeach () ``` -------------------------------- ### Higher-Level ForkUnion APIs in Rust Source: https://github.com/ashvardanian/forkunion/blob/main/README.md Demonstrates using higher-level APIs like `for_n`, `for_slices`, and `for_n_dynamic` to distribute tasks across threads. ```rust pool.for_n(100, |prong| { println!("Running task {} on thread # {}", prong.task_index + 1, prong.thread_index + 1); }); pool.for_slices(100, |prong, count| { println!("Running slice [{}, {}) on thread # {}", prong.task_index, prong.task_index + count, prong.thread_index + 1); }); pool.for_n_dynamic(100, |prong| { println!("Running task {} on thread # {}", prong.task_index + 1, prong.thread_index + 1); }); ``` -------------------------------- ### Add N-body Benchmark Executable Source: https://github.com/ashvardanian/forkunion/blob/main/scripts/CMakeLists.txt This code adds the N-body benchmark executable, sets its C++ standard to C++20, and links it to the `fork_union` library. It also includes compiler-specific configurations for OpenMP support on GCC and Clang. ```cmake add_executable(fork_union_nbody nbody.cpp) target_link_libraries(fork_union_nbody PRIVATE fork_union) set_target_properties( fork_union_nbody PROPERTIES CXX_STANDARD 20 CXX_STANDARD_REQUIRED ON CXX_EXTENSIONS OFF ) if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") message(STATUS "Enabling OpenMP for fork_union_nbody on GCC") target_compile_options(fork_union_nbody PRIVATE -fopenmp -flto -ffast-math) target_link_options(fork_union_nbody PRIVATE -fopenmp) elseif (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") find_program(BREW_EXECUTABLE brew) if (BREW_EXECUTABLE) execute_process( COMMAND ${BREW_EXECUTABLE} --prefix libomp OUTPUT_VARIABLE LIBOMP_PREFIX OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET ) if (LIBOMP_PREFIX AND EXISTS "${LIBOMP_PREFIX}/include/omp.h") message(STATUS "Enabling OpenMP for fork_union_nbody on Clang with Homebrew libomp") target_include_directories(fork_union_nbody PRIVATE ${LIBOMP_PREFIX}/include) target_link_directories(fork_union_nbody PRIVATE ${LIBOMP_PREFIX}/lib) target_compile_options(fork_union_nbody PRIVATE -Xclang -fopenmp) target_link_libraries(fork_union_nbody PRIVATE omp) else () message(STATUS "Homebrew libomp not found - OpenMP disabled for fork_union_nbody") endif () else () message(STATUS "Homebrew not found - OpenMP disabled for fork_union_nbody") endif () endif () set_target_properties_for_fork_union_script(fork_union_nbody) ``` -------------------------------- ### Composing Parallel Iterators with `map` and `filter` Source: https://github.com/ashvardanian/forkunion/blob/main/README.md Demonstrates composing parallel iterators with `filter` and `map` adaptors for chained operations, using a specified thread pool. ```rust (&data[..]) .into_par_iter() .filter(|&x| x % 2 == 0) .map(|x| x * x) .with_pool(&mut pool) .for_each(|value| { println!("Squared even: {}", value); }); ``` -------------------------------- ### Integrate ForkUnion using CMake in C++ Source: https://github.com/ashvardanian/forkunion/blob/main/README.md Use CMake to fetch and link the ForkUnion library into your C++ project. ```cmake FetchContent_Declare( fork_union GIT_REPOSITORY https://github.com/ashvardanian/fork_union GIT_TAG v2.3.1 ) FetchContent_MakeAvailable(fork_union) target_link_libraries(your_target PRIVATE fork_union::fork_union) ``` -------------------------------- ### Efficient Busy Waiting with `yield` Source: https://github.com/ashvardanian/forkunion/blob/main/README.md Replaces standard thread yielding with a cheaper micro-wait instruction to hint the CPU into a low-power state, avoiding kernel calls. ```cpp while (!has_work_to_do()) std::this_thread::yield(); ``` -------------------------------- ### Add ForkUnion Dependency to Rust Project Source: https://github.com/ashvardanian/forkunion/blob/main/README.md Add this to your Cargo.toml to include the ForkUnion library. Use the 'numa' feature for NUMA support on Linux. ```toml [dependencies] fork_union = "2.3.1" # default fork_union = { version = "2.3.1", features = ["numa"] } # with NUMA support on Linux ``` ```toml [dependencies] fork_union = { git = "https://github.com/ashvardanian/fork_union.git", branch = "main-dev" } ``` -------------------------------- ### Build and Run C++ Debug Executables Source: https://github.com/ashvardanian/forkunion/blob/main/README.md Configure CMake for a Debug build type to include debugging symbols. This allows for easier debugging with tools like GDB or VS Code. ```bash cmake -B build_debug -D CMAKE_BUILD_TYPE=Debug -D BUILD_TESTING=ON cmake --build build_debug --config Debug # build with Debug symbols build_debug/fork_union_test_cpp20 # run a single test executable ``` -------------------------------- ### Parallel Iterators with Scratch Space and `fold_with_scratch` Source: https://github.com/ashvardanian/forkunion/blob/main/README.md Utilizes `fold_with_scratch` for parallel reductions, employing cache-line aligned scratch space to prevent false sharing and contention. ```rust // Cache-line aligned wrapper to prevent false sharing let mut scratch: Vec> = (0..pool.threads()).map(|_| CacheAligned(0)).collect(); (&data[..]) .into_par_iter() .with_pool(&mut pool) .fold_with_scratch(scratch.as_mut_slice(), |acc, value, _prong| { acc.0 += *value; }); let total: usize = scratch.iter().map(|a| a.0).sum(); ``` -------------------------------- ### Concurrent Vector Search Across NUMA Nodes in C++ Source: https://github.com/ashvardanian/forkunion/blob/main/README.md Performs a concurrent search for the closest vector to a query across data sharded on NUMA nodes. It utilizes `fork_union` for thread management and synchronization. Assumes NUMA topology has been harvested and pools spawned. ```cpp /// On each NUMA node we'll synchronize the threads struct search_result_t { simsimd_distance_t best_distance {std::numeric_limits::max()}; std::size_t best_index {0}; }; inline search_result_t pick_best(search_result_t const& a, search_result_t const& b) noexcept { return a.best_distance < b.best_distance ? a : b; } /// Uses all CPU threads to search for the closest vector to the @p query. search_result_t search(std::span query) { bool const need_to_spawn_threads = distributed_pool.threads_count() == 0; if (need_to_spawn_threads) { assert(numa_topology.try_harvest() && "Failed to harvest NUMA topology"); assert(numa_topology.nodes_count() == 2 && "Expected exactly 2 NUMA nodes"); assert(distributed_pool.try_spawn(numa_topology, sizeof(search_result_t)) && "Failed to spawn NUMA pools"); } search_result_t result; fu::spin_mutex_t result_update; // ? Lighter `std::mutex` alternative w/out system calls std::size_t const total_vectors = (first_half.size() + second_half.size()) / dimensions; auto slices = distributed_pool.for_slices(total_vectors, [&](fu::colocated_prong<> first, std::size_t count) noexcept { bool const in_second = first.colocation != 0; auto const &shard = in_second ? second_half : first_half; std::size_t const shard_base = in_second ? first_half.size() / dimensions : 0; std::size_t const local_begin = first.task - shard_base; search_result_t thread_local_result; for (std::size_t i = 0; i < count; ++i) { std::size_t const local_index = local_begin + i; std::size_t const global_index = shard_base + local_index; simsimd_distance_t distance; simsimd_f32_cos(query.data(), shard.data() + local_index * dimensions, dimensions, &distance); thread_local_result = pick_best(thread_local_result, {distance, global_index}); } // ! Still synchronizing over a shared mutex for brevity. std::lock_guard lock(result_update); result = pick_best(result, thread_local_result); }); slices.join(); return result; } ``` -------------------------------- ### Parallel Iterators with Static Scheduling Source: https://github.com/ashvardanian/forkunion/blob/main/README.md Uses ForkUnion's parallel iterator API with a specified thread pool for statically shaped workloads, offering Rayon-style ergonomics without global state. ```rust use fork_union as fu; use fork_union::prelude::*; let mut pool = fu::spawn(4); let mut data: Vec = (0..1000).collect(); (&data[..]) .into_par_iter() .with_pool(&mut pool) .for_each(|value| { println!("Value: {}", value); }); ``` -------------------------------- ### Add ForkUnion as Git Submodule in C++ Source: https://github.com/ashvardanian/forkunion/blob/main/README.md Integrate ForkUnion into your C++ project by adding it as a Git submodule. ```bash git submodule add https://github.com/ashvardanian/fork_union.git extern/fork_union ``` -------------------------------- ### Set Target Properties for Fork Union Scripts Source: https://github.com/ashvardanian/forkunion/blob/main/scripts/CMakeLists.txt This function links the target to the `fork_union` library and applies compiler-specific options based on the compiler ID and build type. It enables optimizations in Release mode and sets debugging flags in non-Release modes. ```cmake function (set_target_properties_for_fork_union_script target_name) target_link_libraries(${target_name} PRIVATE fork_union) if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") # This warning annoys us by reminding, that before GCC 4.6 the ABI for passing objects aligned to ≥32-bytes was # different... but that GCC version was released in 2014, over a decade ago. target_compile_options(${target_name} PRIVATE -Wno-psabi) endif () # In release mode, enable optimizations if (CMAKE_BUILD_TYPE STREQUAL "Release") message(STATUS "Enabling optimizations for ${target_name}") target_compile_options( ${target_name} PRIVATE $<$:-O3 -march=native -mtune=native> $<$:/O2 /Ob3> ) endif () # if we're not in Release mode if (NOT CMAKE_BUILD_TYPE STREQUAL "Release") # if we're on GCC/Clang-compatible compiler and not in Release, turn on TSAN here too if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" ) # Using thread sanitizers caused all kinds of stalls on NUMA systems # ~~~ # message(STATUS "Enabling ThreadSanitizer for ${target_name}") # target_compile_options(${target_name} PRIVATE -fsanitize=undefined,thread) # target_link_options(${target_name} PRIVATE -fsanitize=undefined,thread) # ~~~ target_compile_options(${target_name} PRIVATE -g -O0) target_compile_options(${target_name} PRIVATE -fno-omit-frame-pointer) target_link_options(${target_name} PRIVATE) endif () endif () endfunction () ``` -------------------------------- ### Parallel Iterators with Dynamic Scheduling Source: https://github.com/ashvardanian/forkunion/blob/main/README.md Employs dynamic work-stealing for parallel iterators by using `with_schedule` and `DynamicScheduler` with an explicit thread pool. ```rust (&mut data[..]) .into_par_iter() .with_schedule(&mut pool, DynamicScheduler) .for_each(|value| { *value *= 2; }); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.