STT-tensorflow/third_party/sycl/sycl_configure.bzl

261 lines
8.9 KiB
Python

"""SYCL autoconfiguration.
`sycl_configure` depends on the following environment variables:
* HOST_CXX_COMPILER: The host C++ compiler
* HOST_C_COMPILER: The host C compiler
* COMPUTECPP_TOOLKIT_PATH: The path to the ComputeCpp toolkit.
* TRISYCL_INCLUDE_DIR: The path to the include directory of triSYCL.
(if using triSYCL instead of ComputeCPP)
* PYTHON_LIB_PATH: The path to the python lib
"""
_HOST_CXX_COMPILER = "HOST_CXX_COMPILER"
_HOST_C_COMPILER = "HOST_C_COMPILER"
_COMPUTECPP_TOOLKIT_PATH = "COMPUTECPP_TOOLKIT_PATH"
_TRISYCL_INCLUDE_DIR = "TRISYCL_INCLUDE_DIR"
_PYTHON_LIB_PATH = "PYTHON_LIB_PATH"
def _enable_sycl(repository_ctx):
if "TF_NEED_OPENCL_SYCL" in repository_ctx.os.environ:
enable_sycl = repository_ctx.os.environ["TF_NEED_OPENCL_SYCL"].strip()
return enable_sycl == "1"
return False
def _enable_compute_cpp(repository_ctx):
return _COMPUTECPP_TOOLKIT_PATH in repository_ctx.os.environ
def auto_configure_fail(msg):
"""Output failure message when auto configuration fails."""
red = "\033[0;31m"
no_color = "\033[0m"
fail("\n%sAuto-Configuration Error:%s %s\n" % (red, no_color, msg))
# END cc_configure common functions (see TODO above).
def find_c(repository_ctx):
"""Find host C compiler."""
c_name = "gcc"
if _HOST_C_COMPILER in repository_ctx.os.environ:
c_name = repository_ctx.os.environ[_HOST_C_COMPILER].strip()
if c_name.startswith("/"):
return c_name
c = repository_ctx.which(c_name)
if c == None:
fail("Cannot find C compiler, please correct your path.")
return c
def find_cc(repository_ctx):
"""Find host C++ compiler."""
cc_name = "g++"
if _HOST_CXX_COMPILER in repository_ctx.os.environ:
cc_name = repository_ctx.os.environ[_HOST_CXX_COMPILER].strip()
if cc_name.startswith("/"):
return cc_name
cc = repository_ctx.which(cc_name)
if cc == None:
fail("Cannot find C++ compiler, please correct your path.")
return cc
def find_computecpp_root(repository_ctx):
"""Find ComputeCpp compiler."""
sycl_name = ""
if _COMPUTECPP_TOOLKIT_PATH in repository_ctx.os.environ:
sycl_name = repository_ctx.os.environ[_COMPUTECPP_TOOLKIT_PATH].strip()
if sycl_name.startswith("/"):
return sycl_name
fail("Cannot find SYCL compiler, please correct your path")
def find_trisycl_include_dir(repository_ctx):
"""Find triSYCL include directory. """
if _TRISYCL_INCLUDE_DIR in repository_ctx.os.environ:
sycl_name = repository_ctx.os.environ[_TRISYCL_INCLUDE_DIR].strip()
if sycl_name.startswith("/"):
return sycl_name
fail("Cannot find triSYCL include directory, please correct your path")
def find_python_lib(repository_ctx):
"""Returns python path."""
if _PYTHON_LIB_PATH in repository_ctx.os.environ:
return repository_ctx.os.environ[_PYTHON_LIB_PATH].strip()
fail("Environment variable PYTHON_LIB_PATH was not specified re-run ./configure")
def _check_lib(repository_ctx, toolkit_path, lib):
"""Checks if lib exists under sycl_toolkit_path or fail if it doesn't.
Args:
repository_ctx: The repository context.
toolkit_path: The toolkit directory containing the libraries.
ib: The library to look for under toolkit_path.
"""
lib_path = toolkit_path + "/" + lib
if not repository_ctx.path(lib_path).exists:
auto_configure_fail("Cannot find %s" % lib_path)
def _check_dir(repository_ctx, directory):
"""Checks whether the directory exists and fail if it does not.
Args:
repository_ctx: The repository context.
directory: The directory to check the existence of.
"""
if not repository_ctx.path(directory).exists:
auto_configure_fail("Cannot find dir: %s" % directory)
def _symlink_dir(repository_ctx, src_dir, dest_dir):
"""Symlinks all the files in a directory.
Args:
repository_ctx: The repository context.
src_dir: The source directory.
dest_dir: The destination directory to create the symlinks in.
"""
files = repository_ctx.path(src_dir).readdir()
for src_file in files:
repository_ctx.symlink(src_file, dest_dir + "/" + src_file.basename)
def _tpl(repository_ctx, tpl, substitutions = {}, out = None):
if not out:
out = tpl.replace(":", "/")
repository_ctx.template(
out,
Label("//third_party/sycl/%s.tpl" % tpl),
substitutions,
)
def _file(repository_ctx, label):
repository_ctx.template(
label.replace(":", "/"),
Label("//third_party/sycl/%s" % label),
{},
)
_DUMMY_CROSSTOOL_BZL_FILE = """
def error_sycl_disabled():
fail("ERROR: Building with --config=sycl but TensorFlow is not configured " +
"to build with SYCL support. Please re-run ./configure and enter 'Y' " +
"at the prompt to build with SYCL support.")
native.genrule(
name = "error_gen_crosstool",
outs = ["CROSSTOOL"],
cmd = "echo 'Should not be run.' && exit 1",
)
native.filegroup(
name = "crosstool",
srcs = [":CROSSTOOL"],
output_licenses = ["unencumbered"],
)
"""
_DUMMY_CROSSTOOL_BUILD_FILE = """
load("//crosstool:error_sycl_disabled.bzl", "error_sycl_disabled")
error_sycl_disabled()
"""
def _create_dummy_repository(repository_ctx):
# Set up BUILD file for sycl/.
_tpl(repository_ctx, "sycl:build_defs.bzl")
_tpl(repository_ctx, "sycl:BUILD")
_file(repository_ctx, "sycl:LICENSE.text")
_tpl(repository_ctx, "sycl:platform.bzl")
# Create dummy files for the SYCL toolkit since they are still required by
# tensorflow/sycl/platform/default/build_config:sycl.
repository_ctx.file("sycl/include/sycl.hpp", "")
repository_ctx.file("sycl/lib/libComputeCpp.so", "")
# If sycl_configure is not configured to build with SYCL support, and the user
# attempts to build with --config=sycl, add a dummy build rule to intercept
# this and fail with an actionable error message.
repository_ctx.file(
"crosstool/error_sycl_disabled.bzl",
_DUMMY_CROSSTOOL_BZL_FILE,
)
repository_ctx.file("crosstool/BUILD", _DUMMY_CROSSTOOL_BUILD_FILE)
def _sycl_autoconf_imp(repository_ctx):
"""Implementation of the sycl_autoconf rule."""
if not _enable_sycl(repository_ctx):
_create_dummy_repository(repository_ctx)
else:
# copy template files
_tpl(repository_ctx, "sycl:build_defs.bzl")
_tpl(repository_ctx, "sycl:BUILD")
_tpl(repository_ctx, "sycl:platform.bzl")
_tpl(repository_ctx, "crosstool:BUILD")
_file(repository_ctx, "sycl:LICENSE.text")
if _enable_compute_cpp(repository_ctx):
_tpl(
repository_ctx,
"crosstool:computecpp",
{
"%{host_cxx_compiler}": find_cc(repository_ctx),
"%{host_c_compiler}": find_c(repository_ctx),
},
)
computecpp_root = find_computecpp_root(repository_ctx)
_check_dir(repository_ctx, computecpp_root)
_tpl(
repository_ctx,
"crosstool:CROSSTOOL",
{
"%{sycl_include_dir}": computecpp_root,
"%{sycl_impl}": "computecpp",
"%{c++_std}": "-std=c++11",
"%{python_lib_path}": find_python_lib(repository_ctx),
},
)
# symlink libraries
_check_lib(repository_ctx, computecpp_root + "/lib", "libComputeCpp.so")
_symlink_dir(repository_ctx, computecpp_root + "/lib", "sycl/lib")
_symlink_dir(repository_ctx, computecpp_root + "/include", "sycl/include")
_symlink_dir(repository_ctx, computecpp_root + "/bin", "sycl/bin")
else:
trisycl_include_dir = find_trisycl_include_dir(repository_ctx)
_check_dir(repository_ctx, trisycl_include_dir)
_tpl(
repository_ctx,
"crosstool:trisycl",
{
"%{host_cxx_compiler}": find_cc(repository_ctx),
"%{host_c_compiler}": find_c(repository_ctx),
"%{trisycl_include_dir}": trisycl_include_dir,
},
)
_tpl(
repository_ctx,
"crosstool:CROSSTOOL",
{
"%{sycl_include_dir}": trisycl_include_dir,
"%{sycl_impl}": "trisycl",
"%{c++_std}": "-std=c++1y",
"%{python_lib_path}": find_python_lib(repository_ctx),
},
)
_symlink_dir(repository_ctx, trisycl_include_dir, "sycl/include")
sycl_configure = repository_rule(
implementation = _sycl_autoconf_imp,
local = True,
)
"""Detects and configures the SYCL toolchain.
Add the following to your WORKSPACE FILE:
```python
sycl_configure(name = "local_config_sycl")
```
Args:
name: A unique name for this workspace rule.
"""