aboutsummaryrefslogtreecommitdiffhomepage
path: root/tensorflow/stream_executor/lib
diff options
context:
space:
mode:
authorGravatar Manjunath Kudlur <keveman@gmail.com>2015-11-06 16:27:58 -0800
committerGravatar Manjunath Kudlur <keveman@gmail.com>2015-11-06 16:27:58 -0800
commitf41959ccb2d9d4c722fe8fc3351401d53bcf4900 (patch)
treeef0ca22cb2a5ac4bdec9d080d8e0788a53ed496d /tensorflow/stream_executor/lib
TensorFlow: Initial commit of TensorFlow library.
TensorFlow is an open source software library for numerical computation using data flow graphs. Base CL: 107276108
Diffstat (limited to 'tensorflow/stream_executor/lib')
-rw-r--r--tensorflow/stream_executor/lib/array_slice.h17
-rw-r--r--tensorflow/stream_executor/lib/casts.h85
-rw-r--r--tensorflow/stream_executor/lib/demangle.cc38
-rw-r--r--tensorflow/stream_executor/lib/demangle.h16
-rw-r--r--tensorflow/stream_executor/lib/env.h29
-rw-r--r--tensorflow/stream_executor/lib/error.h16
-rw-r--r--tensorflow/stream_executor/lib/human_readable.h58
-rw-r--r--tensorflow/stream_executor/lib/initialize.h35
-rw-r--r--tensorflow/stream_executor/lib/inlined_vector.h16
-rw-r--r--tensorflow/stream_executor/lib/mathutil.h88
-rw-r--r--tensorflow/stream_executor/lib/notification.h16
-rw-r--r--tensorflow/stream_executor/lib/numbers.cc27
-rw-r--r--tensorflow/stream_executor/lib/numbers.h19
-rw-r--r--tensorflow/stream_executor/lib/path.cc50
-rw-r--r--tensorflow/stream_executor/lib/path.h44
-rw-r--r--tensorflow/stream_executor/lib/process_state.cc37
-rw-r--r--tensorflow/stream_executor/lib/process_state.h17
-rw-r--r--tensorflow/stream_executor/lib/ptr_util.h48
-rw-r--r--tensorflow/stream_executor/lib/stacktrace.h18
-rw-r--r--tensorflow/stream_executor/lib/static_threadlocal.h30
-rw-r--r--tensorflow/stream_executor/lib/status.h23
-rw-r--r--tensorflow/stream_executor/lib/status_macros.h54
-rw-r--r--tensorflow/stream_executor/lib/statusor.h234
-rw-r--r--tensorflow/stream_executor/lib/str_util.h30
-rw-r--r--tensorflow/stream_executor/lib/strcat.h17
-rw-r--r--tensorflow/stream_executor/lib/stringpiece.h17
-rw-r--r--tensorflow/stream_executor/lib/stringprintf.h18
-rw-r--r--tensorflow/stream_executor/lib/thread_options.h16
-rw-r--r--tensorflow/stream_executor/lib/threadpool.h19
29 files changed, 1132 insertions, 0 deletions
diff --git a/tensorflow/stream_executor/lib/array_slice.h b/tensorflow/stream_executor/lib/array_slice.h
new file mode 100644
index 0000000000..271b1c15a0
--- /dev/null
+++ b/tensorflow/stream_executor/lib/array_slice.h
@@ -0,0 +1,17 @@
+#ifndef TENSORFLOW_STREAM_EXECUTOR_LIB_ARRAY_SLICE_H_
+#define TENSORFLOW_STREAM_EXECUTOR_LIB_ARRAY_SLICE_H_
+
+#include "tensorflow/core/lib/gtl/array_slice.h"
+
+namespace perftools {
+namespace gputools {
+namespace port {
+
+using tensorflow::gtl::ArraySlice;
+using tensorflow::gtl::MutableArraySlice;
+
+} // namespace port
+} // namespace gputools
+} // namespace perftools
+
+#endif // TENSORFLOW_STREAM_EXECUTOR_LIB_ARRAY_SLICE_H_
diff --git a/tensorflow/stream_executor/lib/casts.h b/tensorflow/stream_executor/lib/casts.h
new file mode 100644
index 0000000000..61ff2ab00e
--- /dev/null
+++ b/tensorflow/stream_executor/lib/casts.h
@@ -0,0 +1,85 @@
+#ifndef TENSORFLOW_STREAM_EXECUTOR_LIB_CASTS_H_
+#define TENSORFLOW_STREAM_EXECUTOR_LIB_CASTS_H_
+
+#include <stdlib.h>
+
+namespace perftools {
+namespace gputools {
+namespace port {
+
+// port::bit_cast<Dest,Source> is a template function that implements the
+// equivalent of "*reinterpret_cast<Dest*>(&source)". We need this in
+// very low-level functions like the protobuf library and fast math
+// support.
+//
+// float f = 3.14159265358979;
+// int i = port::bit_cast<int32>(f);
+// // i = 0x40490fdb
+//
+// The classical address-casting method is:
+//
+// // WRONG
+// float f = 3.14159265358979; // WRONG
+// int i = * reinterpret_cast<int*>(&f); // WRONG
+//
+// The address-casting method actually produces undefined behavior
+// according to ISO C++ specification section 3.10 -15 -. Roughly, this
+// section says: if an object in memory has one type, and a program
+// accesses it with a different type, then the result is undefined
+// behavior for most values of "different type".
+//
+// This is true for any cast syntax, either *(int*)&f or
+// *reinterpret_cast<int*>(&f). And it is particularly true for
+// conversions between integral lvalues and floating-point lvalues.
+//
+// The purpose of 3.10 -15- is to allow optimizing compilers to assume
+// that expressions with different types refer to different memory. gcc
+// 4.0.1 has an optimizer that takes advantage of this. So a
+// non-conforming program quietly produces wildly incorrect output.
+//
+// The problem is not the use of reinterpret_cast. The problem is type
+// punning: holding an object in memory of one type and reading its bits
+// back using a different type.
+//
+// The C++ standard is more subtle and complex than this, but that
+// is the basic idea.
+//
+// Anyways ...
+//
+// port::bit_cast<> calls memcpy() which is blessed by the standard,
+// especially by the example in section 3.9 . Also, of course,
+// port::bit_cast<> wraps up the nasty logic in one place.
+//
+// Fortunately memcpy() is very fast. In optimized mode, with a
+// constant size, gcc 2.95.3, gcc 4.0.1, and msvc 7.1 produce inline
+// code with the minimal amount of data movement. On a 32-bit system,
+// memcpy(d,s,4) compiles to one load and one store, and memcpy(d,s,8)
+// compiles to two loads and two stores.
+//
+// I tested this code with gcc 2.95.3, gcc 4.0.1, icc 8.1, and msvc 7.1.
+//
+// WARNING: if Dest or Source is a non-POD type, the result of the memcpy
+// is likely to surprise you.
+//
+// Props to Bill Gibbons for the compile time assertion technique and
+// Art Komninos and Igor Tandetnik for the msvc experiments.
+//
+// -- mec 2005-10-17
+
+template <class Dest, class Source>
+inline Dest bit_cast(const Source& source) {
+ // Compile time assertion: sizeof(Dest) == sizeof(Source)
+ // A compile error here means your Dest and Source have different sizes.
+ static_assert(sizeof(Dest) == sizeof(Source),
+ "src and dst types must have equal sizes");
+
+ Dest dest;
+ memcpy(&dest, &source, sizeof(dest));
+ return dest;
+}
+
+} // namespace port
+} // namespace gputools
+} // namespace perftools
+
+#endif // TENSORFLOW_STREAM_EXECUTOR_LIB_CASTS_H_
diff --git a/tensorflow/stream_executor/lib/demangle.cc b/tensorflow/stream_executor/lib/demangle.cc
new file mode 100644
index 0000000000..6b837b803a
--- /dev/null
+++ b/tensorflow/stream_executor/lib/demangle.cc
@@ -0,0 +1,38 @@
+#include "tensorflow/stream_executor/lib/demangle.h"
+
+#if (__GNUC__ >= 4 || (__GNUC__ >= 3 && __GNUC_MINOR__ >= 4)) && \
+ !defined(__mips__)
+# define HAS_CXA_DEMANGLE 1
+#else
+# define HAS_CXA_DEMANGLE 0
+#endif
+
+#include <stdlib.h>
+#if HAS_CXA_DEMANGLE
+#include <cxxabi.h>
+#endif
+
+namespace perftools {
+namespace gputools {
+namespace port {
+
+// The API reference of abi::__cxa_demangle() can be found in
+// libstdc++'s manual.
+// https://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.3/a01696.html
+string Demangle(const char *mangled) {
+ string demangled;
+ int status = 0;
+ char *result = NULL;
+#if HAS_CXA_DEMANGLE
+ result = abi::__cxa_demangle(mangled, NULL, NULL, &status);
+#endif
+ if (status == 0 && result != NULL) { // Demangling succeeeded.
+ demangled.append(result);
+ free(result);
+ }
+ return demangled;
+}
+
+} // namespace port
+} // namespace gputools
+} // namespace perftools
diff --git a/tensorflow/stream_executor/lib/demangle.h b/tensorflow/stream_executor/lib/demangle.h
new file mode 100644
index 0000000000..0420f7101f
--- /dev/null
+++ b/tensorflow/stream_executor/lib/demangle.h
@@ -0,0 +1,16 @@
+#ifndef TENSORFLOW_STREAM_EXECUTOR_LIB_DEMANGLE_H_
+#define TENSORFLOW_STREAM_EXECUTOR_LIB_DEMANGLE_H_
+
+#include "tensorflow/stream_executor/platform/port.h"
+
+namespace perftools {
+namespace gputools {
+namespace port {
+
+string Demangle(const char* mangled);
+
+} // namespace port
+} // namespace gputools
+} // namespace perftools
+
+#endif // TENSORFLOW_STREAM_EXECUTOR_LIB_DEMANGLE_H_
diff --git a/tensorflow/stream_executor/lib/env.h b/tensorflow/stream_executor/lib/env.h
new file mode 100644
index 0000000000..74b50ad42d
--- /dev/null
+++ b/tensorflow/stream_executor/lib/env.h
@@ -0,0 +1,29 @@
+#ifndef TENSORFLOW_STREAM_EXECUTOR_LIB_ENV_H_
+#define TENSORFLOW_STREAM_EXECUTOR_LIB_ENV_H_
+
+#include "tensorflow/core/public/env.h"
+#include "tensorflow/stream_executor/lib/stringpiece.h"
+#include "tensorflow/stream_executor/platform/port.h"
+
+namespace perftools {
+namespace gputools {
+namespace port {
+
+using tensorflow::Env;
+using tensorflow::ReadFileToString;
+using tensorflow::Thread;
+using tensorflow::WriteStringToFile;
+
+inline bool FileExists(const string& filename) {
+ return Env::Default()->FileExists(filename);
+}
+
+inline bool FileExists(const port::StringPiece& filename) {
+ return Env::Default()->FileExists(filename.ToString());
+}
+
+} // namespace port
+} // namespace gputools
+} // namespace perftools
+
+#endif // TENSORFLOW_STREAM_EXECUTOR_LIB_ENV_H_
diff --git a/tensorflow/stream_executor/lib/error.h b/tensorflow/stream_executor/lib/error.h
new file mode 100644
index 0000000000..376ddd3d07
--- /dev/null
+++ b/tensorflow/stream_executor/lib/error.h
@@ -0,0 +1,16 @@
+#ifndef TENSORFLOW_STREAM_EXECUTOR_LIB_ERROR_H_
+#define TENSORFLOW_STREAM_EXECUTOR_LIB_ERROR_H_
+
+#include "tensorflow/core/lib/core/error_codes.pb.h"
+
+namespace perftools {
+namespace gputools {
+namespace port {
+
+namespace error = tensorflow::error;
+
+} // namespace port
+} // namespace gputools
+} // namespace perftools
+
+#endif // TENSORFLOW_STREAM_EXECUTOR_LIB_ERROR_H_
diff --git a/tensorflow/stream_executor/lib/human_readable.h b/tensorflow/stream_executor/lib/human_readable.h
new file mode 100644
index 0000000000..78df4a4a70
--- /dev/null
+++ b/tensorflow/stream_executor/lib/human_readable.h
@@ -0,0 +1,58 @@
+#ifndef TENSORFLOW_STREAM_EXECUTOR_LIB_HUMAN_READABLE_H_
+#define TENSORFLOW_STREAM_EXECUTOR_LIB_HUMAN_READABLE_H_
+
+#include <assert.h>
+#include <limits>
+
+#include "tensorflow/stream_executor/lib/stringprintf.h"
+#include "tensorflow/stream_executor/platform/port.h"
+
+namespace perftools {
+namespace gputools {
+namespace port {
+
+class HumanReadableNumBytes {
+ public:
+ static string ToString(int64 num_bytes) {
+ if (num_bytes == std::numeric_limits<int64>::min()) {
+ // Special case for number with not representable nagation.
+ return "-8E";
+ }
+
+ const char* neg_str = GetNegStr(&num_bytes);
+
+ // Special case for bytes.
+ if (num_bytes < 1024LL) {
+ // No fractions for bytes.
+ return port::Printf("%s%lldB", neg_str, num_bytes);
+ }
+
+ static const char units[] = "KMGTPE"; // int64 only goes up to E.
+ const char* unit = units;
+ while (num_bytes >= (1024LL) * (1024LL)) {
+ num_bytes /= (1024LL);
+ ++unit;
+ assert(unit < units + sizeof(units));
+ }
+
+ return port::Printf(((*unit == 'K') ? "%s%.1f%c" : "%s%.2f%c"), neg_str,
+ num_bytes / 1024.0, *unit);
+ }
+
+ private:
+ template <typename T>
+ static const char* GetNegStr(T* value) {
+ if (*value < 0) {
+ *value = -(*value);
+ return "-";
+ } else {
+ return "";
+ }
+ }
+};
+
+} // namespace port
+} // namespace gputools
+} // namespace perftools
+
+#endif // TENSORFLOW_STREAM_EXECUTOR_LIB_HUMAN_READABLE_H_
diff --git a/tensorflow/stream_executor/lib/initialize.h b/tensorflow/stream_executor/lib/initialize.h
new file mode 100644
index 0000000000..d1832d6b26
--- /dev/null
+++ b/tensorflow/stream_executor/lib/initialize.h
@@ -0,0 +1,35 @@
+#ifndef TENSORFLOW_STREAM_EXECUTOR_LIB_INITIALIZE_H_
+#define TENSORFLOW_STREAM_EXECUTOR_LIB_INITIALIZE_H_
+
+#include "tensorflow/stream_executor/platform/port.h"
+
+#if defined(PLATFORM_GOOGLE)
+#else
+
+#undef REGISTER_MODULE_INITIALIZER
+
+namespace perftools {
+namespace gputools {
+namespace port {
+
+class Initializer {
+ public:
+ typedef void (*InitializerFunc)();
+ explicit Initializer(InitializerFunc func) { func(); }
+};
+
+} // namespace port
+} // namespace gputools
+} // namespace perftools
+
+#define REGISTER_INITIALIZER(type, name, body) \
+ static void google_init_##type##_##name() { body; } \
+ perftools::gputools::port::Initializer google_initializer_##type##_##name( \
+ google_init_##type##_##name)
+
+#define REGISTER_MODULE_INITIALIZER(name, body) \
+ REGISTER_INITIALIZER(module, name, body)
+
+#endif // !defined(PLATFORM_GOOGLE)
+
+#endif // TENSORFLOW_STREAM_EXECUTOR_LIB_INITIALIZE_H_
diff --git a/tensorflow/stream_executor/lib/inlined_vector.h b/tensorflow/stream_executor/lib/inlined_vector.h
new file mode 100644
index 0000000000..e1f7a29904
--- /dev/null
+++ b/tensorflow/stream_executor/lib/inlined_vector.h
@@ -0,0 +1,16 @@
+#ifndef TENSORFLOW_STREAM_EXECUTOR_LIB_INLINED_VECTOR_H_
+#define TENSORFLOW_STREAM_EXECUTOR_LIB_INLINED_VECTOR_H_
+
+#include "tensorflow/core/lib/gtl/inlined_vector.h"
+
+namespace perftools {
+namespace gputools {
+namespace port {
+
+using tensorflow::gtl::InlinedVector;
+
+} // namespace port
+} // namespace gputools
+} // namespace perftools
+
+#endif // TENSORFLOW_STREAM_EXECUTOR_LIB_INLINED_VECTOR_H_
diff --git a/tensorflow/stream_executor/lib/mathutil.h b/tensorflow/stream_executor/lib/mathutil.h
new file mode 100644
index 0000000000..dd3d37a19c
--- /dev/null
+++ b/tensorflow/stream_executor/lib/mathutil.h
@@ -0,0 +1,88 @@
+#ifndef TENSORFLOW_STREAM_EXECUTOR_LIB_MATHUTIL_H_
+#define TENSORFLOW_STREAM_EXECUTOR_LIB_MATHUTIL_H_
+
+#include <algorithm>
+#include <cmath>
+#include <limits>
+#include <type_traits>
+#include <vector>
+
+#include "tensorflow/stream_executor/platform/logging.h"
+#include "tensorflow/stream_executor/platform/port.h"
+
+namespace perftools {
+namespace gputools {
+namespace port {
+
+class MathUtil {
+ public:
+ template <typename IntegralType>
+ static IntegralType CeilOfRatio(IntegralType numerator,
+ IntegralType denominator) {
+ return CeilOrFloorOfRatio<IntegralType, true>(numerator, denominator);
+ }
+ template <typename IntegralType>
+ static IntegralType FloorOfRatio(IntegralType numerator,
+ IntegralType denominator) {
+ return CeilOrFloorOfRatio<IntegralType, false>(numerator, denominator);
+ }
+ template <typename IntegralType, bool ceil>
+ static IntegralType CeilOrFloorOfRatio(IntegralType numerator,
+ IntegralType denominator);
+};
+
+// ---- CeilOrFloorOfRatio ----
+// This is a branching-free, cast-to-double-free implementation.
+//
+// Casting to double is in general incorrect because of loss of precision
+// when casting an int64 into a double.
+//
+// There's a bunch of 'recipes' to compute a integer ceil (or floor) on the web,
+// and most of them are incorrect.
+template<typename IntegralType, bool ceil>
+IntegralType MathUtil::CeilOrFloorOfRatio(IntegralType numerator,
+ IntegralType denominator) {
+ static_assert(std::is_integral<IntegralType>::value,
+ "CeilOfRatio_is_only_defined_for_integral_types");
+ assert(denominator != 0);
+ // Dividing the smallest signed integer by -1 is not supported: it would
+ // SIGFPE
+ assert(!std::is_signed<IntegralType>::value ||
+ numerator != std::numeric_limits<IntegralType>::min() ||
+ denominator != -1);
+
+ const IntegralType rounded_toward_zero = numerator / denominator;
+ const IntegralType intermediate_product = rounded_toward_zero * denominator;
+
+ if (ceil) { // Compile-time condition: not an actual branching
+ // When rounded_toward_zero is negative, then an adjustment is never needed:
+ // the real ratio is negative, and so rounded toward zero is the ceil.
+ // When rounded_toward_zero is non-negative, an adjustment is needed if the
+ // sign of the difference numerator - intermediate_product is the same as
+ // the sign of the denominator.
+ //
+ // Using a bool and then a static_cast to IntegralType is not strictly
+ // necessary, but it makes the code clear, and anyway the compiler should
+ // get rid of it.
+ const bool needs_adjustment = (rounded_toward_zero >= 0) &&
+ ((denominator > 0 && numerator > intermediate_product) ||
+ (denominator < 0 && numerator < intermediate_product));
+ const IntegralType adjustment = static_cast<IntegralType>(needs_adjustment);
+ const IntegralType ceil_of_ratio = rounded_toward_zero + adjustment;
+ return ceil_of_ratio;
+ } else {
+ // Floor case: symmetrical to the previous one
+ const bool needs_adjustment = (rounded_toward_zero <= 0) &&
+ ((denominator > 0 && numerator < intermediate_product) ||
+ (denominator < 0 && numerator > intermediate_product));
+ const IntegralType adjustment = static_cast<IntegralType>(needs_adjustment);
+ const IntegralType floor_of_ratio = rounded_toward_zero - adjustment;
+ return floor_of_ratio;
+ }
+}
+
+} // namespace port
+} // namespace gputools
+} // namespace perftools
+
+#endif // TENSORFLOW_STREAM_EXECUTOR_LIB_MATHUTIL_H_
diff --git a/tensorflow/stream_executor/lib/notification.h b/tensorflow/stream_executor/lib/notification.h
new file mode 100644
index 0000000000..2baa458fc9
--- /dev/null
+++ b/tensorflow/stream_executor/lib/notification.h
@@ -0,0 +1,16 @@
+#ifndef TENSORFLOW_STREAM_EXECUTOR_LIB_NOTIFICATION_H_
+#define TENSORFLOW_STREAM_EXECUTOR_LIB_NOTIFICATION_H_
+
+#include "tensorflow/core/lib/core/notification.h"
+
+namespace perftools {
+namespace gputools {
+namespace port {
+
+using tensorflow::Notification;
+
+} // namespace port
+} // namespace gputools
+} // namespace perftools
+
+#endif // TENSORFLOW_STREAM_EXECUTOR_LIB_NOTIFICATION_H_
diff --git a/tensorflow/stream_executor/lib/numbers.cc b/tensorflow/stream_executor/lib/numbers.cc
new file mode 100644
index 0000000000..a9981b0ce6
--- /dev/null
+++ b/tensorflow/stream_executor/lib/numbers.cc
@@ -0,0 +1,27 @@
+#include "tensorflow/stream_executor/lib/numbers.h"
+
+#include <stdlib.h>
+
+namespace perftools {
+namespace gputools {
+namespace port {
+
+bool safe_strto32(const char* str, int32* value) {
+ char* endptr;
+ *value = strtol(str, &endptr, 10); // NOLINT
+ if (endptr != str) {
+ while (isspace(*endptr)) ++endptr;
+ }
+ return *str != '\0' && *endptr == '\0';
+}
+
+// Convert strings to floating point values.
+// Leading and trailing spaces are allowed.
+// Values may be rounded on over- and underflow.
+bool safe_strto32(const string& str, int32* value) {
+ return port::safe_strto32(str.c_str(), value);
+}
+
+} // namespace port
+} // namespace gputools
+} // namespace perftools
diff --git a/tensorflow/stream_executor/lib/numbers.h b/tensorflow/stream_executor/lib/numbers.h
new file mode 100644
index 0000000000..17b2893743
--- /dev/null
+++ b/tensorflow/stream_executor/lib/numbers.h
@@ -0,0 +1,19 @@
+#ifndef TENSORFLOW_STREAM_EXECUTOR_LIB_NUMBERS_H_
+#define TENSORFLOW_STREAM_EXECUTOR_LIB_NUMBERS_H_
+
+#include "tensorflow/stream_executor/platform/port.h"
+
+namespace perftools {
+namespace gputools {
+namespace port {
+
+// Convert strings to floating point values.
+// Leading and trailing spaces are allowed.
+// Values may be rounded on over- and underflow.
+bool safe_strto32(const string& str, int32* value);
+
+} // namespace port
+} // namespace gputools
+} // namespace perftools
+
+#endif // TENSORFLOW_STREAM_EXECUTOR_LIB_NUMBERS_H_
diff --git a/tensorflow/stream_executor/lib/path.cc b/tensorflow/stream_executor/lib/path.cc
new file mode 100644
index 0000000000..a6e76e99b7
--- /dev/null
+++ b/tensorflow/stream_executor/lib/path.cc
@@ -0,0 +1,50 @@
+#include "tensorflow/stream_executor/lib/path.h"
+#include "tensorflow/stream_executor/lib/strcat.h"
+
+using ::perftools::gputools::port::StringPiece;
+using ::perftools::gputools::port::StrAppend;
+
+namespace perftools {
+namespace gputools {
+namespace port {
+namespace internal {
+
+static bool IsAbsolutePath(port::StringPiece path) {
+ return !path.empty() && path[0] == '/';
+}
+
+// For an array of paths of length count, append them all together,
+// ensuring that the proper path separators are inserted between them.
+string JoinPathImpl(std::initializer_list<port::StringPiece> paths) {
+ string result;
+
+ for (port::StringPiece path : paths) {
+ if (path.empty()) continue;
+
+ if (result.empty()) {
+ result = path.ToString();
+ continue;
+ }
+
+ if (result[result.size() - 1] == '/') {
+ if (IsAbsolutePath(path)) {
+ StrAppend(&result, path.substr(1));
+ } else {
+ StrAppend(&result, path);
+ }
+ } else {
+ if (IsAbsolutePath(path)) {
+ StrAppend(&result, path);
+ } else {
+ StrAppend(&result, "/", path);
+ }
+ }
+ }
+
+ return result;
+}
+
+} // namespace internal
+} // namespace port
+} // namespace gputools
+} // namespace perftools
diff --git a/tensorflow/stream_executor/lib/path.h b/tensorflow/stream_executor/lib/path.h
new file mode 100644
index 0000000000..1d648e8de1
--- /dev/null
+++ b/tensorflow/stream_executor/lib/path.h
@@ -0,0 +1,44 @@
+#ifndef TENSORFLOW_STREAM_EXECUTOR_LIB_PATH_H_
+#define TENSORFLOW_STREAM_EXECUTOR_LIB_PATH_H_
+
+#include "tensorflow/stream_executor/lib/stringpiece.h"
+#include "tensorflow/stream_executor/platform/port.h"
+
+namespace perftools {
+namespace gputools {
+namespace port {
+
+namespace internal {
+// TODO(rspringer): Move to cc/implementation file.
+// Not part of the public API.
+string JoinPathImpl(std::initializer_list<port::StringPiece> paths);
+} // namespace internal
+
+// Join multiple paths together.
+// JoinPath unconditionally joins all paths together. For example:
+//
+// Arguments | JoinPath
+// ---------------------------+---------------------
+// '/foo', 'bar' | /foo/bar
+// '/foo/', 'bar' | /foo/bar
+// '/foo', '/bar' | /foo/bar
+// '/foo', '/bar', '/baz' | /foo/bar/baz
+//
+// All paths will be treated as relative paths, regardless of whether or not
+// they start with a leading '/'. That is, all paths will be concatenated
+// together, with the appropriate path separator inserted in between.
+// Arguments must be convertible to port::StringPiece.
+//
+// Usage:
+// string path = file::JoinPath("/var/log", dirname, filename);
+// string path = file::JoinPath(FLAGS_test_srcdir, filename);
+template <typename... T>
+inline string JoinPath(const T&... args) {
+ return internal::JoinPathImpl({args...});
+}
+
+} // namespace port
+} // namespace gputools
+} // namespace perftools
+
+#endif // TENSORFLOW_STREAM_EXECUTOR_LIB_PATH_H_
diff --git a/tensorflow/stream_executor/lib/process_state.cc b/tensorflow/stream_executor/lib/process_state.cc
new file mode 100644
index 0000000000..c20493b263
--- /dev/null
+++ b/tensorflow/stream_executor/lib/process_state.cc
@@ -0,0 +1,37 @@
+#include "tensorflow/stream_executor/lib/process_state.h"
+
+#include <unistd.h>
+
+#include <memory>
+
+namespace perftools {
+namespace gputools {
+namespace port {
+
+string Hostname() {
+ char hostname[1024];
+ gethostname(hostname, sizeof hostname);
+ hostname[sizeof hostname - 1] = 0;
+ return hostname;
+}
+
+bool GetCurrentDirectory(string* dir) {
+ size_t len = 128;
+ std::unique_ptr<char[]> a(new char[len]);
+ for (;;) {
+ char* p = getcwd(a.get(), len);
+ if (p != NULL) {
+ *dir = p;
+ return true;
+ } else if (errno == ERANGE) {
+ len += len;
+ a.reset(new char[len]);
+ } else {
+ return false;
+ }
+ }
+}
+
+} // namespace port
+} // namespace gputools
+} // namespace perftools
diff --git a/tensorflow/stream_executor/lib/process_state.h b/tensorflow/stream_executor/lib/process_state.h
new file mode 100644
index 0000000000..b75879499b
--- /dev/null
+++ b/tensorflow/stream_executor/lib/process_state.h
@@ -0,0 +1,17 @@
+#ifndef TENSORFLOW_STREAM_EXECUTOR_LIB_PROCESS_STATE_H_
+#define TENSORFLOW_STREAM_EXECUTOR_LIB_PROCESS_STATE_H_
+
+#include "tensorflow/stream_executor/platform/port.h"
+
+namespace perftools {
+namespace gputools {
+namespace port {
+
+string Hostname();
+bool GetCurrentDirectory(string* dir);
+
+} // namespace port
+} // namespace gputools
+} // namespace perftools
+
+#endif // TENSORFLOW_STREAM_EXECUTOR_LIB_PROCESS_STATE_H_
diff --git a/tensorflow/stream_executor/lib/ptr_util.h b/tensorflow/stream_executor/lib/ptr_util.h
new file mode 100644
index 0000000000..d10d0bcb8c
--- /dev/null
+++ b/tensorflow/stream_executor/lib/ptr_util.h
@@ -0,0 +1,48 @@
+#ifndef TENSORFLOW_STREAM_EXECUTOR_LIB_PTR_UTIL_H_
+#define TENSORFLOW_STREAM_EXECUTOR_LIB_PTR_UTIL_H_
+
+namespace perftools {
+namespace gputools {
+namespace port {
+
+// Trait to select overloads and return types for MakeUnique.
+template <typename T>
+struct MakeUniqueResult {
+ using scalar = std::unique_ptr<T>;
+};
+template <typename T>
+struct MakeUniqueResult<T[]> {
+ using array = std::unique_ptr<T[]>;
+};
+template <typename T, size_t N>
+struct MakeUniqueResult<T[N]> {
+ using invalid = void;
+};
+
+// MakeUnique<T>(...) is an early implementation of C++14 std::make_unique.
+// It is designed to be 100% compatible with std::make_unique so that the
+// eventual switchover will be a simple renaming operation.
+template <typename T, typename... Args>
+typename MakeUniqueResult<T>::scalar MakeUnique(Args&&... args) { // NOLINT
+ return std::unique_ptr<T>(
+ new T(std::forward<Args>(args)...)); // NOLINT(build/c++11)
+}
+
+// Overload for array of unknown bound.
+// The allocation of arrays needs to use the array form of new,
+// and cannot take element constructor arguments.
+template <typename T>
+typename MakeUniqueResult<T>::array MakeUnique(size_t n) {
+ return std::unique_ptr<T>(new typename std::remove_extent<T>::type[n]());
+}
+
+// Reject arrays of known bound.
+template <typename T, typename... Args>
+typename MakeUniqueResult<T>::invalid MakeUnique(Args&&... /* args */) =
+ delete; // NOLINT
+
+} // namespace port
+} // namespace gputools
+} // namespace perftools
+
+#endif // TENSORFLOW_STREAM_EXECUTOR_LIB_PTR_UTIL_H_
diff --git a/tensorflow/stream_executor/lib/stacktrace.h b/tensorflow/stream_executor/lib/stacktrace.h
new file mode 100644
index 0000000000..e7d478efe3
--- /dev/null
+++ b/tensorflow/stream_executor/lib/stacktrace.h
@@ -0,0 +1,18 @@
+#ifndef TENSORFLOW_STREAM_EXECUTOR_LIB_STACKTRACE_H_
+#define TENSORFLOW_STREAM_EXECUTOR_LIB_STACKTRACE_H_
+
+#include "tensorflow/stream_executor/platform/port.h"
+
+namespace perftools {
+namespace gputools {
+namespace port {
+
+#if !defined(PLATFORM_GOOGLE)
+inline string CurrentStackTrace() { return "No stack trace available"; }
+#endif
+
+} // namespace port
+} // namespace gputools
+} // namespace perftools
+
+#endif // TENSORFLOW_STREAM_EXECUTOR_LIB_STACKTRACE_H_
diff --git a/tensorflow/stream_executor/lib/static_threadlocal.h b/tensorflow/stream_executor/lib/static_threadlocal.h
new file mode 100644
index 0000000000..9227b2cf0d
--- /dev/null
+++ b/tensorflow/stream_executor/lib/static_threadlocal.h
@@ -0,0 +1,30 @@
+// Copyright 2006 Google Inc.
+// All rights reserved.
+// Author: Yaz Saito (saito@google.com)
+#ifndef TENSORFLOW_STREAM_EXECUTOR_LIB_STATIC_THREADLOCAL_H_
+#define TENSORFLOW_STREAM_EXECUTOR_LIB_STATIC_THREADLOCAL_H_
+
+// For POD types in TLS mode, s_obj_VAR is the thread-local variable.
+#define SE_STATIC_THREAD_LOCAL_POD(_Type_, _var_) \
+ static thread_local _Type_ s_obj_##_var_; \
+ namespace { \
+ class ThreadLocal_##_var_ { \
+ public: \
+ ThreadLocal_##_var_() {} \
+ void Init() {} \
+ inline _Type_ *pointer() const { \
+ return &s_obj_##_var_; \
+ } \
+ inline _Type_ *safe_pointer() const { \
+ return &s_obj_##_var_; \
+ } \
+ _Type_ &get() const { \
+ return s_obj_##_var_; \
+ } \
+ bool is_native_tls() const { return true; } \
+ private: \
+ SE_DISALLOW_COPY_AND_ASSIGN(ThreadLocal_##_var_); \
+ } _var_; \
+ }
+
+#endif // TENSORFLOW_STREAM_EXECUTOR_LIB_STATIC_THREADLOCAL_H_
diff --git a/tensorflow/stream_executor/lib/status.h b/tensorflow/stream_executor/lib/status.h
new file mode 100644
index 0000000000..b3ad13b0ae
--- /dev/null
+++ b/tensorflow/stream_executor/lib/status.h
@@ -0,0 +1,23 @@
+#ifndef TENSORFLOW_STREAM_EXECUTOR_LIB_STATUS_H_
+#define TENSORFLOW_STREAM_EXECUTOR_LIB_STATUS_H_
+
+#include "tensorflow/core/public/status.h"
+#include "tensorflow/stream_executor/lib/error.h"
+#include "tensorflow/stream_executor/platform/logging.h"
+
+namespace perftools {
+namespace gputools {
+namespace port {
+
+using tensorflow::Status;
+
+#define SE_CHECK_OK(val) \
+ CHECK_EQ(::perftools::gputools::port::Status::OK(), (val))
+#define SE_ASSERT_OK(val) \
+ ASSERT_EQ(::perftools::gputools::port::Status::OK(), (val))
+
+} // namespace port
+} // namespace gputools
+} // namespace perftools
+
+#endif // TENSORFLOW_STREAM_EXECUTOR_LIB_STATUS_H_
diff --git a/tensorflow/stream_executor/lib/status_macros.h b/tensorflow/stream_executor/lib/status_macros.h
new file mode 100644
index 0000000000..7e1de92a98
--- /dev/null
+++ b/tensorflow/stream_executor/lib/status_macros.h
@@ -0,0 +1,54 @@
+// Helper macros for dealing with the port::Status datatype.
+
+#ifndef TENSORFLOW_STREAM_EXECUTOR_LIB_STATUS_MACROS_H_
+#define TENSORFLOW_STREAM_EXECUTOR_LIB_STATUS_MACROS_H_
+
+// Early-returns the status if it is in error; otherwise, proceeds.
+//
+// The argument expression is guaranteed to be evaluated exactly once.
+#define SE_RETURN_IF_ERROR(__status) \
+ do { \
+ auto status = __status; \
+ if (!status.ok()) { \
+ return status; \
+ } \
+ } while (false)
+
+// Identifier concatenation helper macros.
+#define SE_MACRO_CONCAT_INNER(__x, __y) __x##__y
+#define SE_MACRO_CONCAT(__x, __y) SE_MACRO_CONCAT_INNER(__x, __y)
+
+// Implementation of SE_ASSIGN_OR_RETURN that uses a unique temporary identifier
+// for avoiding collision in the enclosing scope.
+#define SE_ASSIGN_OR_RETURN_IMPL(__lhs, __rhs, __name) \
+ auto __name = (__rhs); \
+ if (!__name.ok()) { \
+ return __name.status(); \
+ } \
+ __lhs = __name.ConsumeValueOrDie();
+
+// Early-returns the status if it is in error; otherwise, assigns the
+// right-hand-side expression to the left-hand-side expression.
+//
+// The right-hand-side expression is guaranteed to be evaluated exactly once.
+#define SE_ASSIGN_OR_RETURN(__lhs, __rhs) \
+ SE_ASSIGN_OR_RETURN_IMPL(__lhs, __rhs, \
+ SE_MACRO_CONCAT(__status_or_value, __COUNTER__))
+
+// Logs the status and returns false if it is in error; otherwise, returns true.
+//
+// The argument expression is guaranteed to be evaluated exactly once.
+//
+// TODO(leary) remove as many of these as possible with port::Status
+// proliferation.
+#define SE_RETURN_STATUS_AS_BOOL(__status) \
+ do { \
+ auto status = __status; \
+ if (__status.ok()) { \
+ return true; \
+ } \
+ LOG(ERROR) << status; \
+ return false; \
+ } while (false)
+
+#endif // TENSORFLOW_STREAM_EXECUTOR_LIB_STATUS_MACROS_H_
diff --git a/tensorflow/stream_executor/lib/statusor.h b/tensorflow/stream_executor/lib/statusor.h
new file mode 100644
index 0000000000..38ce35e46e
--- /dev/null
+++ b/tensorflow/stream_executor/lib/statusor.h
@@ -0,0 +1,234 @@
+// Copyright 2008 Google Inc. All Rights Reserved.
+// Author: acm@google.com (Andrew Morrow)
+// Author: zhengxq@google.com (Xiaoqiang Zheng)
+//
+// StatusOr<T> is the union of a Status object and a T
+// object. StatusOr models the concept of an object that is either a
+// usable value, or an error Status explaining why such a value is
+// not present. To this end, StatusOr<T> does not allow its Status
+// value to be Status::OK. Further, StatusOr<T*> does not allow the
+// contained pointer to be NULL.
+//
+// The primary use-case for StatusOr<T> is as the return value of a
+// function which may fail.
+//
+// Example client usage for a StatusOr<T>, where T is not a pointer:
+//
+// StatusOr<float> result = DoBigCalculationThatCouldFail();
+// if (result.ok()) {
+// float answer = result.ValueOrDie();
+// printf("Big calculation yielded: %f", answer);
+// } else {
+// LOG(ERROR) << result.status();
+// }
+//
+// Example client usage for a StatusOr<T*>:
+//
+// StatusOr<Foo*> result = FooFactory::MakeNewFoo(arg);
+// if (result.ok()) {
+// std::unique_ptr<Foo> foo(result.ValueOrDie());
+// foo->DoSomethingCool();
+// } else {
+// LOG(ERROR) << result.status();
+// }
+//
+// Example client usage for a StatusOr<std::unique_ptr<T>>:
+//
+// StatusOr<std::unique_ptr<Foo>> result = FooFactory::MakeNewFoo(arg);
+// if (result.ok()) {
+// std::unique_ptr<Foo> foo = result.ConsumeValueOrDie();
+// foo->DoSomethingCool();
+// } else {
+// LOG(ERROR) << result.status();
+// }
+//
+// Example factory implementation returning StatusOr<T*>:
+//
+// StatusOr<Foo*> FooFactory::MakeNewFoo(int arg) {
+// if (arg <= 0) {
+// return Status(port::error::INVALID_ARGUMENT,
+// "Arg must be positive");
+// } else {
+// return new Foo(arg);
+// }
+// }
+//
+
+#ifndef TENSORFLOW_STREAM_EXECUTOR_LIB_STATUSOR_H_
+#define TENSORFLOW_STREAM_EXECUTOR_LIB_STATUSOR_H_
+
+#include <new>
+#include "tensorflow/stream_executor/platform/port.h"
+#include <type_traits>
+#include <utility>
+
+#include "tensorflow/stream_executor/lib/error.h"
+#include "tensorflow/stream_executor/lib/status.h"
+#include "tensorflow/stream_executor/platform/logging.h"
+#include "tensorflow/stream_executor/platform/port.h"
+
+namespace perftools {
+namespace gputools {
+namespace port {
+
+template<typename T>
+class StatusOr {
+ template<typename U> friend class StatusOr;
+
+ public:
+ // Construct a new StatusOr with Status::UNKNOWN status
+ StatusOr() : status_(error::UNKNOWN, "") {}
+
+ // Construct a new StatusOr with the given non-ok status. After calling
+ // this constructor, calls to ValueOrDie() is invalid.
+ //
+ // NOTE: Not explicit - we want to use StatusOr<T> as a return
+ // value, so it is convenient and sensible to be able to do 'return
+ // Status()' when the return type is StatusOr<T>.
+ //
+ // REQUIRES: status != Status::OK.
+ // In optimized builds, passing Status::OK here will have the effect
+ // of passing PosixErrorSpace::EINVAL as a fallback.
+ StatusOr(const Status& status); // NOLINT
+
+ // Construct a new StatusOr with the given value. If T is a plain pointer,
+ // value must not be NULL. After calling this constructor, calls to
+ // ValueOrDie() will succeed, and calls to status() will return OK.
+ //
+ // NOTE: Not explicit - we want to use StatusOr<T> as a return type
+ // so it is convenient and sensible to be able to do 'return T()'
+ // when when the return type is StatusOr<T>.
+ //
+ // REQUIRES: if T is a plain pointer, value != NULL.
+ // In optimized builds, passing a NULL pointer here will have
+ // the effect of passing PosixErrorSpace::EINVAL as a fallback.
+ StatusOr(const T& value); // NOLINT
+
+ // Conversion copy constructor, T must be copy constructible from U
+ template <typename U>
+ StatusOr(const StatusOr<U>& other) // NOLINT
+ : status_(other.status_),
+ value_(other.value_) {}
+
+ // Conversion assignment operator, T must be assignable from U
+ template <typename U>
+ StatusOr& operator=(const StatusOr<U>& other) {
+ status_ = other.status_;
+ value_ = other.value_;
+ return *this;
+ }
+
+ // Rvalue-reference overloads of the other constructors and assignment
+ // operators, to support move-only types and avoid unnecessary copying.
+ StatusOr(T&& value); // NOLINT
+
+ // Move conversion operator to avoid unecessary copy.
+ // T must be assignable from U.
+ // Not marked with explicit so the implicit conversion can happen.
+ template <typename U>
+ StatusOr(StatusOr<U>&& other) // NOLINT
+ : status_(std::move(other.status_)),
+ value_(std::move(other.value_)) {}
+
+ // Move assignment opeartor to avoid unnecessary copy.
+ // T must be assignable from U
+ template <typename U>
+ StatusOr& operator=(StatusOr<U>&& other) {
+ status_ = std::move(other.status_);
+ value_ = std::move(other.value_);
+ return *this;
+ }
+
+ // Returns a reference to our status. If this contains a T, then
+ // returns Status::OK.
+ const Status& status() const { return status_; }
+
+ // Returns this->status().ok()
+ bool ok() const { return status_.ok(); }
+
+ // Returns a reference to our current value, requires that this->ok().
+ // If you need to initialize a T object from the stored value,
+ // ConsumeValueOrDie() may be more efficient.
+ const T& ValueOrDie() const;
+
+ // Returns our current value, requires this->ok(). Use this if
+ // you would otherwise want to say std::move(s.ValueOrDie()), for example
+ // if you need to initialize a T object from the stored value and you don't
+ // need subsequent access to the stored value. It uses T's move constructor,
+ // if it has one, so it will work with move-only types, and will often be
+ // more efficient than ValueOrDie, but may leave the stored value
+ // in an arbitrary valid state.
+ T ConsumeValueOrDie();
+
+ private:
+ Status status_;
+ T value_;
+
+ void CheckValueNotNull(const T& value);
+
+ template <typename U>
+ struct IsNull {
+ // For non-pointer U, a reference can never be NULL.
+ static inline bool IsValueNull(const U& t) { return false; }
+ };
+
+ template <typename U>
+ struct IsNull<U*> {
+ static inline bool IsValueNull(const U* t) { return t == NULL; }
+ };
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Implementation details for StatusOr<T>
+
+template <typename T>
+StatusOr<T>::StatusOr(const T& value)
+ : status_(), value_(value) {
+ CheckValueNotNull(value);
+}
+
+template <typename T>
+const T& StatusOr<T>::ValueOrDie() const {
+ assert(status_.ok());
+ return value_;
+}
+
+template <typename T>
+T StatusOr<T>::ConsumeValueOrDie() {
+ assert(status_.ok());
+ return std::move(value_);
+}
+
+template <typename T>
+StatusOr<T>::StatusOr(const Status& status)
+ : status_(status) {
+ assert(!status.ok());
+ if (status.ok()) {
+ status_ =
+ Status(error::INTERNAL,
+ "Status::OK is not a valid constructor argument to StatusOr<T>");
+ }
+}
+
+template <typename T>
+StatusOr<T>::StatusOr(T&& value)
+ : status_() {
+ CheckValueNotNull(value);
+ value_ = std::move(value);
+}
+
+template <typename T>
+void StatusOr<T>::CheckValueNotNull(const T& value) {
+ assert(!IsNull<T>::IsValueNull(value));
+ if (IsNull<T>::IsValueNull(value)) {
+ status_ =
+ Status(error::INTERNAL,
+ "NULL is not a valid constructor argument to StatusOr<T*>");
+ }
+}
+
+} // namespace port
+} // namespace gputools
+} // namespace perftools
+
+#endif // TENSORFLOW_STREAM_EXECUTOR_LIB_STATUSOR_H_
diff --git a/tensorflow/stream_executor/lib/str_util.h b/tensorflow/stream_executor/lib/str_util.h
new file mode 100644
index 0000000000..021f54dfec
--- /dev/null
+++ b/tensorflow/stream_executor/lib/str_util.h
@@ -0,0 +1,30 @@
+#ifndef TENSORFLOW_STREAM_EXECUTOR_LIB_STR_UTIL_H_
+#define TENSORFLOW_STREAM_EXECUTOR_LIB_STR_UTIL_H_
+
+#include "tensorflow/core/lib/strings/str_util.h"
+#include "tensorflow/stream_executor/lib/stringpiece.h"
+
+namespace perftools {
+namespace gputools {
+namespace port {
+
+using tensorflow::str_util::Join;
+using tensorflow::str_util::Split;
+
+// Returns a copy of the input string 'str' with the given 'suffix'
+// removed. If the suffix doesn't match, returns a copy of the original string.
+inline string StripSuffixString(port::StringPiece str, port::StringPiece suffix) {
+ if (str.ends_with(suffix)) {
+ str.remove_suffix(suffix.size());
+ }
+ return str.ToString();
+}
+
+using tensorflow::str_util::Lowercase;
+using tensorflow::str_util::Uppercase;
+
+} // namespace port
+} // namespace gputools
+} // namespace perftools
+
+#endif // TENSORFLOW_STREAM_EXECUTOR_LIB_STR_UTIL_H_
diff --git a/tensorflow/stream_executor/lib/strcat.h b/tensorflow/stream_executor/lib/strcat.h
new file mode 100644
index 0000000000..b3fe4da327
--- /dev/null
+++ b/tensorflow/stream_executor/lib/strcat.h
@@ -0,0 +1,17 @@
+#ifndef TENSORFLOW_STREAM_EXECUTOR_LIB_STRCAT_H_
+#define TENSORFLOW_STREAM_EXECUTOR_LIB_STRCAT_H_
+
+#include "tensorflow/core/lib/strings/strcat.h"
+
+namespace perftools {
+namespace gputools {
+namespace port {
+
+using tensorflow::strings::StrCat;
+using tensorflow::strings::StrAppend;
+
+} // namespace port
+} // namespace gputools
+} // namespace perftools
+
+#endif // TENSORFLOW_STREAM_EXECUTOR_LIB_STRCAT_H_
diff --git a/tensorflow/stream_executor/lib/stringpiece.h b/tensorflow/stream_executor/lib/stringpiece.h
new file mode 100644
index 0000000000..14e6fc99d7
--- /dev/null
+++ b/tensorflow/stream_executor/lib/stringpiece.h
@@ -0,0 +1,17 @@
+#ifndef TENSORFLOW_STREAM_EXECUTOR_LIB_STRINGPIECE_H_
+#define TENSORFLOW_STREAM_EXECUTOR_LIB_STRINGPIECE_H_
+
+#include "tensorflow/core/lib/core/stringpiece.h"
+#include "tensorflow/stream_executor/platform/port.h"
+
+namespace perftools {
+namespace gputools {
+namespace port {
+
+using tensorflow::StringPiece;
+
+} // namespace port
+} // namespace gputools
+} // namespace perftools
+
+#endif // TENSORFLOW_STREAM_EXECUTOR_LIB_STRINGPIECE_H_
diff --git a/tensorflow/stream_executor/lib/stringprintf.h b/tensorflow/stream_executor/lib/stringprintf.h
new file mode 100644
index 0000000000..379e7e9a83
--- /dev/null
+++ b/tensorflow/stream_executor/lib/stringprintf.h
@@ -0,0 +1,18 @@
+#ifndef TENSORFLOW_STREAM_EXECUTOR_LIB_STRINGPRINTF_H_
+#define TENSORFLOW_STREAM_EXECUTOR_LIB_STRINGPRINTF_H_
+
+#include "tensorflow/core/lib/strings/stringprintf.h"
+
+namespace perftools {
+namespace gputools {
+namespace port {
+
+using tensorflow::strings::Printf;
+using tensorflow::strings::Appendf;
+using tensorflow::strings::Appendv;
+
+} // namespace port
+} // namespace gputools
+} // namespace perftools
+
+#endif // TENSORFLOW_STREAM_EXECUTOR_LIB_STRINGPRINTF_H_
diff --git a/tensorflow/stream_executor/lib/thread_options.h b/tensorflow/stream_executor/lib/thread_options.h
new file mode 100644
index 0000000000..7d436578d6
--- /dev/null
+++ b/tensorflow/stream_executor/lib/thread_options.h
@@ -0,0 +1,16 @@
+#ifndef TENSORFLOW_STREAM_EXECUTOR_LIB_THREAD_OPTIONS_H_
+#define TENSORFLOW_STREAM_EXECUTOR_LIB_THREAD_OPTIONS_H_
+
+#include "tensorflow/core/public/env.h"
+
+namespace perftools {
+namespace gputools {
+namespace port {
+
+using tensorflow::ThreadOptions;
+
+} // namespace port
+} // namespace gputools
+} // namespace perftools
+
+#endif // TENSORFLOW_STREAM_EXECUTOR_LIB_THREAD_OPTIONS_H_
diff --git a/tensorflow/stream_executor/lib/threadpool.h b/tensorflow/stream_executor/lib/threadpool.h
new file mode 100644
index 0000000000..3cf297d57b
--- /dev/null
+++ b/tensorflow/stream_executor/lib/threadpool.h
@@ -0,0 +1,19 @@
+#ifndef TENSORFLOW_STREAM_EXECUTOR_LIB_THREADPOOL_H_
+#define TENSORFLOW_STREAM_EXECUTOR_LIB_THREADPOOL_H_
+
+#include "tensorflow/core/lib/core/threadpool.h"
+#include "tensorflow/stream_executor/lib/env.h"
+#include "tensorflow/stream_executor/lib/notification.h"
+#include "tensorflow/stream_executor/lib/thread_options.h"
+
+namespace perftools {
+namespace gputools {
+namespace port {
+
+using tensorflow::thread::ThreadPool;
+
+} // namespace port
+} // namespace gputools
+} // namespace perftools
+
+#endif // TENSORFLOW_STREAM_EXECUTOR_LIB_THREADPOOL_H_