This is an archive of the discontinued LLVM Phabricator instance.

[bazel] Move bazel configuration to a Python script
AbandonedPublic

Authored by thopre on Feb 3 2023, 2:06 PM.

Details

Summary

Move logic to call the bazel overlay script and create targets.bzl and
vars.bzl into a python script to be used when building LLVM from an
external WORKSPACE such as when doing a repository override for
llvm-project in tensorflow MLIR backend. This allows setting up the
overlay more easily and keep the instructions stable upon changes in
LLVM.

Diff Detail

Event Timeline

thopre created this revision.Feb 3 2023, 2:06 PM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 3 2023, 2:06 PM
thopre requested review of this revision.Feb 3 2023, 2:06 PM
aaronmondal added a subscriber: aaronmondal.EditedFeb 6 2023, 3:41 PM

Can we use some kind of formatting/linting for this script, potentially at a later time, unrelated to this relocation commit?

Running something like wemake-python-styleguide on this currently paints the entire file red. I think for now the following edits would be nice for some basic PEP8 compliance.

--- old.py        2023-02-07 00:29:01.552414476 +0100
+++ new.py        2023-02-07 00:29:02.787444050 +0100
@@ -65,7 +65,7 @@
         subprocess.run(cmd, check=True)
     except subprocess.CalledProcessError as e:
         cmd_str = " ".join([str(arg) for arg in cmd])
-        print(f"Failed to execute overlay script: '{cmd}'\n" +
+        print(f"Failed to execute overlay script: '{cmd_str}'\n" +
               f"Exited with code {e.returncode}\n" +
               f"stdout:\n{e.stdout}\n" +
               f"stderr:\n{e.stderr}\n", file=sys.stderr)
@@ -111,7 +111,7 @@
             # Skip if `CMAKE_CXX_STANDARD` is set with
             # `LLVM_REQUIRED_CXX_STANDARD`.
             # Then `v` will not be desired form, like "${...} CACHE"
-            if c[k] != None:
+            if c[k] is not None:
                 continue
 
             # Pick up 1st word as the value.
@@ -153,9 +153,9 @@
     vars = _extract_cmake_settings(llvm_cmake_path)
 
     _write_dict_to_file(
-        filepath = os.path.join(args.dst, "vars.bzl"),
-        header = "# Generated from {}\n\n".format(llvm_cmake),
-        vars = vars,
+        filepath=os.path.join(args.dst, "vars.bzl"),
+        header="# Generated from {}\n\n".format(llvm_cmake),
+        vars=vars,
     )
 
     # Create a starlark file with the requested LLVM targets.
@@ -164,6 +164,7 @@
     with open(targets_bzl_path, "w") as tgt_file:
         print(f"llvm_targets = [{targets_list_str}]", end="", file=tgt_file)
 
+
 if __name__ == "__main__":
-  _check_python_version()
-  main(parse_arguments())
+    _check_python_version()
+    main(parse_arguments())

I'd be happy to add additional edits later in a different commit if that's ok.

Also: Is there a particular reason behind _overlay_directories invoking a python subprocess instead of invoking the script in a starlark rule?

Edit: Found the suggest edit button and added the edits as suggestions 😊

aaronmondal added inline comments.Feb 6 2023, 3:45 PM
utils/bazel/configure_overlay.py
69
115
157–159
169–170
aaronmondal requested changes to this revision.Feb 6 2023, 3:46 PM
This revision now requires changes to proceed.Feb 6 2023, 3:46 PM

I have been using "black" to do python formatting in other places. Maybe we should make that part of the LLVM dev guide. But I think it's better if we make formatting changes separately from the functional changes.

thopre updated this revision to Diff 495482.Feb 7 2023, 5:09 AM
thopre marked 4 inline comments as done.
  • Address black's linting errors
  • Call overlay code in overlay_directories directly instead of using a subprocess

Excuse me, I am not a fan of it.
Could you remain vars.bzl stuff, unless python would have interest to vars?

I am planning for vars.bzl to give configurations to build rules (and repository rules).

FYI, re. _extract_cmake_settings;

  • It would disappear when the central config database (among build systems) would be introduced.
  • It could be rewritten smarter with python. I wrote it under restriction of starlark.

Thank you.

thopre added a comment.Feb 7 2023, 7:29 AM

Excuse me, I am not a fan of it.
Could you remain vars.bzl stuff, unless python would have interest to vars?

I am planning for vars.bzl to give configurations to build rules (and repository rules).

My point is to simplify the work needed to use LLVM as an external bazel dependency with a repository override, as documented in Tensorflow MLIR backend for instance: https://github.com/tensorflow/tensorflow/blob/master/tensorflow/compiler/mlir/README.md
Note that those instructions are not complete as it stands because of vars.bzl which LLVM bazel build system expects but is not created if using a repository override. That's why I wanted to move it into a Python script to be able to call it instead of doing all those manual steps.

FYI, re. _extract_cmake_settings;

  • It would disappear when the central config database (among build systems) would be introduced.

What's the timeline for that to happen? Is there a patch under review already?

  • It could be rewritten smarter with python. I wrote it under restriction of starlark.

I'm happy to simplify it, is there a Python module to deal with CMakeLists.txt or just improve the parsing code?

Thank you.

aaronmondal resigned from this revision.EditedFeb 7 2023, 8:09 AM

Thanks, no more issues from my side :) I also think it's a lot better to do this without the subprocess module👍

I'll have to agree with @chapuni though, Bazel has exceptional support for bash scripts etc, anything that could be expressed in starlark with genrules and bash scripts seems much better to me than python. E.g. overlaying/moving files is like 10x faster in bash than it is in python.

Also, removing the python dependency would potentially make the build much more portable. I don't think this commit would be the right place to do this and I understand that pytorch/tensorflow devs may prefer using python in general.

However, I think the current functionality of the script is not something where python is actually needed. I'm not sure where else we'd need python for the LLVM build, but I'd say that requiring a rather large python dependency in every CI image is not very economical when we already have starlark and bash.

thieta added a comment.Feb 7 2023, 8:50 AM

Python is already a hard requirement for many things in the LLVM ecosystem, so I don't think that is an argument. Other than that I don't know enough about Bazel to know if this is good or not.

thopre added a comment.Feb 7 2023, 1:53 PM

I'll have to agree with @chapuni though, Bazel has exceptional support for bash scripts etc, anything that could be expressed in starlark with genrules and bash scripts seems much better to me than python. E.g. overlaying/moving files is like 10x faster in bash than it is in python.

Also, removing the python dependency would potentially make the build much more portable. I don't think this commit would be the right place to do this and I understand that pytorch/tensorflow devs may prefer using python in general.

However, I think the current functionality of the script is not something where python is actually needed. I'm not sure where else we'd need python for the LLVM build, but I'd say that requiring a rather large python dependency in every CI image is not very economical when we already have starlark and bash.

Does the bazel CI run any test? If so you would already need Python for lit anyway. Also the overlay script is already in Python so continuing in Python makes sense to me. And the code I've moved to Python is very much not compute heavy so I don't think speed is really a concern.

I supposed llvm_configure is the only public entry for users.
I won't oppose if overlay_directories.py may be assumed as 2nd public entry.

One concern. It seems this change tends to miss update of llvm/CMakeLists.txt.
(for example, bazel build doesn't detect changes if llvm/CMakeLists.txt is changed.)
That said, utils/bazel has been flaky for change of directory structure to be mirrored.
We could run bazel sync to satisfy changes, I think

thopre planned changes to this revision.Feb 20 2023, 8:39 AM

I supposed llvm_configure is the only public entry for users.

It is, but its implementation function is not executed when using a --override_repository on the name associated with its repository_rule, as documented in tensorflow's MLIR readme. I failed to draw the right conclusion though: I now think the problem lies in that documentation. Tensorflow has a separate external repository for LLVM before the overlay and that's what should be overriden. I've created a PR against tensorflow to that effect. I'll keep this patch in "plan changes" state for the time being in case there is a reason for tensorflow to recommend overriding the repository defined by llvm_configure.

Thanks for all the feedback!

I won't oppose if overlay_directories.py may be assumed as 2nd public entry.

One concern. It seems this change tends to miss update of llvm/CMakeLists.txt.
(for example, bazel build doesn't detect changes if llvm/CMakeLists.txt is changed.)
That said, utils/bazel has been flaky for change of directory structure to be mirrored.
We could run bazel sync to satisfy changes, I think

thopre abandoned this revision.Mar 15 2023, 2:00 PM

As mentioned, I went for a change in how tensorflow uses a local LLVM repo instead: https://github.com/tensorflow/tensorflow/commit/64a1638818af21c33280287a95ea88ea62ea9237

Thus closing.