
Python lets you do things like ```python "these are " "one string" 'so are' "these" ``` This can be useful for breaking strings over multiple lines. It also often happens unintentionally and indicates that there are subtle errors in the code. There are a lot of variant descriptions that have implicit concatenation harmlessly due to refactors, e.g.: ```python variant("myvariant", default=True, description="this used to be" "on two lines") ``` But there are also real bugs, like this, where the author probably omitted a comma and didn't notice that `black` reformatted the implicit concatenation onto one line: ```python args = [ "--with-thing", "--with-second-thing" "--with-third-thing", ] ``` And other bugs like this, where the author probably intended to add a space, but didn't: ```python options = "${CFLAGS}" "${SPECIAL_PIC_OPTION}" ``` Some things are harmless but confusing: ```python "first part of string {0} " "second part {1}".format("zero", "one") ``` It's not broken. String concatenation happens *before* the `format()` call, and the whole string is formatted. But it sure is hard to read. Unfortunately, you can't detect this stuff with an AST pass, as implicit concatenation is done at the parsing phase. I had to detect this with grep: ```console > grep -l '^[^"]*"[^"]*" "' */package.py > grep -l "^[^']*'[^']*' '" */package.py ``` - [x] Get rid of nearly all implicit string concatenation in packages Signed-off-by: Todd Gamblin <tgamblin@llnl.gov>
163 lines
6.2 KiB
Python
163 lines
6.2 KiB
Python
# Copyright Spack Project Developers. See COPYRIGHT file for details.
|
|
#
|
|
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
|
|
|
from spack.package import *
|
|
|
|
target_arch_list = (
|
|
"armv7a",
|
|
"armv7a-hf",
|
|
"arm64-v8a",
|
|
"arm64-v8.2-a",
|
|
"x86_32",
|
|
"x86_64",
|
|
"armv8a",
|
|
"armv8.2-a",
|
|
"armv8.6-a",
|
|
"armv8r64",
|
|
"x86",
|
|
)
|
|
|
|
|
|
class Armcomputelibrary(SConsPackage):
|
|
"""The Arm Compute Library is a collection of low-level machine learning functions optimized
|
|
for Arm® Cortex®-A, Arm® Neoverse® and Arm® Mali™ GPUs architectures.
|
|
The library provides superior performance to other open source alternatives and
|
|
immediate support for new Arm® technologies e.g. SVE2."""
|
|
|
|
homepage = "https://arm-software.github.io/ComputeLibrary/latest/"
|
|
url = "https://github.com/ARM-software/ComputeLibrary/archive/refs/tags/v23.02.zip"
|
|
git = "https://github.com/ARM-software/ComputeLibrary.git"
|
|
|
|
maintainers("annop-w")
|
|
|
|
license("MIT")
|
|
|
|
version("23.02", sha256="bed1b24047ce00155e552204bc3983e86f46775414c554a34a7ece931d67ec62")
|
|
version("22.11", sha256="2f70f54d84390625222503ea38650c00c49d4b70bc86a6b9aeeebee9d243865f")
|
|
version("22.08", sha256="5d76d07406b105f0bdf74ef80263236cb03baf0ade882f2bf8446bbc239e0079")
|
|
version("22.05", sha256="8ff308448874c6b72c1ce8d9f28af41d8b47c8e5c43b8ccc069da744e3c0a421")
|
|
version("22.02", sha256="0c1fe30b24e78bf5ca313ee8a33ad95e0d2aaddf64d4518ecec6a95e4bfba6e5")
|
|
|
|
depends_on("scons@2.3:")
|
|
|
|
phases = ["build"]
|
|
|
|
variant("build_type", default="release", values=("release", "debug"), description="Build type")
|
|
variant(
|
|
"threads",
|
|
default="cppthreads",
|
|
values=("cppthreads", "openmp"),
|
|
description="Enable C++11 threads/OpenMP backend. OpenMP backend only "
|
|
"works when building with g++ and not clang++.",
|
|
)
|
|
variant(
|
|
"multi_isa",
|
|
default=False,
|
|
description="Build Multi ISA binary version of library. Note works only for armv8.2-a.",
|
|
)
|
|
variant(
|
|
"target_arch",
|
|
default="armv7a",
|
|
values=target_arch_list,
|
|
description="Target Architecture. The x86_32 and x86_64 targets can only be"
|
|
" used with neon=0 and opencl=1.",
|
|
)
|
|
variant("sve", default=False, description="Build for SVE.")
|
|
variant("sve2", default=False, description="Build for SVE2.")
|
|
variant("neon", default=True, description="Enable Arm® Neon™ support")
|
|
variant(
|
|
"experimental_dynamic_fusion",
|
|
default=False,
|
|
description="Build the experimental dynamic fusion files.",
|
|
)
|
|
variant(
|
|
"experimental_fixed_format_kernels",
|
|
default=False,
|
|
description="Enable fixed format kernels for GEMM.",
|
|
)
|
|
variant("benchmark_examples", default=False, description="Build benchmark examples programs.")
|
|
variant("validate_examples", default=False, description="Build validate examples programs.")
|
|
variant("validation_tests", default=False, description="Build validation test programs.")
|
|
variant("benchmark_tests", default=False, description="Build benchmark test programs.")
|
|
|
|
def build_args(self, spec, prefix):
|
|
args = ["-j{0}".format(make_jobs)]
|
|
|
|
if spec.satisfies("build_type=debug"):
|
|
args.append("debug=1")
|
|
elif spec.satisfies("build_type=release"):
|
|
args.append("debug=0")
|
|
|
|
if spec.satisfies("threads=openmp"):
|
|
args.append("cppthreads=0")
|
|
args.append("openmp=1")
|
|
elif spec.satisfies("threads=cppthreads"):
|
|
args.append("cppthreads=1")
|
|
args.append("openmp=0")
|
|
|
|
arch_value = spec.variants["target_arch"].value
|
|
arch_value += "-sve" if spec.variants["sve"].value else ""
|
|
arch_value += "-sve2" if spec.variants["sve2"].value else ""
|
|
args.append("arch={}".format(arch_value))
|
|
args.append("multi_isa={}".format(int(spec.variants["multi_isa"].value)))
|
|
args.append("neon={}".format(int(spec.variants["neon"].value)))
|
|
args.append(
|
|
"experimental_dynamic_fusion={}".format(
|
|
int(spec.variants["experimental_dynamic_fusion"].value)
|
|
)
|
|
)
|
|
args.append(
|
|
"experimental_fixed_format_kernels={}".format(
|
|
int(spec.variants["experimental_fixed_format_kernels"].value)
|
|
)
|
|
)
|
|
args.append("benchmark_examples={}".format(int(spec.variants["benchmark_examples"].value)))
|
|
args.append("validate_examples={}".format(int(spec.variants["validate_examples"].value)))
|
|
args.append("validation_tests={}".format(int(spec.variants["validation_tests"].value)))
|
|
args.append("benchmark_tests={}".format(int(spec.variants["benchmark_tests"].value)))
|
|
args.append("build=native")
|
|
args.append("install_dir={0}".format(prefix))
|
|
|
|
return args
|
|
|
|
def setup_build_environment(self, env):
|
|
# Spack compiler wrapper inject -mcpu flag for some targets.
|
|
# This can conflict with -march set in scons script, so override it here.
|
|
env.set("SPACK_TARGET_ARGS", "")
|
|
|
|
@property
|
|
def libs(self):
|
|
acl_libs = find_libraries(
|
|
["libarm_compute", "libarm_compute_core", "libarm_compute_graph"],
|
|
root=self.spec.prefix,
|
|
shared=True,
|
|
recursive=True,
|
|
)
|
|
return acl_libs
|
|
|
|
@property
|
|
def headers(self):
|
|
incdir = join_path(self.spec.prefix, "include")
|
|
hlist = find_all_headers(incdir)
|
|
hlist.directories = [incdir]
|
|
return hlist
|
|
|
|
@run_after("build")
|
|
def make_sym_link(self):
|
|
# oneDNN expects header and lib files for ACL in arm_compute/ and build/ directory
|
|
prefix = self.spec.prefix
|
|
symlink(join_path(prefix, "include/arm_compute"), join_path(prefix, "arm_compute"))
|
|
symlink(join_path(prefix, "lib"), join_path(prefix, "build"))
|
|
|
|
@run_after("build")
|
|
def copy_additional_header(self):
|
|
# copy some additional header files needed by oneDNN
|
|
cpuinfo_dir = "src/common/cpuinfo"
|
|
mkdirp(join_path(self.spec.prefix, cpuinfo_dir))
|
|
for f in ["CpuInfo.h", "CpuIsaInfo.h", "CpuModel.h"]:
|
|
copy(
|
|
join_path(self.stage.source_path, cpuinfo_dir, f),
|
|
join_path(self.spec.prefix, cpuinfo_dir, f),
|
|
)
|