The implementation of these methods are legacy and they are removed in favor of using the `scf::tileUsingSCF` methods as replacements. To get the latter on par with requirements of the deprecated methods, the tiling allows one to specify the maximum number of tiles to use instead of specifying the tile sizes. When tiling to `scf.forall` this specification is used to generate the `num_threads` version of the operation. A slight deviation from previous implementation is that the deprecated method always generated the `num_threads` variant of the `scf.forall` operation. Instead now this is driven by the tiling options specified. This reduces the indexing math generated when the tile sizes are specified. **Moving from `linalg::tileToForallOp` to `scf::tileUsingSCF`** ``` OpBuilder b; TilingInterface op; ArrayRef<OpFoldResult> numThreads; ArrayAttr mapping; FailureOr<ForallTilingResult> result =linalg::tileToForallOp(b, op, numThreads, mapping); ``` can be replaced by ``` scf::SCFTilingOptions options; options.setNumThreads(numThreads); options.setLoopType(scf::SCFTilingOptions::LoopType::ForallOp); options.setMapping(mapping.getValue()); /*note the difference that setMapping takes an ArrayRef<Attribute> */ FailureOr<scf::SCFTilingResult> result = scf::tileUsingSCF(b, op, options); ``` This generates the `numThreads` version of the `scf.forall` for the inter-tile loops, i.e. ``` ... = scf.forall (%arg0, %arg1) in (%nt0, %nt1) shared_outs(...) ``` **Moving from `linalg::tileToForallOpUsingTileSizes` to `scf::tileUsingSCF`** ``` OpBuilder b; TilingInterface op; ArrayRef<OpFoldResult> tileSizes; ArrayAttr mapping; FailureOr<ForallTilingResult> result =linalg::tileToForallOpUsingTileSizes(b, op, tileSizes, mapping); ``` can be replaced by ``` scf::SCFTilingOptions options; options.setTileSizes(tileSizes); options.setLoopType(scf::SCFTilingOptions::LoopType::ForallOp); options.setMapping(mapping.getValue()); /*note the difference that setMapping takes an ArrayRef<Attribute> */ FailureOr<scf::SCFTilingResult> result = scf::tileUsingSCF(b, op, options); ``` Also note that `linalg::tileToForallOpUsingTileSizes` would effectively call the `linalg::tileToForallOp` by computing the `numThreads` from the `op` and `tileSizes` and generate the `numThreads` version of the `scf.forall`. That is not the case anymore. Instead this will directly generate the `tileSizes` version of the `scf.forall` op ``` ... = scf.forall(%arg0, %arg1) = (%lb0, %lb1) to (%ub0, %ub1) step(%step0, %step1) shared_outs(...) ``` If you actually want to use the `numThreads` version, it is upto the caller to compute the `numThreads` and set `options.setNumThreads` instead of `options.setTileSizes`. Note that there is a slight difference in the num threads version and tile size version. The former requires an additional `affine.max` on the tile size to ensure non-negative tile sizes. When lowering to `numThreads` version this `affine.max` is not needed since by construction the tile sizes are non-negative. In previous implementations, the `numThreads` version generated when using the `linalg::tileToForallOpUsingTileSizes` method would avoid generating the `affine.max` operation. To get the same state, downstream users will have to additionally normalize the `scf.forall` operation. **Changes to `transform.structured.tile_using_forall`** The transform dialect op that called into `linalg::tileToForallOp` and `linalg::tileToForallOpUsingTileSizes` have been modified to call `scf::tileUsingSCF`. The transform dialect op always generates the `numThreads` version of the `scf.forall` op. So when `tile_sizes` are specified for the transform dialect op, first the `tile_sizes` version of the `scf.forall` is generated by the `scf::tileUsingSCF` method which is then further normalized to get back to the same state. So there is no functional change to `transform.structured.tile_using_forall`. It always generates the `numThreads` version of the `scf.forall` op (as it did before this change). --------- Signed-off-by: MaheshRavishankar <mahesh.ravishankar@gmail.com>
Introduction
Warning The Bazel build is experimental and best-effort, supported in line with the policy for LLVM's peripheral support tier. LLVM's official build system is CMake. If in doubt use that. If you make changes to LLVM, you're expected to update the CMake build but you don't need to update Bazel build files. Reviewers should not ask authors to update Bazel build files unless the author has opted in to support Bazel. Keeping the Bazel build files up-to-date is on the people who use the Bazel build.
Bazel is a multi-language build system focused on reproducible builds to enable dependency analysis and caching for fast incremental builds.
The main motivation behind the existence of an LLVM Bazel build is that a number of projects that depend on LLVM use Bazel, and Bazel works best when it knows about the whole source tree (as opposed to installing artifacts coming from another build system). Community members are also welcome to use Bazel for their own development as long as they continue to maintain the official CMake build system. See also, the proposal for adding this configuration.
Quick Start
git clone https://github.com/llvm/llvm-project.git; cd llvm-projectif you don't have a checkout yet.- Install Bazel at the version indicated by .bazelversion,
following the official instructions, if you don't have it installed yet:
https://docs.bazel.build/versions/main/install.html.
- You can also install and use bazelisk which automates downloading the proper bazel version
cd utils/bazel- The
bazel buildcommand depends on the local compiler you want to use.- For clang, go to step 5.
- For gcc or MSVC, go to step 6
- If you are using clang, it is expected that lld is also available.
The
--config=generic_clangflag by default sets the compiler to beclangbinary on thePATH.To provide a specific path to yourbazel build --config=generic_clang @llvm-project//...clang, use the--repo_envBazel flag. For example:bazel build --config=generic_clang --repo_env=CC=/usr/bin/clang --repo_env=CXX=/usr/bin/clang++ @llvm-project//... - If you are using gcc or MSVC, instead of
--config=generic_clang, pass--config=generic_gccor--config=generic_msvc, which sets the compiler to begccbinary on thePATH.To provide a specific path to yourbazel build --config=generic_gcc @llvm-project//...gcc, use the--repo_envBazel flag. For example:bazel build --config=generic_gcc --repo_env=CC=/usr/bin/gcc --repo_env=CXX=/usr/bin/g++ @llvm-project//...
Configuration
The repository .bazelrc will import user-specific settings from a
user.bazelrc file (in addition to the standard locations). Adding your typical
config setting is recommended.
build --config=generic_clang
You can enable disk caching, which will cache build results
build --disk_cache=~/.cache/bazel-disk-cache
You can instruct Bazel to use a ramdisk for its sandboxing operations via --sandbox_base, which can help avoid IO bottlenecks for the symlink strategy used for sandboxing. This is especially important with many inputs and many cores (see https://github.com/bazelbuild/bazel/issues/11868):
build --sandbox_base=/dev/shm
Bear in mind that this requires that your ramdisk is of sufficient size to hold any temporary files. Anecdotally, 1GB should be sufficient.
Coverage
The LLVM, MLIR, and Clang subprojects have configurations for Linux (Clang and GCC), Mac (Clang and GCC), and Windows (MSVC). Configuration options that are platform-specific are selected for in defines. Many are also hardcoded to the values currently used by all supported configurations. If there is a configuration you'd like to use that isn't supported, please send a patch.
Continuous Testing
A Buildkite pipeline runs the full Bazel build on every commit to the main branch. Notifications of failures are sent to the llvm-bazel-alerts google group, which anyone is free to join. Currently, the behavior is just to send an email on each failure using Buildkite's built-in notification system, so if you subscribe, it is highly recommended that you set up email filters or some other mechanism to not flood your inbox. More sophisticated notifications, e.g. only on status change or routed based on blamelist are TODO (contributions welcome).
Usage in Downstream Projects
To use in dependent projects using Bazel, you can import LLVM and then use the
provided configuration rule. See example usage in the examples/ directory.