Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
c8006a5
bazel: add --config=release and ISA coverage test
napetrov Feb 24, 2026
d9d2e59
ci: pass --config=release to bazel build :release in nightly workflows
napetrov Feb 24, 2026
09f5df2
bazel: set default --cpu=all to match Make behavior
napetrov Feb 24, 2026
05219a4
bazel: release target auto-compiles all ISAs via cfg transition
napetrov Feb 24, 2026
569c18a
bazel: fix sh_test load, release transition on headers, ISA test comm…
napetrov Feb 25, 2026
9556c46
bazel: enable DPC++ by default for release target
napetrov Feb 25, 2026
cc0f5e3
ci: explicitly disable DPC++ in release builds
napetrov Feb 25, 2026
41905f3
bazel: remove missing mkl_linkage_test.sh from exports_files
napetrov Feb 25, 2026
7790488
ci: fix bazel disk_cache path in docker nightly workflow
napetrov Feb 28, 2026
c90a914
bazel: remove manual tag from isa_coverage_test (linux-only via targe…
napetrov Mar 7, 2026
5a0a3f5
bazel: fix duplicate load of sh_test in cpp/daal/BUILD
napetrov Mar 7, 2026
1f16ffe
bazel: export mkl_linkage_test.sh in dev/bazel/tests/BUILD
napetrov Mar 7, 2026
a48eb1c
bazel: drop SSE4.2 from ISA coverage
napetrov Apr 27, 2026
9939750
bazel: document release output path
napetrov Apr 30, 2026
c79b954
ci: limit Windows Bazel release build ISA
napetrov May 25, 2026
5da8293
bazel: archive Windows DLL objects before link
napetrov May 26, 2026
75014a9
bazel: keep direct object when archiving Windows DLL inputs
napetrov May 27, 2026
6e92540
bazel: pass Windows DPC link flags after /link
napetrov May 27, 2026
45faee3
bazel: address release review comments
napetrov May 28, 2026
cf4746e
bazel: make ISA coverage test executable
napetrov May 28, 2026
9a220ba
bazel: mark Windows DPC DLL links as shared
napetrov Jun 3, 2026
a1d24f1
Merge branch 'main' into bazel-release-config
napetrov Jun 3, 2026
9e84eb3
bazel: use clang-cl DLL flag for Windows DPC links
napetrov Jun 3, 2026
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
17 changes: 17 additions & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,23 @@ test:dpc-private \
--test_tag_filters="dpc,-public"


# Configuration: 'release'
# The //:release target automatically builds all ISA variants when
# --cpu is unset (auto), and includes DPC++ libs by default.
# Use --cpu=<isa> to restrict ISAs for CI speed, or --release_dpc=false
# to disable DPC++ libs.
# bazel build //:release # CPU + DPC++, all ISAs
# bazel build //:release --release_dpc=false # CPU only, all ISAs
# bazel build //:release --cpu=avx2 # CI: avx2 only

# Configuration: 'dev'
# Fast local development build — compiles only for the host machine's
# highest ISA (auto-detected). Use this to speed up iterative builds.
# NOT suitable for release/packaging.
# bazel build //cpp/oneapi/dal:tests --config=dev
build:dev \
--cpu=auto

# On Windows, dev/bazel/toolchains/cc_toolchain_win.bzl selects the custom
# Intel oneAPI icx/icpx cc_toolchain by default (icx must be on PATH,
# typically via %ONEAPI_ROOT%\setvars.bat). To fall back to the stock
Expand Down
7 changes: 6 additions & 1 deletion .ci/pipeline/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,7 @@ jobs:
displayName: 'bazel-configure'

- script: |
bazel build :release
bazel build :release --release_dpc=false
displayName: 'release'

- script: |
Expand Down Expand Up @@ -451,6 +451,11 @@ jobs:
--test_env DALROOT
displayName: 'Check mkl symbols'

- script: |
bazel test //cpp/daal:isa_coverage_test \
--cpu=all
displayName: 'Check ISA coverage'

- script: |
echo "Cleaning Bazel cache before running example or tests"
bazel clean --expunge
Expand Down
11 changes: 8 additions & 3 deletions .github/workflows/docker-validation-nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ jobs:
mkdir -p ${{ github.workspace }}/bazel-cache

docker run \
-v ${{ github.workspace }}/bazel-cache:/bazel-disk-cache \
onedal-dev \
bazel build :release --disk_cache=/bazel-disk-cache
-v ${{ github.workspace }}/bazel-cache:/root/.cache/bazel-disk \
onedal-dev sh -c "
# Use external disk cache
echo 'build --disk_cache=/root/.cache/bazel-disk' > ~/.bazelrc
# In CI we build for avx2 only (override default "all" ISA release build).
# For a full release with all ISA variants, omit --cpu or use --cpu=all.
bazel build :release --cpu=avx2 --release_dpc=false
"
Comment on lines +82 to 85
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

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

The PR description says CI workflows were updated to build with --config=release, but this workflow was changed to bazel build :release --cpu=avx2. If the intent is to validate the new release behavior (all ISA variants) in CI, this should use the release config/behavior rather than restricting to avx2 (or update the PR description accordingly).

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The workflow intentionally uses --cpu=avx2 for faster CI (documented in the inline comment above the bazel build line). The PR description was inaccurate — updated to clarify that CI overrides the ISA to avx2 for speed, while the //:release transition handles all ISAs when cpu is unset.

9 changes: 8 additions & 1 deletion cpp/daal/BUILD
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
package(default_visibility = ["//visibility:public"])
load("@rules_shell//shell:sh_test.bzl", "sh_test")
load("@onedal//dev/bazel:dal.bzl",
"dal_test_suite",
"dal_collect_test_suites",
Expand All @@ -11,7 +12,6 @@ load("@onedal//dev/bazel:daal.bzl",
"daal_generate_version",
"daal_patch_kernel_defines",
)
load("@rules_shell//shell:sh_test.bzl", "sh_test")

daal_module(
name = "microvmlipp",
Expand Down Expand Up @@ -354,3 +354,10 @@ sh_test(
}) + ["@platforms//os:linux"],
)

sh_test(
name = "isa_coverage_test",
srcs = ["@onedal//dev/bazel/tests:isa_coverage_test.sh"],
args = ["$(location :core_dynamic)"],
data = [":core_dynamic"],
target_compatible_with = ["@platforms//os:linux"],
)
21 changes: 18 additions & 3 deletions dev/bazel/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -264,11 +264,26 @@ The most used Bazel commands are `build`, `test` and `run`.
```

## Build recipes for oneDAL
### Build release package
- On Linux:
### Build release artifacts
- To build the Bazel release artifacts, run:
```sh
bazel build //:release --verbose_failures
bazel build //:release
```
This automatically builds all required ISA variants (SSE2, AVX2, AVX-512) and includes DPC++ libraries by default.

The release tree is placed under `bazel-bin/release/daal/latest`, matching the layout of
oneDAL release directories such as `__release_lnx/daal/latest`. The main outputs are in the
same subdirectories: headers under `include`, libraries under `lib/intel64`, environment
setup under `env/vars.sh`, and pkg-config metadata under `lib/pkgconfig/onedal.pc`.

- To build for a specific CPU architecture only (useful for speeding up CI), use `--cpu`:
```sh
bazel build //:release --cpu=avx2
```
- To disable building DPC++ libraries, use `--release_dpc=false`:
```sh
bazel build //:release --release_dpc=false
```

- On Windows, run from the Visual Studio Developer Command Prompt described
above:
Expand Down
1 change: 1 addition & 0 deletions dev/bazel/cc.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ def _cc_dynamic_lib_impl(ctx):
linking_contexts = linking_contexts,
def_file = ctx.file.def_file,
user_link_flags = ctx.attr.linkopts,
is_windows = is_windows,
)
default_files = dynamic_outputs.files
if is_windows:
Expand Down
36 changes: 30 additions & 6 deletions dev/bazel/cc/link.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -227,13 +227,36 @@ def _static(owner, name, actions, cc_toolchain,

def _link(owner, name, actions, cc_toolchain,
feature_configuration, linking_contexts,
def_file=None, is_executable=False, user_link_flags=[]):
def_file=None, is_executable=False, user_link_flags=[],
is_windows=False):
unpacked_linking_context = onedal_cc_common.unpack_linking_contexts(linking_contexts)
if not is_executable and unpacked_linking_context.objects and unpacked_linking_context.pic_objects:
fail("Dynamic library {} contains non-PIC object files: {}".format(
name, unpacked_linking_context.objects))
all_objects = depset(unpacked_linking_context.pic_objects +
unpacked_linking_context.objects)
object_list = unpacked_linking_context.pic_objects + unpacked_linking_context.objects
additional_inputs = [def_file] if def_file else []
direct_user_link_flags = ["@" + def_file.path] if def_file else []

# Windows link.exe rejects response-file lines longer than 131071
# characters. Full all-ISA DPC DLLs can produce thousands of objects, so
# aggregate them into one private archive and link it whole-archive.
if is_windows and not is_executable and object_list:
direct_objects = [object_list[0]]
archived_objects = object_list[1:]
object_list = direct_objects
if archived_objects:
object_archive = _merge_static_libs(
filename = name + "_objects.lib",
actions = actions,
cc_toolchain = cc_toolchain,
feature_configuration = feature_configuration,
static_libs = archived_objects,
is_windows = True,
)
additional_inputs.append(object_archive)
direct_user_link_flags.append("/WHOLEARCHIVE:" + object_archive.path)

all_objects = depset(object_list)
compilation_outputs = cc_common.create_compilation_outputs(
objects = all_objects,
pic_objects = all_objects,
Expand Down Expand Up @@ -264,19 +287,20 @@ def _link(owner, name, actions, cc_toolchain,
linking_contexts = [linking_context],
output_type = "executable" if is_executable else "dynamic_library",
link_deps_statically = True,
user_link_flags = ["@" + def_file.path] if def_file else [],
additional_inputs = [def_file] if def_file else [],
user_link_flags = direct_user_link_flags,
additional_inputs = additional_inputs,
)
return unpacked_linking_context, linking_outputs

def _dynamic(owner, name, actions, cc_toolchain,
feature_configuration, linking_contexts,
def_file=None, user_link_flags=[]):
def_file=None, user_link_flags=[], is_windows=False):
unpacked_linking_context, linking_outputs = _link(
owner, name, actions, cc_toolchain,
feature_configuration, linking_contexts,
def_file,
user_link_flags=user_link_flags,
is_windows=is_windows,
)
library_to_link = linking_outputs.library_to_link
dynamic_lib = None
Expand Down
2 changes: 1 addition & 1 deletion dev/bazel/config/config.tpl.BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ config_setting(

config_bool_flag(
name = "release_dpc",
build_setting_default = False,
build_setting_default = True,
)

config_bool_flag(
Expand Down
3 changes: 2 additions & 1 deletion dev/bazel/tests/BUILD
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package(default_visibility = ["//visibility:public"])

exports_files([
"mkl_linkage_test.sh",
"release_structure_test.sh",
"isa_coverage_test.sh",
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

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

mkl_linkage_test.sh is no longer exported from this package, but it’s referenced as a file target from //cpp/daal: mkl_linkage_test (srcs = ["//dev/bazel/tests:mkl_linkage_test.sh"]). This will make that test (and LinuxBazel CI) fail to load the script with “no such target … mkl_linkage_test.sh”. Add mkl_linkage_test.sh back to exports_files (alongside isa_coverage_test.sh).

Suggested change
"isa_coverage_test.sh",
"isa_coverage_test.sh",
"mkl_linkage_test.sh",

Copilot uses AI. Check for mistakes.
"mkl_linkage_test.sh",
])
72 changes: 72 additions & 0 deletions dev/bazel/tests/isa_coverage_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#!/bin/sh
#===============================================================================
# Copyright contributors to the oneDAL project
#
# 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.
#===============================================================================
#
# Verifies that libonedal_core.so contains CPU dispatch symbols for all
# required ISA variants: sse2, avx2, avx512 (CpuType E0/E4/E6).
#
# Make builds the required ISA variants by default. Building via //:release
# automatically compiles all ISA variants (cfg transition on release rule).
# This test enforces that contract.

set -eu

LIB="${1:-}"
if [ -z "${LIB}" ]; then
echo "Usage: $0 <path-to-libonedal_core.so>"
exit 1
fi

if [ ! -f "${LIB}" ]; then
echo "ERROR: Library not found: ${LIB}"
exit 1
fi

if ! command -v nm >/dev/null 2>&1; then
echo "ERROR: nm not found on PATH"
exit 1
fi

PASS=0
FAIL=0

check_isa() {
cpu_type="$1" # e.g. CpuTypeE4
isa_name="$2" # e.g. avx2
count=$(nm -D --defined-only "${LIB}" | grep -c "${cpu_type}" || true)
if [ "${count}" -gt 0 ]; then
echo " OK ${isa_name} (${cpu_type}): ${count} dispatch symbols"
PASS=$((PASS + 1))
else
echo " FAIL ${isa_name} (${cpu_type}): 0 dispatch symbols found"
echo " Build via //:release (uses all ISAs via cfg transition) or pass --cpu=all"
FAIL=$((FAIL + 1))
fi
}

echo "=== ISA coverage check: $(basename "${LIB}") ==="
check_isa "CpuTypeE0" "sse2"
check_isa "CpuTypeE4" "avx2"
check_isa "CpuTypeE6" "avx512"

echo ""
if [ "${FAIL}" -gt 0 ]; then
echo "RESULT: FAILED (${FAIL} ISA(s) missing, ${PASS} present)"
exit 1
else
echo "RESULT: PASSED (all required ISA variants present)"
exit 0
fi
62 changes: 44 additions & 18 deletions dev/bazel/toolchains/cc_toolchain_config_win.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,21 @@ def _impl(ctx):
)],
)

# DPC++ links go through the icx clang-cl driver so it can add SYCL device
# runtime libraries. Keep objects/libraries before `/link`, then put
# linker-native MSVC options after it; otherwise icx can treat `/DLL` and
# `/OUT:` as driver inputs and invoke link.exe as an executable link, which
# fails with LNK1561.
dpc_linker_mode_feature = feature(
name = "dpc_linker_mode",
enabled = True,
flag_sets = [flag_set(
actions = all_link_actions + lto_index_actions,
flag_groups = [flag_group(flags = ["/link"])],
with_features = [with_feature_set(features = ["dpc++"])],
)],
)

unfiltered_compile_flags_feature = feature(
name = "unfiltered_compile_flags",
enabled = True,
Expand Down Expand Up @@ -635,13 +650,6 @@ def _impl(ctx):
)],
)

# The link tool is lld-link.exe directly (see _find_tools_icx in
# cc_toolchain_win.bzl). lld-link uses linker-native MSVC syntax:
# /OUT:<path> to name the artifact (exe or dll)
# /IMPLIB:<path> to name the DLL's import library
# /DLL to build a DLL
# These spellings also work when forwarded by icx's clang-cl driver
# (which is how the DPC++ link path uses them).
output_execpath_flags_feature = feature(
name = "output_execpath_flags",
flag_sets = [flag_set(
Expand All @@ -653,17 +661,34 @@ def _impl(ctx):
)],
)

# Non-DPC links use lld-link.exe directly (see _find_tools_icx in
# cc_toolchain_win.bzl), so they need linker-native `/DLL`. DPC++ links go
# through the icx driver; use `/LD` there so the driver itself performs
# the SYCL link as a DLL link before forwarding linker-native flags.
shared_flag_feature = feature(
name = "shared_flag",
flag_sets = [flag_set(
actions = [
ACTION_NAMES.cpp_link_dynamic_library,
ACTION_NAMES.cpp_link_nodeps_dynamic_library,
ACTION_NAMES.lto_index_for_dynamic_library,
ACTION_NAMES.lto_index_for_nodeps_dynamic_library,
],
flag_groups = [flag_group(flags = ["/DLL"])],
)],
flag_sets = [
flag_set(
actions = [
ACTION_NAMES.cpp_link_dynamic_library,
ACTION_NAMES.cpp_link_nodeps_dynamic_library,
ACTION_NAMES.lto_index_for_dynamic_library,
ACTION_NAMES.lto_index_for_nodeps_dynamic_library,
],
flag_groups = [flag_group(flags = ["/DLL"])],
with_features = [with_feature_set(not_features = ["dpc++"])],
),
flag_set(
actions = [
ACTION_NAMES.cpp_link_dynamic_library,
ACTION_NAMES.cpp_link_nodeps_dynamic_library,
ACTION_NAMES.lto_index_for_dynamic_library,
ACTION_NAMES.lto_index_for_nodeps_dynamic_library,
],
flag_groups = [flag_group(flags = ["/LD"])],
with_features = [with_feature_set(features = ["dpc++"])],
),
],
)

# --- assemble feature list ---------------------------------------------
Expand Down Expand Up @@ -712,11 +737,12 @@ def _impl(ctx):
dependency_file_feature,
compiler_input_flags_feature,
compiler_output_flags_feature,
shared_flag_feature,
output_execpath_flags_feature,
default_link_flags_feature,
library_search_directories_feature,
libraries_to_link_feature,
shared_flag_feature,
dpc_linker_mode_feature,
output_execpath_flags_feature,
user_link_flags_feature,
default_dynamic_libraries_feature,
archiver_flags_feature,
Expand Down
Loading