From fbe696a61c17e60803b1cbc162359cbed83f400c Mon Sep 17 00:00:00 2001 From: Ryan Nett <rnett@calpoly.edu> Date: Fri, 25 Jun 2021 12:02:23 -0700 Subject: [PATCH 1/3] Start of log sink mapping Signed-off-by: Ryan Nett <rnett@calpoly.edu> --- tensorflow-core/tensorflow-core-api/pom.xml | 2 + .../internal/c_api/TFDefaultLogSink.java | 36 ++ .../tensorflow/internal/c_api/TFLogEntry.java | 43 ++ .../tensorflow/internal/c_api/TFLogSink.java | 38 ++ .../internal/c_api/global/tensorflow.java | 460 ++++++++++++++++++ .../internal/c_api/presets/tensorflow.java | 49 +- 6 files changed, 626 insertions(+), 2 deletions(-) create mode 100644 tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFDefaultLogSink.java create mode 100644 tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogEntry.java create mode 100644 tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogSink.java diff --git a/tensorflow-core/tensorflow-core-api/pom.xml b/tensorflow-core/tensorflow-core-api/pom.xml index 4ebe1234e80..fd96cca67fd 100644 --- a/tensorflow-core/tensorflow-core-api/pom.xml +++ b/tensorflow-core/tensorflow-core-api/pom.xml @@ -212,6 +212,8 @@ <includePaths> <includePath>${project.basedir}/</includePath> <includePath>${project.basedir}/bazel-${project.artifactId}/external/org_tensorflow/</includePath> + <includePath>${project.basedir}/bazel-${project.artifactId}/external/com_google_absl/</includePath> + <includePath>${project.basedir}/bazel-${project.artifactId}/external/eigen_archive/</includePath> </includePaths> <linkPaths> <linkPath>${project.basedir}/bazel-bin/external/llvm_openmp/</linkPath> diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFDefaultLogSink.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFDefaultLogSink.java new file mode 100644 index 00000000000..8ec76ade84a --- /dev/null +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFDefaultLogSink.java @@ -0,0 +1,36 @@ +// Targeted by JavaCPP version 1.5.4: DO NOT EDIT THIS FILE + +package org.tensorflow.internal.c_api; + +import java.nio.*; +import org.bytedeco.javacpp.*; +import org.bytedeco.javacpp.annotation.*; + +import static org.tensorflow.internal.c_api.global.tensorflow.*; + + +// This is the default log sink. This log sink is used if there are no other +// log sinks registered. To disable the default log sink, set the +// "no_default_logger" Bazel config setting to true or define a +// NO_DEFAULT_LOGGER preprocessor symbol. This log sink will always log to +// stderr. +@Namespace("tensorflow") @Properties(inherit = org.tensorflow.internal.c_api.presets.tensorflow.class) +public class TFDefaultLogSink extends TFLogSink { + static { Loader.load(); } + /** Default native constructor. */ + public TFDefaultLogSink() { super((Pointer)null); allocate(); } + /** Native array allocator. Access with {@link Pointer#position(long)}. */ + public TFDefaultLogSink(long size) { super((Pointer)null); allocateArray(size); } + /** Pointer cast constructor. Invokes {@link Pointer#Pointer(Pointer)}. */ + public TFDefaultLogSink(Pointer p) { super(p); } + private native void allocate(); + private native void allocateArray(long size); + @Override public TFDefaultLogSink position(long position) { + return (TFDefaultLogSink)super.position(position); + } + @Override public TFDefaultLogSink getPointer(long i) { + return new TFDefaultLogSink(this).position(position + i); + } + + public native void Send(@Const @ByRef TFLogEntry entry); +} diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogEntry.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogEntry.java new file mode 100644 index 00000000000..13514222b89 --- /dev/null +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogEntry.java @@ -0,0 +1,43 @@ +// Targeted by JavaCPP version 1.5.4: DO NOT EDIT THIS FILE + +package org.tensorflow.internal.c_api; + +import java.nio.*; +import org.bytedeco.javacpp.*; +import org.bytedeco.javacpp.annotation.*; + +import static org.tensorflow.internal.c_api.global.tensorflow.*; + // namespace internal + +// LogSink support adapted from //base/logging.h +// +// `LogSink` is an interface which can be extended to intercept and process +// all log messages. LogSink implementations must be thread-safe. A single +// instance will be called from whichever thread is performing a logging +// operation. +@Namespace("tensorflow") @NoOffset @Properties(inherit = org.tensorflow.internal.c_api.presets.tensorflow.class) +public class TFLogEntry extends Pointer { + static { Loader.load(); } + /** Pointer cast constructor. Invokes {@link Pointer#Pointer(Pointer)}. */ + public TFLogEntry(Pointer p) { super(p); } + + public TFLogEntry(int severity, @StdString @Cast({"char*", "std::string&&"}) BytePointer message) { super((Pointer)null); allocate(severity, message); } + private native void allocate(int severity, @StdString @Cast({"char*", "std::string&&"}) BytePointer message); + public TFLogEntry(int severity, @StdString @Cast({"char*", "std::string&&"}) String message) { super((Pointer)null); allocate(severity, message); } + private native void allocate(int severity, @StdString @Cast({"char*", "std::string&&"}) String message); + + public TFLogEntry(int severity, @StdString @Cast({"char*", "std::string&&"}) BytePointer fname, int line, + @StdString @Cast({"char*", "std::string&&"}) BytePointer message) { super((Pointer)null); allocate(severity, fname, line, message); } + private native void allocate(int severity, @StdString @Cast({"char*", "std::string&&"}) BytePointer fname, int line, + @StdString @Cast({"char*", "std::string&&"}) BytePointer message); + public TFLogEntry(int severity, @StdString @Cast({"char*", "std::string&&"}) String fname, int line, + @StdString @Cast({"char*", "std::string&&"}) String message) { super((Pointer)null); allocate(severity, fname, line, message); } + private native void allocate(int severity, @StdString @Cast({"char*", "std::string&&"}) String fname, int line, + @StdString @Cast({"char*", "std::string&&"}) String message); + + public native @Cast("absl::LogSeverity") int log_severity(); + public native @StdString @Cast({"char*", "std::string&&"}) BytePointer FName(); + public native int Line(); + public native @StdString @Cast({"char*", "std::string&&"}) BytePointer ToString(); + public native @StdString @Cast({"char*", "std::string&&"}) BytePointer text_message(); +} diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogSink.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogSink.java new file mode 100644 index 00000000000..456b6dbbbd8 --- /dev/null +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogSink.java @@ -0,0 +1,38 @@ +// Targeted by JavaCPP version 1.5.4: DO NOT EDIT THIS FILE + +package org.tensorflow.internal.c_api; + +import java.nio.*; +import org.bytedeco.javacpp.*; +import org.bytedeco.javacpp.annotation.*; + +import static org.tensorflow.internal.c_api.global.tensorflow.*; + + +@Namespace("tensorflow") @Properties(inherit = org.tensorflow.internal.c_api.presets.tensorflow.class) +public class TFLogSink extends Pointer { + static { Loader.load(); } + /** Pointer cast constructor. Invokes {@link Pointer#Pointer(Pointer)}. */ + public TFLogSink(Pointer p) { super(p); } + + + // `Send` is called synchronously during the log statement. The logging + // module guarantees not to call `Send` concurrently on the same log sink. + // Implementations should be careful not to call`LOG` or `CHECK` or take + // any locks that might be held by the `LOG` caller, to avoid deadlock. + // + // `e` is guaranteed to remain valid until the subsequent call to + // `WaitTillSent` completes, so implementations may store a pointer to or + // copy of `e` (e.g. in a thread local variable) for use in `WaitTillSent`. + public native void Send(@Const @ByRef TFLogEntry entry); + + // `WaitTillSent` blocks the calling thread (the thread that generated a log + // message) until the sink has finished processing the log message. + // `WaitTillSent` is called once per log message, following the call to + // `Send`. This may be useful when log messages are buffered or processed + // asynchronously by an expensive log sink. + // The default implementation returns immediately. Like `Send`, + // implementations should be careful not to call `LOG` or `CHECK or take any + // locks that might be held by the `LOG` caller, to avoid deadlock. + public native void WaitTillSent(); +} diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/global/tensorflow.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/global/tensorflow.java index b345ab4dad2..a9a68b12e9f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/global/tensorflow.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/global/tensorflow.java @@ -4739,4 +4739,464 @@ public static native void TFE_ContextExportRunMetadata(TFE_Context ctx, // #endif // TENSORFLOW_C_EAGER_C_API_H_ +// Parsed from tensorflow/core/platform/default/logging.h + +/* 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. +==============================================================================*/ + +// #ifndef TENSORFLOW_CORE_PLATFORM_DEFAULT_LOGGING_H_ +// #define TENSORFLOW_CORE_PLATFORM_DEFAULT_LOGGING_H_ + +// IWYU pragma: private, include "third_party/tensorflow/core/platform/logging.h" +// IWYU pragma: friend third_party/tensorflow/core/platform/logging.h + +// #include <atomic> +// #include <limits> +// #include <memory> +// #include <sstream> +// #include <vector> + +// #include "absl/base/log_severity.h" +// #include "absl/strings/string_view.h" +// #include "tensorflow/core/platform/macros.h" +// #include "tensorflow/core/platform/types.h" + +// TODO(mrry): Prevent this Windows.h #define from leaking out of our headers. +// #undef ERROR + // base_logging::INFO; + // base_logging::WARNING; + // base_logging::ERROR; + // base_logging::FATAL; + // base_logging::NUM_SEVERITIES; + +// Uses the lower operator & precedence to voidify a LogMessage reference, so +// that the ternary VLOG() implementation is balanced, type wise. + +// LogMessageFatal ensures the process will exit in failure after +// logging this message. + +// LogMessageNull supports the DVLOG macro by simply dropping any log messages. + +// #define _TF_LOG_INFO +// ::tensorflow::internal::LogMessage(__FILE__, __LINE__, ::tensorflow::INFO) +// #define _TF_LOG_WARNING +// ::tensorflow::internal::LogMessage(__FILE__, __LINE__, ::tensorflow::WARNING) +// #define _TF_LOG_ERROR +// ::tensorflow::internal::LogMessage(__FILE__, __LINE__, ::tensorflow::ERROR) +// #define _TF_LOG_FATAL +// ::tensorflow::internal::LogMessageFatal(__FILE__, __LINE__) + +// #define _TF_LOG_QFATAL _TF_LOG_FATAL + +// #define LOG(severity) _TF_LOG_##severity + +// #ifdef IS_MOBILE_PLATFORM + +// Turn VLOG off when under mobile devices for considerations of binary size. +// #define VLOG_IS_ON(lvl) ((lvl) <= 0) + +// #else + +// Otherwise, set TF_CPP_MAX_VLOG_LEVEL environment to update minimum log level +// of VLOG, or TF_CPP_VMODULE to set the minimum log level for individual +// translation units. +// #define VLOG_IS_ON(lvl) +// (([](int level, const char* fname) { +// static const bool vmodule_activated = +// ::tensorflow::internal::LogMessage::VmoduleActivated(fname, level); +// return vmodule_activated; +// })(lvl, __FILE__)) + +// #endif + +// #define VLOG(level) +// TF_PREDICT_TRUE(!VLOG_IS_ON(level)) +// ? (void)0 +// : ::tensorflow::internal::Voidifier() & +// ::tensorflow::internal::LogMessage(__FILE__, __LINE__, +// tensorflow::INFO) + +// `DVLOG` behaves like `VLOG` in debug mode (i.e. `#ifndef NDEBUG`). +// Otherwise, it compiles away and does nothing. +// #ifndef NDEBUG +// #define DVLOG VLOG +// #else +// #define DVLOG(verbose_level) +// while (false && (verbose_level) > 0) ::tensorflow::internal::LogMessageNull() +// #endif + +// This macro has a lot going on! +// +// * A local static (`logging_internal_stateful_condition_state`) is +// declared in a scope such that each `LOG_EVERY_N` (etc.) line has its own +// state. +// * `COUNTER`, the third variable, is used to support `<< COUNTER`. It is not +// mangled, so shadowing can be a problem, albeit more of a +// shoot-yourself-in-the-foot one. Don't name your variables `COUNTER`. +// * A single for loop can declare state and also test +// `condition && state.ShouldLog()`, but there's no way to constrain it to run +// only once (or not at all) without declaring another variable. The outer +// for-loop declares this variable (`do_log`). +// * Using for loops instead of if statements means there's no risk of an +// ambiguous dangling else statement. +// #define LOGGING_INTERNAL_STATEFUL_CONDITION(kind, condition, arg) +// for (bool logging_internal_stateful_condition_do_log(condition); +// logging_internal_stateful_condition_do_log; +// logging_internal_stateful_condition_do_log = false) +// for (static ::tensorflow::internal::Log##kind##State +// logging_internal_stateful_condition_state; +// logging_internal_stateful_condition_do_log && +// logging_internal_stateful_condition_state.ShouldLog(arg); +// logging_internal_stateful_condition_do_log = false) +// for (const uint32_t COUNTER ABSL_ATTRIBUTE_UNUSED = +// logging_internal_stateful_condition_state.counter(); +// logging_internal_stateful_condition_do_log; +// logging_internal_stateful_condition_do_log = false) + +// An instance of `LOG_EVERY_N` increments a hidden zero-initialized counter +// every time execution passes through it and logs the specified message when +// the counter's value is a multiple of `n`, doing nothing otherwise. Each +// instance has its own counter. The counter's value can be logged by streaming +// the symbol `COUNTER`. `LOG_EVERY_N` is thread-safe. +// Example: +// +// for (const auto& user : all_users) { +// LOG_EVERY_N(INFO, 1000) << "Processing user #" << COUNTER; +// ProcessUser(user); +// } +// #define LOG_EVERY_N(severity, n) +// LOGGING_INTERNAL_STATEFUL_CONDITION(EveryN, true, n) +// LOG(severity) +// `LOG_FIRST_N` behaves like `LOG_EVERY_N` except that the specified message is +// logged when the counter's value is less than `n`. `LOG_FIRST_N` is +// thread-safe. +// #define LOG_FIRST_N(severity, n) +// LOGGING_INTERNAL_STATEFUL_CONDITION(FirstN, true, n) +// LOG(severity) +// `LOG_EVERY_POW_2` behaves like `LOG_EVERY_N` except that the specified +// message is logged when the counter's value is a power of 2. +// `LOG_EVERY_POW_2` is thread-safe. +// #define LOG_EVERY_POW_2(severity) +// LOGGING_INTERNAL_STATEFUL_CONDITION(EveryPow2, true, 0) +// LOG(severity) +// An instance of `LOG_EVERY_N_SEC` uses a hidden state variable to log the +// specified message at most once every `n_seconds`. A hidden counter of +// executions (whether a message is logged or not) is also maintained and can be +// logged by streaming the symbol `COUNTER`. `LOG_EVERY_N_SEC` is thread-safe. +// Example: +// +// LOG_EVERY_N_SEC(INFO, 2.5) << "Got " << COUNTER << " cookies so far"; +// #define LOG_EVERY_N_SEC(severity, n_seconds) +// LOGGING_INTERNAL_STATEFUL_CONDITION(EveryNSec, true, n_seconds) +// LOG(severity) + +// CHECK dies with a fatal error if condition is not true. It is *not* +// controlled by NDEBUG, so the check will be executed regardless of +// compilation mode. Therefore, it is safe to do things like: +// CHECK(fp->Write(x) == 4) +// #define CHECK(condition) +// if (TF_PREDICT_FALSE(!(condition))) +// LOG(FATAL) << "Check failed: " #condition " " + +// Function is overloaded for integral types to allow static const +// integrals declared in classes and not defined to be used as arguments to +// CHECK* macros. It's not encouraged though. + + + + + + + + + + + +// This formats a value for a failing CHECK_XX statement. Ordinarily, +// it uses the definition for operator<<, with a few special cases below. + +// Overrides for char types provide readable values for unprintable +// characters. +@Namespace("tensorflow::internal") public static native void MakeCheckOpValueString(@Cast("std::ostream*") Pointer os, @Cast("const char") byte v); + +// #if LANG_CXX11 +// We need an explicit specialization for std::nullptr_t. +@Namespace("tensorflow::internal") public static native void MakeCheckOpValueString(@Cast("std::ostream*") Pointer os, Pointer v); +// #endif + +// A container for a string pointer which can be evaluated to a bool - +// true iff the pointer is non-NULL. + +// Build the error message string. Specify no inlining for code size. + +// A helper class for formatting "expr (V1 vs. V2)" in a CHECK_XX +// statement. See MakeCheckOpString for sample usage. Other +// approaches were considered: use of a template method (e.g., +// base::BuildCheckOpString(exprtext, base::Print<T1>, &v1, +// base::Print<T2>, &v2), however this approach has complications +// related to volatile arguments and function-pointer arguments). + +// Helper functions for CHECK_OP macro. +// The (int, int) specialization works around the issue that the compiler +// will not instantiate the template version of the function on values of +// unnamed enum type - see comment below. +// The (size_t, int) and (int, size_t) specialization are to handle unsigned +// comparison errors while still being thorough with the comparison. +// #define TF_DEFINE_CHECK_OP_IMPL(name, op) +// template <typename T1, typename T2> +// inline string* name##Impl(const T1& v1, const T2& v2, +// const char* exprtext) { +// if (TF_PREDICT_TRUE(v1 op v2)) +// return NULL; +// else +// return ::tensorflow::internal::MakeCheckOpString(v1, v2, exprtext); +// } +// inline string* name##Impl(int v1, int v2, const char* exprtext) { +// return name##Impl<int, int>(v1, v2, exprtext); +// } +// inline string* name##Impl(const size_t v1, const int v2, +// const char* exprtext) { +// if (TF_PREDICT_FALSE(v2 < 0)) { +// return ::tensorflow::internal::MakeCheckOpString(v1, v2, exprtext); +// } +// return name##Impl<size_t, size_t>(v1, v2, exprtext); +// } +// inline string* name##Impl(const int v1, const size_t v2, +// const char* exprtext) { +// if (TF_PREDICT_FALSE(v2 >= std::numeric_limits<int>::max())) { +// return ::tensorflow::internal::MakeCheckOpString(v1, v2, exprtext); +// } +// const size_t uval = (size_t)((unsigned)v2); +// return name##Impl<size_t, size_t>(v1, uval, exprtext); +// } + +// We use the full name Check_EQ, Check_NE, etc. in case the file including +// base/logging.h provides its own #defines for the simpler names EQ, NE, etc. +// This happens if, for example, those are used as token names in a +// yacc grammar. + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_EQImpl(int v1, int v2, @Cast("const char*") BytePointer exprtext); + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_EQImpl(int v1, int v2, String exprtext); + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_EQImpl(@Cast("const size_t") long v1, int v2, + @Cast("const char*") BytePointer exprtext); + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_EQImpl(@Cast("const size_t") long v1, int v2, + String exprtext); + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_EQImpl(int v1, @Cast("const size_t") long v2, + @Cast("const char*") BytePointer exprtext); + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_EQImpl(int v1, @Cast("const size_t") long v2, + String exprtext); // Compilation error with CHECK_EQ(NULL, x)? + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_NEImpl(int v1, int v2, @Cast("const char*") BytePointer exprtext); + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_NEImpl(int v1, int v2, String exprtext); + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_NEImpl(@Cast("const size_t") long v1, int v2, + @Cast("const char*") BytePointer exprtext); + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_NEImpl(@Cast("const size_t") long v1, int v2, + String exprtext); + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_NEImpl(int v1, @Cast("const size_t") long v2, + @Cast("const char*") BytePointer exprtext); + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_NEImpl(int v1, @Cast("const size_t") long v2, + String exprtext); // Use CHECK(x == NULL) instead. + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_LEImpl(int v1, int v2, @Cast("const char*") BytePointer exprtext); + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_LEImpl(int v1, int v2, String exprtext); + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_LEImpl(@Cast("const size_t") long v1, int v2, + @Cast("const char*") BytePointer exprtext); + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_LEImpl(@Cast("const size_t") long v1, int v2, + String exprtext); + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_LEImpl(int v1, @Cast("const size_t") long v2, + @Cast("const char*") BytePointer exprtext); + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_LEImpl(int v1, @Cast("const size_t") long v2, + String exprtext); + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_LTImpl(int v1, int v2, @Cast("const char*") BytePointer exprtext); + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_LTImpl(int v1, int v2, String exprtext); + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_LTImpl(@Cast("const size_t") long v1, int v2, + @Cast("const char*") BytePointer exprtext); + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_LTImpl(@Cast("const size_t") long v1, int v2, + String exprtext); + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_LTImpl(int v1, @Cast("const size_t") long v2, + @Cast("const char*") BytePointer exprtext); + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_LTImpl(int v1, @Cast("const size_t") long v2, + String exprtext); + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_GEImpl(int v1, int v2, @Cast("const char*") BytePointer exprtext); + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_GEImpl(int v1, int v2, String exprtext); + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_GEImpl(@Cast("const size_t") long v1, int v2, + @Cast("const char*") BytePointer exprtext); + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_GEImpl(@Cast("const size_t") long v1, int v2, + String exprtext); + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_GEImpl(int v1, @Cast("const size_t") long v2, + @Cast("const char*") BytePointer exprtext); + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_GEImpl(int v1, @Cast("const size_t") long v2, + String exprtext); + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_GTImpl(int v1, int v2, @Cast("const char*") BytePointer exprtext); + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_GTImpl(int v1, int v2, String exprtext); + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_GTImpl(@Cast("const size_t") long v1, int v2, + @Cast("const char*") BytePointer exprtext); + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_GTImpl(@Cast("const size_t") long v1, int v2, + String exprtext); + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_GTImpl(int v1, @Cast("const size_t") long v2, + @Cast("const char*") BytePointer exprtext); + @Namespace("tensorflow::internal") public static native @StdString @Cast({"char*", "std::string*"}) BytePointer Check_GTImpl(int v1, @Cast("const size_t") long v2, + String exprtext); +// #undef TF_DEFINE_CHECK_OP_IMPL + +// In optimized mode, use CheckOpString to hint to compiler that +// the while condition is unlikely. +// #define CHECK_OP_LOG(name, op, val1, val2) +// while (::tensorflow::internal::CheckOpString _result{ +// ::tensorflow::internal::name##Impl( +// ::tensorflow::internal::GetReferenceableValue(val1), +// ::tensorflow::internal::GetReferenceableValue(val2), +// #val1 " " #op " " #val2)}) +// ::tensorflow::internal::LogMessageFatal(__FILE__, __LINE__) << *(_result.str_) + +// #define CHECK_OP(name, op, val1, val2) CHECK_OP_LOG(name, op, val1, val2) + +// CHECK_EQ/NE/... +// #define CHECK_EQ(val1, val2) CHECK_OP(Check_EQ, ==, val1, val2) +// #define CHECK_NE(val1, val2) CHECK_OP(Check_NE, !=, val1, val2) +// #define CHECK_LE(val1, val2) CHECK_OP(Check_LE, <=, val1, val2) +// #define CHECK_LT(val1, val2) CHECK_OP(Check_LT, <, val1, val2) +// #define CHECK_GE(val1, val2) CHECK_OP(Check_GE, >=, val1, val2) +// #define CHECK_GT(val1, val2) CHECK_OP(Check_GT, >, val1, val2) +// #define CHECK_NOTNULL(val) +// ::tensorflow::internal::CheckNotNull(__FILE__, __LINE__, +// "'" #val "' Must be non NULL", (val)) + +// #ifndef NDEBUG +// DCHECK_EQ/NE/... +// #define DCHECK(condition) CHECK(condition) +// #define DCHECK_EQ(val1, val2) CHECK_EQ(val1, val2) +// #define DCHECK_NE(val1, val2) CHECK_NE(val1, val2) +// #define DCHECK_LE(val1, val2) CHECK_LE(val1, val2) +// #define DCHECK_LT(val1, val2) CHECK_LT(val1, val2) +// #define DCHECK_GE(val1, val2) CHECK_GE(val1, val2) +// #define DCHECK_GT(val1, val2) CHECK_GT(val1, val2) + +// #else + +// #define DCHECK(condition) +// while (false && (condition)) LOG(FATAL) + +// NDEBUG is defined, so DCHECK_EQ(x, y) and so on do nothing. +// However, we still want the compiler to parse x and y, because +// we don't want to lose potentially useful errors and warnings. +// _DCHECK_NOP is a helper, and should not be used outside of this file. +// #define _TF_DCHECK_NOP(x, y) +// while (false && ((void)(x), (void)(y), 0)) LOG(FATAL) + +// #define DCHECK_EQ(x, y) _TF_DCHECK_NOP(x, y) +// #define DCHECK_NE(x, y) _TF_DCHECK_NOP(x, y) +// #define DCHECK_LE(x, y) _TF_DCHECK_NOP(x, y) +// #define DCHECK_LT(x, y) _TF_DCHECK_NOP(x, y) +// #define DCHECK_GE(x, y) _TF_DCHECK_NOP(x, y) +// #define DCHECK_GT(x, y) _TF_DCHECK_NOP(x, y) + +// #endif + +// These are for when you don't want a CHECK failure to print a verbose +// stack trace. The implementation of CHECK* in this file already doesn't. +// #define QCHECK(condition) CHECK(condition) +// #define QCHECK_EQ(x, y) CHECK_EQ(x, y) +// #define QCHECK_NE(x, y) CHECK_NE(x, y) +// #define QCHECK_LE(x, y) CHECK_LE(x, y) +// #define QCHECK_LT(x, y) CHECK_LT(x, y) +// #define QCHECK_GE(x, y) CHECK_GE(x, y) +// #define QCHECK_GT(x, y) CHECK_GT(x, y) + +@Namespace("tensorflow::internal") public static native @Cast("tensorflow::int64") long MinLogLevelFromEnv(); + +@Namespace("tensorflow::internal") public static native @Cast("tensorflow::int64") long MaxVLogLevelFromEnv(); + + +// Targeting ../TFLogEntry.java + + +// Targeting ../TFLogSink.java + + +// Targeting ../TFDefaultLogSink.java + + + +// Add or remove a `LogSink` as a consumer of logging data. Thread-safe. +@Namespace("tensorflow") public static native void TFAddLogSink(TFLogSink sink); +@Namespace("tensorflow") public static native void TFRemoveLogSink(TFLogSink sink); + +// Get all the log sinks. Thread-safe. +@Namespace("tensorflow") public static native @Cast("tensorflow::TFLogSink**") @StdVector PointerPointer TFGetLogSinks(); + + // namespace tensorflow + +// #endif // TENSORFLOW_CORE_PLATFORM_DEFAULT_LOGGING_H_ + + +// Parsed from absl/base/log_severity.h + +// Copyright 2017 The Abseil Authors. +// +// 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 +// +// https://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. + +// #ifndef ABSL_BASE_INTERNAL_LOG_SEVERITY_H_ +// #define ABSL_BASE_INTERNAL_LOG_SEVERITY_H_ + +// #include <array> +// #include <ostream> + +// #include "absl/base/attributes.h" +// #include "absl/base/config.h" +/** enum class absl::LogSeverity */ +public static final int + kInfo = 0, + kWarning = 1, + kError = 2, + kFatal = 3; + +// LogSeverities() +// +// Returns an iterable of all standard `absl::LogSeverity` values, ordered from +// least to most severe. + + +// LogSeverityName() +// +// Returns the all-caps string representation (e.g. "INFO") of the specified +// severity level if it is one of the standard levels and "UNKNOWN" otherwise. +@Namespace("absl") public static native @Cast("const char*") BytePointer LogSeverityName(@Cast("absl::LogSeverity") int s); + +// NormalizeLogSeverity() +// +// Values less than `kInfo` normalize to `kInfo`; values greater than `kFatal` +// normalize to `kError` (**NOT** `kFatal`). +@Namespace("absl") public static native @Cast("const absl::LogSeverity") int NormalizeLogSeverity(@Cast("absl::LogSeverity") int s); + +// operator<< +// +// The exact representation of a streamed `absl::LogSeverity` is deliberately +// unspecified; do not rely on it. +@Namespace("absl") public static native @Cast("std::ostream*") @ByRef @Name("operator <<") Pointer shiftLeft(@Cast("std::ostream*") @ByRef Pointer os, @Cast("absl::LogSeverity") int s); + + // namespace absl + +// #endif // ABSL_BASE_INTERNAL_LOG_SEVERITY_H_ + + } diff --git a/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/internal/c_api/presets/tensorflow.java b/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/internal/c_api/presets/tensorflow.java index 6cb3be62eb7..8eaec809863 100644 --- a/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/internal/c_api/presets/tensorflow.java +++ b/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/internal/c_api/presets/tensorflow.java @@ -46,7 +46,9 @@ // "tensorflow/c/env.h", "tensorflow/c/kernels.h", "tensorflow/c/ops.h", - "tensorflow/c/eager/c_api.h" + "tensorflow/c/eager/c_api.h", + "tensorflow/core/platform/default/logging.h", + "absl/base/log_severity.h" }, link = "tensorflow_cc@.2", preload = {"iomp5", "mklml", "mklml_intel", "tensorflow_framework@.2"}, @@ -385,6 +387,49 @@ public void map(InfoMap infoMap) { "TF_ShapeInferenceContextDimValueKnown", "TFE_NewTensorHandle(const tensorflow::Tensor&, TF_Status*)", "TF_InitKernel") - .skip()); + .skip()) + .put( + new Info("tensorflow::uint32", "tensorflow::int32", "uint32", "int32") + .cast() + .valueTypes("int") + .pointerTypes("IntPointer", "int[]")) + .put( + new Info("tensorflow::int16", "tensorflow::uint16", "int16", "uint16") + .cast() + .valueTypes("short") + .pointerTypes("ShortPointer", "short[]")) + .put( + new Info("tensorflow::uint64", "tensorflow::int64", "int64", "uint64") + .cast() + .valueTypes("long") + .pointerTypes("LongPointer", "long[]")) + .put(new Info("absl::string_view", "absl::lts_2020_09_23::string_view", "string", "std::string", "tensorflow::string").annotations("@StdString") + .valueTypes("@Cast({\"char*\", \"std::string&&\"}) BytePointer", "@Cast({\"char*\", \"std::string&&\"}) String") + .pointerTypes("@Cast({\"char*\", \"std::string*\"}) BytePointer")) + .put(new Info("absl::LogSeverity", "LogSeverity", "tensorflow::LogSeverity").cast().valueTypes("int").pointerTypes("IntPointer", "int[]")) + .put(new Info("tensorflow::internal::LogEveryNSecState", + "tensorflow::internal::LogEveryNState", + "tensorflow::internal::LogEveryPow2State", + "tensorflow::internal::LogFirstNState", + "tensorflow::internal::Voidifier", + "tensorflow::internal::LogMessage", + "tensorflow::internal::LogMessageFatal", + "tensorflow::internal::LogMessageNull", + "tensorflow::internal::CheckOpMessageBuilder", + "tensorflow::internal::CheckOpString", + "tensorflow::internal::GetReferenceableValue", + "DVLOG", + "absl::LogSeverities").skip()) + .put(new Info( + "tensorflow::INFO", + "tensorflow::WARNING", + "tensorflow::ERROR", + "tensorflow::FATAL", + "tensorflow::NUM_SEVERITIES", + "_TF_LOG_INFO", + "_TF_LOG_WARNING", + "_TF_LOG_ERROR", + "_TF_LOG_FATAL", + "_TF_LOG_QFATAL").skip()); } } From 8f8aadc04d240dcc41def69e134ddd8020a769f4 Mon Sep 17 00:00:00 2001 From: Ryan Nett <rnett@calpoly.edu> Date: Sat, 26 Jun 2021 18:16:18 -0700 Subject: [PATCH 2/3] Avoid string_view Signed-off-by: Ryan Nett <rnett@calpoly.edu> --- .../tensorflow/internal/c_api/TFLogEntry.java | 15 +---- .../internal/c_api/presets/tensorflow.java | 62 +++++++++++-------- 2 files changed, 37 insertions(+), 40 deletions(-) diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogEntry.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogEntry.java index 13514222b89..7835d15a8a4 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogEntry.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogEntry.java @@ -21,23 +21,10 @@ public class TFLogEntry extends Pointer { /** Pointer cast constructor. Invokes {@link Pointer#Pointer(Pointer)}. */ public TFLogEntry(Pointer p) { super(p); } - public TFLogEntry(int severity, @StdString @Cast({"char*", "std::string&&"}) BytePointer message) { super((Pointer)null); allocate(severity, message); } - private native void allocate(int severity, @StdString @Cast({"char*", "std::string&&"}) BytePointer message); - public TFLogEntry(int severity, @StdString @Cast({"char*", "std::string&&"}) String message) { super((Pointer)null); allocate(severity, message); } - private native void allocate(int severity, @StdString @Cast({"char*", "std::string&&"}) String message); - - public TFLogEntry(int severity, @StdString @Cast({"char*", "std::string&&"}) BytePointer fname, int line, - @StdString @Cast({"char*", "std::string&&"}) BytePointer message) { super((Pointer)null); allocate(severity, fname, line, message); } - private native void allocate(int severity, @StdString @Cast({"char*", "std::string&&"}) BytePointer fname, int line, - @StdString @Cast({"char*", "std::string&&"}) BytePointer message); - public TFLogEntry(int severity, @StdString @Cast({"char*", "std::string&&"}) String fname, int line, - @StdString @Cast({"char*", "std::string&&"}) String message) { super((Pointer)null); allocate(severity, fname, line, message); } - private native void allocate(int severity, @StdString @Cast({"char*", "std::string&&"}) String fname, int line, - @StdString @Cast({"char*", "std::string&&"}) String message); public native @Cast("absl::LogSeverity") int log_severity(); public native @StdString @Cast({"char*", "std::string&&"}) BytePointer FName(); public native int Line(); public native @StdString @Cast({"char*", "std::string&&"}) BytePointer ToString(); - public native @StdString @Cast({"char*", "std::string&&"}) BytePointer text_message(); + public native @StdString @Cast({"", "", "std::string"}) BytePointer text_message(); } diff --git a/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/internal/c_api/presets/tensorflow.java b/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/internal/c_api/presets/tensorflow.java index 8eaec809863..c2befde86f5 100644 --- a/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/internal/c_api/presets/tensorflow.java +++ b/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/internal/c_api/presets/tensorflow.java @@ -403,33 +403,43 @@ public void map(InfoMap infoMap) { .cast() .valueTypes("long") .pointerTypes("LongPointer", "long[]")) - .put(new Info("absl::string_view", "absl::lts_2020_09_23::string_view", "string", "std::string", "tensorflow::string").annotations("@StdString") + .put(new Info("string", "std::string", "tensorflow::string").annotations("@StdString") .valueTypes("@Cast({\"char*\", \"std::string&&\"}) BytePointer", "@Cast({\"char*\", \"std::string&&\"}) String") .pointerTypes("@Cast({\"char*\", \"std::string*\"}) BytePointer")) - .put(new Info("absl::LogSeverity", "LogSeverity", "tensorflow::LogSeverity").cast().valueTypes("int").pointerTypes("IntPointer", "int[]")) - .put(new Info("tensorflow::internal::LogEveryNSecState", - "tensorflow::internal::LogEveryNState", - "tensorflow::internal::LogEveryPow2State", - "tensorflow::internal::LogFirstNState", - "tensorflow::internal::Voidifier", - "tensorflow::internal::LogMessage", - "tensorflow::internal::LogMessageFatal", - "tensorflow::internal::LogMessageNull", - "tensorflow::internal::CheckOpMessageBuilder", - "tensorflow::internal::CheckOpString", - "tensorflow::internal::GetReferenceableValue", - "DVLOG", - "absl::LogSeverities").skip()) - .put(new Info( - "tensorflow::INFO", - "tensorflow::WARNING", - "tensorflow::ERROR", - "tensorflow::FATAL", - "tensorflow::NUM_SEVERITIES", - "_TF_LOG_INFO", - "_TF_LOG_WARNING", - "_TF_LOG_ERROR", - "_TF_LOG_FATAL", - "_TF_LOG_QFATAL").skip()); + .put( + new Info("absl::LogSeverity", "LogSeverity", "tensorflow::LogSeverity") + .cast() + .valueTypes("int") + .pointerTypes("IntPointer", "int[]")) + .put(new Info("tensorflow::TFLogEntry").purify()) + .put( + new Info( + "tensorflow::internal::LogEveryNSecState", + "tensorflow::internal::LogEveryNState", + "tensorflow::internal::LogEveryPow2State", + "tensorflow::internal::LogFirstNState", + "tensorflow::internal::Voidifier", + "tensorflow::internal::LogMessage", + "tensorflow::internal::LogMessageFatal", + "tensorflow::internal::LogMessageNull", + "tensorflow::internal::CheckOpMessageBuilder", + "tensorflow::internal::CheckOpString", + "tensorflow::internal::GetReferenceableValue", + "DVLOG", + "absl::LogSeverities") + .skip()) + .put( + new Info( + "tensorflow::INFO", + "tensorflow::WARNING", + "tensorflow::ERROR", + "tensorflow::FATAL", + "tensorflow::NUM_SEVERITIES", + "_TF_LOG_INFO", + "_TF_LOG_WARNING", + "_TF_LOG_ERROR", + "_TF_LOG_FATAL", + "_TF_LOG_QFATAL") + .skip()); } } From c098372ae55f23eb466a9533cffc5de804a1d9a3 Mon Sep 17 00:00:00 2001 From: Ryan Nett <rnett@calpoly.edu> Date: Sat, 26 Jun 2021 19:57:57 -0700 Subject: [PATCH 3/3] Working prototype Signed-off-by: Ryan Nett <rnett@calpoly.edu> --- tensorflow-core/tensorflow-core-api/pom.xml | 11 ++++ .../annotations/org/tensorflow/op/Ops.java | 6 +- .../tensorflow/internal/c_api/TFLogEntry.java | 2 +- .../tensorflow/internal/c_api/TFLogSink.java | 16 +++++- .../java/org/tensorflow/NativeLogSink.java | 57 +++++++++++++++++++ .../main/java/org/tensorflow/TensorFlow.java | 9 +++ .../internal/c_api/presets/tensorflow.java | 18 +++++- tensorflow-framework/pom.xml | 6 ++ 8 files changed, 116 insertions(+), 9 deletions(-) create mode 100644 tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/NativeLogSink.java diff --git a/tensorflow-core/tensorflow-core-api/pom.xml b/tensorflow-core/tensorflow-core-api/pom.xml index fd96cca67fd..fbbf81e458e 100644 --- a/tensorflow-core/tensorflow-core-api/pom.xml +++ b/tensorflow-core/tensorflow-core-api/pom.xml @@ -47,6 +47,11 @@ <artifactId>ndarray</artifactId> <version>${ndarray.version}</version> </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <version>1.7.31</version> + </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> @@ -73,6 +78,12 @@ <artifactId>jmh-generator-annprocess</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-jdk14</artifactId> + <version>1.7.31</version> + <scope>test</scope> + </dependency> </dependencies> <profiles> diff --git a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/Ops.java b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/Ops.java index 7abb451be2d..c8b7ef1f873 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/Ops.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/Ops.java @@ -376,10 +376,10 @@ public final class Ops { public final SignalOps signal; - public final QuantizationOps quantization; - public final TrainOps train; + public final QuantizationOps quantization; + private final Scope scope; private Ops(Scope scope) { @@ -402,8 +402,8 @@ private Ops(Scope scope) { math = new MathOps(this); audio = new AudioOps(this); signal = new SignalOps(this); - quantization = new QuantizationOps(this); train = new TrainOps(this); + quantization = new QuantizationOps(this); } /** diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogEntry.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogEntry.java index 7835d15a8a4..d0afe9368d8 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogEntry.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogEntry.java @@ -26,5 +26,5 @@ public class TFLogEntry extends Pointer { public native @StdString @Cast({"char*", "std::string&&"}) BytePointer FName(); public native int Line(); public native @StdString @Cast({"char*", "std::string&&"}) BytePointer ToString(); - public native @StdString @Cast({"", "", "std::string"}) BytePointer text_message(); + } diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogSink.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogSink.java index 456b6dbbbd8..9e260ebc5d8 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogSink.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/TFLogSink.java @@ -12,8 +12,20 @@ @Namespace("tensorflow") @Properties(inherit = org.tensorflow.internal.c_api.presets.tensorflow.class) public class TFLogSink extends Pointer { static { Loader.load(); } + /** Default native constructor. */ + public TFLogSink() { super((Pointer)null); allocate(); } + /** Native array allocator. Access with {@link Pointer#position(long)}. */ + public TFLogSink(long size) { super((Pointer)null); allocateArray(size); } /** Pointer cast constructor. Invokes {@link Pointer#Pointer(Pointer)}. */ public TFLogSink(Pointer p) { super(p); } + private native void allocate(); + private native void allocateArray(long size); + @Override public TFLogSink position(long position) { + return (TFLogSink)super.position(position); + } + @Override public TFLogSink getPointer(long i) { + return new TFLogSink(this).position(position + i); + } // `Send` is called synchronously during the log statement. The logging @@ -24,7 +36,7 @@ public class TFLogSink extends Pointer { // `e` is guaranteed to remain valid until the subsequent call to // `WaitTillSent` completes, so implementations may store a pointer to or // copy of `e` (e.g. in a thread local variable) for use in `WaitTillSent`. - public native void Send(@Const @ByRef TFLogEntry entry); + @Virtual(true) public native void Send(@Const @ByRef TFLogEntry entry); // `WaitTillSent` blocks the calling thread (the thread that generated a log // message) until the sink has finished processing the log message. @@ -34,5 +46,5 @@ public class TFLogSink extends Pointer { // The default implementation returns immediately. Like `Send`, // implementations should be careful not to call `LOG` or `CHECK or take any // locks that might be held by the `LOG` caller, to avoid deadlock. - public native void WaitTillSent(); + @Virtual public native void WaitTillSent(); } diff --git a/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/NativeLogSink.java b/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/NativeLogSink.java new file mode 100644 index 00000000000..41a2f628af6 --- /dev/null +++ b/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/NativeLogSink.java @@ -0,0 +1,57 @@ +/* + Copyright 2021 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. + ======================================================================= + + */ +package org.tensorflow; + +import org.bytedeco.javacpp.Pointer; +import org.slf4j.ILoggerFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.tensorflow.internal.c_api.TFLogEntry; +import org.tensorflow.internal.c_api.TFLogSink; +import org.tensorflow.internal.c_api.global.tensorflow; + +public class NativeLogSink extends TFLogSink { + private static final ILoggerFactory factory = LoggerFactory.getILoggerFactory(); + private static final Logger logger = LoggerFactory.getLogger(NativeLogSink.class); + NativeLogSink() { + super(); + } + + @Override + public void Send(TFLogEntry entry) { + //TODO make work, blocked by https://github.com/tensorflow/tensorflow/issues/44995#issuecomment-869091090 + System.out.printf( + "Log message: Severity: %d, Fname: %s, line: %s, string: %s\n", entry.log_severity(), entry.FName().getString(), entry.Line(), entry.ToString().getString()); +// Logger logger = factory.getLogger(entry.FName().getString()); +// switch (entry.log_severity()){ +// case tensorflow.kWarning: +// logger.warn(entry.ToString().getString()); +// break; +// case tensorflow.kError: +// case tensorflow.kFatal: +// logger.error(entry.ToString().getString()); +// break; +// default: +// logger.info(entry.ToString().getString()); +// } + } + + @Override + public void WaitTillSent() { + } +} diff --git a/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/TensorFlow.java b/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/TensorFlow.java index 23f4c62bc7f..4f823660d79 100644 --- a/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/TensorFlow.java +++ b/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/TensorFlow.java @@ -15,6 +15,7 @@ */ package org.tensorflow; +import static org.tensorflow.internal.c_api.global.tensorflow.TFAddLogSink; import static org.tensorflow.internal.c_api.global.tensorflow.TF_DeleteBuffer; import static org.tensorflow.internal.c_api.global.tensorflow.TF_DeleteLibraryHandle; import static org.tensorflow.internal.c_api.global.tensorflow.TF_GetAllOpList; @@ -96,6 +97,13 @@ public static OpList loadLibrary(String filename) { } } + @SuppressWarnings("FieldCanBeLocal") + private static NativeLogSink sink; + private static void setupLogger(){ + sink = new NativeLogSink(); + TFAddLogSink(sink); + } + private static TF_Library libraryLoad(String filename) { try (PointerScope scope = new PointerScope()) { TF_Status status = TF_Status.newStatus(); @@ -137,5 +145,6 @@ private TensorFlow() {} e.printStackTrace(); throw e; } + setupLogger(); } } diff --git a/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/internal/c_api/presets/tensorflow.java b/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/internal/c_api/presets/tensorflow.java index c2befde86f5..a2ac124d58b 100644 --- a/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/internal/c_api/presets/tensorflow.java +++ b/tensorflow-core/tensorflow-core-api/src/main/java/org/tensorflow/internal/c_api/presets/tensorflow.java @@ -403,15 +403,27 @@ public void map(InfoMap infoMap) { .cast() .valueTypes("long") .pointerTypes("LongPointer", "long[]")) - .put(new Info("string", "std::string", "tensorflow::string").annotations("@StdString") - .valueTypes("@Cast({\"char*\", \"std::string&&\"}) BytePointer", "@Cast({\"char*\", \"std::string&&\"}) String") - .pointerTypes("@Cast({\"char*\", \"std::string*\"}) BytePointer")) + .put( + new Info("string", "std::string", "tensorflow::string") + .annotations("@StdString") + .valueTypes( + "@Cast({\"char*\", \"std::string&&\"}) BytePointer", + "@Cast({\"char*\", \"std::string&&\"}) String") + .pointerTypes("@Cast({\"char*\", \"std::string*\"}) BytePointer")) +// .put( +// new Info("absl::string_view") +// .annotations("@StdString") +// .valueTypes( +// "@Cast({\"char*\", \"std::string&&\", \"std::string\"}) BytePointer", +// "@Cast({\"char*\", \"std::string&&\", \"std::string\"}) String")) .put( new Info("absl::LogSeverity", "LogSeverity", "tensorflow::LogSeverity") .cast() .valueTypes("int") .pointerTypes("IntPointer", "int[]")) .put(new Info("tensorflow::TFLogEntry").purify()) + .put(new Info("tensorflow::TFLogSink").virtualize()) + .put(new Info("tensorflow::TFLogEntry::text_message").skip()) .put( new Info( "tensorflow::internal::LogEveryNSecState", diff --git a/tensorflow-framework/pom.xml b/tensorflow-framework/pom.xml index af7f47815d5..ac4c24f774d 100644 --- a/tensorflow-framework/pom.xml +++ b/tensorflow-framework/pom.xml @@ -64,6 +64,12 @@ <artifactId>jmh-generator-annprocess</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-jdk14</artifactId> + <version>1.7.31</version> + <scope>test</scope> + </dependency> <!-- Include native binaries dependencies only for testing --> <dependency> <groupId>org.tensorflow</groupId>