github.com/johnnyeven/libtools@v0.0.0-20191126065708-61829c1adf46/third_party/sycl/sycl_configure.bzl (about)

     1  """SYCL autoconfiguration.
     2  `sycl_configure` depends on the following environment variables:
     3  
     4    * HOST_CXX_COMPILER:  The host C++ compiler
     5    * HOST_C_COMPILER:    The host C compiler
     6    * COMPUTECPP_TOOLKIT_PATH: The path to the ComputeCpp toolkit.
     7    * TRISYCL_INCLUDE_DIR: The path to the include directory of triSYCL.
     8                           (if using triSYCL instead of ComputeCPP)
     9    * PYTHON_LIB_PATH: The path to the python lib
    10  """
    11  
    12  _HOST_CXX_COMPILER = "HOST_CXX_COMPILER"
    13  _HOST_C_COMPILER = "HOST_C_COMPILER"
    14  _COMPUTECPP_TOOLKIT_PATH = "COMPUTECPP_TOOLKIT_PATH"
    15  _TRISYCL_INCLUDE_DIR = "TRISYCL_INCLUDE_DIR"
    16  _PYTHON_LIB_PATH = "PYTHON_LIB_PATH"
    17  
    18  def _enable_sycl(repository_ctx):
    19      if "TF_NEED_OPENCL_SYCL" in repository_ctx.os.environ:
    20          enable_sycl = repository_ctx.os.environ["TF_NEED_OPENCL_SYCL"].strip()
    21          return enable_sycl == "1"
    22      return False
    23  
    24  def _enable_compute_cpp(repository_ctx):
    25      return _COMPUTECPP_TOOLKIT_PATH in repository_ctx.os.environ
    26  
    27  def auto_configure_fail(msg):
    28      """Output failure message when auto configuration fails."""
    29      red = "\033[0;31m"
    30      no_color = "\033[0m"
    31      fail("\n%sAuto-Configuration Error:%s %s\n" % (red, no_color, msg))
    32  
    33  # END cc_configure common functions (see TODO above).
    34  
    35  def find_c(repository_ctx):
    36      """Find host C compiler."""
    37      c_name = "gcc"
    38      if _HOST_C_COMPILER in repository_ctx.os.environ:
    39          c_name = repository_ctx.os.environ[_HOST_C_COMPILER].strip()
    40      if c_name.startswith("/"):
    41          return c_name
    42      c = repository_ctx.which(c_name)
    43      if c == None:
    44          fail("Cannot find C compiler, please correct your path.")
    45      return c
    46  
    47  def find_cc(repository_ctx):
    48      """Find host C++ compiler."""
    49      cc_name = "g++"
    50      if _HOST_CXX_COMPILER in repository_ctx.os.environ:
    51          cc_name = repository_ctx.os.environ[_HOST_CXX_COMPILER].strip()
    52      if cc_name.startswith("/"):
    53          return cc_name
    54      cc = repository_ctx.which(cc_name)
    55      if cc == None:
    56          fail("Cannot find C++ compiler, please correct your path.")
    57      return cc
    58  
    59  def find_computecpp_root(repository_ctx):
    60      """Find ComputeCpp compiler."""
    61      sycl_name = ""
    62      if _COMPUTECPP_TOOLKIT_PATH in repository_ctx.os.environ:
    63          sycl_name = repository_ctx.os.environ[_COMPUTECPP_TOOLKIT_PATH].strip()
    64      if sycl_name.startswith("/"):
    65          return sycl_name
    66      fail("Cannot find SYCL compiler, please correct your path")
    67  
    68  def find_trisycl_include_dir(repository_ctx):
    69      """Find triSYCL include directory. """
    70      if _TRISYCL_INCLUDE_DIR in repository_ctx.os.environ:
    71          sycl_name = repository_ctx.os.environ[_TRISYCL_INCLUDE_DIR].strip()
    72          if sycl_name.startswith("/"):
    73              return sycl_name
    74      fail("Cannot find triSYCL include directory, please correct your path")
    75  
    76  def find_python_lib(repository_ctx):
    77      """Returns python path."""
    78      if _PYTHON_LIB_PATH in repository_ctx.os.environ:
    79          return repository_ctx.os.environ[_PYTHON_LIB_PATH].strip()
    80      fail("Environment variable PYTHON_LIB_PATH was not specified re-run ./configure")
    81  
    82  def _check_lib(repository_ctx, toolkit_path, lib):
    83      """Checks if lib exists under sycl_toolkit_path or fail if it doesn't.
    84  
    85      Args:
    86        repository_ctx: The repository context.
    87        toolkit_path: The toolkit directory containing the libraries.
    88        ib: The library to look for under toolkit_path.
    89      """
    90      lib_path = toolkit_path + "/" + lib
    91      if not repository_ctx.path(lib_path).exists:
    92          auto_configure_fail("Cannot find %s" % lib_path)
    93  
    94  def _check_dir(repository_ctx, directory):
    95      """Checks whether the directory exists and fail if it does not.
    96  
    97      Args:
    98        repository_ctx: The repository context.
    99        directory: The directory to check the existence of.
   100      """
   101      if not repository_ctx.path(directory).exists:
   102          auto_configure_fail("Cannot find dir: %s" % directory)
   103  
   104  def _symlink_dir(repository_ctx, src_dir, dest_dir):
   105      """Symlinks all the files in a directory.
   106  
   107      Args:
   108        repository_ctx: The repository context.
   109        src_dir: The source directory.
   110        dest_dir: The destination directory to create the symlinks in.
   111      """
   112      files = repository_ctx.path(src_dir).readdir()
   113      for src_file in files:
   114          repository_ctx.symlink(src_file, dest_dir + "/" + src_file.basename)
   115  
   116  def _tpl(repository_ctx, tpl, substitutions = {}, out = None):
   117      if not out:
   118          out = tpl.replace(":", "/")
   119      repository_ctx.template(
   120          out,
   121          Label("//third_party/sycl/%s.tpl" % tpl),
   122          substitutions,
   123      )
   124  
   125  def _file(repository_ctx, label):
   126      repository_ctx.template(
   127          label.replace(":", "/"),
   128          Label("//third_party/sycl/%s" % label),
   129          {},
   130      )
   131  
   132  _DUMMY_CROSSTOOL_BZL_FILE = """
   133  def error_sycl_disabled():
   134    fail("ERROR: Building with --config=sycl but TensorFlow is not configured " +
   135         "to build with SYCL support. Please re-run ./configure and enter 'Y' " +
   136         "at the prompt to build with SYCL support.")
   137  
   138    native.genrule(
   139        name = "error_gen_crosstool",
   140        outs = ["CROSSTOOL"],
   141        cmd = "echo 'Should not be run.' && exit 1",
   142    )
   143  
   144    native.filegroup(
   145        name = "crosstool",
   146        srcs = [":CROSSTOOL"],
   147        output_licenses = ["unencumbered"],
   148    )
   149  """
   150  
   151  _DUMMY_CROSSTOOL_BUILD_FILE = """
   152  load("//crosstool:error_sycl_disabled.bzl", "error_sycl_disabled")
   153  
   154  error_sycl_disabled()
   155  """
   156  
   157  def _create_dummy_repository(repository_ctx):
   158      # Set up BUILD file for sycl/.
   159      _tpl(repository_ctx, "sycl:build_defs.bzl")
   160      _tpl(repository_ctx, "sycl:BUILD")
   161      _file(repository_ctx, "sycl:LICENSE.text")
   162      _tpl(repository_ctx, "sycl:platform.bzl")
   163  
   164      # Create dummy files for the SYCL toolkit since they are still required by
   165      # tensorflow/sycl/platform/default/build_config:sycl.
   166      repository_ctx.file("sycl/include/sycl.hpp", "")
   167      repository_ctx.file("sycl/lib/libComputeCpp.so", "")
   168  
   169      # If sycl_configure is not configured to build with SYCL support, and the user
   170      # attempts to build with --config=sycl, add a dummy build rule to intercept
   171      # this and fail with an actionable error message.
   172      repository_ctx.file(
   173          "crosstool/error_sycl_disabled.bzl",
   174          _DUMMY_CROSSTOOL_BZL_FILE,
   175      )
   176      repository_ctx.file("crosstool/BUILD", _DUMMY_CROSSTOOL_BUILD_FILE)
   177  
   178  def _sycl_autoconf_imp(repository_ctx):
   179      """Implementation of the sycl_autoconf rule."""
   180      if not _enable_sycl(repository_ctx):
   181          _create_dummy_repository(repository_ctx)
   182      else:
   183          # copy template files
   184          _tpl(repository_ctx, "sycl:build_defs.bzl")
   185          _tpl(repository_ctx, "sycl:BUILD")
   186          _tpl(repository_ctx, "sycl:platform.bzl")
   187          _tpl(repository_ctx, "crosstool:BUILD")
   188          _file(repository_ctx, "sycl:LICENSE.text")
   189  
   190          if _enable_compute_cpp(repository_ctx):
   191              _tpl(
   192                  repository_ctx,
   193                  "crosstool:computecpp",
   194                  {
   195                      "%{host_cxx_compiler}": find_cc(repository_ctx),
   196                      "%{host_c_compiler}": find_c(repository_ctx),
   197                  },
   198              )
   199  
   200              computecpp_root = find_computecpp_root(repository_ctx)
   201              _check_dir(repository_ctx, computecpp_root)
   202  
   203              _tpl(
   204                  repository_ctx,
   205                  "crosstool:CROSSTOOL",
   206                  {
   207                      "%{sycl_include_dir}": computecpp_root,
   208                      "%{sycl_impl}": "computecpp",
   209                      "%{c++_std}": "-std=c++11",
   210                      "%{python_lib_path}": find_python_lib(repository_ctx),
   211                  },
   212              )
   213  
   214              # symlink libraries
   215              _check_lib(repository_ctx, computecpp_root + "/lib", "libComputeCpp.so")
   216              _symlink_dir(repository_ctx, computecpp_root + "/lib", "sycl/lib")
   217              _symlink_dir(repository_ctx, computecpp_root + "/include", "sycl/include")
   218              _symlink_dir(repository_ctx, computecpp_root + "/bin", "sycl/bin")
   219          else:
   220              trisycl_include_dir = find_trisycl_include_dir(repository_ctx)
   221              _check_dir(repository_ctx, trisycl_include_dir)
   222  
   223              _tpl(
   224                  repository_ctx,
   225                  "crosstool:trisycl",
   226                  {
   227                      "%{host_cxx_compiler}": find_cc(repository_ctx),
   228                      "%{host_c_compiler}": find_c(repository_ctx),
   229                      "%{trisycl_include_dir}": trisycl_include_dir,
   230                  },
   231              )
   232  
   233              _tpl(
   234                  repository_ctx,
   235                  "crosstool:CROSSTOOL",
   236                  {
   237                      "%{sycl_include_dir}": trisycl_include_dir,
   238                      "%{sycl_impl}": "trisycl",
   239                      "%{c++_std}": "-std=c++1y",
   240                      "%{python_lib_path}": find_python_lib(repository_ctx),
   241                  },
   242              )
   243  
   244              _symlink_dir(repository_ctx, trisycl_include_dir, "sycl/include")
   245  
   246  sycl_configure = repository_rule(
   247      implementation = _sycl_autoconf_imp,
   248      local = True,
   249  )
   250  """Detects and configures the SYCL toolchain.
   251  
   252  Add the following to your WORKSPACE FILE:
   253  
   254  ```python
   255  sycl_configure(name = "local_config_sycl")
   256  ```
   257  
   258  Args:
   259    name: A unique name for this workspace rule.
   260  """