463 lines
18 KiB
Python
463 lines
18 KiB
Python
"""Build definitions and rules for XNNPACK."""
|
|
|
|
load("//:emscripten.bzl", "xnnpack_emscripten_benchmark_linkopts", "xnnpack_emscripten_deps", "xnnpack_emscripten_minimal_linkopts", "xnnpack_emscripten_test_linkopts")
|
|
|
|
def xnnpack_visibility():
|
|
"""Visibility of :XNNPACK target.
|
|
|
|
All other targets have private visibility, and can not have external
|
|
dependencies.
|
|
"""
|
|
return ["//visibility:public"]
|
|
|
|
def xnnpack_min_size_copts():
|
|
"""Compiler flags for size-optimized builds."""
|
|
return ["-Os"]
|
|
|
|
def xnnpack_gcc_std_copts():
|
|
"""GCC-like compiler flags to specify language standard for C sources."""
|
|
return ["-std=c99"]
|
|
|
|
def xnnpack_msvc_std_copts():
|
|
"""MSVC compiler flags to specify language standard for C sources."""
|
|
return ["/Drestrict="]
|
|
|
|
def xnnpack_std_cxxopts():
|
|
"""Compiler flags to specify language standard for C++ sources."""
|
|
return ["-std=gnu++14"]
|
|
|
|
def xnnpack_test_deps_for_library():
|
|
"""Depencies needed for a library to use gunit."""
|
|
return ["@com_google_googletest//:gtest_main"]
|
|
|
|
def xnnpack_optional_ruy_copts():
|
|
"""Compiler flags to optionally enable Ruy benchmarks."""
|
|
return []
|
|
|
|
def xnnpack_optional_gemmlowp_copts():
|
|
"""Compiler flags to optionally enable Gemmlowp benchmarks."""
|
|
return []
|
|
|
|
def xnnpack_optional_tflite_copts():
|
|
"""Compiler flags to optionally enable TensorFlow Lite benchmarks."""
|
|
return []
|
|
|
|
def xnnpack_optional_dnnl_copts():
|
|
"""Compiler flags to optionally enable Intel DNNL benchmarks."""
|
|
return []
|
|
|
|
def xnnpack_optional_ruy_deps():
|
|
"""Optional Ruy dependencies."""
|
|
return []
|
|
|
|
def xnnpack_optional_gemmlowp_deps():
|
|
"""Optional Gemmlowp dependencies."""
|
|
return []
|
|
|
|
def xnnpack_optional_tflite_deps():
|
|
"""Optional TensorFlow Lite dependencies."""
|
|
return []
|
|
|
|
def xnnpack_optional_dnnl_deps():
|
|
"""Optional Intel DNNL dependencies."""
|
|
return []
|
|
|
|
def xnnpack_slinky_deps():
|
|
return []
|
|
|
|
def xnnpack_slinky_defines():
|
|
return []
|
|
|
|
def xnnpack_if_kleidiai_enabled(enabled = [], not_enabled = []):
|
|
return select({
|
|
"//:kleidiai_enabled": enabled,
|
|
"//conditions:default": not_enabled,
|
|
})
|
|
|
|
def xnnpack_kleidiai_defines():
|
|
return xnnpack_if_kleidiai_enabled(
|
|
enabled = ["XNN_ENABLE_KLEIDIAI=1"],
|
|
not_enabled = ["XNN_ENABLE_KLEIDIAI=0"],
|
|
)
|
|
|
|
def xnnpack_slow_benchmark_tags():
|
|
return ["manual"]
|
|
|
|
def xnnpack_cc_library(
|
|
name,
|
|
srcs = [],
|
|
x86_srcs = [],
|
|
aarch32_srcs = [],
|
|
aarch64_srcs = [],
|
|
hexagon_srcs = [],
|
|
riscv_srcs = [],
|
|
wasm_srcs = [],
|
|
wasmsimd_srcs = [],
|
|
wasmrelaxedsimd_srcs = [],
|
|
linkopts = [],
|
|
copts = [],
|
|
gcc_copts = xnnpack_gcc_std_copts(),
|
|
msvc_copts = xnnpack_msvc_std_copts(),
|
|
mingw_copts = [],
|
|
msys_copts = [],
|
|
gcc_x86_copts = [],
|
|
msvc_x86_32_copts = [],
|
|
msvc_x86_64_copts = [],
|
|
aarch32_copts = [],
|
|
aarch64_copts = [],
|
|
hexagon_copts = [],
|
|
riscv_copts = [],
|
|
wasm_copts = [],
|
|
wasmsimd_copts = [],
|
|
wasmrelaxedsimd_copts = [],
|
|
optimized_copts = ["-O2"],
|
|
hdrs = [],
|
|
defines = [],
|
|
includes = [],
|
|
deps = [],
|
|
visibility = [":__subpackages__"],
|
|
testonly = False,
|
|
**kwargs):
|
|
"""C/C++/assembly library with architecture-specific configuration.
|
|
|
|
Define a static library with architecture- and instruction-specific
|
|
source files and/or compiler flags.
|
|
|
|
Args:
|
|
name: The name of the library target to define.
|
|
srcs: The list of architecture-independent source files.
|
|
x86_srcs: The list of x86-specific source files.
|
|
aarch32_srcs: The list of AArch32-specific source files.
|
|
aarch64_srcs: The list of AArch64-specific source files.
|
|
hexagon_srcs: The list of Hexagon-specific source files.
|
|
riscv_srcs: The list of RISC-V-specific source files.
|
|
wasm_srcs: The list of WebAssembly 1.0-specific source files.
|
|
wasmsimd_srcs: The list of WebAssembly SIMD-specific source files.
|
|
wasmrelaxedsimd_srcs: The list of WebAssembly Relaxed SIMD-specific
|
|
source files.
|
|
copts: The list of compiler flags to use in all builds. -I flags for
|
|
include/ and src/ directories of XNNPACK are always prepended
|
|
before these user-specified flags.
|
|
gcc_copts: The list of compiler flags to use with GCC-like compilers.
|
|
msvc_copts: The list of compiler flags to use with MSVC compiler.
|
|
mingw_copts: The list of compiler flags to use with MinGW GCC compilers.
|
|
msys_copts: The list of compiler flags to use with MSYS (Cygwin) GCC
|
|
compilers.
|
|
gcc_x86_copts: The list of GCC-like compiler flags to use in x86 (32-bit
|
|
and 64-bit) builds.
|
|
msvc_x86_32_copts: The list of MSVC compiler flags to use in x86 (32-bit)
|
|
builds.
|
|
msvc_x86_64_copts: The list of MSVC compiler flags to use in x86 (64-bit)
|
|
builds.
|
|
aarch32_copts: The list of compiler flags to use in AArch32 builds.
|
|
aarch64_copts: The list of compiler flags to use in AArch64 builds.
|
|
hexagon_copts: The list of compiler flags to use in hexagon builds.
|
|
riscv_copts: The list of compiler flags to use in RISC-V builds.
|
|
wasm_copts: The list of compiler flags to use in WebAssembly 1.0 builds.
|
|
wasmsimd_copts: The list of compiler flags to use in WebAssembly SIMD
|
|
builds.
|
|
wasmrelaxedsimd_copts: The list of compiler flags to use in WebAssembly
|
|
Relaxed SIMD builds.
|
|
optimized_copts: The list of compiler flags to use in optimized builds.
|
|
Defaults to -O2.
|
|
hdrs: The list of header files published by this library to be textually
|
|
included by sources in dependent rules.
|
|
defines: List of predefines macros to be added to the compile line.
|
|
includes: List of include dirs to be added to the compile line.
|
|
deps: The list of other libraries to be linked.
|
|
visibility: The list of packages that can depend on this target.
|
|
testonly: If True only testonly targets (such as tests) can depend on this.
|
|
**kwargs: Other arguments to pass to the cc_library rule.
|
|
"""
|
|
native.cc_library(
|
|
name = name,
|
|
srcs = srcs + select({
|
|
"//build_config:aarch32": aarch32_srcs,
|
|
"//build_config:aarch64": aarch64_srcs,
|
|
"//build_config:riscv": riscv_srcs,
|
|
"//build_config:x86": x86_srcs,
|
|
"//build_config:emscripten_wasm": wasm_srcs,
|
|
"//build_config:emscripten_wasmsimd": wasmsimd_srcs,
|
|
"//build_config:emscripten_wasmrelaxedsimd": wasmrelaxedsimd_srcs,
|
|
"//conditions:default": [],
|
|
}),
|
|
copts = [
|
|
"-Iinclude",
|
|
"-Isrc",
|
|
] + copts + select({
|
|
"//build_config:linux_k8": gcc_x86_copts,
|
|
"//build_config:linux_arm": aarch32_copts,
|
|
"//build_config:linux_armeabi": aarch32_copts,
|
|
"//build_config:linux_armhf": aarch32_copts,
|
|
"//build_config:linux_armv7a": aarch32_copts,
|
|
"//build_config:linux_arm64": aarch64_copts,
|
|
"//build_config:macos_x86_64": gcc_x86_copts,
|
|
"//build_config:macos_x86_64_legacy": gcc_x86_copts,
|
|
"//build_config:macos_arm64": aarch64_copts,
|
|
"//build_config:windows_x86_64_clang": ["/clang:" + opt for opt in gcc_x86_copts],
|
|
"//build_config:windows_x86_64_mingw": mingw_copts + gcc_x86_copts,
|
|
"//build_config:windows_x86_64_msys": msys_copts + gcc_x86_copts,
|
|
"//build_config:windows_x86_64": msvc_x86_64_copts,
|
|
"//build_config:android_armv7": aarch32_copts,
|
|
"//build_config:android_arm64": aarch64_copts,
|
|
"//build_config:android_x86": gcc_x86_copts,
|
|
"//build_config:android_x86_64": gcc_x86_copts,
|
|
"//build_config:ios_arm64": aarch64_copts,
|
|
"//build_config:ios_arm64e": aarch64_copts,
|
|
"//build_config:ios_sim_arm64": aarch64_copts,
|
|
"//build_config:ios_x86_64": gcc_x86_copts,
|
|
"//build_config:watchos_arm64_32": aarch64_copts,
|
|
"//build_config:watchos_x86_64": gcc_x86_copts,
|
|
"//build_config:tvos_arm64": aarch64_copts,
|
|
"//build_config:tvos_x86_64": gcc_x86_copts,
|
|
"//build_config:emscripten_wasm": wasm_copts,
|
|
"//build_config:emscripten_wasmsimd": wasmsimd_copts,
|
|
"//build_config:emscripten_wasmrelaxedsimd": wasmrelaxedsimd_copts,
|
|
"//conditions:default": [],
|
|
}) + select({
|
|
"//build_config:windows_x86_64_clang": ["/clang:" + opt for opt in gcc_copts],
|
|
"//build_config:windows_x86_64_mingw": gcc_copts,
|
|
"//build_config:windows_x86_64_msys": gcc_copts,
|
|
"//build_config:windows_x86_64": msvc_copts,
|
|
"//conditions:default": gcc_copts,
|
|
}) + select({
|
|
"//:optimized_build": optimized_copts,
|
|
"//conditions:default": [],
|
|
}),
|
|
defines = defines,
|
|
deps = deps,
|
|
includes = ["include", "src"] + includes,
|
|
linkstatic = True,
|
|
linkopts = select({
|
|
"//build_config:linux_k8": ["-lpthread"],
|
|
"//build_config:linux_arm": ["-lpthread"],
|
|
"//build_config:linux_armeabi": ["-lpthread"],
|
|
"//build_config:linux_armhf": ["-lpthread"],
|
|
"//build_config:linux_armv7a": ["-lpthread"],
|
|
"//build_config:linux_arm64": ["-lpthread"],
|
|
"//build_config:android": ["-lm"],
|
|
"//conditions:default": [],
|
|
}),
|
|
textual_hdrs = hdrs,
|
|
visibility = visibility,
|
|
testonly = testonly,
|
|
**kwargs,
|
|
)
|
|
|
|
def xnnpack_cxx_library(name, copts = xnnpack_std_cxxopts(), gcc_copts = [], msvc_copts = [], **kwargs):
|
|
xnnpack_cc_library(
|
|
name,
|
|
copts = copts,
|
|
gcc_copts = gcc_copts,
|
|
msvc_copts = msvc_copts,
|
|
**kwargs
|
|
)
|
|
|
|
def xnnpack_unit_test(name, srcs, copts = [], mingw_copts = [], msys_copts = [], deps = [], tags = [], linkopts = [], defines = [], automatic = True, timeout = "short", shard_count = 1, **kwargs):
|
|
"""Unit test binary based on Google Test.
|
|
|
|
Args:
|
|
name: The name of the test target to define.
|
|
srcs: The list of source and header files.
|
|
copts: The list of additional compiler flags for the target. -I flags
|
|
for include/ and src/ directories of XNNPACK are always prepended
|
|
before these user-specified flags.
|
|
mingw_copts: The list of compiler flags to use with MinGW GCC compilers.
|
|
msys_copts: The list of compiler flags to use with MSYS (Cygwin) GCC compilers.
|
|
deps: The list of additional libraries to be linked. Google Test library
|
|
(with main() function) is always added as a dependency and does not
|
|
need to be explicitly specified.
|
|
linkopts: The list of linking options
|
|
defines: List of predefines macros to be added to the compile line.
|
|
tags: List of arbitrary text tags.
|
|
automatic: Whether to create the test or testable binary.
|
|
timeout: How long the test is expected to run before returning.
|
|
shard_count: Specifies the number of parallel shards to use to run the test.
|
|
**kwargs: Other arguments to pass to the cc_test rule.
|
|
"""
|
|
|
|
if automatic:
|
|
native.cc_test(
|
|
name = name,
|
|
srcs = srcs,
|
|
copts = xnnpack_std_cxxopts() + [
|
|
"-Iinclude",
|
|
"-Isrc",
|
|
] + select({
|
|
"//build_config:windows_x86_64_mingw": mingw_copts,
|
|
"//build_config:windows_x86_64_msys": msys_copts,
|
|
"//conditions:default": [],
|
|
}) + select({
|
|
"//build_config:windows_x86_64_clang": ["/clang:-Wno-unused-function"],
|
|
"//build_config:windows_x86_64_mingw": ["-Wno-unused-function"],
|
|
"//build_config:windows_x86_64_msys": ["-Wno-unused-function"],
|
|
"//build_config:windows_x86_64": [],
|
|
"//conditions:default": ["-Wno-unused-function"],
|
|
}) + copts,
|
|
linkopts = select({
|
|
"//build_config:emscripten": xnnpack_emscripten_test_linkopts(),
|
|
"//conditions:default": [],
|
|
}) + linkopts,
|
|
linkstatic = True,
|
|
defines = defines,
|
|
deps = [
|
|
"@com_google_googletest//:gtest_main",
|
|
] + deps + select({
|
|
"//build_config:emscripten": xnnpack_emscripten_deps(),
|
|
"//conditions:default": [],
|
|
}),
|
|
tags = tags,
|
|
timeout = timeout,
|
|
shard_count = shard_count,
|
|
**kwargs,
|
|
)
|
|
else:
|
|
native.cc_binary(
|
|
name = name,
|
|
srcs = srcs,
|
|
copts = xnnpack_std_cxxopts() + [
|
|
"-Iinclude",
|
|
"-Isrc",
|
|
] + select({
|
|
"//build_config:windows_x86_64_mingw": mingw_copts,
|
|
"//build_config:windows_x86_64_msys": msys_copts,
|
|
"//conditions:default": [],
|
|
}) + select({
|
|
"//build_config:windows_x86_64_clang": ["/clang:-Wno-unused-function"],
|
|
"//build_config:windows_x86_64_mingw": ["-Wno-unused-function"],
|
|
"//build_config:windows_x86_64_msys": ["-Wno-unused-function"],
|
|
"//build_config:windows_x86_64": [],
|
|
"//conditions:default": ["-Wno-unused-function"],
|
|
}) + copts,
|
|
linkopts = select({
|
|
"//build_config:emscripten": xnnpack_emscripten_test_linkopts(),
|
|
"//conditions:default": [],
|
|
}),
|
|
linkstatic = True,
|
|
defines = defines,
|
|
deps = [
|
|
"@com_google_googletest//:gtest_main",
|
|
] + deps + select({
|
|
"//build_config:emscripten": xnnpack_emscripten_deps(),
|
|
"//conditions:default": [],
|
|
}),
|
|
testonly = True,
|
|
tags = tags,
|
|
**kwargs,
|
|
)
|
|
|
|
def xnnpack_binary(name, srcs, copts = [], deps = [], linkopts = []):
|
|
"""Minimal binary
|
|
|
|
Args:
|
|
name: The name of the binary target to define.
|
|
srcs: The list of source and header files.
|
|
copts: The list of additional compiler flags for the target. -I flags
|
|
for include/ and src/ directories of XNNPACK are always prepended
|
|
before these user-specified flags.
|
|
deps: The list of libraries to be linked.
|
|
linkopts: The list of additional linker options
|
|
"""
|
|
native.cc_binary(
|
|
name = name,
|
|
srcs = srcs,
|
|
copts = [
|
|
"-Iinclude",
|
|
"-Isrc",
|
|
] + copts,
|
|
linkopts = select({
|
|
"//build_config:emscripten": xnnpack_emscripten_minimal_linkopts(),
|
|
"//conditions:default": [],
|
|
}) + linkopts,
|
|
linkstatic = True,
|
|
deps = deps,
|
|
)
|
|
|
|
def xnnpack_benchmark(name, srcs, copts = [], deps = [], tags = [], defines = []):
|
|
"""Microbenchmark binary based on Google Benchmark
|
|
|
|
Args:
|
|
name: The name of the binary target to define.
|
|
srcs: The list of source and header files.
|
|
copts: The list of additional compiler flags for the target. -I flags
|
|
for include/ and src/ directories of XNNPACK are always prepended
|
|
before these user-specified flags.
|
|
deps: The list of additional libraries to be linked. Google Benchmark
|
|
library is always added as a dependency and does not need to be
|
|
explicitly specified.
|
|
tags: The list of arbitrary text tags.
|
|
defines: The list of arbitrary defines tags.
|
|
"""
|
|
native.cc_test(
|
|
name = name,
|
|
srcs = srcs,
|
|
copts = xnnpack_std_cxxopts() + [
|
|
"-Iinclude",
|
|
"-Isrc",
|
|
] + select({
|
|
"//build_config:windows_x86_64_clang": ["/clang:-Wno-unused-function"],
|
|
"//build_config:windows_x86_64_mingw": ["-Wno-unused-function"],
|
|
"//build_config:windows_x86_64_msys": ["-Wno-unused-function"],
|
|
"//build_config:windows_x86_64": [],
|
|
"//conditions:default": ["-Wno-unused-function"],
|
|
}) + copts,
|
|
linkopts = select({
|
|
"//build_config:emscripten": xnnpack_emscripten_benchmark_linkopts(),
|
|
"//build_config:windows_x86_64_mingw": ["-lshlwapi"],
|
|
"//build_config:windows_x86_64_msys": ["-lshlwapi"],
|
|
"//conditions:default": [],
|
|
}),
|
|
linkstatic = True,
|
|
deps = [
|
|
"@com_google_benchmark//:benchmark",
|
|
] + deps + select({
|
|
"//build_config:emscripten": xnnpack_emscripten_deps(),
|
|
"//conditions:default": [],
|
|
}),
|
|
tags = tags,
|
|
defines = defines,
|
|
args = ["--benchmark_min_time=1x"],
|
|
)
|
|
|
|
SrcListInfo = provider("A list of source files.", fields = {"srcs": "sources"})
|
|
|
|
def _source_list_aspect_impl(_target, ctx):
|
|
srcs = []
|
|
if hasattr(ctx.rule.attr, "srcs"):
|
|
srcs += [s for src in ctx.rule.attr.srcs for s in src.files.to_list()]
|
|
transitive = [dep[SrcListInfo].srcs for dep in ctx.rule.attr.deps]
|
|
return [SrcListInfo(srcs = depset(srcs, transitive = transitive))]
|
|
|
|
source_list_aspect = aspect(
|
|
implementation = _source_list_aspect_impl,
|
|
attr_aspects = ["deps"],
|
|
)
|
|
|
|
def _transitive_source_list_rule_impl(ctx):
|
|
get_repo_name = lambda x: getattr(x, "repo_name", getattr(x, "workspace_name"))
|
|
files = [p for dep in ctx.attr.deps for p in dep[SrcListInfo].srcs.to_list() if get_repo_name(p.owner) == get_repo_name(ctx.label) and p.owner.package.startswith(ctx.label.package)]
|
|
return [DefaultInfo(files = depset(files + ctx.files.srcs))]
|
|
|
|
xnnpack_transitive_source_list = rule(
|
|
implementation = _transitive_source_list_rule_impl,
|
|
attrs = {
|
|
"deps": attr.label_list(aspects = [source_list_aspect]),
|
|
"srcs": attr.label_list(allow_files = True),
|
|
},
|
|
)
|
|
|
|
def _source_list_file_rule_impl(ctx):
|
|
output_file = ctx.actions.declare_file(ctx.label.name + ".list")
|
|
ctx.actions.write(
|
|
output = output_file,
|
|
content = "\n".join([s.path for s in ctx.files.srcs]),
|
|
)
|
|
return [DefaultInfo(files = depset([output_file]))]
|
|
|
|
xnnpack_source_list_file = rule(
|
|
implementation = _source_list_file_rule_impl,
|
|
attrs = {
|
|
"srcs": attr.label_list(allow_files = True),
|
|
},
|
|
)
|