From 715585c50625d8d6177ad5eeeec244bc76070b09 Mon Sep 17 00:00:00 2001 From: Benoit Steiner Date: Wed, 9 Nov 2016 14:57:34 -0800 Subject: Added a new rule to handle the OpenCL backend: we comment it out in google3, and enable it in github. This is because we haven't imported the backed in google3 just yet. Change: 138689620 --- third_party/sycl/BUILD | 0 third_party/sycl/crosstool/BUILD | 0 third_party/sycl/crosstool/BUILD.tpl | 29 +++++ third_party/sycl/crosstool/CROSSTOOL.tpl | 82 +++++++++++++ third_party/sycl/crosstool/computecpp.tpl | 61 +++++++++ third_party/sycl/sycl/BUILD | 0 third_party/sycl/sycl/BUILD.tpl | 43 +++++++ third_party/sycl/sycl/build_defs.bzl.tpl | 13 ++ third_party/sycl/sycl/platform.bzl.tpl | 5 + third_party/sycl/sycl_configure.bzl | 197 ++++++++++++++++++++++++++++++ 10 files changed, 430 insertions(+) create mode 100644 third_party/sycl/BUILD create mode 100644 third_party/sycl/crosstool/BUILD create mode 100755 third_party/sycl/crosstool/BUILD.tpl create mode 100755 third_party/sycl/crosstool/CROSSTOOL.tpl create mode 100755 third_party/sycl/crosstool/computecpp.tpl create mode 100644 third_party/sycl/sycl/BUILD create mode 100755 third_party/sycl/sycl/BUILD.tpl create mode 100755 third_party/sycl/sycl/build_defs.bzl.tpl create mode 100755 third_party/sycl/sycl/platform.bzl.tpl create mode 100644 third_party/sycl/sycl_configure.bzl (limited to 'third_party/sycl') diff --git a/third_party/sycl/BUILD b/third_party/sycl/BUILD new file mode 100644 index 0000000000..e69de29bb2 diff --git a/third_party/sycl/crosstool/BUILD b/third_party/sycl/crosstool/BUILD new file mode 100644 index 0000000000..e69de29bb2 diff --git a/third_party/sycl/crosstool/BUILD.tpl b/third_party/sycl/crosstool/BUILD.tpl new file mode 100755 index 0000000000..f539a376c8 --- /dev/null +++ b/third_party/sycl/crosstool/BUILD.tpl @@ -0,0 +1,29 @@ +licenses(["notice"]) # Apache 2.0 + +package(default_visibility = ["//visibility:public"]) + +cc_toolchain_suite( + name = "toolchain", + toolchains = { + "local|compiler": ":cc-compiler-local", + }, +) + +cc_toolchain( + name = "cc-compiler-local", + all_files = ":empty", + compiler_files = ":empty", + cpu = "local", + dwp_files = ":empty", + dynamic_runtime_libs = [":empty"], + linker_files = ":empty", + objcopy_files = ":empty", + static_runtime_libs = [":empty"], + strip_files = ":empty", + supports_param_files = 0, +) + +filegroup( + name = "empty", + srcs = [], +) diff --git a/third_party/sycl/crosstool/CROSSTOOL.tpl b/third_party/sycl/crosstool/CROSSTOOL.tpl new file mode 100755 index 0000000000..2108a5b9f0 --- /dev/null +++ b/third_party/sycl/crosstool/CROSSTOOL.tpl @@ -0,0 +1,82 @@ +major_version: "local" +minor_version: "" +default_target_cpu: "same_as_host" + +default_toolchain { + cpu: "k8" + toolchain_identifier: "local_linux" +} + +toolchain { + abi_version: "local" + abi_libc_version: "local" + builtin_sysroot: "" + compiler: "compiler" + host_system_name: "local" + needsPic: true + supports_gold_linker: false + supports_incremental_linker: false + supports_fission: false + supports_interface_shared_objects: false + supports_normalizing_ar: false + supports_start_end_lib: false + supports_thin_archives: false + target_libc: "local" + target_cpu: "local" + target_system_name: "local" + toolchain_identifier: "local_linux" + + tool_path { name: "ar" path: "/usr/bin/ar" } + tool_path { name: "compat-ld" path: "/usr/bin/ld" } + tool_path { name: "cpp" path: "/usr/bin/cpp" } + tool_path { name: "dwp" path: "/usr/bin/dwp" } + tool_path { name: "gcc" path: "computecpp" } + # Use "-std=c++11" for nvcc. For consistency, force both the host compiler + # and the device compiler to use "-std=c++11". + cxx_flag: "-std=c++11" + linker_flag: "-lstdc++" + linker_flag: "-B/usr/bin/" + + # TODO(bazel-team): In theory, the path here ought to exactly match the path + # used by gcc. That works because bazel currently doesn't track files at + # absolute locations and has no remote execution, yet. However, this will need + # to be fixed, maybe with auto-detection? + cxx_builtin_include_directory: "/usr/lib/gcc/" + cxx_builtin_include_directory: "/usr/lib" + cxx_builtin_include_directory: "/usr/lib64" + cxx_builtin_include_directory: "/usr/local/include" + cxx_builtin_include_directory: "/usr/include" + + cxx_builtin_include_directory: "%{computecpp_toolkit_path}" + + tool_path { name: "gcov" path: "/usr/bin/gcov" } + + # C(++) compiles invoke the compiler (as that is the one knowing where + # to find libraries), but we provide LD so other rules can invoke the linker. + tool_path { name: "ld" path: "/usr/bin/ld" } + + tool_path { name: "nm" path: "/usr/bin/nm" } + tool_path { name: "objcopy" path: "/usr/bin/objcopy" } + objcopy_embed_flag: "-I" + objcopy_embed_flag: "binary" + tool_path { name: "objdump" path: "/usr/bin/objdump" } + tool_path { name: "strip" path: "/usr/bin/strip" } + + # Make C++ compilation deterministic. Use linkstamping instead of these + # compiler symbols. + unfiltered_cxx_flag: "-Wno-builtin-macro-redefined" + unfiltered_cxx_flag: "-D__DATE__=\"redacted\"" + unfiltered_cxx_flag: "-D__TIMESTAMP__=\"redacted\"" + unfiltered_cxx_flag: "-D__TIME__=\"redacted\"" + + # All warnings are enabled. Maybe enable -Werror as well? + compiler_flag: "-Wall" + + # Anticipated future default. + linker_flag: "-Wl,-no-as-needed" + # Stamp the binary with a unique identifier. + linker_flag: "-Wl,--build-id=md5" + linker_flag: "-Wl,--hash-style=gnu" + + linking_mode_flags { mode: DYNAMIC } +} diff --git a/third_party/sycl/crosstool/computecpp.tpl b/third_party/sycl/crosstool/computecpp.tpl new file mode 100755 index 0000000000..4860e9f0a0 --- /dev/null +++ b/third_party/sycl/crosstool/computecpp.tpl @@ -0,0 +1,61 @@ +#!/usr/bin/env python + +from argparse import ArgumentParser +import os +import subprocess +import re +import sys +import pipes + +CPU_CXX_COMPILER = ('%{host_cxx_compiler}') +CPU_C_COMPILER = ('%{host_c_compiler}') + +CURRENT_DIR = os.path.dirname(sys.argv[0]) +COMPUTECPP_ROOT = CURRENT_DIR +"/../sycl/" +COMPUTECPP_DRIVER= COMPUTECPP_ROOT+"bin/compute++" +COMPUTECPP_INCLUDE = COMPUTECPP_ROOT+"include" + +def main(): + computecpp_compiler_flags = [""] + computecpp_compiler_flags = [flag for flag in sys.argv[1:]] + computecpp_compiler_flags = computecpp_compiler_flags + ["-D_GLIBCXX_USE_CXX11_ABI=0"] + + output_file_index = computecpp_compiler_flags.index("-o") +1 + output_file_name = computecpp_compiler_flags[output_file_index] + + if(output_file_index == 1): + # we are linking + return subprocess.call([CPU_CXX_COMPILER] +computecpp_compiler_flags ) + + # find what we compile + compiling_cpp = 0 + if("-c" in computecpp_compiler_flags): + compiled_file_index = computecpp_compiler_flags.index("-c") +1 + compited_file_name = computecpp_compiler_flags[compiled_file_index] + if(compited_file_name.endswith(('.cc', '.c++', '.cpp', '.CPP', '.C', '.cxx'))): + compiling_cpp = 1; + + if(compiling_cpp == 1): + filename, file_extension = os.path.splitext(output_file_name) + bc_out = filename + ".sycl" + + computecpp_compiler_flags = ['-DTENSORFLOW_USE_SYCL', '-Wno-unused-variable','-I', COMPUTECPP_INCLUDE,'-isystem', + COMPUTECPP_INCLUDE, "-std=c++11", "-sycl", "-emit-llvm", "-no-serial-memop"] + computecpp_compiler_flags + + # dont want that in case of compiling with computecpp first + host_compiler_flags = [""] + host_compiler_flags = [flag for flag in sys.argv[1:] + if not flag.startswith(('-MF','-MD',)) + if not ".d" in flag] + + x = subprocess.call([COMPUTECPP_DRIVER] +computecpp_compiler_flags ) + if(x == 0): + host_compiler_flags = ['-DTENSORFLOW_USE_SYCL', '-Wno-unused-variable', '-I', COMPUTECPP_INCLUDE, "--include",bc_out] + host_compiler_flags + return subprocess.call([CPU_CXX_COMPILER] +host_compiler_flags ) + return x + else: + # compile for C + return subprocess.call([CPU_C_COMPILER] +computecpp_compiler_flags) + +if __name__ == '__main__': + sys.exit(main()) diff --git a/third_party/sycl/sycl/BUILD b/third_party/sycl/sycl/BUILD new file mode 100644 index 0000000000..e69de29bb2 diff --git a/third_party/sycl/sycl/BUILD.tpl b/third_party/sycl/sycl/BUILD.tpl new file mode 100755 index 0000000000..9e83b1994c --- /dev/null +++ b/third_party/sycl/sycl/BUILD.tpl @@ -0,0 +1,43 @@ +licenses(["notice"]) # Apache 2.0 + +load("@local_config_sycl//sycl:build_defs.bzl", "if_sycl") +load("platform", "sycl_library_path") + +load("platform", "readlink_command") + +package(default_visibility = ["//visibility:public"]) + +config_setting( + name = "using_sycl", + values = { + "define": "using_sycl=true", + }, +) + +cc_library( + name = "sycl_headers", + hdrs = glob([ + "**/*.h", + ]), + includes = [".", "include"], +) + +cc_library( + name = "syclrt", + srcs = [ + sycl_library_path("ComputeCpp") + ], + data = [ + sycl_library_path("ComputeCpp") + ], + includes = ["include/"], + linkstatic = 1, +) + +cc_library( + name = "sycl", + deps = if_sycl([ + ":sycl_headers", + ":syclrt", + ]), +) diff --git a/third_party/sycl/sycl/build_defs.bzl.tpl b/third_party/sycl/sycl/build_defs.bzl.tpl new file mode 100755 index 0000000000..09bef0a661 --- /dev/null +++ b/third_party/sycl/sycl/build_defs.bzl.tpl @@ -0,0 +1,13 @@ +# Macros for building SYCL code. + +def if_sycl(if_true, if_false = []): + """Shorthand for select()'ing on whether we're building with SYCL. + + Returns a select statement which evaluates to if_true if we're building + with SYCL enabled. Otherwise, the select statement evaluates to if_false. + + """ + return select({ + "@local_config_sycl//sycl:using_sycl": if_true, + "//conditions:default": if_false + }) diff --git a/third_party/sycl/sycl/platform.bzl.tpl b/third_party/sycl/sycl/platform.bzl.tpl new file mode 100755 index 0000000000..cb4b3356b2 --- /dev/null +++ b/third_party/sycl/sycl/platform.bzl.tpl @@ -0,0 +1,5 @@ +def sycl_library_path(name): + return "lib/lib{}.so".format(name) + +def readlink_command(): + return "readlink" diff --git a/third_party/sycl/sycl_configure.bzl b/third_party/sycl/sycl_configure.bzl new file mode 100644 index 0000000000..2dd82198ff --- /dev/null +++ b/third_party/sycl/sycl_configure.bzl @@ -0,0 +1,197 @@ +# -*- 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. +""" + +_HOST_CXX_COMPILER = "HOST_CXX_COMPILER" +_HOST_C_COMPILER= "HOST_C_COMPILER" +_COMPUTECPP_TOOLKIT_PATH = "COMPUTECPP_TOOLKIT_PATH" + +def _enable_sycl(repository_ctx): + if "TF_NEED_OPENCL" in repository_ctx.os.environ: + enable_sycl = repository_ctx.os.environ["TF_NEED_OPENCL"].strip() + return enable_sycl == "1" + return False + +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 _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.tpl" % 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/. + _file(repository_ctx, "sycl:build_defs.bzl") + _file(repository_ctx, "sycl:BUILD") + _file(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 + _file(repository_ctx, "sycl:build_defs.bzl") + _file(repository_ctx, "sycl:BUILD") + _file(repository_ctx, "sycl:platform.bzl") + _file(repository_ctx, "crosstool:BUILD") + _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", + { + "%{computecpp_toolkit_path}" : computecpp_root, + }) + + # 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") + +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. +""" -- cgit v1.2.3