Update to SYCL bazel toolchain.

This commit is contained in:
luke iwanski 2016-10-17 21:14:25 +01:00
parent 2050900830
commit 1f88ec8eef
16 changed files with 307 additions and 268 deletions

85
configure vendored
View File

@ -365,17 +365,64 @@ fi
# OpenCL configuration
if [ "$TF_NEED_OPENCL" == "1" ]; then
# Determine which C++ compiler should be used as the host compiler
while true; do
fromuser=""
if [ -z "$HOST_CXX_COMPILER" ]; then
default_cxx_host_compiler=$(which g++|| true)
read -p "Please specify which C++ compiler should be used as the host C++ compiler. [Default is $default_cxx_host_compiler]: " HOST_CXX_COMPILER
fromuser="1"
if [ -z "$HOST_CXX_COMPILER" ]; then
HOST_CXX_COMPILER=$default_cxx_host_compiler
fi
fi
if [ -e "$HOST_CXX_COMPILER" ]; then
export HOST_CXX_COMPILER
break
fi
echo "Invalid C++ compiler path. ${HOST_CXX_COMPILER} cannot be found" 1>&2
if [ -z "$fromuser" ]; then
exit 1
fi
HOST_CXX_COMPILER=""
# Retry
done
# Determine which C compiler should be used as the host compiler
while true; do
fromuser=""
if [ -z "$HOST_C_COMPILER" ]; then
default_c_host_compiler=$(which gcc|| true)
read -p "Please specify which C compiler should be used as the host C compiler. [Default is $default_c_host_compiler]: " HOST_C_COMPILER
fromuser="1"
if [ -z "$HOST_C_COMPILER" ]; then
HOST_C_COMPILER=$default_c_host_compiler
fi
fi
if [ -e "$HOST_C_COMPILER" ]; then
export HOST_C_COMPILER
break
fi
echo "Invalid C compiler path. ${HOST_C_COMPILER} cannot be found" 1>&2
if [ -z "$fromuser" ]; then
exit 1
fi
HOST_C_COMPILER=""
# Retry
done
while true; do
# Configure the OPENCL version to use.
TF_OPENCL_VERSION="1.2"
# Point to ComputeCPP root
if [ -z "$COMPUTECPP_PATH" ]; then
default_computecpp_path=/usr/local/computecpp
read -p "Please specify the location where ComputeCPP $TF_OPENCL_VERSION is installed. Refer to README.md for more details. [Default is $default_computecpp_path]: " COMPUTECPP_PATH
# Point to ComputeCpp root
if [ -z "$COMPUTECPP_TOOLKIT_PATH" ]; then
default_computecpp_toolkit_path=/usr/local/computecpp
read -p "Please specify the location where ComputeCpp $TF_OPENCL_VERSION is installed. Refer to README.md for more details. [Default is $default_computecpp_toolkit_path]: " COMPUTECPP_TOOLKIT_PATH
fromuser="1"
if [ -z "$COMPUTECPP_PATH" ]; then
COMPUTECPP_PATH=$default_computecpp_path
if [ -z "$COMPUTECPP_TOOLKIT_PATH" ]; then
COMPUTECPP_TOOLKIT_PATH=$default_computecpp_toolkit_path
fi
fi
@ -383,38 +430,20 @@ while true; do
SYCL_RT_LIB_PATH="lib/libComputeCpp.so"
fi
if [ -e "${COMPUTECPP_PATH}/${SYCL_RT_LIB_PATH}" ]; then
if [ -e "${COMPUTECPP_TOOLKIT_PATH}/${SYCL_RT_LIB_PATH}" ]; then
export COMPUTECPP_TOOLKIT_PATH
break
fi
echo "Invalid path to SYCL $TF_OPENCL_VERSION library. ${COMPUTECPP_PATH}/${SYCL_RT_LIB_PATH} cannot be found"
echo "Invalid SYCL $TF_OPENCL_VERSION library path. ${COMPUTECPP_TOOLKIT_PATH}/${SYCL_RT_LIB_PATH} cannot be found"
if [ -z "$fromuser" ]; then
exit 1
fi
# Retry
TF_OPENCL_VERSION=""
COMPUTECPP_PATH=""
COMPUTECPP_TOOLKIT_PATH=""
done
cat > third_party/sycl/sycl.config <<EOF
# COMPUTECPP_PATH refers to the ComputeCPP toolkit.
COMPUTECPP_PATH="$COMPUTECPP_PATH"
# The OpenCL version that should be used in this build
TF_OPENCL_VERSION=$TF_OPENCL_VERSION
EOF
export WARNING=$DO_NOT_SUBMIT_WARNING
perl -pi -e "s,#cxx_builtin_include_directory: {COMPUTECPP_INCLUDE},# \$ENV{WARNING}\ncxx_builtin_include_directory: \"${COMPUTECPP_PATH}\",s" third_party/sycl/crosstool/CROSSTOOL
# Configure the platform name.
perl -pi -e "s,PLATFORM = \".*\",PLATFORM = \"$OSNAME\",s" third_party/sycl/platform.bzl
# Invoke the cuda_config.sh and set up the TensorFlow's canonical view of the Cuda libraries
(cd third_party/sycl; ./sycl_config.sh;) || exit -1
# end of if "$TF_NEED_OPENCL" == "1"
fi

View File

@ -10,6 +10,7 @@ exports_files(["LICENSE"])
load("//tensorflow:tensorflow.bzl", "tf_copts")
load("//tensorflow:tensorflow.bzl", "tf_cuda_library")
load("@local_config_cuda//cuda:platform.bzl", "cuda_library_path")
load("@local_config_sycl//sycl:platform.bzl", "sycl_library_path")
cc_library(
name = "gtest",
@ -127,6 +128,21 @@ cc_library(
],
)
cc_library(
name = "sycl",
data = [
"@local_config_sycl//sycl:{}".format(sycl_library_path("ComputeCpp")),
],
linkopts = select({
"//conditions:default": [
"-Wl,-rpath,../local_config_sycl/sycl/lib",
],
}),
deps = [
"@local_config_sycl//sycl:syclrt",
],
)
filegroup(
name = "android_srcs",
srcs = glob(["*.h"]),

View File

@ -1,11 +1,14 @@
# TensorFlow external dependencies that can be loaded in WORKSPACE files.
load("//third_party/gpus:cuda_configure.bzl", "cuda_configure")
load("//third_party/sycl:sycl_configure.bzl", "sycl_configure")
# If TensorFlow is linked as a submodule.
# path_prefix and tf_repo_name are no longer used.
def tf_workspace(path_prefix = "", tf_repo_name = ""):
cuda_configure(name = "local_config_cuda")
sycl_configure(name = "local_config_sycl")
if path_prefix:
print("path_prefix was specified to tf_workspace but is no longer used and will be removed in the future.")
if tf_repo_name:

44
third_party/sycl/BUILD vendored Executable file → Normal file
View File

@ -1,44 +0,0 @@
licenses(["restricted"]) # MPL2, portions GPL v3, LGPL v3, BSD-like
load("//third_party/sycl:build_defs.bzl", "if_sycl")
load("platform", "sycl_library_path")
load("platform", "sycl_static_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",
]),
)

29
third_party/sycl/crosstool/BUILD vendored Executable file → Normal file
View File

@ -1,29 +0,0 @@
licenses(["restricted"])
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 = [],
)

29
third_party/sycl/crosstool/BUILD.tpl vendored Executable file
View File

@ -0,0 +1,29 @@
licenses(["restricted"])
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 = [],
)

View File

@ -47,7 +47,7 @@ toolchain {
cxx_builtin_include_directory: "/usr/local/include"
cxx_builtin_include_directory: "/usr/include"
#cxx_builtin_include_directory: {COMPUTECPP_INCLUDE}
cxx_builtin_include_directory: "%{computecpp_toolkit_path}"
tool_path { name: "gcov" path: "/usr/bin/gcov" }

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python2.7
#!/usr/bin/env python
from argparse import ArgumentParser
import os
@ -7,11 +7,11 @@ import re
import sys
import pipes
CPU_CXX_COMPILER = ('/usr/bin/clang++-3.6')
CPU_C_COMPILER = ('/usr/bin/clang-3.6')
CPU_CXX_COMPILER = ('%{host_cxx_compiler}')
CPU_C_COMPILER = ('%{host_c_compiler}')
CURRENT_DIR = os.path.dirname(sys.argv[0])
COMPUTECPP_ROOT = CURRENT_DIR +"/../"
COMPUTECPP_ROOT = CURRENT_DIR +"/../sycl/"
COMPUTECPP_DRIVER= COMPUTECPP_ROOT+"bin/compute++"
COMPUTECPP_INCLUDE = COMPUTECPP_ROOT+"include"

View File

@ -1,17 +0,0 @@
SYCL_VERSION = ""
PLATFORM = ""
def sycl_sdk_version():
return SYCL_VERSION
def sycl_library_path(name, version = sycl_sdk_version()):
if not version:
return "lib/lib{}.so".format(name)
else:
return "lib/lib{}.so.{}".format(name, version)
def sycl_static_library_path(name):
return "lib/lib{}_static.a".format(name)
def readlink_command():
return "readlink"

0
third_party/sycl/sycl/BUILD vendored Normal file
View File

43
third_party/sycl/sycl/BUILD.tpl vendored Executable file
View File

@ -0,0 +1,43 @@
licenses(["restricted"]) # MPL2, portions GPL v3, LGPL v3, BSD-like
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",
]),
)

View File

@ -1,10 +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({
"//third_party/sycl:using_sycl": if_true,
"@local_config_sycl//sycl:using_sycl": if_true,
"//conditions:default": if_false
})

5
third_party/sycl/sycl/platform.bzl.tpl vendored Executable file
View File

@ -0,0 +1,5 @@
def sycl_library_path(name):
return "lib/lib{}.so".format(name)
def readlink_command():
return "readlink"

View File

@ -1,143 +0,0 @@
#!/usr/bin/env bash
# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
# A simple script to configure the SYCL tree needed for the TensorFlow OpenCL
# build. We need both COMPUTECPP toolkit $TF_OPENCL_VERSION.
# Useage:
# * User edit sycl.config to point ComputeCPP toolkit to its local path
# * run sycl_config.sh to generate symbolic links in the source tree to reflect
# * the file organizations needed by TensorFlow.
print_usage() {
cat << EOF
Usage: $0 [--check]
Configure TensorFlow's canonical view of SYCL libraries using sycl.config.
Arguments:
--check: Only check that the proper SYCL dependencies has already been
properly configured in the source tree. It also creates symbolic links to
the files in the gen-tree to make bazel happy.
EOF
}
CHECK_ONLY=0
# Parse the arguments. Add more arguments as the "case" line when needed.
while [[ $# -gt 0 ]]; do
argument="$1"
shift
case $argument in
--check)
CHECK_ONLY=1
;;
*)
echo "Error: unknown arguments"
print_usage
exit -1
;;
esac
done
source sycl.config || exit -1
OUTPUTDIR=${OUTPUTDIR:-../..}
COMPUTECPP_PATH=${COMPUTECPP_PATH:-/usr/local/computecpp}
# An error message when the SYCL toolkit is not found
function SYCLError {
echo ERROR: $1
cat << EOF
##############################################################################
##############################################################################
SYCL $TF_OPENCL_VERSION toolkit is missing.
1. Download and install the ComputeCPP $TF_OPENCL_VERSION toolkit;
2. Run configure from the root of the source tree, before rerunning bazel;
Please refer to README.md for more details.
##############################################################################
##############################################################################
EOF
exit -1
}
# Check that the SYCL libraries have already been properly configured in the source tree.
# We still need to create links to the gen-tree to make bazel happy.
function CheckAndLinkToSrcTree {
ERROR_FUNC=$1
FILE=$2
if test ! -e $FILE; then
$ERROR_FUNC "$PWD/$FILE cannot be found"
fi
# Link the output file to the source tree, avoiding self links if they are
# the same. This could happen if invoked from the source tree by accident.
if [ ! $($READLINK_CMD -f $PWD) == $($READLINK_CMD -f $OUTPUTDIR/third_party/sycl) ]; then
mkdir -p $(dirname $OUTPUTDIR/third_party/sycl/$FILE)
ln -sf $PWD/$FILE $OUTPUTDIR/third_party/sycl/$FILE
fi
}
OSNAME=`uname -s`
if [ "$OSNAME" == "Linux" ]; then
SYCL_LIB_PATH="lib"
SYCL_RT_LIB_PATH="lib/libComputeCpp.so"
SYCL_RT_LIB_STATIC_PATH="lib/libComputeCpp.a"
READLINK_CMD="readlink"
fi
if [ "$CHECK_ONLY" == "1" ]; then
CheckAndLinkToSrcTree SYCLError include/SYCL/sycl.h
CheckAndLinkToSrcTree SYCLError $SYCL_RT_LIB_STATIC_PATH
CheckAndLinkToSrcTree CudaError $SYCL_RT_LIB_PATH
exit 0
fi
# Actually configure the source tree for TensorFlow's canonical view of SYCL
# libraries.
if test ! -e ${COMPUTECPP_PATH}/${SYCL_RT_LIB_PATH}; then
SYCLError "cannot find ${COMPUTECPP_PATH}/${SYCL_RT_LIB_PATH}"
fi
# Helper function to build symbolic links for all files in a directory.
function LinkOneDir {
SRC_PREFIX=$1
DST_PREFIX=$2
SRC_DIR=$3
DST_DIR=$(echo $SRC_DIR | sed "s,^$SRC_PREFIX,$DST_PREFIX,")
mkdir -p $DST_DIR
FILE_LIST=$(find -L $SRC_DIR -maxdepth 1 -type f)
if test "$FILE_LIST" != ""; then
ln -sf $FILE_LIST $DST_DIR/ || exit -1
fi
}
export -f LinkOneDir
# Build links for all files in the directory, including subdirectories.
function LinkAllFiles {
SRC_DIR=$1
DST_DIR=$2
find -L $SRC_DIR -type d | xargs -I {} bash -c "LinkOneDir $SRC_DIR $DST_DIR {}" || exit -1
}
# Set up the symbolic links for SYCL toolkit. We link at individual file level,
# not at the directory level.
# This is because the external library may have a different file layout from our desired structure.
mkdir -p $OUTPUTDIR/third_party/sycl
echo "Setting up SYCL include"
LinkAllFiles ${COMPUTECPP_PATH}/include $OUTPUTDIR/third_party/sycl/include || exit -1
echo "Setting up SYCL ${SYCL_LIB_PATH}"
LinkAllFiles ${COMPUTECPP_PATH}/${SYCL_LIB_PATH} $OUTPUTDIR/third_party/sycl/${SYCL_LIB_PATH} || exit -1
echo "Setting up SYCL bin"
LinkAllFiles ${COMPUTECPP_PATH}/bin $OUTPUTDIR/third_party/sycl/bin || exit -1

144
third_party/sycl/sycl_configure.bzl vendored Normal file
View File

@ -0,0 +1,144 @@
# -*- 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 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 = ""
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 = ""
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),
{})
def _sycl_autoconf_imp(repository_ctx):
"""Implementation of the sycl_autoconf rule."""
# 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.
"""

View File

@ -1,7 +1,7 @@
build:cuda --crosstool_top=@local_config_cuda//crosstool:toolchain
build:cuda --define=using_cuda=true --define=using_cuda_nvcc=true
build:sycl --crosstool_top=//third_party/sycl/crosstool:toolchain
build:sycl --crosstool_top=@local_config_sycl//crosstool:toolchain
build:sycl --define=using_sycl=true
build --force_python=py$PYTHON_MAJOR_VERSION