diff --git a/CMakeLists.txt b/CMakeLists.txt index 3c69ded92..28e0f3a4e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -244,7 +244,7 @@ if (NOT USE_PRE_BUILT_NGRAPH) ExternalProject_Add( ext_ngraph GIT_REPOSITORY https://github.com/NervanaSystems/ngraph - GIT_TAG v0.25.1-rc.0 + GIT_TAG v0.25.1-rc.2 CMAKE_ARGS -DNGRAPH_DISTRIBUTED_ENABLE=${NGRAPH_DISTRIBUTED_ENABLE} -DNGRAPH_INSTALL_PREFIX=${NGRAPH_ARTIFACTS_DIR} diff --git a/README.md b/README.md index 1f961154b..26079d40e 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,7 @@ Once TensorFlow's dependencies are installed, clone the `ngraph-bridge` repo: git clone https://github.com/tensorflow/ngraph-bridge.git cd ngraph-bridge - git checkout v0.19.0-rc0 + git checkout v0.19.0-rc1 Run the following Python script to build TensorFlow, nGraph, and the bridge. Use Python 3.5: diff --git a/bazel/BUILD b/bazel/BUILD index e30eef426..b7853ff56 100644 --- a/bazel/BUILD +++ b/bazel/BUILD @@ -14,6 +14,9 @@ # limitations under the License. # ============================================================================== load("//:cxx_abi_option.bzl", "CXX_ABI") +load( + "@org_tensorflow//tensorflow:tensorflow.bzl", + "tf_cc_binary") cc_library( name = "ngraph_bridge_headers", @@ -47,22 +50,22 @@ cc_library( "logging/tf_graph_writer.h", ]), copts = [ - "-I external/ngraph_bridge/src", - "-I external/ngraph_bridge/logging", + "-I external/ngraph/src", + "-I logging", ], visibility = ["//visibility:public"], ) -cc_binary( - name = 'libngraph_bridge.so', +cc_library( + name = 'ngraph_bridge_lib', srcs = [ "ngraph_bridge/ngraph_api.cc", "ngraph_bridge/ngraph_assign_clusters.cc", - "ngraph_bridge/ngraph_assign_clusters.h", "ngraph_bridge/ngraph_builder.cc", "ngraph_bridge/ngraph_backend_manager.cc", "ngraph_bridge/ngraph_capture_variables.cc", "ngraph_bridge/ngraph_cluster_manager.cc", + "ngraph_bridge/ngraph_conversions.cc", "ngraph_bridge/ngraph_deassign_clusters.cc", "ngraph_bridge/ngraph_encapsulate_clusters.cc", "ngraph_bridge/ngraph_encapsulate_impl.cc", @@ -76,17 +79,20 @@ cc_binary( "ngraph_bridge/ngraph_utils.cc", "ngraph_bridge/tf_deadness_analysis.cc", "ngraph_bridge/tf_graphcycles.cc", + "ngraph_bridge/ops/ngraph_ops.cc", "ngraph_bridge/version.cc", "ngraph_bridge/grappler/ngraph_optimizer.cc", "ngraph_bridge/grappler/ngraph_add_identityn.cc", "logging/ngraph_log.cc", "logging/tf_graph_writer.cc", ], - linkshared = 1, deps = [ ":ngraph_bridge_headers", - "@local_config_tf//:libtensorflow_framework", - "@local_config_tf//:tf_header_lib", + "@org_tensorflow//tensorflow/core:core_cpu_headers_lib", + "@org_tensorflow//tensorflow/core/grappler/clusters:cluster", + "@org_tensorflow//tensorflow/core/grappler/optimizers:custom_graph_optimizer_registry", + "@org_tensorflow//tensorflow/core:framework_headers_lib", + "@org_tensorflow//tensorflow/core:protos_all_cc", "@ngraph//:ngraph_headers", "@ngraph//:ngraph_core", "@ngraph//:ngraph_version", @@ -97,18 +103,46 @@ cc_binary( "-D_FORTIFY_SOURCE=2", "-Wformat", "-Wformat-security", - "-Wformat", "-fstack-protector-all", - "-D NDEBUG", - '-D SHARED_LIB_PREFIX=\\"lib\\"', - '-D SHARED_LIB_SUFFIX=\\".so\\"', + '-D NGRAPH_BRIDGE_STATIC_LIB_ENABLE', '-D NGRAPH_TF_USE_GRAPPLER_OPTIMIZER', + "-I ngraph_bridge", + "-I logging", "-I external/ngraph/src", ] + CXX_ABI, + linkstatic = True, linkopts = [ "-Wl,-z,noexecstack", "-Wl,-z,relro", "-Wl,-z,now", ], visibility = ["//visibility:public"], + alwayslink = 1, +) + +tf_cc_binary( + name = 'hello_tf', + srcs = [ + "examples/cpp/hello_tf.cpp", + ], + deps = [ + "@org_tensorflow//tensorflow/cc:client_session", + "@org_tensorflow//tensorflow/cc:ops", + "@org_tensorflow//tensorflow/core:tensorflow", + ":ngraph_bridge_lib", + "@ngraph//:cpu_backend", + ], + copts = [ + "-pthread", + "-std=c++11", + "-D_FORTIFY_SOURCE=2", + "-Wformat", + "-Wformat-security", + "-fstack-protector-all", + "-I ngraph_bridge", + "-I external/ngraph/src", + "-I logging", + ] + CXX_ABI, + linkstatic=True, + visibility = ["//visibility:public"], ) diff --git a/bazel/WORKSPACE b/bazel/WORKSPACE index aa234e466..49e133ec2 100644 --- a/bazel/WORKSPACE +++ b/bazel/WORKSPACE @@ -15,21 +15,51 @@ # ============================================================================== workspace(name = "ngraph_bridge") -load("@//tf_configure:tf_configure.bzl", "tf_configure") load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") +load("@//tf_configure:tf_configure.bzl", "tf_configure") tf_configure( name = "local_config_tf", ) +# TensorFlow depends on "io_bazel_rules_closure" so we need this here. +# Needs to be kept in sync with the same target in TensorFlow's WORKSPACE file. +http_archive( + name = "io_bazel_rules_closure", + sha256 = "5b00383d08dd71f28503736db0500b6fb4dda47489ff5fc6bed42557c07c6ba9", + strip_prefix = "rules_closure-308b05b2419edb5c8ee0471b67a40403df940149", + urls = [ + "https://storage.googleapis.com/mirror.tensorflow.org/github.com/bazelbuild/rules_closure/archive/308b05b2419edb5c8ee0471b67a40403df940149.tar.gz", + "https://github.com/bazelbuild/rules_closure/archive/308b05b2419edb5c8ee0471b67a40403df940149.tar.gz", # 2019-06-13 + ], +) + +http_archive( + name = "bazel_skylib", + sha256 = "2ef429f5d7ce7111263289644d233707dba35e39696377ebab8b0bc701f7818e", + urls = ["https://github.com/bazelbuild/bazel-skylib/releases/download/0.8.0/bazel-skylib.0.8.0.tar.gz"], +) + +http_archive( + name = "org_tensorflow", + sha256 = "aa2a6a1daafa3af66807cfe0bc77bfe1144a9a53df9a96bab52e3e575b3047ed", + strip_prefix = "tensorflow-1.14.0", + urls = [ + "http://mirror.tensorflow.org/github.com/tensorflow/tensorflow/archive/v1.14.0.tar.gz", + "https://github.com/tensorflow/tensorflow/archive/v1.14.0.tar.gz", + ], +) +load("@org_tensorflow//tensorflow:workspace.bzl", "tf_workspace") +tf_workspace(path_prefix = "", tf_repo_name = "org_tensorflow") + http_archive( name = "ngraph", build_file = "//:bazel/ngraph.BUILD", - sha256 = "030a0c22a098a958e1856b7930bdd7d1694ec882b61de3108afa8e59ff960e42", - strip_prefix = "ngraph-0.25.1-rc.0", + sha256 = "d3e0ebf807dd4179c91a41c80639b75f5ea8ca39cdfe3a5697da56a7df894f11", + strip_prefix = "ngraph-0.25.1-rc.2", urls = [ - "https://mirror.bazel.build/github.com/NervanaSystems/ngraph/archive/v0.25.1-rc.0.tar.gz", - "https://github.com/NervanaSystems/ngraph/archive/v0.25.1-rc.0.tar.gz" + "https://mirror.bazel.build/github.com/NervanaSystems/ngraph/archive/v0.25.1-rc.2.tar.gz", + "https://github.com/NervanaSystems/ngraph/archive/v0.25.1-rc.2.tar.gz" ], ) @@ -69,21 +99,21 @@ http_archive( http_archive( name = "mkl_dnn", build_file = "//:bazel/mkl_dnn.BUILD", - sha256 = "38a1c02104ee9f630c1ad68164119cd58ad0aaf59e04ccbe7bd5781add7bfbea", - strip_prefix = "mkl-dnn-0.18", + sha256 = "1ae0e8a1a3df58deadc08ca0a01f8d3720600b26ca9e53685493e8e8250243b2", + strip_prefix = "mkl-dnn-0.20.2", urls = [ - "http://mirror.tensorflow.org/github.com/intel/mkl-dnn/archive/v0.18.tar.gz", - "https://github.com/intel/mkl-dnn/archive/v0.18.tar.gz", + "http://mirror.tensorflow.org/github.com/intel/mkl-dnn/archive/v0.20.2.tar.gz", + "https://github.com/intel/mkl-dnn/archive/v0.20.2.tar.gz", ], ) http_archive( name = "mkl_linux", build_file = "//:bazel/mkl.BUILD", - sha256 = "f4129843d5c2996419f96f10928edd02b2150998861a088dc7cfa1b6a058102a", - strip_prefix = "mklml_lnx_2019.0.3.20190220", + sha256 = "a936d6b277a33d2a027a024ea8e65df62bd2e162c7ca52c48486ed9d5dc27160", + strip_prefix = "mklml_lnx_2019.0.5.20190502", urls = [ - "http://mirror.tensorflow.org/github.com/intel/mkl-dnn/releases/download/v0.18/mklml_lnx_2019.0.3.20190220.tgz", - "https://github.com/intel/mkl-dnn/releases/download/v0.18/mklml_lnx_2019.0.3.20190220.tgz", + "http://mirror.tensorflow.org/github.com/intel/mkl-dnn/releases/download/v0.20/mklml_lnx_2019.0.5.20190502.tgz", + "https://github.com/intel/mkl-dnn/releases/download/v0.20/mklml_lnx_2019.0.5.20190502.tgz", ], ) diff --git a/bazel/mkl_dnn.BUILD b/bazel/mkl_dnn.BUILD index 275c9ffaf..a3416d902 100644 --- a/bazel/mkl_dnn.BUILD +++ b/bazel/mkl_dnn.BUILD @@ -46,8 +46,8 @@ template_rule( out = "include/mkldnn_version.h", substitutions = { "@MKLDNN_VERSION_MAJOR@": "0", - "@MKLDNN_VERSION_MINOR@": "18", - "@MKLDNN_VERSION_PATCH@": "0", + "@MKLDNN_VERSION_MINOR@": "20", + "@MKLDNN_VERSION_PATCH@": "2", "@MKLDNN_VERSION_HASH@": "N/A", }, ) @@ -61,6 +61,8 @@ cc_library( "src/cpu/*.hpp", "src/cpu/gemm/*.cpp", "src/cpu/gemm/*.hpp", + "src/cpu/gemm/bf16/*.hpp", + "src/cpu/gemm/bf16/*.cpp", "src/cpu/gemm/f32/*.cpp", "src/cpu/gemm/f32/*.hpp", "src/cpu/gemm/s8x8s32/*.cpp", @@ -111,6 +113,8 @@ cc_library( "src/cpu/*.hpp", "src/cpu/gemm/*.cpp", "src/cpu/gemm/*.hpp", + "src/cpu/gemm/bf16/*.hpp", + "src/cpu/gemm/bf16/*.cpp", "src/cpu/gemm/f32/*.cpp", "src/cpu/gemm/f32/*.hpp", "src/cpu/gemm/s8x8s32/*.cpp", diff --git a/bazel/ngraph.BUILD b/bazel/ngraph.BUILD index c6b0d7f17..e42178495 100644 --- a/bazel/ngraph.BUILD +++ b/bazel/ngraph.BUILD @@ -38,7 +38,9 @@ cc_library( "src/ngraph/op/*.cpp", "src/ngraph/op/fused/*.cpp", "src/ngraph/op/experimental/batch_mat_mul.cpp", + "src/ngraph/op/experimental/compiled_kernel.cpp", "src/ngraph/op/experimental/dyn_broadcast.cpp", + "src/ngraph/op/experimental/dyn_replace_slice.cpp", "src/ngraph/op/experimental/dyn_pad.cpp", "src/ngraph/op/experimental/dyn_reshape.cpp", "src/ngraph/op/experimental/dyn_slice.cpp", @@ -50,6 +52,7 @@ cc_library( "src/ngraph/op/experimental/quantized_conv_relu.cpp", "src/ngraph/op/experimental/quantized_max_pool.cpp", "src/ngraph/op/experimental/shape_of.cpp", + "src/ngraph/op/experimental/range.cpp", "src/ngraph/op/experimental/quantized_dot.cpp", "src/ngraph/op/experimental/quantized_dot_bias.cpp", "src/ngraph/op/experimental/tile.cpp", @@ -78,77 +81,24 @@ cc_library( "-D_FORTIFY_SOURCE=2", "-Wformat", "-Wformat-security", - "-Wformat", "-fstack-protector-all", '-D SHARED_LIB_PREFIX=\\"lib\\"', '-D SHARED_LIB_SUFFIX=\\".so\\"', - '-D NGRAPH_VERSION=\\"v0.20.0-rc.0\\"', + '-D NGRAPH_VERSION=\\"v0.25.1-rc.2\\"', "-D NGRAPH_DEX_ONLY", '-D PROJECT_ROOT_DIR=\\"\\"', + '-D NGRAPH_STATIC_LIB_ENABLE' ] + CXX_ABI, linkopts = [ "-Wl,-z,noexecstack", "-Wl,-z,relro", "-Wl,-z,now", ], + linkstatic = True, visibility = ["//visibility:public"], alwayslink = 1, ) -cc_binary( - name = 'libinterpreter_backend.so', - srcs = glob([ - "src/ngraph/except.hpp", - "src/ngraph/runtime/interpreter/*.cpp", - "src/ngraph/state/rng_state.cpp", - "src/ngraph/runtime/hybrid/hybrid_tensor.cpp", - "src/ngraph/runtime/hybrid/hybrid_backend.cpp", - "src/ngraph/runtime/hybrid/hybrid_backend.hpp", - "src/ngraph/runtime/hybrid/hybrid_executable.cpp", - "src/ngraph/runtime/hybrid/hybrid_executable.hpp", - "src/ngraph/runtime/hybrid/hybrid_util.cpp", - "src/ngraph/runtime/hybrid/hybrid_util.hpp", - "src/ngraph/runtime/hybrid/op/function_call.cpp", - "src/ngraph/runtime/hybrid/op/function_call.hpp", - "src/ngraph/runtime/hybrid/pass/default_placement.cpp", - "src/ngraph/runtime/hybrid/pass/default_placement.hpp", - "src/ngraph/runtime/hybrid/pass/dump.cpp", - "src/ngraph/runtime/hybrid/pass/dump.hpp", - "src/ngraph/runtime/hybrid/pass/fix_get_output_element.cpp", - "src/ngraph/runtime/hybrid/pass/fix_get_output_element.hpp", - "src/ngraph/runtime/hybrid/pass/liveness.cpp", - "src/ngraph/runtime/hybrid/pass/liveness.hpp", - "src/ngraph/runtime/hybrid/pass/memory_layout.cpp", - "src/ngraph/runtime/hybrid/pass/memory_layout.hpp", - ]), - deps = [ - ":ngraph_headers", - ":ngraph_core", - ], - copts = [ - "-I external/ngraph/src", - "-I external/ngraph/src/ngraph", - "-I external/nlohmann_json_lib/include/", - "-D_FORTIFY_SOURCE=2", - "-Wformat", - "-Wformat-security", - "-Wformat", - "-fstack-protector-all", - '-D SHARED_LIB_PREFIX=\\"lib\\"', - '-D SHARED_LIB_SUFFIX=\\".so\\"', - '-D NGRAPH_VERSION=\\"v0.20.0-rc.0\\"', - "-D NGRAPH_DEX_ONLY", - '-D PROJECT_ROOT_DIR=\\"\\"', - ] + CXX_ABI, - linkopts = [ - "-Wl,-z,noexecstack", - "-Wl,-z,relro", - "-Wl,-z,now", - ], - linkshared = 1, - visibility = ["//visibility:public"], -) - cc_library( name = 'ngraph_version', srcs = glob([ @@ -164,11 +114,10 @@ cc_library( "-D_FORTIFY_SOURCE=2", "-Wformat", "-Wformat-security", - "-Wformat", "-fstack-protector-all", '-D SHARED_LIB_PREFIX=\\"lib\\"', '-D SHARED_LIB_SUFFIX=\\".so\\"', - '-D NGRAPH_VERSION=\\"v0.20.0-rc.0\\"', + '-D NGRAPH_VERSION=\\"v0.25.1-rc.2\\"', "-D NGRAPH_DEX_ONLY", '-D PROJECT_ROOT_DIR=\\"\\"', ] + CXX_ABI, @@ -181,15 +130,20 @@ cc_library( alwayslink = 1, ) -cc_binary( - name = 'libcpu_backend.so', - srcs = glob([ +cc_library( + name = 'cpu_backend', + hdrs = glob([ "src/ngraph/runtime/cpu/*.hpp", "src/ngraph/runtime/cpu/*.h", "src/ngraph/runtime/cpu/kernel/*.hpp", + "src/ngraph/state/rng_state.hpp", + ]), + srcs = glob([ "src/ngraph/runtime/cpu/cpu_backend.cpp", "src/ngraph/runtime/cpu/cpu_builder.cpp", + "src/ngraph/runtime/cpu/cpu_builder_registry.cpp", "src/ngraph/runtime/cpu/cpu_call_frame.cpp", + "src/ngraph/runtime/cpu/cpu_debug_tracer.cpp", "src/ngraph/runtime/cpu/cpu_executor.cpp", "src/ngraph/runtime/cpu/cpu_external_function.cpp", "src/ngraph/runtime/cpu/cpu_kernels.cpp", @@ -215,6 +169,7 @@ cc_binary( "src/ngraph/runtime/cpu/builder/convert_layout.cpp", "src/ngraph/runtime/cpu/builder/convolution.cpp", "src/ngraph/runtime/cpu/builder/dot.cpp", + "src/ngraph/runtime/cpu/builder/dropout.cpp", "src/ngraph/runtime/cpu/builder/embedding_lookup.cpp", "src/ngraph/runtime/cpu/builder/erf.cpp", "src/ngraph/runtime/cpu/builder/gather.cpp", @@ -253,6 +208,7 @@ cc_binary( "src/ngraph/runtime/cpu/builder/get_output_element.cpp", "src/ngraph/runtime/cpu/builder/sum.cpp", "src/ngraph/runtime/cpu/builder/topk.cpp", + "src/ngraph/runtime/cpu/builder/tile.cpp", "src/ngraph/runtime/cpu/builder/update_slice.cpp", "src/ngraph/runtime/cpu/kernel/pad.cpp", "src/ngraph/runtime/cpu/kernel/reduce_max.cpp", @@ -268,6 +224,7 @@ cc_binary( "src/ngraph/runtime/cpu/op/conv_relu.cpp", "src/ngraph/runtime/cpu/op/convert_layout.cpp", "src/ngraph/runtime/cpu/op/deconv.cpp", + "src/ngraph/runtime/cpu/op/dropout.cpp", "src/ngraph/runtime/cpu/op/group_conv_bias.cpp", "src/ngraph/runtime/cpu/op/halide_op.cpp", "src/ngraph/runtime/cpu/op/leaky_relu.cpp", @@ -293,7 +250,6 @@ cc_binary( "src/ngraph/runtime/cpu/pass/cpu_rnn_fusion.cpp", "src/ngraph/runtime/cpu/pass/cpu_workspace_insertion.cpp", "src/ngraph/runtime/cpu/ngraph_version.cpp", - "src/ngraph/state/rng_state.hpp", "src/ngraph/state/rng_state.cpp", ]), deps = [ @@ -310,21 +266,24 @@ cc_binary( "-D_FORTIFY_SOURCE=2", "-Wformat", "-Wformat-security", - "-Wformat", "-fstack-protector-all", '-D SHARED_LIB_PREFIX=\\"lib\\"', '-D SHARED_LIB_SUFFIX=\\".so\\"', - '-D NGRAPH_VERSION=\\"0.19.0-rc.4\\"', + '-D NGRAPH_VERSION=\\"0.25.1-rc.2\\"', "-D NGRAPH_DEX_ONLY", "-D NGRAPH_TBB_ENABLE", '-D PROJECT_ROOT_DIR=\\"\\"', + '-D NGRAPH_CPU_STATIC_LIB_ENABLE' ] + CXX_ABI, linkopts = [ "-Wl,-z,noexecstack", "-Wl,-z,relro", "-Wl,-z,now", + "-Wl,-Bsymbolic-functions", + "-Wl,--exclude-libs=ALL", ], - linkshared = 1, + linkstatic = True, visibility = ["//visibility:public"], + alwayslink = 1, ) diff --git a/build_ngtf.py b/build_ngtf.py index 3f468a8df..9b5d13593 100755 --- a/build_ngtf.py +++ b/build_ngtf.py @@ -53,7 +53,7 @@ def main(): ''' # Component versions - ngraph_version = "v0.25.1-rc.0" + ngraph_version = "v0.25.1-rc.2" tf_version = "v1.14.0" # Command line parser options diff --git a/configure_bazel.sh b/configure_bazel.sh index 6ed4cd618..f451436b4 100755 --- a/configure_bazel.sh +++ b/configure_bazel.sh @@ -36,6 +36,7 @@ TF_CXX_ABI=( $(python -c 'import tensorflow as tf; print(" ".join(str(tf.__cxx11 write_action_env_to_bazelrc "TF_HEADER_DIR" ${TF_CFLAGS:2} write_action_env_to_bazelrc "TF_SHARED_LIBRARY_DIR" ${TF_LFLAGS:2} +write_to_bazelrc "build --define=grpc_no_ares=true" # Write the CXX ABI to the file echo "CXX_ABI = ['-D_GLIBCXX_USE_CXX11_ABI=$TF_CXX_ABI']" > cxx_abi_option.bzl diff --git a/examples/cpp/hello_tf.cpp b/examples/cpp/hello_tf.cpp new file mode 100644 index 000000000..e8097a30e --- /dev/null +++ b/examples/cpp/hello_tf.cpp @@ -0,0 +1,130 @@ +/******************************************************************************* + * Copyright 2017-2019 Intel Corporation + * + * 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. + *******************************************************************************/ + +#include "tensorflow/core/framework/graph.pb.h" +#include "tensorflow/core/framework/op.h" +#include "tensorflow/core/framework/tensor_types.h" +#include "tensorflow/core/graph/algorithm.h" +#include "tensorflow/core/graph/default_device.h" +#include "tensorflow/core/graph/graph.h" +#include "tensorflow/core/graph/graph_constructor.h" +#include "tensorflow/core/platform/env.h" + +#include "tensorflow/cc/client/client_session.h" +#include "tensorflow/cc/ops/standard_ops.h" +#include "tensorflow/core/framework/tensor.h" +#include "tensorflow/core/public/session.h" + +#include "ngraph_bridge/ngraph_api.h" +#include "ngraph_bridge/ngraph_backend_manager.h" +#include "ngraph_bridge/version.h" + +using namespace std; + +// Prints the available backends +void PrintAvailableBackends() { + // Get the list of backends + auto supported_backends = + tensorflow::ngraph_bridge::BackendManager::GetSupportedBackendNames(); + vector backends(supported_backends.begin(), supported_backends.end()); + + cout << "Available backends: " << endl; + for (auto& backend_name : backends) { + cout << "Backend: " << backend_name << std::endl; + } +} + +// Create a simple computation graph and run +void RunSimpleNetworkExample() { + // Create the graph + tensorflow::Scope root = tensorflow::Scope::NewRootScope(); + // Matrix A = [3 2; -1 0] + auto A = tensorflow::ops::Const(root, {{0.03f, 0.022f}, {-0.001f, 0.025f}}); + // Vector b = [3 5] + auto b = tensorflow::ops::Const(root, {{0.345f, 0.35f}}); + // v = Ab^T + auto v = tensorflow::ops::MatMul(root.WithOpName("v"), A, b, + tensorflow::ops::MatMul::TransposeB(true)); + // R = softmax(v) + auto R = tensorflow::ops::Softmax(root, v); + + // Turn off optimizations so that all the nodes are processed + tensorflow::SessionOptions options; + options.config.mutable_graph_options() + ->mutable_optimizer_options() + ->set_opt_level(tensorflow::OptimizerOptions_Level_L0); + options.config.mutable_graph_options() + ->mutable_rewrite_options() + ->set_constant_folding(tensorflow::RewriterConfig::OFF); + + if (tensorflow::ngraph_bridge::ngraph_tf_is_grappler_enabled()) { + auto* custom_config = options.config.mutable_graph_options() + ->mutable_rewrite_options() + ->add_custom_optimizers(); + + custom_config->set_name("ngraph-optimizer"); + (*custom_config->mutable_parameter_map())["ngraph_backend"].set_s("CPU"); + (*custom_config->mutable_parameter_map())["device_id"].set_s("1"); + + options.config.mutable_graph_options() + ->mutable_rewrite_options() + ->set_min_graph_nodes(-1); + + options.config.mutable_graph_options() + ->mutable_rewrite_options() + ->set_meta_optimizer_iterations(tensorflow::RewriterConfig::ONE); + } + + tensorflow::ClientSession session(root, options); + + std::vector outputs; + session.Run({R}, &outputs); + + // Print the output + std::cout << "Result: " << outputs[0].matrix() << std::endl; +} + +void PrintVersion() { + // nGraph Bridge version info + std::cout << "Bridge version: " + << tensorflow::ngraph_bridge::ngraph_tf_version() << std::endl; + std::cout << "nGraph version: " + << tensorflow::ngraph_bridge::ngraph_lib_version() << std::endl; + std::cout << "CXX11_ABI Used: " + << tensorflow::ngraph_bridge::ngraph_tf_cxx11_abi_flag() + << std::endl; + std::cout << "Grappler Enabled? " + << (tensorflow::ngraph_bridge::ngraph_tf_is_grappler_enabled() + ? std::string("Yes") + : std::string("No")) + << std::endl; + std::cout << "Variables Enabled? " + << (tensorflow::ngraph_bridge::ngraph_tf_are_variables_enabled() + ? std::string("Yes") + : std::string("No")) + << std::endl; + + PrintAvailableBackends(); +} + +int main(int argc, char** argv) { + PrintVersion(); + + // Run a simple example + RunSimpleNetworkExample(); + + return 0; +} diff --git a/examples/cpp/infer_multiple_networks/BUILD b/examples/cpp/infer_multiple_networks/BUILD new file mode 100644 index 000000000..8ddf49dc8 --- /dev/null +++ b/examples/cpp/infer_multiple_networks/BUILD @@ -0,0 +1,33 @@ +load("//:cxx_abi_option.bzl", "CXX_ABI") +load("@org_tensorflow//tensorflow:tensorflow.bzl", "tf_cc_binary") + +tf_cc_binary( + name = 'infer_multi', + srcs = [ + "main.cc", + "inference_engine.h", + "inference_engine.cc", + "tf_label_image_utils.cc" + ], + deps = [ + "@org_tensorflow//tensorflow/cc:cc_ops", + "@org_tensorflow//tensorflow/cc:client_session", + "@org_tensorflow//tensorflow/core:tensorflow", + "//:ngraph_bridge_lib", + "@ngraph//:cpu_backend", + ], + copts = [ + "-pthread", + "-std=c++11", + "-D_FORTIFY_SOURCE=2", + "-Wformat", + "-Wformat-security", + "-Wformat", + "-fstack-protector-all", + "-I ngraph_bridge", + "-I external/ngraph/src", + "-I logging", + ] + CXX_ABI, + linkstatic=False, + visibility = ["//visibility:public"], +) \ No newline at end of file diff --git a/examples/cpp/infer_multiple_networks/inference_engine.cc b/examples/cpp/infer_multiple_networks/inference_engine.cc index 81c8411c4..0c7df4ed2 100644 --- a/examples/cpp/infer_multiple_networks/inference_engine.cc +++ b/examples/cpp/infer_multiple_networks/inference_engine.cc @@ -19,14 +19,15 @@ #include #include -#include "inference_engine.h" -#include "ngraph/event_tracing.hpp" -#include "ngraph_backend_manager.h" -#include "version.h" - #include "tensorflow/core/platform/macros.h" #include "tensorflow/core/protobuf/rewriter_config.pb.h" +#include "ngraph/event_tracing.hpp" + +#include "examples/cpp/infer_multiple_networks/inference_engine.h" +#include "ngraph_bridge/ngraph_backend_manager.h" +#include "ngraph_bridge/version.h" + using tensorflow::SessionOptions; using tensorflow::RewriterConfig; using tensorflow::OptimizerOptions_Level_L0; @@ -197,10 +198,13 @@ Status InferenceEngine::CreateSession(const string& graph_filename, // The following is related to Grappler - which we are turning off // Until we get a library fully running if (tf::ngraph_bridge::ngraph_tf_is_grappler_enabled()) { - options.config.mutable_graph_options() - ->mutable_rewrite_options() - ->add_custom_optimizers() - ->set_name("ngraph-optimizer"); + auto* custom_config = options.config.mutable_graph_options() + ->mutable_rewrite_options() + ->add_custom_optimizers(); + + custom_config->set_name("ngraph-optimizer"); + (*custom_config->mutable_parameter_map())["ngraph_backend"].set_s("CPU"); + (*custom_config->mutable_parameter_map())["device_id"].set_s("1"); options.config.mutable_graph_options() ->mutable_rewrite_options() @@ -208,7 +212,7 @@ Status InferenceEngine::CreateSession(const string& graph_filename, options.config.mutable_graph_options() ->mutable_rewrite_options() - ->set_meta_optimizer_iterations(RewriterConfig::ONE); + ->set_meta_optimizer_iterations(tensorflow::RewriterConfig::ONE); } // Load the network diff --git a/examples/cpp/infer_multiple_networks/main.cc b/examples/cpp/infer_multiple_networks/main.cc index 7ddd1eee5..622cd5156 100644 --- a/examples/cpp/infer_multiple_networks/main.cc +++ b/examples/cpp/infer_multiple_networks/main.cc @@ -14,6 +14,8 @@ * limitations under the License. *******************************************************************************/ +#include + #include "tensorflow/cc/client/client_session.h" #include "tensorflow/cc/ops/standard_ops.h" #include "tensorflow/core/framework/graph.pb.h" @@ -31,12 +33,11 @@ #include "tensorflow/core/public/session.h" #include "tensorflow/core/util/command_line_flags.h" -#include #include "ngraph/event_tracing.hpp" -#include "ngraph_backend_manager.h" -#include "version.h" -#include "inference_engine.h" +#include "examples/cpp/infer_multiple_networks/inference_engine.h" +#include "ngraph_bridge/ngraph_backend_manager.h" +#include "ngraph_bridge/version.h" using namespace std; namespace tf = tensorflow; diff --git a/examples/cpp/infer_single/infer_single.cpp b/examples/cpp/infer_single/infer_single.cpp index 50ec3d354..766b07bae 100644 --- a/examples/cpp/infer_single/infer_single.cpp +++ b/examples/cpp/infer_single/infer_single.cpp @@ -14,6 +14,9 @@ * limitations under the License. *******************************************************************************/ +#include +#include "vector" + #include "tensorflow/cc/client/client_session.h" #include "tensorflow/cc/ops/standard_ops.h" #include "tensorflow/core/framework/graph.pb.h" @@ -29,11 +32,10 @@ #include "tensorflow/core/public/session.h" #include "tensorflow/core/util/command_line_flags.h" -#include #include "ngraph/event_tracing.hpp" -#include "ngraph_backend_manager.h" -#include "vector" -#include "version.h" + +#include "ngraph_bridge/ngraph_backend_manager.h" +#include "ngraph_bridge/version.h" using namespace std; namespace tf = tensorflow; diff --git a/examples/cpp/tf_label_image_utils.cc b/examples/cpp/tf_label_image_utils.cc index ed609b415..00379f5f4 100644 --- a/examples/cpp/tf_label_image_utils.cc +++ b/examples/cpp/tf_label_image_utils.cc @@ -80,7 +80,7 @@ limitations under the License. #include "tensorflow/core/public/session.h" #include "tensorflow/core/util/command_line_flags.h" -#include "ngraph_api.h" +#include "ngraph_bridge/ngraph_api.h" // These are all common classes it's handy to reference with no namespace. // using tensorflow::Flag; diff --git a/ngraph_bridge/CMakeLists.txt b/ngraph_bridge/CMakeLists.txt index 79b665d79..912dfa812 100644 --- a/ngraph_bridge/CMakeLists.txt +++ b/ngraph_bridge/CMakeLists.txt @@ -146,7 +146,7 @@ if(NGRAPH_BRIDGE_STATIC_LIB_ENABLE) target_link_libraries( ${LIB_NAME_STATIC} - ngraph_logger + ngraph_logger ${TensorFlow_FRAMEWORK_LIBRARY} ngraph_lib lib_cpu_backend_static diff --git a/ngraph_bridge/enable_variable_ops/ngraph_replace_op_utilities.cc b/ngraph_bridge/enable_variable_ops/ngraph_replace_op_utilities.cc index e45104875..4f535ca5b 100644 --- a/ngraph_bridge/enable_variable_ops/ngraph_replace_op_utilities.cc +++ b/ngraph_bridge/enable_variable_ops/ngraph_replace_op_utilities.cc @@ -194,11 +194,15 @@ Status ReplaceVariable(Graph* graph, Node* node, Node** replacement, // Though edges will be removed when we remove the node // we specifically remove the edges to be sure Status ReplaceInputControlEdges(Graph* graph, Node* node, Node* replacement) { + std::vector edges_to_remove; for (auto edge : node->in_edges()) { NGRAPH_VLOG(4) << "Replacing: " << edge->DebugString(); if (!edge->IsControlEdge()) continue; graph->AddEdge(edge->src(), edge->src_output(), replacement, edge->dst_input()); + edges_to_remove.push_back(edge); + } + for (auto edge : edges_to_remove) { graph->RemoveEdge(edge); } return Status::OK(); @@ -208,6 +212,7 @@ Status ReplaceInputControlEdges(Graph* graph, Node* node, Node* replacement) { // we specifically remove the edges to be sure Status ReplaceOutputEdges(Graph* graph, Node* node, Node* replacement) { std::vector edges; + std::vector edges_to_remove; for (auto edge : node->out_edges()) { edges.push_back(edge); } @@ -216,9 +221,11 @@ Status ReplaceOutputEdges(Graph* graph, Node* node, Node* replacement) { NGRAPH_VLOG(4) << "Replacing: " << edge->DebugString(); graph->AddEdge(replacement, edge->src_output(), edge->dst(), edge->dst_input()); + edges_to_remove.push_back(edge); + } + for (auto edge : edges_to_remove) { graph->RemoveEdge(edge); } - return Status::OK(); } diff --git a/ngraph_bridge/ngraph_builder.cc b/ngraph_bridge/ngraph_builder.cc index 5f9d67b39..27094c8e9 100644 --- a/ngraph_bridge/ngraph_builder.cc +++ b/ngraph_bridge/ngraph_builder.cc @@ -4915,7 +4915,7 @@ Status Builder::TranslateGraph( // ought to be `const Node*`, but GetReversePostOrder doesn't use `const` vector ordered; - GetReversePostOrder(*input_graph, &ordered); + GetReversePostOrder(*input_graph, &ordered, NodeComparatorName()); // // Split ops into params, retvals, and all others. diff --git a/ngraph_bridge/ngraph_capture_variables.cc b/ngraph_bridge/ngraph_capture_variables.cc index a751a8479..915fa869a 100644 --- a/ngraph_bridge/ngraph_capture_variables.cc +++ b/ngraph_bridge/ngraph_capture_variables.cc @@ -98,20 +98,18 @@ Status CaptureVariables(Graph* graph, const std::set skip_these_nodes) { edge->dst_input()); edges_to_remove.push_back(edge); } - // Though edges will be removed when we remove the node - // we specifically remove the edges to be sure - for (auto edge : edges_to_remove) { - graph->RemoveEdge(edge); - } for (auto edge : node->out_edges()) { - edges.push_back(edge); - } - - for (auto edge : edges) { NGRAPH_VLOG(4) << "Replacing: " << edge->DebugString(); graph->AddEdge(replacement, edge->src_output(), edge->dst(), edge->dst_input()); + edges_to_remove.push_back(edge); + } + + // Though edges will be removed when we remove the node + // we specifically remove the edges to be sure + for (auto edge : edges_to_remove) { + NGRAPH_VLOG(4) << "Removing: " << edge->DebugString(); graph->RemoveEdge(edge); } diff --git a/ngraph_bridge/ngraph_rewrite_for_tracking.cc b/ngraph_bridge/ngraph_rewrite_for_tracking.cc index add5871e9..c39013eee 100644 --- a/ngraph_bridge/ngraph_rewrite_for_tracking.cc +++ b/ngraph_bridge/ngraph_rewrite_for_tracking.cc @@ -90,23 +90,26 @@ Status RewriteForTracking(Graph* graph, int graph_id) { NGRAPH_VLOG(4) << "Replacing Node " << node->DebugString() << " with " << replacement->DebugString(); - // Though edges will be removed when we remove the node - // we specifically remove the edges to be sure + std::vector edges_to_remove; + for (auto edge : node->in_edges()) { - NGRAPH_VLOG(4) << "Replacing: " << edge->DebugString(); + NGRAPH_VLOG(4) << "Replacing: In Edge " << edge->DebugString(); graph->AddEdge(edge->src(), edge->src_output(), replacement, edge->dst_input()); - graph->RemoveEdge(edge); + edges_to_remove.push_back(edge); } - std::vector edges; for (auto edge : node->out_edges()) { - edges.push_back(edge); - } - for (auto edge : edges) { - NGRAPH_VLOG(4) << "Replacing: " << edge->DebugString(); + NGRAPH_VLOG(4) << "Replacing: OutEdge " << edge->DebugString(); graph->AddEdge(replacement, edge->src_output(), edge->dst(), edge->dst_input()); + edges_to_remove.push_back(edge); + } + + // Though edges will be removed when we remove the node + // we specifically remove the edges to be sure + for (auto edge : edges_to_remove) { + NGRAPH_VLOG(4) << "Removing: Edges " << edge->DebugString(); graph->RemoveEdge(edge); } diff --git a/ngraph_bridge/version.cc b/ngraph_bridge/version.cc index 335a2384d..02188c42b 100644 --- a/ngraph_bridge/version.cc +++ b/ngraph_bridge/version.cc @@ -32,7 +32,7 @@ // candidate such as v0.7.0-rc0 // The code in master will always have the last released version number // with a suffix of '-master' -#define NG_TF_VERSION_SUFFIX "-rc0" +#define NG_TF_VERSION_SUFFIX "-rc1" #define VERSION_STR_HELPER(x) #x #define VERSION_STR(x) VERSION_STR_HELPER(x) diff --git a/python/setup.in.py b/python/setup.in.py index a0a48ec68..b8365e2dc 100644 --- a/python/setup.in.py +++ b/python/setup.in.py @@ -59,7 +59,7 @@ def get_tag(self): setup( name='ngraph_tensorflow_bridge', - version='0.19.0rc0', + version='0.19.0rc1', description='Intel nGraph compiler and runtime for TensorFlow', long_description=long_description, long_description_content_type="text/markdown", diff --git a/test/ci/buildkite/ngtf-cpu_centos-grappler.yaml b/test/ci/buildkite/ngtf-cpu_centos-grappler.yaml index 6f177b335..86a4df1e8 100644 --- a/test/ci/buildkite/ngtf-cpu_centos-grappler.yaml +++ b/test/ci/buildkite/ngtf-cpu_centos-grappler.yaml @@ -100,7 +100,8 @@ agents: - "queue=cpu" - - wait + - wait: ~ + continue_on_failure: true - command: | rm -rf /localdisk/buildkite/artifacts/$BUILDKITE_BUILD_ID label: ":wastebasket: Cleanup" diff --git a/test/ci/buildkite/ngtf-cpu_centos.yaml b/test/ci/buildkite/ngtf-cpu_centos.yaml index 70e761aee..d02406f19 100644 --- a/test/ci/buildkite/ngtf-cpu_centos.yaml +++ b/test/ci/buildkite/ngtf-cpu_centos.yaml @@ -12,19 +12,6 @@ - wait - - command: | - source /localdisk/buildkite/artifacts/$BUILDKITE_BUILD_ID/venv/bin/activate - export PATH=/opt/llvm-3.9.0/bin/:$$PATH - maint/check-code-format.sh - - label: ":pencil: Code Format ?" - timeout_in_minutes: 30 - agents: - - "queue=cpu-centos" - parallelism: 1 - - - wait - - command: | source /localdisk/buildkite/artifacts/$BUILDKITE_BUILD_ID/venv/bin/activate python3 build_ngtf.py --artifacts /localdisk/buildkite/artifacts/$BUILDKITE_BUILD_ID \ @@ -41,7 +28,7 @@ - command: | source /localdisk/buildkite/artifacts/$BUILDKITE_BUILD_ID/venv/bin/activate pip install -U \ - /localdisk/buildkite/artifacts/$BUILDKITE_BUILD_ID/tensorflow/tensorflow-1.14.0-cp36-cp36m-linux_x86_64.whl + /localdisk/buildkite/artifacts/$BUILDKITE_BUILD_ID/tensorflow/tensorflow-1.14.0-cp34-cp34m-linux_x86_64.whl PYTHONPATH=`pwd` python3 test/ci/buildkite/test_runner.py \ --artifacts /localdisk/buildkite/artifacts/$BUILDKITE_BUILD_ID --test_bazel bazel clean --expunge @@ -67,7 +54,7 @@ - command: | source /localdisk/buildkite/artifacts/$BUILDKITE_BUILD_ID/venv/bin/activate pip install psutil && pip install -U \ - /localdisk/buildkite/artifacts/$BUILDKITE_BUILD_ID/tensorflow/tensorflow-1.14.0-cp36-cp36m-linux_x86_64.whl + /localdisk/buildkite/artifacts/$BUILDKITE_BUILD_ID/tensorflow/tensorflow-1.14.0-cp34-cp34m-linux_x86_64.whl pip install -U /localdisk/buildkite/artifacts/$BUILDKITE_BUILD_ID/ngraph_tensorflow_bridge-*.whl label: ":gear: Install" @@ -112,7 +99,8 @@ agents: - "queue=cpu-centos" - - wait + - wait: ~ + continue_on_failure: true - command: | rm -rf /localdisk/buildkite/artifacts/$BUILDKITE_BUILD_ID label: ":wastebasket: Cleanup" diff --git a/test/ci/buildkite/ngtf-cpu_macos.yaml b/test/ci/buildkite/ngtf-cpu_macos.yaml index 5945953ee..6f4443c6f 100644 --- a/test/ci/buildkite/ngtf-cpu_macos.yaml +++ b/test/ci/buildkite/ngtf-cpu_macos.yaml @@ -85,7 +85,8 @@ agents: - "queue=mac" - - wait + - wait: ~ + continue_on_failure: true - command: | rm -rf /usr/local/var/buildkite-agent/artifacts/$BUILDKITE_BUILD_ID label: ":wastebasket: Cleanup" diff --git a/test/ci/buildkite/ngtf-cpu_model-test.yaml b/test/ci/buildkite/ngtf-cpu_model-test.yaml index c6cb85caa..733d4be73 100644 --- a/test/ci/buildkite/ngtf-cpu_model-test.yaml +++ b/test/ci/buildkite/ngtf-cpu_model-test.yaml @@ -13,7 +13,7 @@ - command: | source /localdisk/buildkite/artifacts/$BUILDKITE_BUILD_ID/venv/bin/activate python3 build_ngtf.py --artifacts /localdisk/buildkite/artifacts/$BUILDKITE_BUILD_ID \ - --use_tensorflow_from_location /localdisk/buildkite-agent/prebuilt_tensorflow_1_14_0_rc0 + --use_tensorflow_from_location /localdisk/buildkite-agent/prebuilt_tensorflow_1_14_0 label: ":hammer_and_wrench: Build" timeout_in_minutes: 60 @@ -25,7 +25,7 @@ - command: | source /localdisk/buildkite/artifacts/$BUILDKITE_BUILD_ID/venv/bin/activate pip install psutil && pip install -U \ - /localdisk/buildkite/artifacts/$BUILDKITE_BUILD_ID/tensorflow/tensorflow-1.14.0rc0-cp36-cp36m-linux_x86_64.whl + /localdisk/buildkite/artifacts/$BUILDKITE_BUILD_ID/tensorflow/tensorflow-1.14.0-cp36-cp36m-linux_x86_64.whl pip install -U /localdisk/buildkite/artifacts/$BUILDKITE_BUILD_ID/ngraph_tensorflow_bridge-*.whl label: ":gear: Install" @@ -38,7 +38,7 @@ - command: | source /localdisk/buildkite/artifacts/$BUILDKITE_BUILD_ID/venv/bin/activate cd test/model_level_tests - python test_main.py --models benchmarks,MLP,ngraph-models,nmt,tfmodels,unet --run_basic_tests; cd ../.. + python test_main.py --models benchmarks,MLP,ngraph-models,nmt,tfmodels --run_basic_tests; cd ../.. label: ":kafka: Model tests" timeout_in_minutes: 40 @@ -46,9 +46,10 @@ - "queue=cpu" parallelism: 1 - - wait + - wait: ~ + continue_on_failure: true - command: | rm -rf /localdisk/buildkite/artifacts/$BUILDKITE_BUILD_ID label: ":wastebasket: Cleanup" agents: - - "queue=cpu" \ No newline at end of file + - "queue=cpu" diff --git a/test/ci/buildkite/ngtf-cpu_tf_bin.yaml b/test/ci/buildkite/ngtf-cpu_tf_bin.yaml index efc224a82..41fe53c98 100644 --- a/test/ci/buildkite/ngtf-cpu_tf_bin.yaml +++ b/test/ci/buildkite/ngtf-cpu_tf_bin.yaml @@ -8,7 +8,7 @@ label: ":gear: Setup" timeout_in_minutes: 30 agents: - - "queue=cpu_tf_bin" + - "queue=cpu" parallelism: 1 - wait @@ -20,7 +20,7 @@ label: ":pencil: Code Format ?" timeout_in_minutes: 30 agents: - - "queue=cpu_tf_bin" + - "queue=cpu" parallelism: 1 - wait @@ -32,7 +32,7 @@ label: ":hammer_and_wrench: Build" timeout_in_minutes: 60 agents: - - "queue=cpu_tf_bin" + - "queue=cpu" parallelism: 1 - wait @@ -45,7 +45,7 @@ label: ":bazel: Bazel Build" timeout_in_minutes: 30 agents: - - "queue=cpu_tf_bin" + - "queue=cpu" - wait - command: | @@ -55,7 +55,7 @@ label: ":chrome: C++ Unit Test" timeout_in_minutes: 30 agents: - - "queue=cpu_tf_bin" + - "queue=cpu" - wait - command: | @@ -67,7 +67,7 @@ label: ":python: nGraph Pytest" timeout_in_minutes: 30 agents: - - "queue=cpu_tf_bin" + - "queue=cpu" - wait - command: | @@ -79,7 +79,7 @@ label: ":python: TensorFlow Pytest" timeout_in_minutes: 60 agents: - - "queue=cpu_tf_bin" + - "queue=cpu" - wait @@ -90,11 +90,14 @@ label: ":bar_chart: ResNet50" timeout_in_minutes: 30 agents: - - "queue=cpu_tf_bin" - - wait + - "queue=cpu" + + - wait: ~ + continue_on_failure: true + - command: | rm -rf /localdisk/buildkite/artifacts/$BUILDKITE_BUILD_ID label: ":wastebasket: Cleanup" agents: - - "queue=cpu_tf_bin" + - "queue=cpu" diff --git a/test/ci/buildkite/ngtf-cpu_ubuntu-bin-build.yaml b/test/ci/buildkite/ngtf-cpu_ubuntu-bin-build.yaml index 98975646a..a5ae188af 100644 --- a/test/ci/buildkite/ngtf-cpu_ubuntu-bin-build.yaml +++ b/test/ci/buildkite/ngtf-cpu_ubuntu-bin-build.yaml @@ -46,7 +46,8 @@ agents: - "queue=cpu-centos" - - wait + - wait: ~ + continue_on_failure: true - command: | rm -rf /localdisk/buildkite/artifacts/$BUILDKITE_BUILD_ID label: ":wastebasket: Cleanup" diff --git a/test/ci/buildkite/ngtf-cpu_ubuntu-variables.yaml b/test/ci/buildkite/ngtf-cpu_ubuntu-variables.yaml index 9f4c72029..303f55513 100644 --- a/test/ci/buildkite/ngtf-cpu_ubuntu-variables.yaml +++ b/test/ci/buildkite/ngtf-cpu_ubuntu-variables.yaml @@ -98,7 +98,8 @@ agents: - "queue=cpu" - - wait + - wait: ~ + continue_on_failure: true - command: | rm -rf /localdisk/buildkite/artifacts/$BUILDKITE_BUILD_ID label: ":wastebasket: Cleanup" diff --git a/test/ci/buildkite/ngtf-cpu_ubuntu.yaml b/test/ci/buildkite/ngtf-cpu_ubuntu.yaml index 776410b6a..edaae3e40 100644 --- a/test/ci/buildkite/ngtf-cpu_ubuntu.yaml +++ b/test/ci/buildkite/ngtf-cpu_ubuntu.yaml @@ -110,7 +110,9 @@ agents: - "queue=cpu" - - wait + - wait: ~ + continue_on_failure: true + - command: | rm -rf /localdisk/buildkite/artifacts/$BUILDKITE_BUILD_ID label: ":wastebasket: Cleanup" diff --git a/test/ci/buildkite/ngtf-cpu_ubuntu_18_04.yaml b/test/ci/buildkite/ngtf-cpu_ubuntu_18_04.yaml index 4e5844365..8145f0395 100644 --- a/test/ci/buildkite/ngtf-cpu_ubuntu_18_04.yaml +++ b/test/ci/buildkite/ngtf-cpu_ubuntu_18_04.yaml @@ -103,7 +103,9 @@ timeout_in_minutes: 30 agents: - "queue=r0.16" - - wait + + - wait: ~ + continue_on_failure: true - command: | rm -rf /localdisk/buildkite/artifacts/$BUILDKITE_BUILD_ID label: ":wastebasket: Cleanup" diff --git a/test/ci/buildkite/ngtf-gpu_ubuntu.yaml b/test/ci/buildkite/ngtf-gpu_ubuntu.yaml index 985344c19..5f7d580b0 100644 --- a/test/ci/buildkite/ngtf-gpu_ubuntu.yaml +++ b/test/ci/buildkite/ngtf-gpu_ubuntu.yaml @@ -89,7 +89,9 @@ agents: - "queue=gpu" - - wait + - wait: ~ + continue_on_failure: true + - command: | rm -rf /localdisk/buildkite/artifacts/$BUILDKITE_BUILD_ID label: ":wastebasket: Cleanup" diff --git a/test/model_level_tests/README.md b/test/model_level_tests/README.md index 39a876195..def284a6a 100644 --- a/test/model_level_tests/README.md +++ b/test/model_level_tests/README.md @@ -88,7 +88,7 @@ On CPU: | a3c | :heavy_check_mark: | :heavy_multiplication_x: | :heavy_multiplication_x: | :heavy_check_mark: | ngraph-models | dcgan | :heavy_check_mark: | :heavy_multiplication_x: | :heavy_multiplication_x: | :heavy_check_mark: | ngraph-models | unet | ?? | :heavy_multiplication_x: | ?? | :heavy_check_mark: | unet -| ssd mobilenet v1 | ?? | :heavy_multiplication_x: | ?? | :heavy_check_mark: | tfmodels +| ssd mobilenet v1 | ?? | :heavy_multiplication_x: | ?? | ?? | tfmodels | nmt | :heavy_check_mark: | :heavy_multiplication_x: | :heavy_check_mark: | :heavy_multiplication_x: | nmt | bert | :heavy_check_mark: | :heavy_multiplication_x: | :heavy_check_mark: | :heavy_multiplication_x: | bert | minigo | :heavy_check_mark: | :heavy_multiplication_x: | :heavy_check_mark: | :heavy_multiplication_x: | minigo diff --git a/test/model_level_tests/models/MLP/test1/expected.json b/test/model_level_tests/models/MLP/test1/expected.json index 53aeed6a3..b432d0335 100644 --- a/test/model_level_tests/models/MLP/test1/expected.json +++ b/test/model_level_tests/models/MLP/test1/expected.json @@ -7,9 +7,9 @@ "num_nodes_marked_for_clustering": 0 }, "1": { - "num_ng_clusters": 17, - "num_nodes_in_graph": 310, - "num_nodes_marked_for_clustering": 244 + "num_ng_clusters": 15, + "num_nodes_in_graph": 311, + "num_nodes_marked_for_clustering": 249 } }, "time": 10 @@ -22,9 +22,24 @@ "num_nodes_marked_for_clustering": 0 }, "1": { - "num_ng_clusters": 17, - "num_nodes_in_graph": 329, - "num_nodes_marked_for_clustering": 262 + "num_ng_clusters": 15, + "num_nodes_in_graph": 330, + "num_nodes_marked_for_clustering": 267 + } + }, + "time": 10 + }, + "varopts": { + "logparse": { + "0": { + "num_ng_clusters": 0, + "num_nodes_in_graph": 50, + "num_nodes_marked_for_clustering": 0 + }, + "1": { + "num_ng_clusters": 15, + "num_nodes_in_graph": 312, + "num_nodes_marked_for_clustering": 250 } }, "time": 10 diff --git a/test/model_level_tests/models/MLP/test2/expected.json b/test/model_level_tests/models/MLP/test2/expected.json index ffbf6c47b..b80f3f53d 100644 --- a/test/model_level_tests/models/MLP/test2/expected.json +++ b/test/model_level_tests/models/MLP/test2/expected.json @@ -7,9 +7,9 @@ "num_nodes_marked_for_clustering": 0 }, "1": { - "num_ng_clusters": 21, - "num_nodes_in_graph": 448, - "num_nodes_marked_for_clustering": 358 + "num_ng_clusters": 19, + "num_nodes_in_graph": 449, + "num_nodes_marked_for_clustering": 363 } }, "time": 13 @@ -22,9 +22,24 @@ "num_nodes_marked_for_clustering": 0 }, "1": { - "num_ng_clusters": 21, - "num_nodes_in_graph": 478, - "num_nodes_marked_for_clustering": 387 + "num_ng_clusters": 19, + "num_nodes_in_graph": 479, + "num_nodes_marked_for_clustering": 392 + } + }, + "time": 13 + }, + "varopts": { + "logparse": { + "0": { + "num_ng_clusters": 0, + "num_nodes_in_graph": 83, + "num_nodes_marked_for_clustering": 0 + }, + "1": { + "num_ng_clusters": 19, + "num_nodes_in_graph": 450, + "num_nodes_marked_for_clustering": 364 } }, "time": 13 diff --git a/test/model_level_tests/models/nmt/test1/core_run.sh b/test/model_level_tests/models/nmt/test1/core_run.sh index f728079f0..2d441f33b 100755 --- a/test/model_level_tests/models/nmt/test1/core_run.sh +++ b/test/model_level_tests/models/nmt/test1/core_run.sh @@ -2,8 +2,8 @@ if [ -e "/tmp/mnt/nmt_model" ];then rm -rf "/tmp/mnt/nmt_model" ; fi OMP_NUM_THREADS=28 KMP_AFFINITY=granularity=fine,compact,1,0 \ -python -m nmt.nmt --src=vi --tgt=en --vocab_prefix=/mnt/data/nmt_data/vocab \ - --train_prefix=/mnt/data/nmt_data/train --dev_prefix=/mnt/data/nmt_data/tst2012 \ - --test_prefix=/mnt/data/nmt_data/tst2013 --out_dir=/tmp/mnt/nmt_model \ +python -m nmt.nmt --src=vi --tgt=en --vocab_prefix=/mnt/data/validation_gold_dataset/nmt_data/vocab \ + --train_prefix=/mnt/data/validation_gold_dataset/nmt_data/train --dev_prefix=/mnt/data/validation_gold_dataset/nmt_data/tst2012 \ + --test_prefix=/mnt/data/validation_gold_dataset/nmt_data/tst2013 --out_dir=/tmp/mnt/nmt_model \ --num_train_steps=1 --steps_per_stats=100 --num_layers=1 \ - --dropout=0.2 --metrics=bleu \ No newline at end of file + --dropout=0.2 --metrics=bleu diff --git a/test/model_level_tests/test_main.py b/test/model_level_tests/test_main.py index 8452e0bc9..66fa6443d 100644 --- a/test/model_level_tests/test_main.py +++ b/test/model_level_tests/test_main.py @@ -127,10 +127,21 @@ def ready_repo(model_dir, repo_dl_loc): command_executor(model_dir + '/getting_repo_ready.sh', verbose=True) +# Currently there are 2 types of tests. parsing the logs and timing the run +def valid_test_types(): + return set(['time', 'logparse']) + + +# Check if the contents of this iterable contains only valid test types +def check_test_types(iterable): + return all(map(lambda i: i in valid_test_types(), iterable)) + + # TODO: this function needs to accept "do-i-dump-pbtxt"? and if so, a cleanup needs to happen later. # Also this function could return the list of pbtxts it generated (but does it need to? we can infer it) # TODO: this function should also take the level/intensity of test to run -def run_test_suite(model_dir, configuration, disabled, print_parsed): +def run_test_suite(model_dir, configuration, disabled, print_parsed, + ignore_test): try: # TODO: assert TF version. Some models may not run on TF1.12 etc model_dir = os.path.abspath(model_dir) @@ -239,14 +250,21 @@ def run_test_suite(model_dir, configuration, disabled, print_parsed): not custom_parser_present) except: assert False, 'Failed to parse ' + expected_json_file - passed, fail_help_string = compare_parsed_values( - parsed_vals, expected.get('logparse', {})) - if not passed: - print('Failed in test ' + flname + - '. Help message: ' + fail_help_string) - failed_tests.append(flname) - continue - if 'time' in expected: + assert check_test_types(expected.keys( + )), "Got unexpected key in " + expected.keys( + ) + ". Should have been " + ','.join(valid_test_types) + # We run the test if 'logparse' is present in the expected values to check + # for and it is not in the ignore list + if ('logparse' in expected) and ( + 'logparse' not in ignore_test): + passed, fail_help_string = compare_parsed_values( + parsed_vals, expected['logparse']) + if not passed: + print('Failed in test ' + flname + + '. Help message: ' + fail_help_string) + failed_tests.append(flname) + continue + if ('time' in expected) and ('time' not in ignore_test): actual_runtime = tend - tstart # TODO: decide this criteria. time can be pretty variable # TODO: the percentage (0.1) for the time bound might be passed through `expected.json` @@ -372,7 +390,7 @@ def get_disabled_tests_info(): action='store', type=str, help='Comma separated list of model names', - default='') + ) parser.add_argument( '--list', action='store_true', @@ -399,6 +417,13 @@ def get_disabled_tests_info(): help= 'Print the parsed values from log parsing. Useful when checking in a new model and we want to know its expected values' ) + parser.add_argument( + '--ignore_test', + type=str, + default=None, + help= + 'Comma separated string. Given an expected json file, ignore these tests. Can take values "", "logparse", "time", "logparse,time", "time,logparse"' + ) # This script must be run from this location assert cwd.split('/')[-1] == 'model_level_tests' @@ -419,6 +444,12 @@ def get_disabled_tests_info(): args.run_basic_tests or args.run_functional_tests ), 'No type of test enabled. Please choose --run_basic_tests, --run_functional_tests or both' + ignore_test = [] if ( + args.ignore_test is None) else args.ignore_test.split(',') + assert ((ignore_test=='') or check_test_types(ignore_test) + ), "Types of possible tests: " + ','.join(valid_test_types()) + \ + ", but requested to skip " + args.ignore_test + requested_test_suites = os.listdir( 'models') if args.models == '' else args.models.split(',') @@ -434,12 +465,14 @@ def get_disabled_tests_info(): failed_tests = {} skipped_tests = {} for test_suite in requested_test_suites: - print('Testing model/test-suite: ' + test_suite) + print('\n' + '=' * 20 + 'Testing model/test-suite: ' + test_suite + + '=' * 20) if test_suite not in disabled_test_suite: if args.run_basic_tests: passed_tests_in_suite, failed_tests_in_suite, skipped_tests_in_suite = run_test_suite( './models/' + test_suite, args.configuration, - disabled_sub_test.get(test_suite, []), args.print_parsed) + disabled_sub_test.get(test_suite, []), args.print_parsed, + ignore_test) passed_tests[test_suite] = passed_tests_in_suite failed_tests[test_suite] = failed_tests_in_suite skipped_tests[test_suite] = skipped_tests_in_suite @@ -450,6 +483,8 @@ def get_disabled_tests_info(): print('Passed:\n' + '\033[92m' + print_format(passed_tests) + '\033[0m') print('Skipped:\n' + '\033[93m' + print_format(skipped_tests) + '\033[0m') print('Failed:\n' + '\033[91m' + print_format(failed_tests) + '\033[0m') + all_tests_passed = all([len(failed_tests[k]) == 0 for k in failed_tests]) + exit(0 if all_tests_passed else 1) # TODO add a test comparing with TF run? # TODO verbose or quiet? @@ -464,21 +499,4 @@ def get_disabled_tests_info(): # Level3: parse prints we put. These tests are run without "NGRAPH_TF_LOG_PLACEMENT=1". the framework can provide some default parsers, but users are free to add pyscripts that provide functions for custom script parsers # These tests can be long # So we can offer options to do: {1}, {1,2}, {1,2,3}, {3} (or do we allow options for any combination of tests?) -# NOTE: Level3 and Level1 test are same (mechanics wise). Merge them. Then we have only 2 types of tests - -# Each model dir represents 1 repo to download. A model dir can have multiple sub tests (each sub-test could represent a different model, or the same model tested under different settings) - -# Structure of "expected json" -# dictionary of expected values. key is a config, value is the expected values json. there is a "default" config, but one can add other configs (for example for other backends etc) - -# Sample run script: -# python test_main.py --run_logparse_tests --models MLP - -# feature 1: dumps shell script at the end. dumps shell script even when the framework crashes -# feature 2: prints list of tests and their descriptions (--list) -# feature 3: "expected" values can be varied by different configs -# feature 4: cleanup script -# feature 5: sub tests folders must start with 'test' (else ignored). Can have 'disabled' in their names to disable -# feature 6: default and user-specified log parsers (named custom_log_parser.py, which is expected to contain a function custom_parse_logs) -# feature 7: filename is supposed to be expected.json -# feature 8: enable_ngraph can be placed in each test dir or in the model dir for all subtests to share. test folder's patch overrides global model folder patch +# NOTE: Level3 and Level1 test are same (mechanics wise). We have only 2 types of tests, though Level2 is unimplemented for now diff --git a/test/python/test_conv2D_KernelChecks.py b/test/python/test_conv2D_KernelChecks.py index 5edd79478..2284478e2 100644 --- a/test/python/test_conv2D_KernelChecks.py +++ b/test/python/test_conv2D_KernelChecks.py @@ -63,7 +63,11 @@ def make_filter_and_backprop_args(self): return x1, x2 - def test_conv2d_stride_in_batch_not_supported(self): + @pytest.mark.parametrize(("strides",), ( + ([2, 1, 1, 1],), + ([1, 1, 1, 2],), + )) + def test_conv2d_stride_in_batch_not_supported(self, strides): inp_values, filt_values = self.make_filter_and_backprop_args() def run_test(sess): @@ -80,19 +84,6 @@ def run_test(sess): self.with_ngraph(run_test) assert "Strides in batch and depth dimensions is not supported: Conv2D" in excinfo.value.message - def test_conv2d_stride_in_depth_not_supported(self): - inp_values, filt_values = self.make_filter_and_backprop_args() - - def run_test(sess): - inp = array_ops.placeholder(dtypes.float32) - filt = array_ops.placeholder(dtypes.float32) - return sess.run( - nn_ops.conv2d(inp, filt, strides=[1, 1, 1, 2], padding="SAME"), - { - inp: inp_values, - filt: filt_values - }) - - with pytest.raises(Exception) as excinfo: - self.with_ngraph(run_test) - assert "Strides in batch and depth dimensions is not supported: Conv2D" in excinfo.value.message + # TF also fails + with pytest.raises(Exception) as excinfo1: + self.without_ngraph(run_test) diff --git a/test/python/test_modeltester.py b/test/python/test_modeltester.py index aa0cde81d..1cab4abac 100644 --- a/test/python/test_modeltester.py +++ b/test/python/test_modeltester.py @@ -27,6 +27,7 @@ from common import NgraphTest from tools.build_utils import command_executor +import ngraph_bridge class TestModelTester(NgraphTest): @@ -35,8 +36,18 @@ class TestModelTester(NgraphTest): def test_MLP(self): cwd = os.getcwd() os.chdir('../model_level_tests/') + grappler = ngraph_bridge.is_grappler_enabled() + varopts = ngraph_bridge.are_variables_enabled() + if grappler: + if varopts: + assert False, "Varopts and grappler does not build together right now" + else: + config = "grappler" + else: + config = "varopts" if varopts else "default" try: command_executor( - "python test_main.py --run_basic_tests --models MLP") + "python test_main.py --run_basic_tests --models MLP --ignore_test time --configuration " + + config) finally: os.chdir(cwd) diff --git a/tools/test_utils.py b/tools/test_utils.py index 760b678d4..d7bafc493 100755 --- a/tools/test_utils.py +++ b/tools/test_utils.py @@ -592,12 +592,16 @@ def run_bazel_build_test(venv_dir, build_dir): # Now run the configure command_executor(['bash', 'configure_bazel.sh']) - # Build the bridge - command_executor(['bazel', 'build', 'libngraph_bridge.so']) + # Build the cpp app - hello_tf + command_executor(['bazel', 'build', 'hello_tf']) - # Build the backends - command_executor(['bazel', 'build', '@ngraph//:libinterpreter_backend.so']) - command_executor(['bazel', 'build', '@ngraph//:libcpu_backend.so']) + # Run the cpp app - hello_tf + command_executor(['bazel-bin/hello_tf']) + + # Now built the bigger app + command_executor([ + 'bazel', 'build', '//examples/cpp/infer_multiple_networks:infer_multi' + ]) # Return to the original directory os.chdir(root_pwd) @@ -610,12 +614,11 @@ def run_bazel_build(): # Now run the configure command_executor(['bash', 'configure_bazel.sh']) - # Build the bridge - command_executor(['bazel', 'build', 'libngraph_bridge.so']) + # Build the cpp app - hello_tf + command_executor(['bazel', 'build', 'hello_tf']) - # Build the backend - command_executor(['bazel', 'build', '@ngraph//:libinterpreter_backend.so']) - command_executor(['bazel', 'build', '@ngraph//:libcpu_backend.so']) + # Run the cpp app - hello_tf + command_executor(['bazel-bin/hello_tf']) # Return to the original directory os.chdir(root_pwd)