Skip to content

CPUArch dispatching and unified shared library #113

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

Open
wants to merge 61 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
9378b05
Initial implementation of CPUArch dispatcher and unified shared library
Alexsandruss Apr 23, 2025
d812859
Fix cpuid header
Alexsandruss Apr 23, 2025
08a272e
Remove dynamic _svs_* loading
Alexsandruss Apr 23, 2025
c7343aa
Remove tests for _svs_* loader
Alexsandruss Apr 23, 2025
56a84e7
TEMP: enable cmake verbosity options
Alexsandruss Apr 24, 2025
6cecfed
Correct instantiation macros workflow
Alexsandruss Apr 24, 2025
edd5c9b
Extend support to L2 and IP distances
Alexsandruss Apr 24, 2025
5ae4861
Revert "TEMP: enable cmake verbosity options"
Alexsandruss Apr 24, 2025
c8c9190
Extend x86_64 archs check
Alexsandruss Apr 25, 2025
43ee728
Remove pybind11 module name define
Alexsandruss Apr 25, 2025
f42bece
Linting and other fixes
Alexsandruss Apr 28, 2025
2ebee92
Enable microarch dispatcher for all build targets
Alexsandruss Apr 29, 2025
83588cf
Install archspec in all github workflows;
Alexsandruss Apr 29, 2025
27790b8
Add error message for unknown CMAKE_SYSTEM_PROCESSOR
Alexsandruss Apr 29, 2025
5fe8239
Fixes for aarch64 uArch targets list
Alexsandruss Apr 29, 2025
8980d7d
Fix license exception
Alexsandruss Apr 29, 2025
0c88c73
Add host microarch output
Alexsandruss Apr 29, 2025
9e2934c
Fix aarch64 support
Alexsandruss Apr 29, 2025
2a4ada7
Fix macOS-ARM support
Alexsandruss Apr 29, 2025
a27aa8b
Fix macOS-ARM support v2
Alexsandruss Apr 30, 2025
4c307f7
Remove unnecessary registers on ARM
Alexsandruss Apr 30, 2025
c2251dd
Change native options in last build target
Alexsandruss Apr 30, 2025
fd675dc
Change macOS-ARM check to based on brand string
Alexsandruss Apr 30, 2025
5ee411e
Align naming: cpuarch -> microarch
Alexsandruss Apr 30, 2025
085114a
Remove uArchs spec in setup.py
Alexsandruss Apr 30, 2025
a86397f
Add basic uArch python bindings;
Alexsandruss May 2, 2025
1f5f531
Restructure cpuid and uArch headers
Alexsandruss May 2, 2025
5570b82
Fix typo in m1 branch
Alexsandruss May 2, 2025
fb277e9
Update x86_64 targets
Alexsandruss May 2, 2025
e45db18
Revert "Update x86_64 targets"
Alexsandruss May 2, 2025
4dfd0ce
Add x86_64_v4 target
Alexsandruss May 6, 2025
30b2fcd
Change MICROARCH_OBJECT_FILES setting
Alexsandruss May 6, 2025
b9167b8
Change microarch Python API
Alexsandruss May 6, 2025
5360dd2
fix: make microarch compatiable with sde usecase
yuejiaointel May 7, 2025
0fbff56
fix: move dispatcher pipeline to public repo
yuejiaointel May 7, 2025
6360464
fix: add compielrs and os to test dispatcher
yuejiaointel May 7, 2025
2d594f5
fix: test x86 only
yuejiaointel May 7, 2025
bb397db
fix: test x86 only
yuejiaointel May 7, 2025
936635a
fix: use actual os name instead of self hosted runners
yuejiaointel May 7, 2025
37184df
fix: checkout erros
yuejiaointel May 7, 2025
a54d187
fix: checkout erros
yuejiaointel May 7, 2025
b3ac750
fix: add comiler matric for x86 targets as well
yuejiaointel May 7, 2025
1095355
add: add cpu name and avx support info print
yuejiaointel May 7, 2025
449d49c
fix: fix cpu info print for arm and macos
yuejiaointel May 8, 2025
687a5fd
fix: format
yuejiaointel May 8, 2025
aa5bf2b
Add microarch_info example
Alexsandruss May 8, 2025
bd4bcef
Merge dispatcher testing with SDE into build-linux pipeline
Alexsandruss May 8, 2025
658c770
Fix typo in pipeline
Alexsandruss May 8, 2025
d520b37
Add `describe` static function to `svs.microarch`and fix pipelines
Alexsandruss May 8, 2025
f3f076b
Remove merged dispatcher testing; macos pipeline fix; test_microarch.…
Alexsandruss May 8, 2025
d07fead
Fix for SDE
Alexsandruss May 8, 2025
e9ee015
Replace x86_64 base uarch (nehalem) with x86_64_v2
Alexsandruss May 12, 2025
ee2309c
Fix for base uarch flags
Alexsandruss May 12, 2025
11c6c09
Exp.: change base uarch to sandybridge
Alexsandruss May 12, 2025
9010819
Exp.: change base uarch to haswell
Alexsandruss May 13, 2025
5d639a5
Revert x86_64 base uarch changes
Alexsandruss May 13, 2025
ce48782
Change template args for DistanceImpl
Alexsandruss May 13, 2025
b1a51c5
Extend macros to correct linking
Alexsandruss May 14, 2025
74dc321
Linting
Alexsandruss May 14, 2025
aea0390
Fix for ARM platforms and correct naming
Alexsandruss May 14, 2025
e539cac
Fix for ARM platforms
Alexsandruss May 14, 2025
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
34 changes: 34 additions & 0 deletions .github/scripts/get_cpu_info.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/bin/bash
# Copyright 2025 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.

# Script to get CPU information using platform-agnostic python packages

# Install python packages if not present in the environment
if ! python -m pip show archspec > /dev/null 2>&1; then
python -m pip install archspec
fi

if ! python -m pip show py-cpuinfo > /dev/null 2>&1; then
python -m pip install py-cpuinfo
fi

# Print host microarchitecture
python -c "import archspec.cpu; \
print('Host Microarchitecture[archspec]:', archspec.cpu.host().name)"

# Print full CPU information
python -c "import pprint, cpuinfo; \
print('CPU info[py-cpuinfo]:'); \
pprint.pprint(cpuinfo.get_cpu_info(), indent=4, compact=True)"
19 changes: 19 additions & 0 deletions .github/scripts/install_sde.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/bin/bash
# Copyright 2025 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.

wget --content-disposition "https://downloadmirror.intel.com/850782/sde-external-9.53.0-2025-03-16-lin.tar.xz"
tar -xf sde-external-*-lin.tar.xz
cd sde-external-*/
echo "$PWD" >> $GITHUB_PATH
18 changes: 18 additions & 0 deletions .github/workflows/build-linux-arm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ jobs:
steps:
- uses: actions/checkout@v4

- name: Get CPU info
run: |
bash ${GITHUB_WORKSPACE}/.github/scripts/get_cpu_info.sh
- name: Configure build
working-directory: ${{ runner.temp }}
env:
Expand All @@ -70,3 +74,17 @@ jobs:
CTEST_OUTPUT_ON_FAILURE: 1
working-directory: ${{ runner.temp }}/build/tests
run: ctest -C ${{ matrix.build_type }}

- name: Build Python Bindings
env:
CXX: ${{ matrix.cxx }}
CC: ${{ matrix.cc }}
run: |
cd bindings/python
python -m pip install .
- name: Run Python Microarch Test
run: |
cd bindings/python
python -c "import svs; svs.microarch.describe()"
python -m unittest discover -p "test_microarch.py" -s .
24 changes: 24 additions & 0 deletions .github/workflows/build-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ jobs:
source /opt/intel/oneapi/setvars.sh
printenv >> $GITHUB_ENV

- name: Install Intel(R) SDE
run: source ${GITHUB_WORKSPACE}/.github/scripts/install_sde.sh

- name: Get CPU info
run: bash ${GITHUB_WORKSPACE}/.github/scripts/get_cpu_info.sh

- name: Configure build
working-directory: ${{ runner.temp }}
env:
Expand Down Expand Up @@ -86,3 +92,21 @@ jobs:
CTEST_OUTPUT_ON_FAILURE: 1
working-directory: ${{ runner.temp }}/build/examples/cpp
run: ctest -C RelWithDebugInfo

- name: Build Python Bindings
env:
CXX: ${{ matrix.cxx }}
CC: ${{ matrix.cc }}
run: |
cd bindings/python
python -m pip install .

- name: Run Python Microarch Test with SDE
run: |
cd bindings/python
for flag in nhm hsw skx clx icl; do
echo "SDE emulation: $flag"
export SDE_FLAG=$flag
sde64 -$flag -- python -c "import svs; svs.microarch.describe()"
sde64 -$flag -- python -m unittest discover -p "test_microarch.py" -s .
done
29 changes: 29 additions & 0 deletions .github/workflows/build-macos.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ jobs:
steps:
- uses: actions/checkout@v4

- name: Get CPU info
run: |
bash ${GITHUB_WORKSPACE}/.github/scripts/get_cpu_info.sh
- name: Install Compiler
run: |
echo "Installing ${{ matrix.package }}..."
Expand Down Expand Up @@ -83,3 +87,28 @@ jobs:
CTEST_OUTPUT_ON_FAILURE: 1
working-directory: ${{ runner.temp }}/build/tests
run: ctest -C ${{ matrix.build_type }}

- name: Build Python Bindings
env:
CXX: ${{ matrix.cxx }}
CC: ${{ matrix.cc }}
run: |
if [[ "${{ matrix.needs_prefix }}" == "true" ]]; then
# For non-default packages like llvm@15, get the install prefix
COMPILER_PREFIX=$(brew --prefix ${{ matrix.package }})
export CC="${COMPILER_PREFIX}/bin/${{ matrix.cc_name }}"
export CXX="${COMPILER_PREFIX}/bin/${{ matrix.cxx_name }}"
else
# For versioned GCC installs, the name is usually directly available
export CC="${{ matrix.cc_name }}"
export CXX="${{ matrix.cxx_name }}"
fi
cd bindings/python
python -m pip install .
- name: Run Python Microarch Test
run: |
cd bindings/python
python -c "import svs; svs.microarch.describe()"
python -m unittest discover -p "test_microarch.py" -s .
4 changes: 4 additions & 0 deletions .github/workflows/cibuildwheel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ jobs:
- name: Install cibuildwheel
run: python -m pip install cibuildwheel

- name: Get CPU info
run: |
bash ${GITHUB_WORKSPACE}/.github/scripts/get_cpu_info.sh

# Install inside the temporary working directory.
- name: Build Wheel
env:
Expand Down
3 changes: 3 additions & 0 deletions .licenserc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ header:
- 'THIRD-PARTY-PROGRAMS'
- '.github/renovate.json'
- 'cmake/mkl_functions'
- 'cmake/microarch_targets_aarch64'
- 'cmake/microarch_targets_aarch64_darwin'
- 'cmake/microarch_targets_x86_64'
- 'cmake/patches/tomlplusplus_v330.patch'
- 'docker/x86_64/manylinux2014/oneAPI.repo'
- 'docs/cpp/index/loader-compatibility.csv'
Expand Down
5 changes: 4 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ target_compile_options(

include("cmake/options.cmake")

include("cmake/microarch.cmake")
include("cmake/clang-tidy.cmake")
include("cmake/eve.cmake")
include("cmake/pthread.cmake")
Expand All @@ -80,6 +81,8 @@ include("cmake/toml.cmake")
##### Build Objects
#####

create_microarch_instantiations()

if(SVS_BUILD_BINARIES)
add_subdirectory(utils)
endif()
Expand Down Expand Up @@ -112,7 +115,7 @@ set(LIB_CONFIG_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/svs")

# Install headers and target information.
install(
TARGETS svs_devel svs_compile_options svs_native_options
TARGETS svs_devel svs_compile_options svs_microarch_options_base
EXPORT svs-targets
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
Expand Down
4 changes: 2 additions & 2 deletions benchmark/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ set(SHARED_LIBRARY_FILES
src/inverted/memory/executables/memory_test.cpp
)

add_library(svs_benchmark_library SHARED ${SHARED_LIBRARY_FILES})
add_library(svs_benchmark_library SHARED ${SHARED_LIBRARY_FILES} ${MICROARCH_OBJECT_FILES})
target_include_directories(svs_benchmark_library PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include)

# Minimal
Expand Down Expand Up @@ -104,7 +104,7 @@ target_link_libraries(
PUBLIC
${SVS_LIB}
svs_compile_options
svs_native_options
svs_microarch_options_base
fmt::fmt
)

Expand Down
117 changes: 20 additions & 97 deletions bindings/python/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,68 +24,9 @@ FetchContent_Declare(
)
FetchContent_MakeAvailable(pybind11)

# Try to find the Python executable.
#
# If it's given as part of the Cmake arguments given by "scikit build", then use that.
# Otherwise, fall back to using plain old "python".
# If *THAT* doesn't work, give up.
if(DEFINED PYTHON_EXECUTABLE)
set(SVS_PYTHON_EXECUTABLE "${PYTHON_EXECUTABLE}")
else()
set(SVS_PYTHON_EXECUTABLE "python")
endif()

# The micro architectures to compile for.
if(NOT DEFINED SVS_MICROARCHS)
set(SVS_MICROARCHS native)
endif()

# Include the SVS library directly.
add_subdirectory("../.." "${CMAKE_CURRENT_BINARY_DIR}/svs")

# Run the python script to get optimization flags for the desired back-ends.
#
# FLAGS_SCRIPT - Path to the Python script that will take the compiler, compiler version,
# and list of desired microarchitectures and generate optimization flags for each
# microarchitecture.
#
# FLAGS_TEXT_FILE - List of optimization flags for each architecture.
# Expected format:
# -march=arch1,-mtune=arch1
# -march=arch2,-mtune=arch2
# ...
# -march=archN,-mtune=archN
#
# The number of lines should be equal to the number of microarchitectures.
# NOTE: The entries within each line are separated by a comma on purpose to allow CMake
# to read the whole file as a List and then use string replacement on the commas to turn
# each line into a list in its own right.
#
# TEMP_JSON - JSON Manifest file describing the generated binaries. This is meant to be
# included in the Python package to allow the Python code to reason about the packaged
# libraries and select the correct one for loading.
#
set(FLAGS_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/microarch.py")
set(FLAGS_TEXT_FILE "${CMAKE_CURRENT_BINARY_DIR}/optimization_flags.txt")
set(FLAGS_MANIFEST_JSON "${CMAKE_CURRENT_BINARY_DIR}/flags_manifest.json")

execute_process(
COMMAND
${SVS_PYTHON_EXECUTABLE}
${FLAGS_SCRIPT}
${FLAGS_TEXT_FILE}
${FLAGS_MANIFEST_JSON}
--compiler ${CMAKE_CXX_COMPILER_ID}
--compiler-version ${CMAKE_CXX_COMPILER_VERSION}
--microarchitectures ${SVS_MICROARCHS}
COMMAND_ERROR_IS_FATAL ANY
)

file(STRINGS "${FLAGS_TEXT_FILE}" OPTIMIZATION_FLAGS)
message("Flags: ${OPTIMIZATION_FLAGS}")
list(LENGTH OPTIMIZATION_FLAGS OPT_FLAGS_LENGTH)
message("Length of flags: ${OPT_FLAGS_LENGTH}")

# C++ files makind up the python bindings.
set(CPP_FILES
src/allocator.cpp
Expand All @@ -98,51 +39,33 @@ set(CPP_FILES
src/svs_mkl.cpp
)

# Generate a shared library for each target microarchitecture.
foreach(MICRO OPT_FLAGS IN ZIP_LISTS SVS_MICROARCHS OPTIMIZATION_FLAGS)
set(LIB_NAME "_svs_${MICRO}")
set(LIB_NAME "_svs")
pybind11_add_module(${LIB_NAME} MODULE ${CPP_FILES} ${MICROARCH_OBJECT_FILES})
target_link_libraries(${LIB_NAME} PRIVATE pybind11::module)
target_link_libraries(${LIB_NAME} PUBLIC svs::svs)
# Dependency "fmt::fmt" obtained from "svs"
target_link_libraries(${LIB_NAME} PRIVATE svs::compile_options fmt::fmt svs::microarch_options_base)
target_include_directories(
${LIB_NAME}
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
)

pybind11_add_module(${LIB_NAME} MODULE ${CPP_FILES})
target_link_libraries(${LIB_NAME} PUBLIC svs::svs)
# Dependency "fmt::fmt" obtained from "svs"
target_link_libraries(${LIB_NAME} PRIVATE svs::compile_options fmt::fmt)
if(DEFINED SKBUILD)
install(TARGETS ${LIB_NAME} DESTINATION .)

string(REPLACE "," ";" OPT_FLAGS ${OPT_FLAGS})
message("OPT Flags: ${OPT_FLAGS}")
target_compile_options(${LIB_NAME} PRIVATE ${OPT_FLAGS})
# The extension module may need to load build or included libraries when loaded.

# Header files.
target_include_directories(
# Placing build depedencies in the package and using relative RPATHs that
# don't point outside of the package means that the built package is
# relocatable. This allows for safe binary redistribution.
set_target_properties(
${LIB_NAME}
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
PROPERTIES
INSTALL_RPATH "$ORIGIN/${CMAKE_INSTALL_LIBDIR}"
)

# Comunicate to the C++ library the desired name of the library
target_compile_options(${LIB_NAME} PRIVATE "-DSVS_MODULE_NAME=${LIB_NAME}")

# If scikit build is running the compilation process,
if(DEFINED SKBUILD)
install(TARGETS ${LIB_NAME} DESTINATION .)

# The extension module may need to load build or included libraries when loaded.

# Placing build depedencies in the package and using relative RPATHs that
# don't point outside of the package means that the built package is
# relocatable. This allows for safe binary redistribution.
set_target_properties(
${LIB_NAME}
PROPERTIES
INSTALL_RPATH "$ORIGIN/${CMAKE_INSTALL_LIBDIR}"
)
endif()
endforeach()
endif()

if(DEFINED SKBUILD)
# Install the manifest JSON file.
# This is kind of a hack to avoid the needing to explicitly move JSON file into the
# source folder of the python library.
install(FILES ${FLAGS_MANIFEST_JSON} DESTINATION .)

# Install header files.
install(
DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/include/svs"
Expand Down
Loading
Loading