From abe9ab326625105adb3c9d46c027931aec947d1f Mon Sep 17 00:00:00 2001 From: "A. Unique TensorFlower" Date: Sun, 31 Jul 2016 22:07:30 -0800 Subject: [PATCH 001/134] Merge changes from github. Change: 128958134 --- README.md | 8 +- RELEASE.md | 50 +++++--- tensorflow/contrib/makefile/Makefile | 16 ++- tensorflow/contrib/makefile/build_all_ios.sh | 12 ++ .../makefile/compile_ios_tensorflow.sh | 27 +---- tensorflow/contrib/makefile/tf_op_files.txt | 1 + .../common_runtime/optimization_registry.h | 2 +- .../simple_graph_execution_state.h | 2 +- tensorflow/core/graph/gradients.cc | 2 - tensorflow/core/graph/graph.cc | 3 - tensorflow/core/kernels/argmax_op.cc | 2 +- tensorflow/core/kernels/cwise_op_conj.cc | 6 +- .../core/kernels/cwise_op_gpu_conj.cu.cc | 3 +- tensorflow/core/kernels/cwise_op_sub.cc | 6 + tensorflow/core/kernels/cwise_ops_test.cc | 37 +++--- .../core/kernels/lookup_table_init_op.cc | 2 +- tensorflow/core/ops/math_ops.cc | 52 ++++++++- tensorflow/core/ops/ops.pbtxt | 36 ++++++ tensorflow/core/public/version.h | 4 +- .../reading_data/convert_to_records.py | 1 - .../reading_data/fully_connected_preloaded.py | 3 - .../fully_connected_preloaded_var.py | 3 - .../reading_data/fully_connected_reader.py | 2 - .../examples/image_retraining/retrain_test.py | 2 - .../examples/learn/wide_n_deep_tutorial.py | 4 +- .../examples/skflow/multioutput_regression.py | 1 - .../tutorials/mnist/fully_connected_feed.py | 2 +- tensorflow/g3doc/api_docs/cc/ClassEnv.md | 54 ++++++++- .../g3doc/api_docs/cc/ClassEnvWrapper.md | 4 +- tensorflow/g3doc/api_docs/cc/ClassTensor.md | 54 +++++++-- .../g3doc/api_docs/cc/ClassTensorShape.md | 12 ++ .../api_docs/cc/ClassTensorShapeUtils.md | 16 ++- .../g3doc/api_docs/cc/StructTF_Buffer.md | 2 +- tensorflow/g3doc/api_docs/index.md | 6 +- .../functions_and_classes/shard0/tf.nn.rnn.md | 6 +- .../shard6/tf.train.exponential_decay.md | 2 +- tensorflow/g3doc/api_docs/python/nn.md | 6 +- tensorflow/g3doc/get_started/os_setup.md | 107 +++++++++++++----- tensorflow/g3doc/how_tos/using_gpu/index.md | 2 +- tensorflow/python/ops/rnn.py | 3 +- tensorflow/python/ops/rnn_cell.py | 5 + tensorflow/python/platform/tf_logging.py | 2 +- .../python/training/learning_rate_decay.py | 8 +- tensorflow/tensorboard/README.md | 10 +- .../ci_build/Dockerfile.debian.jessie.cpu | 3 + tensorflow/tools/ci_build/builds/pip.sh | 3 +- .../tools/ci_build/ci_parameterized_build.sh | 6 +- tensorflow/tools/dist_test/Dockerfile | 2 +- tensorflow/tools/dist_test/server/Dockerfile | 2 +- .../tools/dist_test/server/Dockerfile.test | 2 +- tensorflow/tools/docker/Dockerfile | 2 +- tensorflow/tools/docker/Dockerfile.devel | 2 +- tensorflow/tools/docker/Dockerfile.devel-gpu | 4 +- tensorflow/tools/docker/Dockerfile.gpu | 2 +- .../docker/parameterized_docker_build.sh | 6 +- tensorflow/tools/pip_package/setup.py | 2 +- third_party/gpus/crosstool/CROSSTOOL | 4 + 57 files changed, 461 insertions(+), 167 deletions(-) diff --git a/README.md b/README.md index 923b094e4a8..e0ac8f6eff9 100644 --- a/README.md +++ b/README.md @@ -33,10 +33,10 @@ and discussion.** People who are a little more adventurous can also try our nightly binaries: -* Linux CPU-only: [Python 2](http://ci.tensorflow.org/view/Nightly/job/nightly-matrix-cpu/TF_BUILD_CONTAINER_TYPE=CPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON2,label=cpu-slave/lastSuccessfulBuild/artifact/pip_test/whl/tensorflow-0.9.0-cp27-none-linux_x86_64.whl) ([build history](http://ci.tensorflow.org/view/Nightly/job/nightly-matrix-cpu/TF_BUILD_CONTAINER_TYPE=CPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON2,label=cpu-slave/)) / [Python 3.4](http://ci.tensorflow.org/view/Nightly/job/nightly-matrix-cpu/TF_BUILD_CONTAINER_TYPE=CPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON3,label=cpu-slave/lastSuccessfulBuild/artifact/pip_test/whl/tensorflow-0.9.0-cp34-cp34m-linux_x86_64.whl) ([build history](http://ci.tensorflow.org/view/Nightly/job/nightly-matrix-cpu/TF_BUILD_CONTAINER_TYPE=CPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON3,label=cpu-slave/)) / [Python 3.5](http://ci.tensorflow.org/view/Nightly/job/nightly-python35-linux-cpu/lastSuccessfulBuild/artifact/pip_test/whl/tensorflow-0.9.0-cp35-cp35m-linux_x86_64.whl) ([build history](http://ci.tensorflow.org/view/Nightly/job/nightly-python35-linux-cpu/)) -* Linux GPU: [Python 2](http://ci.tensorflow.org/view/Nightly/job/nigntly-matrix-linux-gpu/TF_BUILD_CONTAINER_TYPE=GPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON2,label=gpu-linux/lastSuccessfulBuild/artifact/pip_test/whl/tensorflow-0.9.0-cp27-none-linux_x86_64.whl) ([build history](http://ci.tensorflow.org/view/Nightly/job/nigntly-matrix-linux-gpu/TF_BUILD_CONTAINER_TYPE=GPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON2,label=gpu-linux/)) / [Python 3.4](http://ci.tensorflow.org/view/Nightly/job/nigntly-matrix-linux-gpu/TF_BUILD_CONTAINER_TYPE=GPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON3,label=gpu-linux/lastSuccessfulBuild/artifact/pip_test/whl/tensorflow-0.9.0-cp34-cp34m-linux_x86_64.whl) ([build history](http://ci.tensorflow.org/view/Nightly/job/nigntly-matrix-linux-gpu/TF_BUILD_CONTAINER_TYPE=GPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON3,label=gpu-linux/)) / [Python 3.5](http://ci.tensorflow.org/view/Nightly/job/nigntly-matrix-linux-gpu/TF_BUILD_CONTAINER_TYPE=GPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON3.5,label=gpu-linux/140/artifact/pip_test/whl/tensorflow-0.8.0-cp35-cp35m-linux_x86_64.whl) ([build history](http://ci.tensorflow.org/view/Nightly/job/nigntly-matrix-linux-gpu/TF_BUILD_CONTAINER_TYPE=GPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON3.5,label=gpu-linux/)) -* Mac CPU-only: [Python 2](http://ci.tensorflow.org/view/Nightly/job/nightly-matrix-cpu/TF_BUILD_CONTAINER_TYPE=CPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON2,label=mac1-slave/lastSuccessfulBuild/artifact/pip_test/whl/tensorflow-0.9.0-py2-none-any.whl) ([build history](http://ci.tensorflow.org/view/Nightly/job/nightly-matrix-cpu/TF_BUILD_CONTAINER_TYPE=CPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON2,label=mac1-slave/)) / [Python 3](http://ci.tensorflow.org/view/Nightly/job/nightly-matrix-cpu/TF_BUILD_CONTAINER_TYPE=CPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON3,label=mac1-slave/lastSuccessfulBuild/artifact/pip_test/whl/tensorflow-0.9.0-py3-none-any.whl) ([build history](http://ci.tensorflow.org/view/Nightly/job/nightly-matrix-cpu/TF_BUILD_CONTAINER_TYPE=CPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON3,label=mac1-slave/)) -* Mac GPU: [Python 2](http://ci.tensorflow.org/view/Nightly/job/nigntly-matrix-mac-gpu/TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON2,label=gpu-mac/lastSuccessfulBuild/artifact/pip_test/whl/tensorflow-0.9.0-py2-none-any.whl) ([build history](http://ci.tensorflow.org/view/Nightly/job/nigntly-matrix-mac-gpu/TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON2,label=gpu-mac/)) / [Python 3](http://ci.tensorflow.org/view/Nightly/job/nigntly-matrix-mac-gpu/TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON3,label=gpu-mac/lastSuccessfulBuild/artifact/pip_test/whl/tensorflow-0.9.0-py3-none-any.whl) ([build history](http://ci.tensorflow.org/view/Nightly/job/nigntly-matrix-mac-gpu/TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON3,label=gpu-mac/)) +* Linux CPU-only: [Python 2](http://ci.tensorflow.org/view/Nightly/job/nightly-matrix-cpu/TF_BUILD_CONTAINER_TYPE=CPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON2,label=cpu-slave/lastSuccessfulBuild/artifact/pip_test/whl/tensorflow-0.10.0rc0-cp27-none-linux_x86_64.whl) ([build history](http://ci.tensorflow.org/view/Nightly/job/nightly-matrix-cpu/TF_BUILD_CONTAINER_TYPE=CPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON2,label=cpu-slave/)) / [Python 3.4](http://ci.tensorflow.org/view/Nightly/job/nightly-matrix-cpu/TF_BUILD_CONTAINER_TYPE=CPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON3,label=cpu-slave/lastSuccessfulBuild/artifact/pip_test/whl/tensorflow-0.10.0rc0-cp34-cp34m-linux_x86_64.whl) ([build history](http://ci.tensorflow.org/view/Nightly/job/nightly-matrix-cpu/TF_BUILD_CONTAINER_TYPE=CPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON3,label=cpu-slave/)) / [Python 3.5](http://ci.tensorflow.org/view/Nightly/job/nightly-python35-linux-cpu/lastSuccessfulBuild/artifact/pip_test/whl/tensorflow-0.10.0rc0-cp35-cp35m-linux_x86_64.whl) ([build history](http://ci.tensorflow.org/view/Nightly/job/nightly-python35-linux-cpu/)) +* Linux GPU: [Python 2](http://ci.tensorflow.org/view/Nightly/job/nigntly-matrix-linux-gpu/TF_BUILD_CONTAINER_TYPE=GPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON2,label=gpu-linux/lastSuccessfulBuild/artifact/pip_test/whl/tensorflow-0.10.0rc0-cp27-none-linux_x86_64.whl) ([build history](http://ci.tensorflow.org/view/Nightly/job/nigntly-matrix-linux-gpu/TF_BUILD_CONTAINER_TYPE=GPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON2,label=gpu-linux/)) / [Python 3.4](http://ci.tensorflow.org/view/Nightly/job/nigntly-matrix-linux-gpu/TF_BUILD_CONTAINER_TYPE=GPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON3,label=gpu-linux/lastSuccessfulBuild/artifact/pip_test/whl/tensorflow-0.10.0rc0-cp34-cp34m-linux_x86_64.whl) ([build history](http://ci.tensorflow.org/view/Nightly/job/nigntly-matrix-linux-gpu/TF_BUILD_CONTAINER_TYPE=GPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON3,label=gpu-linux/)) / [Python 3.5](http://ci.tensorflow.org/view/Nightly/job/nigntly-matrix-linux-gpu/TF_BUILD_CONTAINER_TYPE=GPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON3.5,label=gpu-linux/140/artifact/pip_test/whl/tensorflow-0.8.0-cp35-cp35m-linux_x86_64.whl) ([build history](http://ci.tensorflow.org/view/Nightly/job/nigntly-matrix-linux-gpu/TF_BUILD_CONTAINER_TYPE=GPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON3.5,label=gpu-linux/)) +* Mac CPU-only: [Python 2](http://ci.tensorflow.org/view/Nightly/job/nightly-matrix-cpu/TF_BUILD_CONTAINER_TYPE=CPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON2,label=mac1-slave/lastSuccessfulBuild/artifact/pip_test/whl/tensorflow-0.10.0rc0-py2-none-any.whl) ([build history](http://ci.tensorflow.org/view/Nightly/job/nightly-matrix-cpu/TF_BUILD_CONTAINER_TYPE=CPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON2,label=mac1-slave/)) / [Python 3](http://ci.tensorflow.org/view/Nightly/job/nightly-matrix-cpu/TF_BUILD_CONTAINER_TYPE=CPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON3,label=mac1-slave/lastSuccessfulBuild/artifact/pip_test/whl/tensorflow-0.10.0rc0-py3-none-any.whl) ([build history](http://ci.tensorflow.org/view/Nightly/job/nightly-matrix-cpu/TF_BUILD_CONTAINER_TYPE=CPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON3,label=mac1-slave/)) +* Mac GPU: [Python 2](http://ci.tensorflow.org/view/Nightly/job/nigntly-matrix-mac-gpu/TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON2,label=gpu-mac/lastSuccessfulBuild/artifact/pip_test/whl/tensorflow-0.10.0rc0-py2-none-any.whl) ([build history](http://ci.tensorflow.org/view/Nightly/job/nigntly-matrix-mac-gpu/TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON2,label=gpu-mac/)) / [Python 3](http://ci.tensorflow.org/view/Nightly/job/nigntly-matrix-mac-gpu/TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON3,label=gpu-mac/lastSuccessfulBuild/artifact/pip_test/whl/tensorflow-0.10.0rc0-py3-none-any.whl) ([build history](http://ci.tensorflow.org/view/Nightly/job/nigntly-matrix-mac-gpu/TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON3,label=gpu-mac/)) * [Android](http://ci.tensorflow.org/view/Nightly/job/nightly-matrix-android/TF_BUILD_CONTAINER_TYPE=ANDROID,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=NO_PIP,TF_BUILD_PYTHON_VERSION=PYTHON2,label=android-slave/lastSuccessfulBuild/artifact/bazel-out/local_linux/bin/tensorflow/examples/android/tensorflow_demo.apk) ([build history](http://ci.tensorflow.org/view/Nightly/job/nightly-matrix-android/TF_BUILD_CONTAINER_TYPE=ANDROID,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=NO_PIP,TF_BUILD_PYTHON_VERSION=PYTHON2,label=android-slave/)) #### *Try your first TensorFlow program* diff --git a/RELEASE.md b/RELEASE.md index dd9558dd90b..4c9c33bf0dc 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,16 +1,40 @@ -# Changes Since Last Release -## Features and Improvements -* Connectionist Temporal Classification ops are now "official" (see, e.g., - `tf.nn.ctc_loss`) -* Preliminary graph-construction C API, for use by language bindings. -* Major revision to the graph-construction C++ API. Scoping mechanism to make op - naming, specifying control dependencies etc. more consistent. C++ values can - be used directly as operands, making op construction more concise. +# Release 0.10.0 -## Breaking Changes to the API -* `env.h` replaces use of `New*File()` functions to use `std::unique_ptr` - return arguments, removing the old raw pointer returns. +## Major Features and Improvements + +* Added support for C++ shape inference +* Added graph-construction C API +* Major revision to the graph-construction C++ API +* Support makefile build for iOS +* Added Mac GPU support +* Full version of TF-Slim available as `tf.contrib.slim` +* Added k-Means clustering and WALS matrix factorization + +## Big Fixes and Other Changes + +* Allow gradient computation for scalar values. +* Performance improvements for gRPC +* Improved support for fp16 +* New high-level ops in tf.contrib.{layers,metrics} +* New features for TensorBoard, such as shape display, exponential smoothing +* Faster and more stable Google Cloud Storage (GCS) filesystem support +* Support for zlib compression and decompression for TFRecordReader and TFRecordWriter +* Support for reading (animated) GIFs +* Improved support for SparseTensor +* Added support for more probability distributions (Dirichlet, Beta, Bernoulli, etc.) +* Added Python interfaces to reset resource containers. +* Many bugfixes and performance improvements +* Many documentation fixes + +## Thanks to our Contributors + +This release contains contributions from many people at Google, as well as: + +Alex Rothberg, Andrew Royer, Austin Marshall, @BlackCoal, Bob Adolf, Brian Diesel, Charles-Emmanuel Dias, @chemelnucfin, Chris Lesniewski, Daeyun Shin, Daniel Rodriguez, Danijar Hafner, Darcy Liu, Kristinn R. Thórisson, Daniel Castro, Dmitry Savintsev, Kashif Rasul, Dylan Paiton, Emmanuel T. Odeke, Ernest Grzybowski, Gavin Sherry, Gideon Dresdner, Gregory King, Harold Cooper, @heinzbeinz, Henry Saputra, Huarong Huo, Huazuo Gao, Igor Babuschkin, Igor Macedo Quintanilha, Ivan Ukhov, James Fysh, Jan Wilken Dörrie, Jihun Choi, Johnny Lim, Jonathan Raiman, Justin Francis, @lilac, Li Yi, Marc Khoury, Marco Marchesi, Max Melnick, Micael Carvalho, @mikowals, Mostafa Gazar, Nico Galoppo, Nishant Agrawal, Petr Janda, Yuncheng Li, @raix852, Robert Rose, @Robin-des-Bois, Rohit Girdhar, Sam Abrahams, satok16, Sergey Kishchenko, Sharkd Tu, @shotat, Siddharth Agrawal, Simon Denel, @sono-bfio, SunYeop Lee, Thijs Vogels, @tobegit3hub, @Undo1, Wang Yang, Wenjian Huang, Yaroslav Bulatov, Yuan Tang, Yunfeng Wang, Ziming Dong + +We are also grateful to all who filed issues or helped resolve them, asked and +answered questions, and were part of inspiring discussions. # Release 0.9.0 @@ -55,7 +79,7 @@ This release contains contributions from many people at Google, as well as: -Aaron Schumacher, Aidan Dang, Akihiko ITOH, Aki Sukegawa, Arbit Chen, Aziz Alto, Danijar Hafner, Erik Erwitt, Fabrizio Milo, Felix Maximilian Möller, Henry Saputra, Sung Kim, Igor Babuschkin, Jan Zikes, Jeremy Barnes, Jesper Steen Møller, Johannes Mayer, Justin Harris, Kashif Rasul, Kevin Robinson, Loo Rong Jie, Lucas Moura, Łukasz Bieniasz-Krzywiec, Mario Cho, Maxim Grechkin, Michael Heilman, Mostafa Rahmani, Mourad Mourafiq, @ninotoshi, Orion Reblitz-Richardson, Yuncheng Li, @raoqiyu, Robert DiPietro, Sam Abrahams, Sebastian Raschka, Siddharth Agrawal, @snakecharmer1024, Stephen Roller, Sung Kim, SunYeop Lee, Thijs Vogels, Till Hoffmann, Victor Melo, Ville Kallioniemi, Waleed Abdulla, Wenjian Huang, Yaroslav Bulatov, Yeison Rodriguez, Yuan (Terry) Tang, Yuxin Wu, @zhongzyd, Ziming Dong, Zohar Jackson +Aaron Schumacher, Aidan Dang, Akihiko ITOH, Aki Sukegawa, Arbit Chen, Aziz Alto, Danijar Hafner, Erik Erwitt, Fabrizio Milo, Felix Maximilian Möller, Henry Saputra, Sung Kim, Igor Babuschkin, Jan Zikes, Jeremy Barnes, Jesper Steen Møller, Johannes Mayer, Justin Harris, Kashif Rasul, Kevin Robinson, Loo Rong Jie, Lucas Moura, Łukasz Bieniasz-Krzywiec, Mario Cho, Maxim Grechkin, Michael Heilman, Mostafa Rahmani, Mourad Mourafiq, @ninotoshi, Orion Reblitz-Richardson, Yuncheng Li, @raoqiyu, Robert DiPietro, Sam Abrahams, Sebastian Raschka, Siddharth Agrawal, @snakecharmer1024, Stephen Roller, Sung Kim, SunYeop Lee, Thijs Vogels, Till Hoffmann, Victor Melo, Ville Kallioniemi, Waleed Abdulla, Wenjian Huang, Yaroslav Bulatov, Yeison Rodriguez, Yuan Tang, Yuxin Wu, @zhongzyd, Ziming Dong, Zohar Jackson We are also grateful to all who filed issues or helped resolve them, asked and answered questions, and were part of inspiring discussions. @@ -97,7 +121,7 @@ answered questions, and were part of inspiring discussions. This release contains contributions from many people at Google, as well as: -Abhinav Upadhyay, Aggelos Avgerinos, Alan Wu, Alexander G. de G. Matthews, Aleksandr Yahnev, @amchercashin, Andy Kitchen, Aurelien Geron, Awni Hannun, @BanditCat, Bas Veeling, Cameron Chen, @cg31, Cheng-Lung Sung, Christopher Bonnett, Dan Becker, Dan Van Boxel, Daniel Golden, Danijar Hafner, Danny Goodman, Dave Decker, David Dao, David Kretch, Dongjoon Hyun, Dustin Dorroh, @e-lin, Eurico Doirado, Erik Erwitt, Fabrizio Milo, @gaohuazuo, Iblis Lin, Igor Babuschkin, Isaac Hodes, Isaac Turner, Iván Vallés, J Yegerlehner, Jack Zhang, James Wexler, Jan Zikes, Jay Young, Jeff Hodges, @jmtatsch, Johnny Lim, Jonas Meinertz Hansen, Kanit Wongsuphasawat, Kashif Rasul, Ken Shirriff, Kenneth Mitchner, Kenta Yonekura, Konrad Magnusson, Konstantin Lopuhin, @lahwran, @lekaha, @liyongsea, Lucas Adams, @makseq, Mandeep Singh, @manipopopo, Mark Amery, Memo Akten, Michael Heilman, Michael Peteuil, Nathan Daly, Nicolas Fauchereau, @ninotoshi, Olav Nymoen, @panmari, @papelita1234, Pedro Lopes, Pranav Sailesh Mani, RJ Ryan, Rob Culliton, Robert DiPietro, @ronrest, Sam Abrahams, Sarath Shekkizhar, Scott Graham, Sebastian Raschka, Sung Kim, Surya Bhupatiraju, Syed Ahmed, Till Hoffmann, @timsl, @urimend, @vesnica, Vlad Frolov, Vlad Zagorodniy, Wei-Ting Kuo, Wenjian Huang, William Dmitri Breaden Madden, Wladimir Schmidt, Yuwen Yan, Yuxin Wu, Yuya Kusakabe, @zhongzyd, @znah. +Abhinav Upadhyay, Aggelos Avgerinos, Alan Wu, Alexander G. de G. Matthews, Aleksandr Yahnev, @amchercashin, Andy Kitchen, Aurelien Geron, Awni Hannun, @BanditCat, Bas Veeling, Cameron Chen, @cg31, Cheng-Lung Sung, Christopher Bonnett, Dan Becker, Dan Van Boxel, Daniel Golden, Danijar Hafner, Danny Goodman, Dave Decker, David Dao, David Kretch, Dongjoon Hyun, Dustin Dorroh, @e-lin, Eurico Doirado, Erik Erwitt, Fabrizio Milo, @gaohuazuo, Iblis Lin, Igor Babuschkin, Isaac Hodes, Isaac Turner, Iván Vallés, J Yegerlehner, Jack Zhang, James Wexler, Jan Zikes, Jay Young, Jeff Hodges, @jmtatsch, Johnny Lim, Jonas Meinertz Hansen, Kanit Wongsuphasawat, Kashif Rasul, Ken Shirriff, Kenneth Mitchner, Kenta Yonekura, Konrad Magnusson, Konstantin Lopuhin, @lahwran, @lekaha, @liyongsea, Lucas Adams, @makseq, Mandeep Singh, @manipopopo, Mark Amery, Memo Akten, Michael Heilman, Michael Peteuil, Nathan Daly, Nicolas Fauchereau, @ninotoshi, Olav Nymoen, @panmari, @papelita1234, Pedro Lopes, Pranav Sailesh Mani, RJ Ryan, Rob Culliton, Robert DiPietro, @ronrest, Sam Abrahams, Sarath Shekkizhar, Scott Graham, Sebastian Raschka, Sung Kim, Surya Bhupatiraju, Syed Ahmed, Till Hoffmann, @timsl, @urimend, @vesnica, Vlad Frolov, Vlad Zagorodniy, Wei-Ting Kuo, Wenjian Huang, William Dmitri Breaden Madden, Wladimir Schmidt, Yuan Tang, Yuwen Yan, Yuxin Wu, Yuya Kusakabe, @zhongzyd, @znah. We are also grateful to all who filed issues or helped resolve them, asked and answered questions, and were part of inspiring discussions. diff --git a/tensorflow/contrib/makefile/Makefile b/tensorflow/contrib/makefile/Makefile index 8b93f3d6c03..4987e9bcd40 100644 --- a/tensorflow/contrib/makefile/Makefile +++ b/tensorflow/contrib/makefile/Makefile @@ -112,6 +112,8 @@ LIBDIR := $(GENDIR)lib/ BINDIR := $(GENDIR)bin/ PBTGENDIR := $(GENDIR)proto_text/ PROTOGENDIR := $(GENDIR)proto/ +DEPDIR := $(GENDIR)dep/ +$(shell mkdir -p $(DEPDIR) >/dev/null) # Settings for the target compiler. CXX := $(CC_PREFIX) gcc @@ -119,6 +121,7 @@ OPTFLAGS := -O0 CXXFLAGS := --std=c++11 -DIS_SLIM_BUILD $(OPTFLAGS) LDFLAGS := \ -L/usr/local/lib +DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td INCLUDES := \ -I. \ @@ -349,6 +352,10 @@ ifeq ($(TARGET),IOS) -L$(GENDIR)protobuf_ios/lib \ -lz endif + OBJDIR := $(OBJDIR)ios_$(IOS_ARCH)/ + LIBDIR := $(LIBDIR)ios_$(IOS_ARCH)/ + BINDIR := $(BINDIR)ios_$(IOS_ARCH)/ + DEPDIR := $(DEPDIR)ios_$(IOS_ARCH)/ endif # This library is the main target for this makefile. It will contain a minimal @@ -442,7 +449,9 @@ $(BENCHMARK_NAME): $(BENCHMARK_OBJS) $(LIB_PATH) # Matches on the normal hand-written TensorFlow C++ source files. $(OBJDIR)%.o: %.cc | $(PBT_GEN_FILES) @mkdir -p $(dir $@) - $(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@ + @mkdir -p $(dir $(DEPDIR)$*) + $(CXX) $(CXXFLAGS) $(DEPFLAGS) $(INCLUDES) -c $< -o $@ + @mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d # Compiles C++ source files that have been generated by protoc. $(OBJDIR)%.pb.o: $(PROTOGENDIR)%.pb.cc @@ -509,3 +518,8 @@ clean: cleantarget: rm -rf $(OBJDIR) rm -rf $(BINDIR) + +$(DEPDIR)/%.d: ; +.PRECIOUS: $(DEPDIR)/%.d + +-include $(patsubst %,$(DEPDIR)/%.d,$(basename $(TF_CC_SRCS))) diff --git a/tensorflow/contrib/makefile/build_all_ios.sh b/tensorflow/contrib/makefile/build_all_ios.sh index 6b6ed389fc8..e16d33aac61 100755 --- a/tensorflow/contrib/makefile/build_all_ios.sh +++ b/tensorflow/contrib/makefile/build_all_ios.sh @@ -42,6 +42,18 @@ rm -rf tensorflow/contrib/makefile/downloads # Pull down the required versions of the frameworks we need. tensorflow/contrib/makefile/download_dependencies.sh +# TODO(petewarden) - Some new code in Eigen triggers a clang bug, so work +# around it by patching the source. +sed -e 's#static uint32x4_t p4ui_CONJ_XOR = vld1q_u32( conj_XOR_DATA );#static uint32x4_t p4ui_CONJ_XOR; // = vld1q_u32( conj_XOR_DATA ); - Removed by script#' \ +-i '' \ +tensorflow/contrib/makefile/downloads/eigen-latest/eigen/src/Core/arch/NEON/Complex.h +sed -e 's#static uint32x2_t p2ui_CONJ_XOR = vld1_u32( conj_XOR_DATA );#static uint32x2_t p2ui_CONJ_XOR;// = vld1_u32( conj_XOR_DATA ); - Removed by scripts#' \ +-i '' \ +tensorflow/contrib/makefile/downloads/eigen-latest/eigen/src/Core/arch/NEON/Complex.h +sed -e 's#static uint64x2_t p2ul_CONJ_XOR = vld1q_u64( p2ul_conj_XOR_DATA );#static uint64x2_t p2ul_CONJ_XOR;// = vld1q_u64( p2ul_conj_XOR_DATA ); - Removed by script#' \ +-i '' \ +tensorflow/contrib/makefile/downloads/eigen-latest/eigen/src/Core/arch/NEON/Complex.h + # Compile protobuf for the target iOS device architectures. tensorflow/contrib/makefile/compile_ios_protobuf.sh ${JOBS_COUNT} diff --git a/tensorflow/contrib/makefile/compile_ios_tensorflow.sh b/tensorflow/contrib/makefile/compile_ios_tensorflow.sh index be1a1d3ec54..0c0edb7bd14 100755 --- a/tensorflow/contrib/makefile/compile_ios_tensorflow.sh +++ b/tensorflow/contrib/makefile/compile_ios_tensorflow.sh @@ -28,19 +28,6 @@ GENDIR=tensorflow/contrib/makefile/gen/ LIBDIR=${GENDIR}lib LIB_PREFIX=libtensorflow-core -# TODO(petewarden) - Some new code in Eigen triggers a clang bug, so work -# around it by patching the source. -sed -e 's#static uint32x4_t p4ui_CONJ_XOR = vld1q_u32( conj_XOR_DATA );#static uint32x4_t p4ui_CONJ_XOR; // = vld1q_u32( conj_XOR_DATA ); - Removed by script#' \ --i '' \ -tensorflow/contrib/makefile/downloads/eigen-latest/eigen/src/Core/arch/NEON/Complex.h -sed -e 's#static uint32x2_t p2ui_CONJ_XOR = vld1_u32( conj_XOR_DATA );#static uint32x2_t p2ui_CONJ_XOR;// = vld1_u32( conj_XOR_DATA ); - Removed by scripts#' \ --i '' \ -tensorflow/contrib/makefile/downloads/eigen-latest/eigen/src/Core/arch/NEON/Complex.h -sed -e 's#static uint64x2_t p2ul_CONJ_XOR = vld1q_u64( p2ul_conj_XOR_DATA );#static uint64x2_t p2ul_CONJ_XOR;// = vld1q_u64( p2ul_conj_XOR_DATA ); - Removed by script#' \ --i '' \ -tensorflow/contrib/makefile/downloads/eigen-latest/eigen/src/Core/arch/NEON/Complex.h - -make -f tensorflow/contrib/makefile/Makefile cleantarget make -f tensorflow/contrib/makefile/Makefile \ TARGET=IOS IOS_ARCH=ARMV7 LIB_NAME=${LIB_PREFIX}-armv7.a OPTFLAGS="$1" $2 $3 if [ $? -ne 0 ] @@ -49,7 +36,6 @@ then exit 1 fi -make -f tensorflow/contrib/makefile/Makefile cleantarget make -f tensorflow/contrib/makefile/Makefile \ TARGET=IOS IOS_ARCH=ARMV7S LIB_NAME=${LIB_PREFIX}-armv7s.a OPTFLAGS="$1" $2 $3 if [ $? -ne 0 ] @@ -58,7 +44,6 @@ then exit 1 fi -make -f tensorflow/contrib/makefile/Makefile cleantarget make -f tensorflow/contrib/makefile/Makefile \ TARGET=IOS IOS_ARCH=ARM64 LIB_NAME=${LIB_PREFIX}-arm64.a OPTFLAGS="$1" $2 $3 if [ $? -ne 0 ] @@ -67,7 +52,6 @@ then exit 1 fi -make -f tensorflow/contrib/makefile/Makefile cleantarget make -f tensorflow/contrib/makefile/Makefile \ TARGET=IOS IOS_ARCH=I386 LIB_NAME=${LIB_PREFIX}-i386.a OPTFLAGS="$1" $2 $3 if [ $? -ne 0 ] @@ -76,7 +60,6 @@ then exit 1 fi -make -f tensorflow/contrib/makefile/Makefile cleantarget make -f tensorflow/contrib/makefile/Makefile \ TARGET=IOS IOS_ARCH=X86_64 LIB_NAME=${LIB_PREFIX}-x86_64.a OPTFLAGS="$1" $2 $3 if [ $? -ne 0 ] @@ -86,10 +69,10 @@ then fi lipo \ -${LIBDIR}/${LIB_PREFIX}-armv7.a \ -${LIBDIR}/${LIB_PREFIX}-armv7s.a \ -${LIBDIR}/${LIB_PREFIX}-arm64.a \ -${LIBDIR}/${LIB_PREFIX}-i386.a \ -${LIBDIR}/${LIB_PREFIX}-x86_64.a \ +${LIBDIR}/ios_ARMV7/${LIB_PREFIX}-armv7.a \ +${LIBDIR}/ios_ARMV7S/${LIB_PREFIX}-armv7s.a \ +${LIBDIR}/ios_ARM64/${LIB_PREFIX}-arm64.a \ +${LIBDIR}/ios_I386/${LIB_PREFIX}-i386.a \ +${LIBDIR}/ios_X86_64/${LIB_PREFIX}-x86_64.a \ -create \ -output ${LIBDIR}/${LIB_PREFIX}.a diff --git a/tensorflow/contrib/makefile/tf_op_files.txt b/tensorflow/contrib/makefile/tf_op_files.txt index 098007b9078..cb29041dc4a 100644 --- a/tensorflow/contrib/makefile/tf_op_files.txt +++ b/tensorflow/contrib/makefile/tf_op_files.txt @@ -46,6 +46,7 @@ tensorflow/core/kernels/pad_op.cc tensorflow/core/kernels/pack_op.cc tensorflow/core/kernels/ops_util.cc tensorflow/core/kernels/no_op.cc +tensorflow/core/kernels/mirror_pad_op.cc tensorflow/core/kernels/maxpooling_op.cc tensorflow/core/kernels/matmul_op.cc tensorflow/core/kernels/lrn_op.cc diff --git a/tensorflow/core/common_runtime/optimization_registry.h b/tensorflow/core/common_runtime/optimization_registry.h index 54e2c0e4991..46fb97fe4b8 100644 --- a/tensorflow/core/common_runtime/optimization_registry.h +++ b/tensorflow/core/common_runtime/optimization_registry.h @@ -27,7 +27,7 @@ limitations under the License. #include "tensorflow/core/graph/graph.h" namespace tensorflow { -class SessionOptions; +struct SessionOptions; // All the parameters used by an optimization pass are packaged in // this struct. They should be enough for the optimization pass to use diff --git a/tensorflow/core/common_runtime/simple_graph_execution_state.h b/tensorflow/core/common_runtime/simple_graph_execution_state.h index 6f3b97f83d3..595da551d43 100644 --- a/tensorflow/core/common_runtime/simple_graph_execution_state.h +++ b/tensorflow/core/common_runtime/simple_graph_execution_state.h @@ -35,7 +35,7 @@ limitations under the License. #include "tensorflow/core/platform/types.h" namespace tensorflow { -class SessionOptions; +struct SessionOptions; class StepStats; class Timeline; diff --git a/tensorflow/core/graph/gradients.cc b/tensorflow/core/graph/gradients.cc index 01e9b686381..09c3d8d5679 100644 --- a/tensorflow/core/graph/gradients.cc +++ b/tensorflow/core/graph/gradients.cc @@ -35,8 +35,6 @@ namespace tensorflow { // TODO(andydavis) Remove some of the code duplicated between this module // and that in 'common_runtime/function.cc'. // A few string constant used throughout this module. -static const char* const kArgOp = "_Arg"; -static const char* const kRetOp = "_Retval"; static const char* const kGradientOp = "SymbolicGradient"; static const char* const kNodeLabel = "Func"; diff --git a/tensorflow/core/graph/graph.cc b/tensorflow/core/graph/graph.cc index 3607db7e81b..a0cdd4fcfc4 100644 --- a/tensorflow/core/graph/graph.cc +++ b/tensorflow/core/graph/graph.cc @@ -29,9 +29,6 @@ namespace tensorflow { // Node string Node::DebugString() const { - if (this == nullptr) { - return "{nullptr}"; - } string ret = strings::StrCat("{name:'", name(), "' id:", id_); if (IsSource()) { strings::StrAppend(&ret, " source}"); diff --git a/tensorflow/core/kernels/argmax_op.cc b/tensorflow/core/kernels/argmax_op.cc index 4dd551021ee..595bd7bd5e4 100644 --- a/tensorflow/core/kernels/argmax_op.cc +++ b/tensorflow/core/kernels/argmax_op.cc @@ -59,7 +59,7 @@ class ArgOp : public OpKernel { OP_REQUIRES(context, dim >= 0, errors::InvalidArgument("dim must be >= 0")); OP_REQUIRES(context, dim < input_dims, - errors::InvalidArgument("Minimum tensor rank: ", dim, + errors::InvalidArgument("Minimum tensor rank: ", dim + 1, " but got: ", input_dims)); OP_REQUIRES( context, input.dim_size(dim) > 0, diff --git a/tensorflow/core/kernels/cwise_op_conj.cc b/tensorflow/core/kernels/cwise_op_conj.cc index d6dc565c813..61b1d98f1e2 100644 --- a/tensorflow/core/kernels/cwise_op_conj.cc +++ b/tensorflow/core/kernels/cwise_op_conj.cc @@ -19,7 +19,9 @@ namespace tensorflow { REGISTER2(UnaryOp, CPU, "Conj", functor::conj, complex64, complex128); #if GOOGLE_CUDA -// REGISTER_KERNEL_BUILDER(Name("Conj").Device(DEVICE_GPU), -// UnaryOp>); +REGISTER_KERNEL_BUILDER(Name("Conj").Device(DEVICE_GPU).TypeConstraint("T"), + UnaryOp>); +REGISTER_KERNEL_BUILDER(Name("Conj").Device(DEVICE_GPU).TypeConstraint("T"), + UnaryOp>); #endif } // namespace tensorflow diff --git a/tensorflow/core/kernels/cwise_op_gpu_conj.cu.cc b/tensorflow/core/kernels/cwise_op_gpu_conj.cu.cc index 43ead4c5c82..e7dff5d0ac5 100644 --- a/tensorflow/core/kernels/cwise_op_gpu_conj.cu.cc +++ b/tensorflow/core/kernels/cwise_op_gpu_conj.cu.cc @@ -19,7 +19,8 @@ limitations under the License. namespace tensorflow { namespace functor { -// DEFINE_UNARY1(conj, complex64); // not working + DEFINE_UNARY1(conj, complex64); + DEFINE_UNARY1(conj, complex128); } // namespace functor } // namespace tensorflow diff --git a/tensorflow/core/kernels/cwise_op_sub.cc b/tensorflow/core/kernels/cwise_op_sub.cc index e6cb8d0d24b..8fade5f6671 100644 --- a/tensorflow/core/kernels/cwise_op_sub.cc +++ b/tensorflow/core/kernels/cwise_op_sub.cc @@ -18,6 +18,12 @@ limitations under the License. namespace tensorflow { REGISTER7(BinaryOp, CPU, "Sub", functor::sub, float, Eigen::half, double, int32, int64, complex64, complex128); +#if defined(__ANDROID_TYPES_SLIM__) +// We only register the first type when we have multi-argument calls in the +// case where we're trying to reduce executable size, but it turns out that the +// int32 version of this op is needed, so explicitly include it. +REGISTER(BinaryOp, CPU, "Sub", functor::sub, int32); +#endif // __ANDROID_TYPES_SLIM__ #if GOOGLE_CUDA REGISTER4(BinaryOp, GPU, "Sub", functor::sub, float, Eigen::half, double, int64); diff --git a/tensorflow/core/kernels/cwise_ops_test.cc b/tensorflow/core/kernels/cwise_ops_test.cc index 2cf51878ba5..823e7e14ed9 100644 --- a/tensorflow/core/kernels/cwise_ops_test.cc +++ b/tensorflow/core/kernels/cwise_ops_test.cc @@ -23,13 +23,14 @@ limitations under the License. namespace tensorflow { -// Creates a Graph which applies a unary "func" on a 3D float tensor -// of "num" elements. -static Graph* Unary(const string& func, int num) { +// Creates a Graph which applies a unary "func" on a 3D tensor of +// type T with "num" elements. +template +static Graph* Unary(const string& func, int num, DataType dtype) { Graph* g = new Graph(OpRegistry::Global()); - Tensor data(DT_FLOAT, TensorShape({64, 64, num / (64 * 64)})); + Tensor data(dtype, TensorShape({64, 64, num / (64 * 64)})); CHECK_GT(data.NumElements(), 0); - data.flat().setRandom(); + data.flat().setRandom(); test::graph::Unary(g, func, test::graph::Constant(g, data), 0); return g; } @@ -40,17 +41,23 @@ static int RowsAndColsArg(int r, int c) { return r * kRows + c; } static int RowsFromArg(int arg) { return (arg / kRows); } static int ColsFromArg(int arg) { return (arg % kRows); } -#define BM_UNARY(DEVICE, FUNC) \ - static void BM_##DEVICE##_##FUNC(int iters, int num) { \ - const int64 tot = static_cast(iters) * num; \ - testing::ItemsProcessed(tot); \ - testing::BytesProcessed(tot * sizeof(float)); \ - test::Benchmark(#DEVICE, Unary(#FUNC, num)).Run(iters); \ - } \ - BENCHMARK(BM_##DEVICE##_##FUNC)->Range(4 << 10, 1 << 20); +#define BM_UNARY(DEVICE, FUNC, T, TYPE) \ + static void BM_##DEVICE##_##FUNC##_##TYPE(int iters, int num) { \ + const int64 tot = static_cast(iters) * num; \ + testing::ItemsProcessed(tot); \ + testing::BytesProcessed(tot * sizeof(T)); \ + test::Benchmark(#DEVICE, Unary(#FUNC, num, TYPE)).Run(iters); \ + } \ + BENCHMARK(BM_##DEVICE##_##FUNC##_##TYPE)->Range(4 << 10, 1 << 20); -BM_UNARY(cpu, Floor); -BM_UNARY(gpu, Floor); +BM_UNARY(cpu, Floor, float, DT_FLOAT); +BM_UNARY(gpu, Floor, float, DT_FLOAT); +BM_UNARY(cpu, Floor, double, DT_DOUBLE); +BM_UNARY(gpu, Floor, double, DT_DOUBLE); +BM_UNARY(cpu, Conj, std::complex, DT_COMPLEX64); +BM_UNARY(gpu, Conj, std::complex, DT_COMPLEX64); +BM_UNARY(cpu, Conj, std::complex, DT_COMPLEX128); +BM_UNARY(gpu, Conj, std::complex, DT_COMPLEX128); // data func scalar. static Graph* BinaryScalar(int num, const string& func) { diff --git a/tensorflow/core/kernels/lookup_table_init_op.cc b/tensorflow/core/kernels/lookup_table_init_op.cc index 10fe91de9af..6303a0f5cfb 100644 --- a/tensorflow/core/kernels/lookup_table_init_op.cc +++ b/tensorflow/core/kernels/lookup_table_init_op.cc @@ -80,7 +80,7 @@ class KeyValueTensorIterator Status status() const override { return status_; } - int64 total_size() const { + int64 total_size() const override { return keys_ == nullptr ? -1 : keys_->NumElements(); } diff --git a/tensorflow/core/ops/math_ops.cc b/tensorflow/core/ops/math_ops.cc index c7a047b03dd..dd41bf2a671 100644 --- a/tensorflow/core/ops/math_ops.cc +++ b/tensorflow/core/ops/math_ops.cc @@ -499,7 +499,8 @@ REGISTER_OP("Add") .Doc(R"doc( Returns x + y element-wise. -*NOTE*: Add supports broadcasting. AddN does not. +*NOTE*: `Add` supports broadcasting. `AddN` does not. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) )doc"); REGISTER_OP("Sub") @@ -507,6 +508,9 @@ REGISTER_OP("Sub") .SetShapeFn(BroadcastBinaryOpShapeFn) .Doc(R"doc( Returns x - y element-wise. + +*NOTE*: `Sub` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) )doc"); REGISTER_OP("Mul") @@ -515,10 +519,16 @@ REGISTER_OP("Mul") .SetShapeFn(BroadcastBinaryOpShapeFn) .Doc(R"doc( Returns x * y element-wise. + +*NOTE*: `Mul` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) )doc"); REGISTER_OP("Div").BINARY_MORE().SetShapeFn(BroadcastBinaryOpShapeFn).Doc(R"doc( Returns x / y element-wise. + +*NOTE*: `Div` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) )doc"); REGISTER_OP("SquaredDifference") @@ -527,6 +537,9 @@ REGISTER_OP("SquaredDifference") .SetShapeFn(BroadcastBinaryOpShapeFn) .Doc(R"doc( Returns (x - y)(x - y) element-wise. + +*NOTE*: `SquaredDifference` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) )doc"); #undef BINARY_FEWER @@ -540,7 +553,10 @@ REGISTER_OP("Maximum") .SetIsCommutative() .SetShapeFn(BroadcastBinaryOpShapeFn) .Doc(R"doc( -Returns the max of x and y (i.e. x > y ? x : y) element-wise, broadcasts. +Returns the max of x and y (i.e. x > y ? x : y) element-wise. + +*NOTE*: `Maximum` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) )doc"); REGISTER_OP("Minimum") @@ -551,7 +567,10 @@ REGISTER_OP("Minimum") .SetIsCommutative() .SetShapeFn(BroadcastBinaryOpShapeFn) .Doc(R"doc( -Returns the min of x and y (i.e. x < y ? x : y) element-wise, broadcasts. +Returns the min of x and y (i.e. x < y ? x : y) element-wise. + +*NOTE*: `Minimum` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) )doc"); REGISTER_OP("Mod") @@ -562,6 +581,9 @@ REGISTER_OP("Mod") .SetShapeFn(BroadcastBinaryOpShapeFn) .Doc(R"doc( Returns element-wise remainder of division. + +*NOTE*: `Mod` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) )doc"); REGISTER_OP("Pow") @@ -679,24 +701,36 @@ REGISTER_OP("Less") .COMPARISON() .Doc(R"doc( Returns the truth value of (x < y) element-wise. + +*NOTE*: `Less` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) )doc"); REGISTER_OP("LessEqual") .COMPARISON() .Doc(R"doc( Returns the truth value of (x <= y) element-wise. + +*NOTE*: `LessEqual` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) )doc"); REGISTER_OP("Greater") .COMPARISON() .Doc(R"doc( Returns the truth value of (x > y) element-wise. + +*NOTE*: `Greater` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) )doc"); REGISTER_OP("GreaterEqual") .COMPARISON() .Doc(R"doc( Returns the truth value of (x >= y) element-wise. + +*NOTE*: `GreaterEqual` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) )doc"); #undef COMPARISON @@ -718,12 +752,18 @@ REGISTER_OP("Equal") .EQUALITY_COMPARISON() .Doc(R"doc( Returns the truth value of (x == y) element-wise. + +*NOTE*: `Equal` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) )doc"); REGISTER_OP("NotEqual") .EQUALITY_COMPARISON() .Doc(R"doc( Returns the truth value of (x != y) element-wise. + +*NOTE*: `NotEqual` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) )doc"); #undef EQUALITY_COMPARISON @@ -749,12 +789,18 @@ REGISTER_OP("LogicalAnd") .BINARY_LOGICAL() .Doc(R"doc( Returns the truth value of x AND y element-wise. + +*NOTE*: `LogicalAnd` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) )doc"); REGISTER_OP("LogicalOr") .BINARY_LOGICAL() .Doc(R"doc( Returns the truth value of x OR y element-wise. + +*NOTE*: `LogicalOr` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) )doc"); #undef BINARY_LOGICAL diff --git a/tensorflow/core/ops/ops.pbtxt b/tensorflow/core/ops/ops.pbtxt index 7e222976805..01bb4bc82f8 100644 --- a/tensorflow/core/ops/ops.pbtxt +++ b/tensorflow/core/ops/ops.pbtxt @@ -4489,6 +4489,42 @@ op { summary: "Decode a PNG-encoded image to a uint8 or uint16 tensor." description: "The attr `channels` indicates the desired number of color channels for the\ndecoded image.\n\nAccepted values are:\n\n* 0: Use the number of channels in the PNG-encoded image.\n* 1: output a grayscale image.\n* 3: output an RGB image.\n* 4: output an RGBA image.\n\nIf needed, the PNG-encoded image is transformed to match the requested number\nof color channels." } +op { + name: "DecodeGif" + input_arg { + name: "contents" + description: "0-D. The GIF-encoded image." + type: DT_STRING + } + output_arg { + name: "image" + description: "3-D with shape `[height, width, channels]`." + type_attr: "dtype" + } + attr { + name: "channels" + type: "int" + default_value { + i: 0 + } + description: "Number of color channels for the decoded image." + } + attr { + name: "dtype" + type: "type" + default_value { + type: DT_UINT8 + } + allowed_values { + list { + type: DT_UINT8 + type: DT_UINT16 + } + } + } + summary: "Decode a GIF-encoded image to a uint8 or uint16 tensor." + description: "The attr `channels` indicates the desired number of color channels for the\ndecoded image.\n\nAccepted values are:\n\n* 0: Use the number of channels in the GIF-encoded image.\n* 1: output a grayscale image.\n* 3: output an RGB image.\n* 4: output an RGBA image.\n\nIf needed, the GIF-encoded image is transformed to match the requested number\nof color channels." +} op { name: "DecodeRaw" input_arg { diff --git a/tensorflow/core/public/version.h b/tensorflow/core/public/version.h index 443eabaee02..2c260b1a9a0 100644 --- a/tensorflow/core/public/version.h +++ b/tensorflow/core/public/version.h @@ -19,8 +19,8 @@ limitations under the License. // TensorFlow uses semantic versioning, see http://semver.org/. #define TF_MAJOR_VERSION 0 -#define TF_MINOR_VERSION 9 -#define TF_PATCH_VERSION 0 +#define TF_MINOR_VERSION 10 +#define TF_PATCH_VERSION 0rc0 // TF_VERSION_SUFFIX is non-empty for pre-releases (e.g. "-alpha", "-alpha.1", // "-beta", "-rc", "-rc.1") diff --git a/tensorflow/examples/how_tos/reading_data/convert_to_records.py b/tensorflow/examples/how_tos/reading_data/convert_to_records.py index 2e3035731ad..566d554e7f3 100644 --- a/tensorflow/examples/how_tos/reading_data/convert_to_records.py +++ b/tensorflow/examples/how_tos/reading_data/convert_to_records.py @@ -19,7 +19,6 @@ from __future__ import division from __future__ import print_function import os -import numpy import tensorflow as tf from tensorflow.contrib.learn.python.learn.datasets import mnist diff --git a/tensorflow/examples/how_tos/reading_data/fully_connected_preloaded.py b/tensorflow/examples/how_tos/reading_data/fully_connected_preloaded.py index 8a43158062c..9a33afd93ab 100644 --- a/tensorflow/examples/how_tos/reading_data/fully_connected_preloaded.py +++ b/tensorflow/examples/how_tos/reading_data/fully_connected_preloaded.py @@ -30,10 +30,7 @@ from __future__ import absolute_import from __future__ import division from __future__ import print_function -import os.path import time - -import numpy import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data diff --git a/tensorflow/examples/how_tos/reading_data/fully_connected_preloaded_var.py b/tensorflow/examples/how_tos/reading_data/fully_connected_preloaded_var.py index 0711bed920f..b4c80e53b66 100644 --- a/tensorflow/examples/how_tos/reading_data/fully_connected_preloaded_var.py +++ b/tensorflow/examples/how_tos/reading_data/fully_connected_preloaded_var.py @@ -29,10 +29,7 @@ from __future__ import absolute_import from __future__ import division from __future__ import print_function -import os.path import time - -import numpy import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data diff --git a/tensorflow/examples/how_tos/reading_data/fully_connected_reader.py b/tensorflow/examples/how_tos/reading_data/fully_connected_reader.py index bdd821373fd..351d531e253 100644 --- a/tensorflow/examples/how_tos/reading_data/fully_connected_reader.py +++ b/tensorflow/examples/how_tos/reading_data/fully_connected_reader.py @@ -29,8 +29,6 @@ from __future__ import print_function import os.path import time - -import numpy import tensorflow as tf from tensorflow.examples.tutorials.mnist import mnist diff --git a/tensorflow/examples/image_retraining/retrain_test.py b/tensorflow/examples/image_retraining/retrain_test.py index 91108abde09..072998ae600 100644 --- a/tensorflow/examples/image_retraining/retrain_test.py +++ b/tensorflow/examples/image_retraining/retrain_test.py @@ -18,12 +18,10 @@ from __future__ import absolute_import from __future__ import division from __future__ import print_function -import os import tensorflow as tf from tensorflow.examples.image_retraining import retrain from tensorflow.python.framework import test_util -from tensorflow.python.platform import googletest class ImageRetrainingTest(test_util.TensorFlowTestCase): diff --git a/tensorflow/examples/learn/wide_n_deep_tutorial.py b/tensorflow/examples/learn/wide_n_deep_tutorial.py index f80b839156c..5a23087b5a7 100644 --- a/tensorflow/examples/learn/wide_n_deep_tutorial.py +++ b/tensorflow/examples/learn/wide_n_deep_tutorial.py @@ -59,7 +59,7 @@ def maybe_download(): urllib.urlretrieve("https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.data", train_file.name) # pylint: disable=line-too-long train_file_name = train_file.name train_file.close() - print("Training data is downlaoded to %s" % train_file_name) + print("Training data is downloaded to %s" % train_file_name) if FLAGS.test_data: test_file_name = FLAGS.test_data @@ -68,7 +68,7 @@ def maybe_download(): urllib.urlretrieve("https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.test", test_file.name) # pylint: disable=line-too-long test_file_name = test_file.name test_file.close() - print("Test data is downlaoded to %s" % test_file_name) + print("Test data is downloaded to %s" % test_file_name) return train_file_name, test_file_name diff --git a/tensorflow/examples/skflow/multioutput_regression.py b/tensorflow/examples/skflow/multioutput_regression.py index ef76a6ce270..cf978e23d4d 100644 --- a/tensorflow/examples/skflow/multioutput_regression.py +++ b/tensorflow/examples/skflow/multioutput_regression.py @@ -23,7 +23,6 @@ from __future__ import print_function import numpy as np import matplotlib.pyplot as plt -from sklearn import datasets from sklearn.metrics import mean_squared_error from tensorflow.contrib import learn diff --git a/tensorflow/examples/tutorials/mnist/fully_connected_feed.py b/tensorflow/examples/tutorials/mnist/fully_connected_feed.py index 5ab6024c2b8..cd936d653e0 100644 --- a/tensorflow/examples/tutorials/mnist/fully_connected_feed.py +++ b/tensorflow/examples/tutorials/mnist/fully_connected_feed.py @@ -83,7 +83,7 @@ def fill_feed_dict(data_set, images_pl, labels_pl): feed_dict: The feed dictionary mapping from placeholders to values. """ # Create the feed_dict for the placeholders filled with the next - # `batch size ` examples. + # `batch size` examples. images_feed, labels_feed = data_set.next_batch(FLAGS.batch_size, FLAGS.fake_data) feed_dict = { diff --git a/tensorflow/g3doc/api_docs/cc/ClassEnv.md b/tensorflow/g3doc/api_docs/cc/ClassEnv.md index 1e5b0ade49a..0010c0fbb23 100644 --- a/tensorflow/g3doc/api_docs/cc/ClassEnv.md +++ b/tensorflow/g3doc/api_docs/cc/ClassEnv.md @@ -38,7 +38,7 @@ Returns the file system schemes registered for this Env . -#### `Status tensorflow::Env::NewRandomAccessFile(const string &fname, RandomAccessFile **result)` {#Status_tensorflow_Env_NewRandomAccessFile} +#### `Status tensorflow::Env::NewRandomAccessFile(const string &fname, std::unique_ptr< RandomAccessFile > *result)` {#Status_tensorflow_Env_NewRandomAccessFile} Creates a brand new random access read-only file with the specified name. @@ -48,7 +48,7 @@ The returned file may be concurrently accessed by multiple threads. The ownership of the returned RandomAccessFile is passed to the caller and the object should be deleted when is not used. The file object shouldn't live longer than the Env object. -#### `Status tensorflow::Env::NewWritableFile(const string &fname, WritableFile **result)` {#Status_tensorflow_Env_NewWritableFile} +#### `Status tensorflow::Env::NewWritableFile(const string &fname, std::unique_ptr< WritableFile > *result)` {#Status_tensorflow_Env_NewWritableFile} Creates an object that writes to a new file with the specified name. @@ -58,7 +58,7 @@ The returned file will only be accessed by one thread at a time. The ownership of the returned WritableFile is passed to the caller and the object should be deleted when is not used. The file object shouldn't live longer than the Env object. -#### `Status tensorflow::Env::NewAppendableFile(const string &fname, WritableFile **result)` {#Status_tensorflow_Env_NewAppendableFile} +#### `Status tensorflow::Env::NewAppendableFile(const string &fname, std::unique_ptr< WritableFile > *result)` {#Status_tensorflow_Env_NewAppendableFile} Creates an object that either appends to an existing file, or writes to a new file (if the file does not exist to begin with). @@ -68,7 +68,7 @@ The returned file will only be accessed by one thread at a time. The ownership of the returned WritableFile is passed to the caller and the object should be deleted when is not used. The file object shouldn't live longer than the Env object. -#### `Status tensorflow::Env::NewReadOnlyMemoryRegionFromFile(const string &fname, ReadOnlyMemoryRegion **result)` {#Status_tensorflow_Env_NewReadOnlyMemoryRegionFromFile} +#### `Status tensorflow::Env::NewReadOnlyMemoryRegionFromFile(const string &fname, std::unique_ptr< ReadOnlyMemoryRegion > *result)` {#Status_tensorflow_Env_NewReadOnlyMemoryRegionFromFile} Creates a readonly region of memory with the file context. @@ -96,6 +96,20 @@ Deletes the named file. +#### `Status tensorflow::Env::DeleteRecursively(const string &dirname, int64 *undeleted_files, int64 *undeleted_dirs)` {#Status_tensorflow_Env_DeleteRecursively} + +Deletes the specified directory and all subdirectories and files underneath it. undeleted_files and undeleted_dirs stores the number of files and directories that weren't deleted (unspecified if the return status is not OK). REQUIRES: undeleted_files, undeleted_dirs to be not null. Typical return codes. + + + +OK - dirname exists and we were able to delete everything underneath. + +NOT_FOUND - dirname doesn't exist + +PERMISSION_DENIED - dirname or some descendant is not writable + +UNIMPLEMENTED - Some underlying functions (like Delete) are not implemented + #### `Status tensorflow::Env::CreateDir(const string &dirname)` {#Status_tensorflow_Env_CreateDir} Creates the specified directory. @@ -108,6 +122,28 @@ Deletes the specified directory. +#### `Status tensorflow::Env::Stat(const string &fname, FileStatistics *stat)` {#Status_tensorflow_Env_Stat} + +Obtains statistics for the given path. + + + +#### `Status tensorflow::Env::IsDirectory(const string &fname)` {#Status_tensorflow_Env_IsDirectory} + +Returns whether the given path is a directory or not. Typical return codes (not guaranteed exhaustive): + + + +OK - The path exists and is a directory. + +FAILED_PRECONDITION - The path exists and is not a directory. + +NOT_FOUND - The path entry does not exist. + +PERMISSION_DENIED - Insufficient permissions. + +UNIMPLEMENTED - The file factory doesn't support directories. + #### `Status tensorflow::Env::GetFileSize(const string &fname, uint64 *file_size)` {#Status_tensorflow_Env_GetFileSize} Stores the size of `fname` in `*file_size`. @@ -126,7 +162,13 @@ Returns the number of micro-seconds since some fixed point in time. Only useful -#### `virtual void tensorflow::Env::SleepForMicroseconds(int micros)=0` {#virtual_void_tensorflow_Env_SleepForMicroseconds} +#### `virtual uint64 tensorflow::Env::NowSeconds()` {#virtual_uint64_tensorflow_Env_NowSeconds} + +Returns the number of seconds since some fixed point in time. Only useful for computing deltas of time. + + + +#### `virtual void tensorflow::Env::SleepForMicroseconds(int64 micros)=0` {#virtual_void_tensorflow_Env_SleepForMicroseconds} Sleeps/delays the thread for the prescribed number of micro-seconds. @@ -144,7 +186,7 @@ Caller takes ownership of the result and must delete it eventually (the deletion -#### `virtual void tensorflow::Env::SchedClosureAfter(int micros, std::function< void()> closure)=0` {#virtual_void_tensorflow_Env_SchedClosureAfter} +#### `virtual void tensorflow::Env::SchedClosureAfter(int64 micros, std::function< void()> closure)=0` {#virtual_void_tensorflow_Env_SchedClosureAfter} diff --git a/tensorflow/g3doc/api_docs/cc/ClassEnvWrapper.md b/tensorflow/g3doc/api_docs/cc/ClassEnvWrapper.md index 2e284ac8159..f0041f5be92 100644 --- a/tensorflow/g3doc/api_docs/cc/ClassEnvWrapper.md +++ b/tensorflow/g3doc/api_docs/cc/ClassEnvWrapper.md @@ -48,7 +48,7 @@ Returns the number of micro-seconds since some fixed point in time. Only useful -#### `void tensorflow::EnvWrapper::SleepForMicroseconds(int micros) override` {#void_tensorflow_EnvWrapper_SleepForMicroseconds} +#### `void tensorflow::EnvWrapper::SleepForMicroseconds(int64 micros) override` {#void_tensorflow_EnvWrapper_SleepForMicroseconds} Sleeps/delays the thread for the prescribed number of micro-seconds. @@ -66,7 +66,7 @@ Caller takes ownership of the result and must delete it eventually (the deletion -#### `void tensorflow::EnvWrapper::SchedClosureAfter(int micros, std::function< void()> closure) override` {#void_tensorflow_EnvWrapper_SchedClosureAfter} +#### `void tensorflow::EnvWrapper::SchedClosureAfter(int64 micros, std::function< void()> closure) override` {#void_tensorflow_EnvWrapper_SchedClosureAfter} diff --git a/tensorflow/g3doc/api_docs/cc/ClassTensor.md b/tensorflow/g3doc/api_docs/cc/ClassTensor.md index cc271aae374..e221a026935 100644 --- a/tensorflow/g3doc/api_docs/cc/ClassTensor.md +++ b/tensorflow/g3doc/api_docs/cc/ClassTensor.md @@ -8,9 +8,13 @@ Represents an n-dimensional array of values. #### `tensorflow::Tensor::Tensor()` {#tensorflow_Tensor_Tensor} -Default Tensor constructor. Creates a 1-dimension, 0-element float tensor. +Creates a 1-dimensional, 0-element float tensor. +The returned Tensor is not a scalar (shape {}), but is instead an empty one-dimensional Tensor (shape {0}, NumElements() == 0). Since it has no elements, it does not need to be assigned a value and is initialized by default ( IsInitialized() is true). If this is undesirable, consider creating a one-element scalar which does require initialization: +```c++ Tensor(DT_FLOAT, TensorShape({})) + +``` #### `tensorflow::Tensor::Tensor(DataType type, const TensorShape &shape)` {#tensorflow_Tensor_Tensor} @@ -32,9 +36,9 @@ Creates a tensor with the input `type` and `shape`, using the allocator `a` and #### `tensorflow::Tensor::Tensor(DataType type)` {#tensorflow_Tensor_Tensor} -Creates an uninitialized Tensor of the given data type. - +Creates an empty Tensor of the given data type. +Like Tensor() , returns a 1-dimensional, 0-element Tensor with IsInitialized() returning True. See the Tensor() documentation for details. #### `tensorflow::Tensor::Tensor(const Tensor &other)` {#tensorflow_Tensor_Tensor} @@ -42,12 +46,18 @@ Creates an uninitialized Tensor of the given data type. -#### `tensorflow::Tensor::~Tensor()` {#tensorflow_Tensor_Tensor} +#### `tensorflow::Tensor::Tensor(Tensor &&other)` {#tensorflow_Tensor_Tensor} Copy constructor. +#### `tensorflow::Tensor::~Tensor()` {#tensorflow_Tensor_Tensor} + + + + + #### `DataType tensorflow::Tensor::dtype() const` {#DataType_tensorflow_Tensor_dtype} Returns the data type. @@ -98,9 +108,9 @@ Convenience accessor for the tensor shape. #### `bool tensorflow::Tensor::IsInitialized() const` {#bool_tensorflow_Tensor_IsInitialized} -Has this Tensor been initialized? - +If necessary, has this Tensor been initialized? +Zero-element Tensors are always considered initialized, even if they have never been assigned to and do not have any memory allocated. #### `size_t tensorflow::Tensor::TotalBytes() const` {#size_t_tensorflow_Tensor_TotalBytes} @@ -120,6 +130,12 @@ Assign operator. This tensor shares other's underlying storage. +#### `Tensor & tensorflow::Tensor::operator=(Tensor &&other)` {#Tensor_tensorflow_Tensor_operator_} + +Move operator. See move constructor for details. + + + #### `bool tensorflow::Tensor::CopyFrom(const Tensor &other, const TensorShape &shape) TF_MUST_USE_RESULT` {#bool_tensorflow_Tensor_CopyFrom} Copy the other tensor into this tensor and reshape it. @@ -190,6 +206,12 @@ auto mat = my_mat.matrix();// CHECK fails as type mismatch. +#### `TTypes< T, NDIMS >::Tensor tensorflow::Tensor::bit_casted_tensor()` {#TTypes_T_NDIMS_Tensor_tensorflow_Tensor_bit_casted_tensor} + +Return the tensor data to an `Eigen::Tensor` with the same size but a bitwise cast to the specified dtype `T`. + +Using a bitcast is useful for move and copy operations. NOTE: this is the same as `tensor()` except a bitcast is allowed. + #### `TTypes::Flat tensorflow::Tensor::flat()` {#TTypes_T_Flat_tensorflow_Tensor_flat} Return the tensor data as an `Eigen::Tensor` of the data type and a specified shape. @@ -239,6 +261,12 @@ Returns the data as an Eigen::Tensor with NDIMS dimensions, collapsing all Tenso +#### `TTypes< T, NDIMS >::Tensor tensorflow::Tensor::bit_casted_shaped(gtl::ArraySlice< int64 > new_sizes)` {#TTypes_T_NDIMS_Tensor_tensorflow_Tensor_bit_casted_shaped} + +Return the tensor data to an `Eigen::Tensor` with the new shape specified in `new_sizes` and cast to a new dtype `T`. + +Using a bitcast is useful for move and copy operations. The allowed bitcast is the only difference from `shaped()`. + #### `TTypes< T, NDIMS >::UnalignedTensor tensorflow::Tensor::unaligned_shaped(gtl::ArraySlice< int64 > new_sizes)` {#TTypes_T_NDIMS_UnalignedTensor_tensorflow_Tensor_unaligned_shaped} @@ -269,6 +297,12 @@ Const versions of all the methods above. +#### `TTypes< T, NDIMS >::ConstTensor tensorflow::Tensor::bit_casted_tensor() const` {#TTypes_T_NDIMS_ConstTensor_tensorflow_Tensor_bit_casted_tensor} + +Return the tensor data to an `Eigen::Tensor` with the same size but a bitwise cast to the specified dtype `T`. + +Using a bitcast is useful for move and copy operations. NOTE: this is the same as `tensor()` except a bitcast is allowed. + #### `TTypes::ConstFlat tensorflow::Tensor::flat() const` {#TTypes_T_ConstFlat_tensorflow_Tensor_flat} @@ -287,6 +321,12 @@ Const versions of all the methods above. +#### `TTypes< T, NDIMS >::ConstTensor tensorflow::Tensor::bit_casted_shaped(gtl::ArraySlice< int64 > new_sizes) const` {#TTypes_T_NDIMS_ConstTensor_tensorflow_Tensor_bit_casted_shaped} + +Return the tensor data to an `Eigen::Tensor` with the new shape specified in `new_sizes` and cast to a new dtype `T`. + +Using a bitcast is useful for move and copy operations. The allowed bitcast is the only difference from `shaped()`. + #### `TTypes< T, NDIMS >::UnalignedConstTensor tensorflow::Tensor::unaligned_shaped(gtl::ArraySlice< int64 > new_sizes) const` {#TTypes_T_NDIMS_UnalignedConstTensor_tensorflow_Tensor_unaligned_shaped} @@ -337,7 +377,7 @@ The returned ` StringPiece ` may point to memory location on devices that the CP NOTE: The underlying tensor buffer is refcounted, so the lifetime of the contents mapped by the ` StringPiece ` matches the lifetime of the buffer; callers should arrange to make sure the buffer does not get destroyed while the ` StringPiece ` is still used. -REQUIRES: `DataTypeCanUseMemcpy( dtype() )`. +REQUIRES: `DataTypeCanUseMemcpy(dtype())`. #### `void tensorflow::Tensor::UnsafeCopyFromInternal(const Tensor &, const TensorShape &)` {#void_tensorflow_Tensor_UnsafeCopyFromInternal} diff --git a/tensorflow/g3doc/api_docs/cc/ClassTensorShape.md b/tensorflow/g3doc/api_docs/cc/ClassTensorShape.md index d0be205c3b0..5eba11a0df7 100644 --- a/tensorflow/g3doc/api_docs/cc/ClassTensorShape.md +++ b/tensorflow/g3doc/api_docs/cc/ClassTensorShape.md @@ -60,6 +60,18 @@ Copy the specified shape. +#### `tensorflow::TensorShape::TensorShape(TensorShape &&b)` {#tensorflow_TensorShape_TensorShape} + +Move the specified shape. After moving, is safe for destruction and. + + + +#### `void tensorflow::TensorShape::operator=(TensorShape &&b)` {#void_tensorflow_TensorShape_operator_} + + + + + #### `void tensorflow::TensorShape::Clear()` {#void_tensorflow_TensorShape_Clear} Clear a tensor shape. diff --git a/tensorflow/g3doc/api_docs/cc/ClassTensorShapeUtils.md b/tensorflow/g3doc/api_docs/cc/ClassTensorShapeUtils.md index 6010dd48b7e..761feccae20 100644 --- a/tensorflow/g3doc/api_docs/cc/ClassTensorShapeUtils.md +++ b/tensorflow/g3doc/api_docs/cc/ClassTensorShapeUtils.md @@ -36,13 +36,25 @@ Static helper routines for ` TensorShape `. Includes a few common predicates on -#### `static Status tensorflow::TensorShapeUtils::MakeShape(const int32 *dims, int n, TensorShape *out)` {#static_Status_tensorflow_TensorShapeUtils_MakeShape} +#### `static Status tensorflow::TensorShapeUtils::MakeShape(const int32 *dims, int64 n, TensorShape *out)` {#static_Status_tensorflow_TensorShapeUtils_MakeShape} Returns a ` TensorShape ` whose dimensions are `dims[0]`, `dims[1]`, ..., `dims[n-1]`. -#### `static Status tensorflow::TensorShapeUtils::MakeShape(const int64 *dims, int n, TensorShape *out)` {#static_Status_tensorflow_TensorShapeUtils_MakeShape} +#### `static Status tensorflow::TensorShapeUtils::MakeShape(const int64 *dims, int64 n, TensorShape *out)` {#static_Status_tensorflow_TensorShapeUtils_MakeShape} + + + + + +#### `static Status tensorflow::TensorShapeUtils::MakeShape(gtl::ArraySlice< int32 > shape, TensorShape *out)` {#static_Status_tensorflow_TensorShapeUtils_MakeShape} + + + + + +#### `static Status tensorflow::TensorShapeUtils::MakeShape(gtl::ArraySlice< int64 > shape, TensorShape *out)` {#static_Status_tensorflow_TensorShapeUtils_MakeShape} diff --git a/tensorflow/g3doc/api_docs/cc/StructTF_Buffer.md b/tensorflow/g3doc/api_docs/cc/StructTF_Buffer.md index c435db80298..084beffe66a 100644 --- a/tensorflow/g3doc/api_docs/cc/StructTF_Buffer.md +++ b/tensorflow/g3doc/api_docs/cc/StructTF_Buffer.md @@ -18,7 +18,7 @@ -#### `void(* TF_Buffer::data_deallocator) (void *data, size_t length))(void *data, size_t length)` {#void_TF_Buffer_data_deallocator_void_data_size_t_length_} +#### `void(* TF_Buffer::data_deallocator)(void *data, size_t length))(void *data, size_t length)` {#void_TF_Buffer_data_deallocator_void_data_size_t_length_} diff --git a/tensorflow/g3doc/api_docs/index.md b/tensorflow/g3doc/api_docs/index.md index d074c0ece33..311908dca32 100644 --- a/tensorflow/g3doc/api_docs/index.md +++ b/tensorflow/g3doc/api_docs/index.md @@ -10,9 +10,9 @@ languages like Go, Java, JavaScript, Lua, R, and perhaps others. With [SWIG](http://swig.org), it's relatively easy to develop a TensorFlow interface for your favorite language. -Note: Many practical aspects of usage are covered in the Mechanics tab, and -some additional documentation not specific to any particular language API is -available in the Resources tab. +Note: Many practical aspects of usage are covered in the TUTORIALS and +HOW TO tab, and some additional documentation not specific to any +particular language API is available in the RESOURCES tab. * [Python API](python/index.md) * [C++ API](cc/index.md) diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.nn.rnn.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.nn.rnn.md index 19caecfb70a..d9e935f8fb3 100644 --- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.nn.rnn.md +++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.nn.rnn.md @@ -2,15 +2,15 @@ Creates a recurrent neural network specified by RNNCell `cell`. -##### The simplest form of RNN network generated is: - +The simplest form of RNN network generated is: +```py state = cell.zero_state(...) outputs = [] for input_ in inputs: output, state = cell(input_, state) outputs.append(output) return (outputs, state) - +``` However, a few other options are available: An initial state can be provided. diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard6/tf.train.exponential_decay.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard6/tf.train.exponential_decay.md index d90c8ee7269..42d8f100769 100644 --- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard6/tf.train.exponential_decay.md +++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard6/tf.train.exponential_decay.md @@ -28,7 +28,7 @@ learning_rate = tf.train.exponential_decay(starter_learning_rate, global_step, 100000, 0.96, staircase=True) # Passing global_step to minimize() will increment it at each step. learning_step = ( - tf.GradientDescentOptimizer(learning_rate) + tf.train.GradientDescentOptimizer(learning_rate) .minimize(...my loss..., global_step=global_step) ) ``` diff --git a/tensorflow/g3doc/api_docs/python/nn.md b/tensorflow/g3doc/api_docs/python/nn.md index 67f6e0f55e9..075f85b2495 100644 --- a/tensorflow/g3doc/api_docs/python/nn.md +++ b/tensorflow/g3doc/api_docs/python/nn.md @@ -1631,15 +1631,15 @@ automatically performed. Creates a recurrent neural network specified by RNNCell `cell`. -##### The simplest form of RNN network generated is: - +The simplest form of RNN network generated is: +```py state = cell.zero_state(...) outputs = [] for input_ in inputs: output, state = cell(input_, state) outputs.append(output) return (outputs, state) - +``` However, a few other options are available: An initial state can be provided. diff --git a/tensorflow/g3doc/get_started/os_setup.md b/tensorflow/g3doc/get_started/os_setup.md index 92f77b27b07..ef837af395f 100644 --- a/tensorflow/g3doc/get_started/os_setup.md +++ b/tensorflow/g3doc/get_started/os_setup.md @@ -61,31 +61,37 @@ Then, select the correct binary to install: ```bash # Ubuntu/Linux 64-bit, CPU only, Python 2.7 -$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.9.0-cp27-none-linux_x86_64.whl +$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.10.0rc0-cp27-none-linux_x86_64.whl # Ubuntu/Linux 64-bit, GPU enabled, Python 2.7 # Requires CUDA toolkit 7.5 and CuDNN v4. For other versions, see "Install from sources" below. -$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow-0.9.0-cp27-none-linux_x86_64.whl +$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow-0.10.0rc0-cp27-none-linux_x86_64.whl # Mac OS X, CPU only, Python 2.7: -$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/mac/tensorflow-0.9.0-py2-none-any.whl +$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/mac/cpu/tensorflow-0.10.0rc0-py2-none-any.whl + +# Mac OS X, GPU enabled, Python 2.7: +$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/mac/gpu/tensorflow-0.10.0rc0-py2-none-any.whl # Ubuntu/Linux 64-bit, CPU only, Python 3.4 -$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.9.0-cp34-cp34m-linux_x86_64.whl +$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.10.0rc0-cp34-cp34m-linux_x86_64.whl # Ubuntu/Linux 64-bit, GPU enabled, Python 3.4 # Requires CUDA toolkit 7.5 and CuDNN v4. For other versions, see "Install from sources" below. -$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow-0.9.0-cp34-cp34m-linux_x86_64.whl +$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow-0.10.0rc0-cp34-cp34m-linux_x86_64.whl # Ubuntu/Linux 64-bit, CPU only, Python 3.5 -$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.9.0-cp35-cp35m-linux_x86_64.whl +$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.10.0rc0-cp35-cp35m-linux_x86_64.whl # Ubuntu/Linux 64-bit, GPU enabled, Python 3.5 # Requires CUDA toolkit 7.5 and CuDNN v4. For other versions, see "Install from sources" below. -$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow-0.9.0-cp35-cp35m-linux_x86_64.whl +$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow-0.10.0rc0-cp35-cp35m-linux_x86_64.whl # Mac OS X, CPU only, Python 3.4 or 3.5: -$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/mac/tensorflow-0.9.0-py3-none-any.whl +$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/mac/cpu/tensorflow-0.10.0rc0-py3-none-any.whl + +# Mac OS X, GPU enabled, Python 3.4 or 3.5: +$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/mac/gpu/tensorflow-0.10.0rc0-py3-none-any.whl ``` Install TensorFlow: @@ -151,31 +157,37 @@ Now, install TensorFlow just as you would for a regular Pip installation. First ```bash # Ubuntu/Linux 64-bit, CPU only, Python 2.7 -(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.9.0-cp27-none-linux_x86_64.whl +(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.10.0rc0-cp27-none-linux_x86_64.whl # Ubuntu/Linux 64-bit, GPU enabled, Python 2.7 # Requires CUDA toolkit 7.5 and CuDNN v4. For other versions, see "Install from sources" below. -(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow-0.9.0-cp27-none-linux_x86_64.whl +(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow-0.10.0rc0-cp27-none-linux_x86_64.whl # Mac OS X, CPU only, Python 2.7: -(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/mac/tensorflow-0.9.0-py2-none-any.whl +(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/mac/cpu/tensorflow-0.10.0rc0-py2-none-any.whl + +# Mac OS X, GPU enabled, Python 2.7: +(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/mac/gpu/tensorflow-0.10.0rc0-py2-none-any.whl # Ubuntu/Linux 64-bit, CPU only, Python 3.4 -(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.9.0-cp34-cp34m-linux_x86_64.whl +(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.10.0rc0-cp34-cp34m-linux_x86_64.whl # Ubuntu/Linux 64-bit, GPU enabled, Python 3.4 # Requires CUDA toolkit 7.5 and CuDNN v4. For other versions, see "Install from sources" below. -(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow-0.9.0-cp34-cp34m-linux_x86_64.whl +(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow-0.10.0rc0-cp34-cp34m-linux_x86_64.whl # Ubuntu/Linux 64-bit, CPU only, Python 3.5 -(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.9.0-cp35-cp35m-linux_x86_64.whl +(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.10.0rc0-cp35-cp35m-linux_x86_64.whl # Ubuntu/Linux 64-bit, GPU enabled, Python 3.5 # Requires CUDA toolkit 7.5 and CuDNN v4. For other versions, see "Install from sources" below. -(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow-0.9.0-cp35-cp35m-linux_x86_64.whl +(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow-0.10.0rc0-cp35-cp35m-linux_x86_64.whl # Mac OS X, CPU only, Python 3.4 or 3.5: -(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/mac/tensorflow-0.9.0-py3-none-any.whl +(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/mac/cpu/tensorflow-0.10.0rc0-py3-none-any.whl + +# Mac OS X, GPU enabled, Python 3.4 or 3.5: +(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/mac/gpu/tensorflow-0.10.0rc0-py3-none-any.whl ``` Finally install TensorFlow: @@ -228,6 +240,7 @@ packages needed by TensorFlow. * Activate the conda environment and install TensorFlow in it. * After the install you will activate the conda environment each time you want to use TensorFlow. +* Optionally install ipython and other packages into the conda environment Install Anaconda: @@ -248,6 +261,7 @@ $ conda create -n tensorflow python=3.5 Activate the environment and use conda or pip to install TensorFlow inside it. + ### Using conda A community maintained conda package is available [from conda-forge](https://github.com/conda-forge/tensorflow-feedstock). @@ -275,31 +289,37 @@ Now, install TensorFlow just as you would for a regular Pip installation. First ```bash # Ubuntu/Linux 64-bit, CPU only, Python 2.7 -(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.9.0-cp27-none-linux_x86_64.whl +(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.10.0rc0-cp27-none-linux_x86_64.whl # Ubuntu/Linux 64-bit, GPU enabled, Python 2.7 # Requires CUDA toolkit 7.5 and CuDNN v4. For other versions, see "Install from sources" below. -(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow-0.9.0-cp27-none-linux_x86_64.whl +(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow-0.10.0rc0-cp27-none-linux_x86_64.whl # Mac OS X, CPU only, Python 2.7: -(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/mac/tensorflow-0.9.0-py2-none-any.whl +(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/mac/cpu/tensorflow-0.10.0rc0-py2-none-any.whl + +# Mac OS X, GPU enabled, Python 2.7: +(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/mac/gpu/tensorflow-0.10.0rc0-py2-none-any.whl # Ubuntu/Linux 64-bit, CPU only, Python 3.4 -(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.9.0-cp34-cp34m-linux_x86_64.whl +(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.10.0rc0-cp34-cp34m-linux_x86_64.whl # Ubuntu/Linux 64-bit, GPU enabled, Python 3.4 # Requires CUDA toolkit 7.5 and CuDNN v4. For other versions, see "Install from sources" below. -(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow-0.9.0-cp34-cp34m-linux_x86_64.whl +(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow-0.10.0rc0-cp34-cp34m-linux_x86_64.whl # Ubuntu/Linux 64-bit, CPU only, Python 3.5 -(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.9.0-cp35-cp35m-linux_x86_64.whl +(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.10.0rc0-cp35-cp35m-linux_x86_64.whl # Ubuntu/Linux 64-bit, GPU enabled, Python 3.5 # Requires CUDA toolkit 7.5 and CuDNN v4. For other versions, see "Install from sources" below. -(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow-0.9.0-cp35-cp35m-linux_x86_64.whl +(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow-0.10.0rc0-cp35-cp35m-linux_x86_64.whl # Mac OS X, CPU only, Python 3.4 or 3.5: -(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/mac/tensorflow-0.9.0-py3-none-any.whl +(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/mac/cpu/tensorflow-0.10.0rc0-py3-none-any.whl + +# Mac OS X, GPU enabled, Python 3.4 or 3.5: +(tensorflow)$ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/mac/gpu/tensorflow-0.10.0rc0-py3-none-any.whl ``` Finally install TensorFlow: @@ -336,6 +356,19 @@ $ source activate tensorflow (tensorflow)$ source deactivate ``` +### Install IPython + +To use tensorflow with IPython it may be necessary to install IPython into the tensorflow environment: + +```bash +$ source activate tensorflow +(tensorflow)$ conda install ipython +``` + +Similarly, other Python packages like pandas may need to get installed into the tensorflow environment +before they can be used together with tensorflow. + + ## Docker installation [Docker](http://docker.com/) is a system to build self contained versions of a @@ -352,7 +385,7 @@ code. * `gcr.io/tensorflow/tensorflow:latest-devel-gpu`: GPU Binary image plus source code. -We also have tags with `latest` replaced by a released version (e.g., `0.9.0-gpu`). +We also have tags with `latest` replaced by a released version (e.g., `0.10.0rc0-gpu`). With Docker the installation is as follows: @@ -594,6 +627,8 @@ which you can install as follows: $ sudo easy_install ipython ``` +#### Optional: Setup GPU for Mac + If you plan to build with GPU support you will need to make sure you have GNU coreutils installed via homebrew: @@ -634,6 +669,26 @@ $ sudo mv lib/libcudnn* /Developer/NVIDIA/CUDA-7.5/lib $ sudo ln -s /Developer/NVIDIA/CUDA-7.5/lib/libcudnn* /usr/local/cuda/lib/ ``` +To verify the CUDA installation, you can build and run deviceQuery to make sure +it passes. + +```bash +$ cp -r /usr/local/cuda/samples ~/cuda-samples +$ pushd ~/cuda-samples +$ make +$ popd +$ ~/cuda-samples/bin/x86_64/darwin/release/deviceQuery +``` + +If you want to compile tensorflow and have the XCode 7.3 installed, note that +Xcode 7.3 is not yet compatible with CUDA 7.5. You will need to download Xcode +7.2 and select it as your default: + +```bash +$ sudo xcode-select -s /Application/Xcode-7.2/Xcode.app +``` + + ### Configure the installation Run the `configure` script at the root of the tree. The configure script @@ -719,7 +774,7 @@ $ bazel build -c opt --config=cuda //tensorflow/tools/pip_package:build_pip_pack $ bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg # The name of the .whl file will depend on your platform. -$ sudo pip install /tmp/tensorflow_pkg/tensorflow-0.9.0-py2-none-any.whl +$ sudo pip install /tmp/tensorflow_pkg/tensorflow-0.10.0rc0-py2-none-any.whl ``` ## Setting up TensorFlow for Development diff --git a/tensorflow/g3doc/how_tos/using_gpu/index.md b/tensorflow/g3doc/how_tos/using_gpu/index.md index e3e16fa5752..47f14a95189 100644 --- a/tensorflow/g3doc/how_tos/using_gpu/index.md +++ b/tensorflow/g3doc/how_tos/using_gpu/index.md @@ -58,7 +58,7 @@ within that context will have the same device assignment. with tf.device('/cpu:0'): a = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[2, 3], name='a') b = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[3, 2], name='b') -c = tf.matmul(a, b) + c = tf.matmul(a, b) # Creates a session with log_device_placement set to True. sess = tf.Session(config=tf.ConfigProto(log_device_placement=True)) # Runs the op. diff --git a/tensorflow/python/ops/rnn.py b/tensorflow/python/ops/rnn.py index ed7412ba9d7..48d9cab3e40 100644 --- a/tensorflow/python/ops/rnn.py +++ b/tensorflow/python/ops/rnn.py @@ -75,13 +75,14 @@ def rnn(cell, inputs, initial_state=None, dtype=None, """Creates a recurrent neural network specified by RNNCell `cell`. The simplest form of RNN network generated is: + ```py state = cell.zero_state(...) outputs = [] for input_ in inputs: output, state = cell(input_, state) outputs.append(output) return (outputs, state) - + ``` However, a few other options are available: An initial state can be provided. diff --git a/tensorflow/python/ops/rnn_cell.py b/tensorflow/python/ops/rnn_cell.py index 33ae2ee30bf..1a6ea6fcecd 100644 --- a/tensorflow/python/ops/rnn_cell.py +++ b/tensorflow/python/ops/rnn_cell.py @@ -87,6 +87,11 @@ def _state_size_with_prefix(state_size, prefix=None): class RNNCell(object): """Abstract object representing an RNN cell. + The definition of cell in this package differs from the definition used in the + literature. In the literature, cell refers to an object with a single scalar + output. The definition in this package refers to a horizontal array of such + units. + An RNN cell, in the most abstract setting, is anything that has a state and performs some operation that takes a matrix of inputs. This operation results in an output matrix with `self.output_size` columns. diff --git a/tensorflow/python/platform/tf_logging.py b/tensorflow/python/platform/tf_logging.py index dd3b380581e..8a97ab2c9b2 100644 --- a/tensorflow/python/platform/tf_logging.py +++ b/tensorflow/python/platform/tf_logging.py @@ -53,7 +53,7 @@ error = _logger.error fatal = _logger.fatal info = _logger.info warn = _logger.warn -warning = _logger.warn +warning = _logger.warning _level_names = { FATAL: 'FATAL', diff --git a/tensorflow/python/training/learning_rate_decay.py b/tensorflow/python/training/learning_rate_decay.py index f24f1f4a087..ef369e90953 100644 --- a/tensorflow/python/training/learning_rate_decay.py +++ b/tensorflow/python/training/learning_rate_decay.py @@ -54,7 +54,7 @@ def exponential_decay(learning_rate, global_step, decay_steps, decay_rate, 100000, 0.96, staircase=True) # Passing global_step to minimize() will increment it at each step. learning_step = ( - tf.GradientDescentOptimizer(learning_rate) + tf.train.GradientDescentOptimizer(learning_rate) .minimize(...my loss..., global_step=global_step) ) ``` @@ -195,7 +195,7 @@ def polynomial_decay(learning_rate, global_step, decay_steps, power=0.5) # Passing global_step to minimize() will increment it at each step. learning_step = ( - tf.GradientDescentOptimizer(learning_rate) + tf.train.GradientDescentOptimizer(learning_rate) .minimize(...my loss..., global_step=global_step) ) ``` @@ -268,7 +268,7 @@ def natural_exp_decay(learning_rate, global_step, decay_steps, decay_rate, # Passing global_step to minimize() will increment it at each step. learning_step = ( - tf.GradientDescentOptimizer(learning_rate) + tf.train.GradientDescentOptimizer(learning_rate) .minimize(...my loss..., global_step=global_step) ) ``` @@ -327,7 +327,7 @@ def inverse_time_decay(learning_rate, global_step, decay_steps, decay_rate, # Passing global_step to minimize() will increment it at each step. learning_step = ( - tf.GradientDescentOptimizer(learning_rate) + tf.train.GradientDescentOptimizer(learning_rate) .minimize(...my loss..., global_step=global_step) ) ``` diff --git a/tensorflow/tensorboard/README.md b/tensorflow/tensorboard/README.md index a53a80eb478..49a1656cddc 100644 --- a/tensorflow/tensorboard/README.md +++ b/tensorflow/tensorboard/README.md @@ -54,18 +54,18 @@ work, but there may be bugs or performance issues. The first step in using TensorBoard is acquiring data from your TensorFlow run. For this, you need [summary -ops](https://www.tensorflow.org/versions/r0.9/api_docs/python/train.html#summary-operations). +ops](https://www.tensorflow.org/versions/r0.10/api_docs/python/train.html#summary-operations). Summary ops are ops, like -[`tf.matmul`](https://www.tensorflow.org/versions/r0.9/api_docs/python/math_ops.html#matmul) +[`tf.matmul`](https://www.tensorflow.org/versions/r0.10/api_docs/python/math_ops.html#matmul) or -[`tf.nn.relu`](https://www.tensorflow.org/versions/r0.9/api_docs/python/nn.html#relu), +[`tf.nn.relu`](https://www.tensorflow.org/versions/r0.10/api_docs/python/nn.html#relu), which means they take in tensors, produce tensors, and are evaluated from within a TensorFlow graph. However, summary ops have a twist: the Tensors they produce contain serialized protobufs, which are written to disk and sent to TensorBoard. To visualize the summary data in TensorBoard, you should evaluate the summary op, retrieve the result, and then write that result to disk using a SummaryWriter. A full explanation, with examples, is in [the -tutorial](https://www.tensorflow.org/versions/r0.9/how_tos/summaries_and_tensorboard/index.html). +tutorial](https://www.tensorflow.org/versions/r0.10/how_tos/summaries_and_tensorboard/index.html). ### Tags: Giving names to data @@ -178,7 +178,7 @@ TensorFlow model. To get best use of the graph visualizer, you should use name scopes to hierarchically group the ops in your graph - otherwise, the graph may be difficult to decipher. For more information, including examples, see [the graph visualizer -tutorial](https://www.tensorflow.org/versions/r0.9/how_tos/graph_viz/index.html#tensorboard-graph-visualization). +tutorial](https://www.tensorflow.org/versions/r0.10/how_tos/graph_viz/index.html#tensorboard-graph-visualization). # Frequently Asked Questions diff --git a/tensorflow/tools/ci_build/Dockerfile.debian.jessie.cpu b/tensorflow/tools/ci_build/Dockerfile.debian.jessie.cpu index 2ed7a308241..fa74320b1e5 100644 --- a/tensorflow/tools/ci_build/Dockerfile.debian.jessie.cpu +++ b/tensorflow/tools/ci_build/Dockerfile.debian.jessie.cpu @@ -10,6 +10,9 @@ RUN /install/install_deb_packages.sh RUN /install/install_pip_packages.sh RUN /install/install_bazel.sh +# Fix a virtualenv install issue specific to Debian Jessie. +RUN pip install --upgrade virtualenv + # Set up bazelrc. COPY install/.bazelrc /root/.bazelrc ENV BAZELRC /root/.bazelrc diff --git a/tensorflow/tools/ci_build/builds/pip.sh b/tensorflow/tools/ci_build/builds/pip.sh index 5ee57da4b3d..8dffbfd2d95 100755 --- a/tensorflow/tools/ci_build/builds/pip.sh +++ b/tensorflow/tools/ci_build/builds/pip.sh @@ -106,7 +106,8 @@ fi PIP_BUILD_TARGET="//tensorflow/tools/pip_package:build_pip_package" GPU_FLAG="" -if [[ ${CONTAINER_TYPE} == "cpu" ]]; then +if [[ ${CONTAINER_TYPE} == "cpu" ]] || \ + [[ ${CONTAINER_TYPE} == "debian.jessie.cpu" ]]; then bazel build -c opt ${MAVX_FLAG} ${PIP_BUILD_TARGET} || \ die "Build failed." elif [[ ${CONTAINER_TYPE} == "gpu" ]]; then diff --git a/tensorflow/tools/ci_build/ci_parameterized_build.sh b/tensorflow/tools/ci_build/ci_parameterized_build.sh index b231a9c202e..73464ffc04b 100755 --- a/tensorflow/tools/ci_build/ci_parameterized_build.sh +++ b/tensorflow/tools/ci_build/ci_parameterized_build.sh @@ -191,7 +191,7 @@ if [[ -z "$(which docker)" ]]; then fi # Process container type -if [[ ${CTYPE} == "cpu" ]]; then +if [[ ${CTYPE} == "cpu" ]] || [[ ${CTYPE} == "debian.jessie.cpu" ]]; then : elif [[ ${CTYPE} == "gpu" ]]; then OPT_FLAG="${OPT_FLAG} --config=cuda" @@ -298,7 +298,9 @@ if [[ ${TF_BUILD_IS_PIP} == "no_pip" ]] || BAZEL_TARGET=${TF_BUILD_BAZEL_TARGET} fi - if [[ ${CTYPE} == "cpu" ]] || [[ ${CTYPE} == "gpu" ]]; then + if [[ ${CTYPE} == "cpu" ]] || \ + [[ ${CTYPE} == "debian.jessie.cpu" ]] || \ + [[ ${CTYPE} == "gpu" ]]; then # Run Bazel NO_PIP_MAIN_CMD="${MAIN_CMD} ${BAZEL_CMD} ${OPT_FLAG} "\ "${EXTRA_ARGS} ${BAZEL_TARGET}" diff --git a/tensorflow/tools/dist_test/Dockerfile b/tensorflow/tools/dist_test/Dockerfile index 66787ca7f8b..f39046252ba 100644 --- a/tensorflow/tools/dist_test/Dockerfile +++ b/tensorflow/tools/dist_test/Dockerfile @@ -20,7 +20,7 @@ RUN /var/gcloud/google-cloud-sdk/bin/gcloud components install kubectl # Install nightly TensorFlow pip # TODO(cais): Should we build it locally instead? RUN pip install \ - http://ci.tensorflow.org/view/Nightly/job/nightly-matrix-cpu/TF_BUILD_CONTAINER_TYPE=CPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON2,label=cpu-slave/lastSuccessfulBuild/artifact/pip_test/whl/tensorflow-0.9.0-cp27-none-linux_x86_64.whl + http://ci.tensorflow.org/view/Nightly/job/nightly-matrix-cpu/TF_BUILD_CONTAINER_TYPE=CPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON2,label=cpu-slave/lastSuccessfulBuild/artifact/pip_test/whl/tensorflow-0.10.0rc0-cp27-none-linux_x86_64.whl # Copy test files COPY scripts /var/tf-dist-test/scripts diff --git a/tensorflow/tools/dist_test/server/Dockerfile b/tensorflow/tools/dist_test/server/Dockerfile index c3bf751735e..68bacefaca0 100644 --- a/tensorflow/tools/dist_test/server/Dockerfile +++ b/tensorflow/tools/dist_test/server/Dockerfile @@ -36,7 +36,7 @@ RUN curl -O https://bootstrap.pypa.io/get-pip.py && \ # Install TensorFlow CPU version from nightly build RUN pip --no-cache-dir install \ - http://ci.tensorflow.org/view/Nightly/job/nightly-matrix-cpu/TF_BUILD_CONTAINER_TYPE=CPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON2,label=cpu-slave/lastSuccessfulBuild/artifact/pip_test/whl/tensorflow-0.9.0-cp27-none-linux_x86_64.whl + http://ci.tensorflow.org/view/Nightly/job/nightly-matrix-cpu/TF_BUILD_CONTAINER_TYPE=CPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON2,label=cpu-slave/lastSuccessfulBuild/artifact/pip_test/whl/tensorflow-0.10.0rc0-cp27-none-linux_x86_64.whl # Copy files, including the GRPC server binary at # server/grpc_tensorflow_server.py diff --git a/tensorflow/tools/dist_test/server/Dockerfile.test b/tensorflow/tools/dist_test/server/Dockerfile.test index de4411a05cd..f0895acc5e4 100644 --- a/tensorflow/tools/dist_test/server/Dockerfile.test +++ b/tensorflow/tools/dist_test/server/Dockerfile.test @@ -42,7 +42,7 @@ RUN pip install --upgrade pandas==0.18.1 # Install TensorFlow CPU version. RUN pip --no-cache-dir install \ - http://ci.tensorflow.org/view/Nightly/job/nightly-matrix-cpu/TF_BUILD_CONTAINER_TYPE=CPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON2,label=cpu-slave/lastSuccessfulBuild/artifact/pip_test/whl/tensorflow-0.9.0-cp27-none-linux_x86_64.whl + http://ci.tensorflow.org/view/Nightly/job/nightly-matrix-cpu/TF_BUILD_CONTAINER_TYPE=CPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON2,label=cpu-slave/lastSuccessfulBuild/artifact/pip_test/whl/tensorflow-0.10.0rc0-cp27-none-linux_x86_64.whl # Copy files, including the GRPC server binary at # server/grpc_tensorflow_server.py diff --git a/tensorflow/tools/docker/Dockerfile b/tensorflow/tools/docker/Dockerfile index 31c3cd4d30a..3bdebd69b91 100644 --- a/tensorflow/tools/docker/Dockerfile +++ b/tensorflow/tools/docker/Dockerfile @@ -32,7 +32,7 @@ RUN pip --no-cache-dir install \ && \ python -m ipykernel.kernelspec -ENV TENSORFLOW_VERSION 0.9.0 +ENV TENSORFLOW_VERSION 0.10.0rc0 # --- DO NOT EDIT OR DELETE BETWEEN THE LINES --- # # These lines will be edited automatically by parameterized_docker_build.sh. # diff --git a/tensorflow/tools/docker/Dockerfile.devel b/tensorflow/tools/docker/Dockerfile.devel index 5e8693525be..4f994bdbc8e 100644 --- a/tensorflow/tools/docker/Dockerfile.devel +++ b/tensorflow/tools/docker/Dockerfile.devel @@ -81,7 +81,7 @@ RUN mkdir /bazel && \ RUN git clone --recursive https://github.com/tensorflow/tensorflow.git && \ cd tensorflow && \ - git checkout r0.9 + git checkout r0.10 WORKDIR /tensorflow # TODO(craigcitro): Don't install the pip package, since it makes it diff --git a/tensorflow/tools/docker/Dockerfile.devel-gpu b/tensorflow/tools/docker/Dockerfile.devel-gpu index 2be630b48c4..e9081d5502f 100644 --- a/tensorflow/tools/docker/Dockerfile.devel-gpu +++ b/tensorflow/tools/docker/Dockerfile.devel-gpu @@ -80,9 +80,9 @@ RUN mkdir /bazel && \ # Download and build TensorFlow. -RUN git clone -b r0.9 --recursive --recurse-submodules https://github.com/tensorflow/tensorflow.git && \ +RUN git clone -b r0.10 --recursive --recurse-submodules https://github.com/tensorflow/tensorflow.git && \ cd tensorflow && \ - git checkout r0.9 + git checkout r0.10 WORKDIR /tensorflow # Configure the build for our CUDA configuration. diff --git a/tensorflow/tools/docker/Dockerfile.gpu b/tensorflow/tools/docker/Dockerfile.gpu index db91720cd9e..e08ef1aa758 100644 --- a/tensorflow/tools/docker/Dockerfile.gpu +++ b/tensorflow/tools/docker/Dockerfile.gpu @@ -32,7 +32,7 @@ RUN pip --no-cache-dir install \ && \ python -m ipykernel.kernelspec -ENV TENSORFLOW_VERSION 0.9.0 +ENV TENSORFLOW_VERSION 0.10.0rc0 # --- DO NOT EDIT OR DELETE BETWEEN THE LINES --- # # These lines will be edited automatically by parameterized_docker_build.sh. # diff --git a/tensorflow/tools/docker/parameterized_docker_build.sh b/tensorflow/tools/docker/parameterized_docker_build.sh index 5a1324e09fa..bfae655076b 100755 --- a/tensorflow/tools/docker/parameterized_docker_build.sh +++ b/tensorflow/tools/docker/parameterized_docker_build.sh @@ -179,8 +179,10 @@ if [[ "${DO_PIP_BUILD}" == "1" ]]; then export TF_BUILD_IS_OPT="OPT" export TF_BUILD_IS_PIP="PIP" - export TF_BUILD_APPEND_CI_DOCKER_EXTRA_PARAMS=\ -"-e TF_CUDA_COMPUTE_CAPABILITIES=3.0,3.5,5.2" + if [[ "${TF_DOCKER_BUILD_TYPE}" == "gpu" ]]; then + export TF_BUILD_APPEND_CI_DOCKER_EXTRA_PARAMS=\ +"${TF_BUILD_APPEND_CI_DOCKER_EXTRA_PARAMS} -e TF_CUDA_COMPUTE_CAPABILITIES=3.0,3.5,5.2" + fi pushd "${SCRIPT_DIR}/../../../" rm -rf pip_test/whl && diff --git a/tensorflow/tools/pip_package/setup.py b/tensorflow/tools/pip_package/setup.py index b3787c0edc5..1fda9fd49fb 100644 --- a/tensorflow/tools/pip_package/setup.py +++ b/tensorflow/tools/pip_package/setup.py @@ -27,7 +27,7 @@ from setuptools import find_packages, setup, Command, Extension from setuptools.command.install import install as InstallCommandBase from setuptools.dist import Distribution -_VERSION = '0.9.0' +_VERSION = '0.10.0rc0' numpy_version = "1.8.2" if platform.system() == "Darwin": diff --git a/third_party/gpus/crosstool/CROSSTOOL b/third_party/gpus/crosstool/CROSSTOOL index 8db81a9603b..f72bb9321a7 100644 --- a/third_party/gpus/crosstool/CROSSTOOL +++ b/third_party/gpus/crosstool/CROSSTOOL @@ -18,6 +18,10 @@ default_toolchain { cpu: "darwin" toolchain_identifier: "local_darwin" } +default_toolchain { + cpu: "ppc" + toolchain_identifier: "local_linux" +} toolchain { abi_version: "local" From 88a9d230289e317240070fd2d546357e3bd861fc Mon Sep 17 00:00:00 2001 From: "A. Unique TensorFlower" Date: Sun, 31 Jul 2016 22:31:51 -0800 Subject: [PATCH 002/134] Update ops-related pbtxt files. Change: 128959624 --- tensorflow/core/ops/ops.pbtxt | 57 +++++++++++------------------------ 1 file changed, 18 insertions(+), 39 deletions(-) diff --git a/tensorflow/core/ops/ops.pbtxt b/tensorflow/core/ops/ops.pbtxt index 01bb4bc82f8..046923bdb46 100644 --- a/tensorflow/core/ops/ops.pbtxt +++ b/tensorflow/core/ops/ops.pbtxt @@ -98,7 +98,7 @@ op { } } summary: "Returns x + y element-wise." - description: "*NOTE*: Add supports broadcasting. AddN does not." + description: "*NOTE*: `Add` supports broadcasting. `AddN` does not. More about broadcasting\n[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)" } op { name: "AddN" @@ -4489,42 +4489,6 @@ op { summary: "Decode a PNG-encoded image to a uint8 or uint16 tensor." description: "The attr `channels` indicates the desired number of color channels for the\ndecoded image.\n\nAccepted values are:\n\n* 0: Use the number of channels in the PNG-encoded image.\n* 1: output a grayscale image.\n* 3: output an RGB image.\n* 4: output an RGBA image.\n\nIf needed, the PNG-encoded image is transformed to match the requested number\nof color channels." } -op { - name: "DecodeGif" - input_arg { - name: "contents" - description: "0-D. The GIF-encoded image." - type: DT_STRING - } - output_arg { - name: "image" - description: "3-D with shape `[height, width, channels]`." - type_attr: "dtype" - } - attr { - name: "channels" - type: "int" - default_value { - i: 0 - } - description: "Number of color channels for the decoded image." - } - attr { - name: "dtype" - type: "type" - default_value { - type: DT_UINT8 - } - allowed_values { - list { - type: DT_UINT8 - type: DT_UINT16 - } - } - } - summary: "Decode a GIF-encoded image to a uint8 or uint16 tensor." - description: "The attr `channels` indicates the desired number of color channels for the\ndecoded image.\n\nAccepted values are:\n\n* 0: Use the number of channels in the GIF-encoded image.\n* 1: output a grayscale image.\n* 3: output an RGB image.\n* 4: output an RGBA image.\n\nIf needed, the GIF-encoded image is transformed to match the requested number\nof color channels." -} op { name: "DecodeRaw" input_arg { @@ -5095,6 +5059,7 @@ op { } } summary: "Returns x / y element-wise." + description: "*NOTE*: `Div` supports broadcasting. More about broadcasting\n[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)" } op { name: "DrawBoundingBoxes" @@ -5506,6 +5471,7 @@ op { } } summary: "Returns the truth value of (x == y) element-wise." + description: "*NOTE*: `Equal` supports broadcasting. More about broadcasting\n[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)" is_commutative: true } op { @@ -6186,6 +6152,7 @@ op { } } summary: "Returns the truth value of (x > y) element-wise." + description: "*NOTE*: `Greater` supports broadcasting. More about broadcasting\n[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)" } op { name: "GreaterEqual" @@ -6219,6 +6186,7 @@ op { } } summary: "Returns the truth value of (x >= y) element-wise." + description: "*NOTE*: `GreaterEqual` supports broadcasting. More about broadcasting\n[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)" } op { name: "HSVToRGB" @@ -7104,6 +7072,7 @@ op { } } summary: "Returns the truth value of (x < y) element-wise." + description: "*NOTE*: `Less` supports broadcasting. More about broadcasting\n[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)" } op { name: "LessEqual" @@ -7137,6 +7106,7 @@ op { } } summary: "Returns the truth value of (x <= y) element-wise." + description: "*NOTE*: `LessEqual` supports broadcasting. More about broadcasting\n[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)" } op { name: "Lgamma" @@ -7359,6 +7329,7 @@ op { type: DT_BOOL } summary: "Returns the truth value of x AND y element-wise." + description: "*NOTE*: `LogicalAnd` supports broadcasting. More about broadcasting\n[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)" is_commutative: true } op { @@ -7388,6 +7359,7 @@ op { type: DT_BOOL } summary: "Returns the truth value of x OR y element-wise." + description: "*NOTE*: `LogicalOr` supports broadcasting. More about broadcasting\n[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)" is_commutative: true } op { @@ -8245,7 +8217,8 @@ op { } } } - summary: "Returns the max of x and y (i.e. x > y ? x : y) element-wise, broadcasts." + summary: "Returns the max of x and y (i.e. x > y ? x : y) element-wise." + description: "*NOTE*: `Maximum` supports broadcasting. More about broadcasting\n[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)" is_commutative: true } op { @@ -8428,7 +8401,8 @@ op { } } } - summary: "Returns the min of x and y (i.e. x < y ? x : y) element-wise, broadcasts." + summary: "Returns the min of x and y (i.e. x < y ? x : y) element-wise." + description: "*NOTE*: `Minimum` supports broadcasting. More about broadcasting\n[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)" is_commutative: true } op { @@ -8528,6 +8502,7 @@ op { } } summary: "Returns element-wise remainder of division." + description: "*NOTE*: `Mod` supports broadcasting. More about broadcasting\n[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)" } op { name: "Mul" @@ -8562,6 +8537,7 @@ op { } } summary: "Returns x * y element-wise." + description: "*NOTE*: `Mul` supports broadcasting. More about broadcasting\n[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)" is_commutative: true } op { @@ -8863,6 +8839,7 @@ op { } } summary: "Returns the truth value of (x != y) element-wise." + description: "*NOTE*: `NotEqual` supports broadcasting. More about broadcasting\n[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)" is_commutative: true } op { @@ -14643,6 +14620,7 @@ op { } } summary: "Returns (x - y)(x - y) element-wise." + description: "*NOTE*: `SquaredDifference` supports broadcasting. More about broadcasting\n[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)" is_commutative: true } op { @@ -15094,6 +15072,7 @@ op { } } summary: "Returns x - y element-wise." + description: "*NOTE*: `Sub` supports broadcasting. More about broadcasting\n[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)" } op { name: "Sum" From 6834af5c459171d7551f6e8b812adeff5a833b5e Mon Sep 17 00:00:00 2001 From: "A. Unique TensorFlower" Date: Sun, 31 Jul 2016 22:33:27 -0800 Subject: [PATCH 003/134] Update generated Python Op docs. Change: 128959704 --- .../g3doc/api_docs/python/control_flow_ops.md | 24 ++++++++++++++++ .../functions_and_classes/shard0/tf.mod.md | 3 ++ .../functions_and_classes/shard0/tf.mul.md | 3 ++ .../shard0/tf.not_equal.md | 3 ++ .../shard1/tf.greater_equal.md | 3 ++ .../shard2/tf.minimum.md | 5 +++- .../shard4/tf.greater.md | 3 ++ .../functions_and_classes/shard4/tf.sub.md | 3 ++ .../functions_and_classes/shard5/tf.add.md | 3 +- .../functions_and_classes/shard5/tf.div.md | 3 ++ .../shard5/tf.logical_and.md | 3 ++ .../shard6/tf.maximum.md | 5 +++- .../functions_and_classes/shard7/tf.less.md | 3 ++ .../shard7/tf.logical_or.md | 3 ++ .../functions_and_classes/shard8/tf.equal.md | 3 ++ .../shard8/tf.less_equal.md | 3 ++ .../shard9/tf.nn.rnn_cell.RNNCell.md | 5 ++++ .../shard9/tf.squared_difference.md | 3 ++ tensorflow/g3doc/api_docs/python/math_ops.md | 28 +++++++++++++++++-- tensorflow/g3doc/api_docs/python/rnn_cell.md | 5 ++++ tensorflow/g3doc/api_docs/python/train.md | 2 +- 21 files changed, 109 insertions(+), 7 deletions(-) diff --git a/tensorflow/g3doc/api_docs/python/control_flow_ops.md b/tensorflow/g3doc/api_docs/python/control_flow_ops.md index 579633aa3b8..9a92c60b850 100644 --- a/tensorflow/g3doc/api_docs/python/control_flow_ops.md +++ b/tensorflow/g3doc/api_docs/python/control_flow_ops.md @@ -361,6 +361,9 @@ to your graph. Returns the truth value of x AND y element-wise. +*NOTE*: `LogicalAnd` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) + ##### Args: @@ -396,6 +399,9 @@ Returns the truth value of NOT x element-wise. Returns the truth value of x OR y element-wise. +*NOTE*: `LogicalOr` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) + ##### Args: @@ -427,6 +433,9 @@ operators to your graph. Returns the truth value of (x == y) element-wise. +*NOTE*: `Equal` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) + ##### Args: @@ -445,6 +454,9 @@ Returns the truth value of (x == y) element-wise. Returns the truth value of (x != y) element-wise. +*NOTE*: `NotEqual` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) + ##### Args: @@ -463,6 +475,9 @@ Returns the truth value of (x != y) element-wise. Returns the truth value of (x < y) element-wise. +*NOTE*: `Less` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) + ##### Args: @@ -481,6 +496,9 @@ Returns the truth value of (x < y) element-wise. Returns the truth value of (x <= y) element-wise. +*NOTE*: `LessEqual` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) + ##### Args: @@ -499,6 +517,9 @@ Returns the truth value of (x <= y) element-wise. Returns the truth value of (x > y) element-wise. +*NOTE*: `Greater` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) + ##### Args: @@ -517,6 +538,9 @@ Returns the truth value of (x > y) element-wise. Returns the truth value of (x >= y) element-wise. +*NOTE*: `GreaterEqual` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) + ##### Args: diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.mod.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.mod.md index 5bfe1058a77..86978890b5a 100644 --- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.mod.md +++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.mod.md @@ -2,6 +2,9 @@ Returns element-wise remainder of division. +*NOTE*: `Mod` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) + ##### Args: diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.mul.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.mul.md index 3d6fa568645..2efd16e8915 100644 --- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.mul.md +++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.mul.md @@ -2,6 +2,9 @@ Returns x * y element-wise. +*NOTE*: `Mul` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) + ##### Args: diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.not_equal.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.not_equal.md index 9c187922232..5ed8df49d5c 100644 --- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.not_equal.md +++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.not_equal.md @@ -2,6 +2,9 @@ Returns the truth value of (x != y) element-wise. +*NOTE*: `NotEqual` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) + ##### Args: diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard1/tf.greater_equal.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard1/tf.greater_equal.md index 9d68429c36c..d6ce057c133 100644 --- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard1/tf.greater_equal.md +++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard1/tf.greater_equal.md @@ -2,6 +2,9 @@ Returns the truth value of (x >= y) element-wise. +*NOTE*: `GreaterEqual` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) + ##### Args: diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard2/tf.minimum.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard2/tf.minimum.md index bff13483f4d..9bcd03f6e78 100644 --- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard2/tf.minimum.md +++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard2/tf.minimum.md @@ -1,6 +1,9 @@ ### `tf.minimum(x, y, name=None)` {#minimum} -Returns the min of x and y (i.e. x < y ? x : y) element-wise, broadcasts. +Returns the min of x and y (i.e. x < y ? x : y) element-wise. + +*NOTE*: `Minimum` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) ##### Args: diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard4/tf.greater.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard4/tf.greater.md index c629a0286f3..99b34aaca47 100644 --- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard4/tf.greater.md +++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard4/tf.greater.md @@ -2,6 +2,9 @@ Returns the truth value of (x > y) element-wise. +*NOTE*: `Greater` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) + ##### Args: diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard4/tf.sub.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard4/tf.sub.md index 2d1da0f0b98..83dbd7a93c8 100644 --- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard4/tf.sub.md +++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard4/tf.sub.md @@ -2,6 +2,9 @@ Returns x - y element-wise. +*NOTE*: `Sub` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) + ##### Args: diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard5/tf.add.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard5/tf.add.md index 738f0337d30..da82da60762 100644 --- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard5/tf.add.md +++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard5/tf.add.md @@ -2,7 +2,8 @@ Returns x + y element-wise. -*NOTE*: Add supports broadcasting. AddN does not. +*NOTE*: `Add` supports broadcasting. `AddN` does not. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) ##### Args: diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard5/tf.div.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard5/tf.div.md index 92eba7927a0..61616c0e6b2 100644 --- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard5/tf.div.md +++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard5/tf.div.md @@ -2,6 +2,9 @@ Returns x / y element-wise. +*NOTE*: `Div` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) + ##### Args: diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard5/tf.logical_and.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard5/tf.logical_and.md index dd5b563c8ba..2b5f011ccdc 100644 --- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard5/tf.logical_and.md +++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard5/tf.logical_and.md @@ -2,6 +2,9 @@ Returns the truth value of x AND y element-wise. +*NOTE*: `LogicalAnd` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) + ##### Args: diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard6/tf.maximum.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard6/tf.maximum.md index 309946f4352..aec816dcbad 100644 --- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard6/tf.maximum.md +++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard6/tf.maximum.md @@ -1,6 +1,9 @@ ### `tf.maximum(x, y, name=None)` {#maximum} -Returns the max of x and y (i.e. x > y ? x : y) element-wise, broadcasts. +Returns the max of x and y (i.e. x > y ? x : y) element-wise. + +*NOTE*: `Maximum` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) ##### Args: diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard7/tf.less.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard7/tf.less.md index 8791d0366aa..3a00afa8db5 100644 --- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard7/tf.less.md +++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard7/tf.less.md @@ -2,6 +2,9 @@ Returns the truth value of (x < y) element-wise. +*NOTE*: `Less` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) + ##### Args: diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard7/tf.logical_or.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard7/tf.logical_or.md index be18e65e92e..e04b6a15d2c 100644 --- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard7/tf.logical_or.md +++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard7/tf.logical_or.md @@ -2,6 +2,9 @@ Returns the truth value of x OR y element-wise. +*NOTE*: `LogicalOr` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) + ##### Args: diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard8/tf.equal.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard8/tf.equal.md index 998db9189ff..332a12f7255 100644 --- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard8/tf.equal.md +++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard8/tf.equal.md @@ -2,6 +2,9 @@ Returns the truth value of (x == y) element-wise. +*NOTE*: `Equal` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) + ##### Args: diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard8/tf.less_equal.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard8/tf.less_equal.md index 65d7eb50842..c8ce84b6691 100644 --- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard8/tf.less_equal.md +++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard8/tf.less_equal.md @@ -2,6 +2,9 @@ Returns the truth value of (x <= y) element-wise. +*NOTE*: `LessEqual` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) + ##### Args: diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard9/tf.nn.rnn_cell.RNNCell.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard9/tf.nn.rnn_cell.RNNCell.md index 5ecf4e515fe..ab13073fd5d 100644 --- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard9/tf.nn.rnn_cell.RNNCell.md +++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard9/tf.nn.rnn_cell.RNNCell.md @@ -1,5 +1,10 @@ Abstract object representing an RNN cell. +The definition of cell in this package differs from the definition used in the +literature. In the literature, cell refers to an object with a single scalar +output. The definition in this package refers to a horizontal array of such +units. + An RNN cell, in the most abstract setting, is anything that has a state and performs some operation that takes a matrix of inputs. This operation results in an output matrix with `self.output_size` columns. diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard9/tf.squared_difference.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard9/tf.squared_difference.md index d6bb175669c..19f25f473da 100644 --- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard9/tf.squared_difference.md +++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard9/tf.squared_difference.md @@ -2,6 +2,9 @@ Returns (x - y)(x - y) element-wise. +*NOTE*: `SquaredDifference` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) + ##### Args: diff --git a/tensorflow/g3doc/api_docs/python/math_ops.md b/tensorflow/g3doc/api_docs/python/math_ops.md index 4a9ead85023..05379613268 100644 --- a/tensorflow/g3doc/api_docs/python/math_ops.md +++ b/tensorflow/g3doc/api_docs/python/math_ops.md @@ -21,7 +21,8 @@ operators to your graph. Returns x + y element-wise. -*NOTE*: Add supports broadcasting. AddN does not. +*NOTE*: `Add` supports broadcasting. `AddN` does not. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) ##### Args: @@ -41,6 +42,9 @@ Returns x + y element-wise. Returns x - y element-wise. +*NOTE*: `Sub` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) + ##### Args: @@ -59,6 +63,9 @@ Returns x - y element-wise. Returns x * y element-wise. +*NOTE*: `Mul` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) + ##### Args: @@ -77,6 +84,9 @@ Returns x * y element-wise. Returns x / y element-wise. +*NOTE*: `Div` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) + ##### Args: @@ -164,6 +174,9 @@ as well. Returns element-wise remainder of division. +*NOTE*: `Mod` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) + ##### Args: @@ -504,7 +517,10 @@ Returns element-wise largest integer not greater than x. ### `tf.maximum(x, y, name=None)` {#maximum} -Returns the max of x and y (i.e. x > y ? x : y) element-wise, broadcasts. +Returns the max of x and y (i.e. x > y ? x : y) element-wise. + +*NOTE*: `Maximum` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) ##### Args: @@ -522,7 +538,10 @@ Returns the max of x and y (i.e. x > y ? x : y) element-wise, broadcasts. ### `tf.minimum(x, y, name=None)` {#minimum} -Returns the min of x and y (i.e. x < y ? x : y) element-wise, broadcasts. +Returns the min of x and y (i.e. x < y ? x : y) element-wise. + +*NOTE*: `Minimum` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) ##### Args: @@ -749,6 +768,9 @@ Computes the complementary error function of `x` element-wise. Returns (x - y)(x - y) element-wise. +*NOTE*: `SquaredDifference` supports broadcasting. More about broadcasting +[here](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) + ##### Args: diff --git a/tensorflow/g3doc/api_docs/python/rnn_cell.md b/tensorflow/g3doc/api_docs/python/rnn_cell.md index 94b48f5d416..5fcbd27966a 100644 --- a/tensorflow/g3doc/api_docs/python/rnn_cell.md +++ b/tensorflow/g3doc/api_docs/python/rnn_cell.md @@ -13,6 +13,11 @@ Module for constructing RNN Cells. Abstract object representing an RNN cell. +The definition of cell in this package differs from the definition used in the +literature. In the literature, cell refers to an object with a single scalar +output. The definition in this package refers to a horizontal array of such +units. + An RNN cell, in the most abstract setting, is anything that has a state and performs some operation that takes a matrix of inputs. This operation results in an output matrix with `self.output_size` columns. diff --git a/tensorflow/g3doc/api_docs/python/train.md b/tensorflow/g3doc/api_docs/python/train.md index 792fb2bcb78..1a98ead371f 100644 --- a/tensorflow/g3doc/api_docs/python/train.md +++ b/tensorflow/g3doc/api_docs/python/train.md @@ -851,7 +851,7 @@ learning_rate = tf.train.exponential_decay(starter_learning_rate, global_step, 100000, 0.96, staircase=True) # Passing global_step to minimize() will increment it at each step. learning_step = ( - tf.GradientDescentOptimizer(learning_rate) + tf.train.GradientDescentOptimizer(learning_rate) .minimize(...my loss..., global_step=global_step) ) ``` From d713ac488950f3b83ae6b16f1d123ad42a55ecdf Mon Sep 17 00:00:00 2001 From: Shanqing Cai Date: Mon, 1 Aug 2016 06:37:07 -0800 Subject: [PATCH 004/134] Add gcs_test/Dockerfile to version roll That is, cover the file with update_version.sh Also manually update the artifact URL to 0.10.0rc0 to fix the current breakage in nightly gcs smoke test: http://ci.tensorflow.org/view/Nightly/job/nightly-gcs-smoke/ Change: 128984024 --- tensorflow/tools/ci_build/update_version.sh | 7 +++++++ tensorflow/tools/gcs_test/Dockerfile | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/tensorflow/tools/ci_build/update_version.sh b/tensorflow/tools/ci_build/update_version.sh index 1d1e492ef87..dd02d02d17f 100755 --- a/tensorflow/tools/ci_build/update_version.sh +++ b/tensorflow/tools/ci_build/update_version.sh @@ -131,6 +131,13 @@ check_existence file "${TEST_SERVER_DOCKER_FILE}" sed -i -r -e "s/(.*tensorflow-)([0-9]+\.[0-9]+\.[[:alnum:]]+)(-.*\.whl)/\1${MAJOR}.${MINOR}.${PATCH}\3/g" "${TEST_SERVER_DOCKER_FILE}" +# Update tensorflow/tools/gcs_test/Dockerfile +GCS_TEST_DOCKER_FILE="${TF_SRC_DIR}/tools/gcs_test/Dockerfile" + +check_existence file "${GCS_TEST_DOCKER_FILE}" + +sed -i -r -e "s/(.*tensorflow-)([0-9]+\.[0-9]+\.[[:alnum:]]+)(-.*\.whl)/\1${MAJOR}.${MINOR}.${PATCH}\3/g" "${GCS_TEST_DOCKER_FILE}" + # Updates to be made if there are major / minor version changes MAJOR_MINOR_CHANGE=0 diff --git a/tensorflow/tools/gcs_test/Dockerfile b/tensorflow/tools/gcs_test/Dockerfile index be3ad40b157..2831a07de76 100644 --- a/tensorflow/tools/gcs_test/Dockerfile +++ b/tensorflow/tools/gcs_test/Dockerfile @@ -16,7 +16,7 @@ RUN ./install_google_cloud_sdk.bash --disable-prompts --install-dir=/var/gcloud # Install nightly TensorFlow pip RUN pip install \ - http://ci.tensorflow.org/view/Nightly/job/nightly-matrix-cpu/TF_BUILD_CONTAINER_TYPE=CPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON2,label=cpu-slave/lastSuccessfulBuild/artifact/pip_test/whl/tensorflow-0.9.0-cp27-none-linux_x86_64.whl + http://ci.tensorflow.org/view/Nightly/job/nightly-matrix-cpu/TF_BUILD_CONTAINER_TYPE=CPU,TF_BUILD_IS_OPT=OPT,TF_BUILD_IS_PIP=PIP,TF_BUILD_PYTHON_VERSION=PYTHON2,label=cpu-slave/lastSuccessfulBuild/artifact/pip_test/whl/tensorflow-0.10.0rc0-cp27-none-linux_x86_64.whl # Copy test files RUN mkdir -p /gcs-smoke/python From 52c04186145a7bed645a972eb7243d0795c67ab2 Mon Sep 17 00:00:00 2001 From: David Soergel Date: Mon, 1 Aug 2016 07:49:30 -0800 Subject: [PATCH 005/134] Fix bug re DataFrame->FeatureColumn Change: 128989209 --- .../layers/python/layers/feature_column.py | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/tensorflow/contrib/layers/python/layers/feature_column.py b/tensorflow/contrib/layers/python/layers/feature_column.py index 3e31ac02f9b..410387772a3 100644 --- a/tensorflow/contrib/layers/python/layers/feature_column.py +++ b/tensorflow/contrib/layers/python/layers/feature_column.py @@ -1337,7 +1337,7 @@ def crossed_column(columns, hash_bucket_size, combiner="sum", class DataFrameColumn(_FeatureColumn, collections.namedtuple("DataFrameColumn", - ["name", "series"])): + ["column_name", "series"])): """Represents a feature column produced from a `DataFrame`. Instances of this class are immutable. A `DataFrame` column may be dense or @@ -1345,13 +1345,17 @@ class DataFrameColumn(_FeatureColumn, batch_size. Args: - name: a name for this column + column_name: a name for this column series: a `Series` to be wrapped, which has already had its base features substituted with `PredefinedSeries`. """ - def __new__(cls, name, series): - return super(DataFrameColumn, cls).__new__(cls, name, series) + def __new__(cls, column_name, series): + return super(DataFrameColumn, cls).__new__(cls, column_name, series) + + @property + def name(self): + return self.column_name @property def config(self): @@ -1379,7 +1383,17 @@ class DataFrameColumn(_FeatureColumn, input_tensor, weight_collections=None, trainable=True): - return input_tensor + # DataFrame typically provides Tensors of shape [batch_size], + # but Estimator requires shape [batch_size, 1] + dims = input_tensor.get_shape().ndims + if dims == 0: + raise ValueError( + "Can't build input layer from tensor of shape (): {}".format( + self.column_name)) + elif dims == 1: + return array_ops.expand_dims(input_tensor, 1) + else: + return input_tensor # TODO(soergel): This mirrors RealValuedColumn for now, but should become # better abstracted with less code duplication when we add other kinds. From 48e869f0e34c548df28f97d331e8755b372f2a23 Mon Sep 17 00:00:00 2001 From: David Soergel Date: Mon, 1 Aug 2016 07:57:35 -0800 Subject: [PATCH 006/134] Add kwargs to Transform.apply for num_epochs Change: 128989804 --- .../learn/python/learn/dataframe/dataframe.py | 5 ++-- .../python/learn/dataframe/estimator_utils.py | 7 +++-- .../learn/python/learn/dataframe/series.py | 9 +++--- .../learn/dataframe/tensorflow_dataframe.py | 29 +++++-------------- .../learn/python/learn/dataframe/transform.py | 12 ++++---- .../learn/dataframe/transforms/batch.py | 4 +-- .../dataframe/transforms/binary_transforms.py | 6 ++-- .../dataframe/transforms/boolean_mask.py | 5 ++-- .../learn/dataframe/transforms/csv_parser.py | 2 +- .../learn/dataframe/transforms/densify.py | 5 ++-- .../learn/dataframe/transforms/difference.py | 4 +-- .../dataframe/transforms/example_parser.py | 2 +- .../dataframe/transforms/in_memory_source.py | 2 +- .../dataframe/transforms/reader_source.py | 24 ++++----------- .../learn/dataframe/transforms/sparsify.py | 5 ++-- .../python/learn/dataframe/transforms/sum.py | 4 +-- .../dataframe/transforms/unary_transforms.py | 4 +-- .../dataframe/tensorflow_dataframe_test.py | 3 +- 18 files changed, 57 insertions(+), 75 deletions(-) diff --git a/tensorflow/contrib/learn/python/learn/dataframe/dataframe.py b/tensorflow/contrib/learn/python/learn/dataframe/dataframe.py index 31093b9937a..6e03f086425 100644 --- a/tensorflow/contrib/learn/python/learn/dataframe/dataframe.py +++ b/tensorflow/contrib/learn/python/learn/dataframe/dataframe.py @@ -117,10 +117,11 @@ class DataFrame(object): value = [value] self.assign(**dict(zip(key, value))) - def build(self): + def build(self, **kwargs): # We do not allow passing a cache here, because that would encourage # working around the rule that DataFrames cannot be expected to be # synced with each other (e.g., they shuffle independently). cache = {} - tensors = {name: c.build(cache) for name, c in self._columns.items()} + tensors = {name: c.build(cache, **kwargs) + for name, c in self._columns.items()} return tensors diff --git a/tensorflow/contrib/learn/python/learn/dataframe/estimator_utils.py b/tensorflow/contrib/learn/python/learn/dataframe/estimator_utils.py index bff0c4e4af0..313ae41cfe8 100644 --- a/tensorflow/contrib/learn/python/learn/dataframe/estimator_utils.py +++ b/tensorflow/contrib/learn/python/learn/dataframe/estimator_utils.py @@ -91,7 +91,8 @@ def _build_alternate_universe( def to_feature_columns_and_input_fn(dataframe, base_input_keys_with_defaults, feature_keys, - target_keys=None): + target_keys=None, + **kwargs): """Build a list of FeatureColumns and an input_fn for use with Estimator. Args: @@ -103,6 +104,7 @@ def to_feature_columns_and_input_fn(dataframe, These may include base features and/or derived features. target_keys: the names of columns to be used as targets. None is acceptable for unsupervised learning. + **kwargs: Additional keyword arguments, unused here. Returns: A tuple of two elements: @@ -155,10 +157,11 @@ def to_feature_columns_and_input_fn(dataframe, # Build an input_fn suitable for use with Estimator. def input_fn(): + """An input_fn() for feeding the given set of DataFrameColumns.""" # It's important to build all the tensors together in one DataFrame. # If we did df.select() for both key sets and then build those, the two # resulting DataFrames would be shuffled independently. - tensors = limited_dataframe.build() + tensors = limited_dataframe.build(**kwargs) base_input_features = {key: tensors[key] for key in base_input_keys} targets = {key: tensors[key] for key in target_keys} diff --git a/tensorflow/contrib/learn/python/learn/dataframe/series.py b/tensorflow/contrib/learn/python/learn/dataframe/series.py index 12daa7d7cb8..5893db3aad2 100644 --- a/tensorflow/contrib/learn/python/learn/dataframe/series.py +++ b/tensorflow/contrib/learn/python/learn/dataframe/series.py @@ -98,7 +98,7 @@ class Series(object): return transform_cls return register - def build(self, cache): + def build(self, cache, **kwargs): """Returns a Tensor.""" raise NotImplementedError() @@ -122,7 +122,7 @@ class PredefinedSeries(Series): def required_base_features(self): return {self.name: self.feature_spec} - def build(self, cache): + def build(self, cache, **kwargs): try: return cache[self.name] except KeyError: @@ -171,10 +171,11 @@ class TransformedSeries(Series): result.update(s.required_base_features) return result - def build(self, cache=None): + def build(self, cache=None, **kwargs): if cache is None: cache = {} - all_outputs = self._transform.build_transitive(self._input_series, cache) + all_outputs = self._transform.build_transitive( + self._input_series, cache, **kwargs) return getattr(all_outputs, self._output_name) def __repr__(self): diff --git a/tensorflow/contrib/learn/python/learn/dataframe/tensorflow_dataframe.py b/tensorflow/contrib/learn/python/learn/dataframe/tensorflow_dataframe.py index 45df3ac16d5..4b6091dc16c 100644 --- a/tensorflow/contrib/learn/python/learn/dataframe/tensorflow_dataframe.py +++ b/tensorflow/contrib/learn/python/learn/dataframe/tensorflow_dataframe.py @@ -83,7 +83,8 @@ class TensorFlowDataFrame(df.DataFrame): graph=None, session=None, start_queues=True, - initialize_variables=True): + initialize_variables=True, + **kwargs): """Builds and runs the columns of the `DataFrame` and yields batches. This is a generator that yields a dictionary mapping column names to @@ -97,6 +98,7 @@ class TensorFlowDataFrame(df.DataFrame): start_queues: if true, queues will be started before running and halted after producting `n` batches. initialize_variables: if true, variables will be initialized. + **kwargs: Additional keyword arguments, unused here. Yields: A dictionary, mapping column names to the values resulting from running @@ -107,7 +109,7 @@ class TensorFlowDataFrame(df.DataFrame): with graph.as_default(): if session is None: session = sess.Session() - self_built = self.build() + self_built = self.build(**kwargs) keys = list(self_built.keys()) cols = list(self_built.values()) if initialize_variables: @@ -208,7 +210,7 @@ class TensorFlowDataFrame(df.DataFrame): @classmethod def _from_csv_base(cls, filepatterns, get_default_values, has_header, - column_names, num_epochs, num_threads, enqueue_size, + column_names, num_threads, enqueue_size, batch_size, queue_capacity, min_after_dequeue, shuffle, seed): """Create a `DataFrame` from CSV files. @@ -223,9 +225,6 @@ class TensorFlowDataFrame(df.DataFrame): each column, given the column names. has_header: whether or not the CSV files have headers. column_names: a list of names for the columns in the CSV files. - num_epochs: the number of times that the reader should loop through all - the file names. If set to `None`, then the reader will continue - indefinitely. num_threads: the number of readers that will work in parallel. enqueue_size: block size for each read operation. batch_size: desired batch size. @@ -265,7 +264,6 @@ class TensorFlowDataFrame(df.DataFrame): reader_kwargs=reader_kwargs, enqueue_size=enqueue_size, batch_size=batch_size, - num_epochs=num_epochs, queue_capacity=queue_capacity, shuffle=shuffle, min_after_dequeue=min_after_dequeue, @@ -287,7 +285,6 @@ class TensorFlowDataFrame(df.DataFrame): default_values, has_header=True, column_names=None, - num_epochs=None, num_threads=1, enqueue_size=None, batch_size=32, @@ -306,9 +303,6 @@ class TensorFlowDataFrame(df.DataFrame): default_values: a list of default values for each column. has_header: whether or not the CSV files have headers. column_names: a list of names for the columns in the CSV files. - num_epochs: the number of times that the reader should loop through all - the file names. If set to `None`, then the reader will continue - indefinitely. num_threads: the number of readers that will work in parallel. enqueue_size: block size for each read operation. batch_size: desired batch size. @@ -332,7 +326,7 @@ class TensorFlowDataFrame(df.DataFrame): return default_values return cls._from_csv_base(filepatterns, get_default_values, has_header, - column_names, num_epochs, num_threads, + column_names, num_threads, enqueue_size, batch_size, queue_capacity, min_after_dequeue, shuffle, seed) @@ -342,7 +336,6 @@ class TensorFlowDataFrame(df.DataFrame): feature_spec, has_header=True, column_names=None, - num_epochs=None, num_threads=1, enqueue_size=None, batch_size=32, @@ -362,9 +355,6 @@ class TensorFlowDataFrame(df.DataFrame): `VarLenFeature`. has_header: whether or not the CSV files have headers. column_names: a list of names for the columns in the CSV files. - num_epochs: the number of times that the reader should loop through all - the file names. If set to `None`, then the reader will continue - indefinitely. num_threads: the number of readers that will work in parallel. enqueue_size: block size for each read operation. batch_size: desired batch size. @@ -387,7 +377,7 @@ class TensorFlowDataFrame(df.DataFrame): return [_get_default_value(feature_spec[name]) for name in column_names] dataframe = cls._from_csv_base(filepatterns, get_default_values, has_header, - column_names, num_epochs, num_threads, + column_names, num_threads, enqueue_size, batch_size, queue_capacity, min_after_dequeue, shuffle, seed) @@ -405,7 +395,6 @@ class TensorFlowDataFrame(df.DataFrame): filepatterns, features, reader_cls=io_ops.TFRecordReader, - num_epochs=None, num_threads=1, enqueue_size=None, batch_size=32, @@ -421,9 +410,6 @@ class TensorFlowDataFrame(df.DataFrame): `FixedLenFeature`. reader_cls: a subclass of `tensorflow.ReaderBase` that will be used to read the `Example`s. - num_epochs: the number of times that the reader should loop through all - the file names. If set to `None`, then the reader will continue - indefinitely. num_threads: the number of readers that will work in parallel. enqueue_size: block size for each read operation. batch_size: desired batch size. @@ -454,7 +440,6 @@ class TensorFlowDataFrame(df.DataFrame): filenames, enqueue_size=enqueue_size, batch_size=batch_size, - num_epochs=num_epochs, queue_capacity=queue_capacity, shuffle=shuffle, min_after_dequeue=min_after_dequeue, diff --git a/tensorflow/contrib/learn/python/learn/dataframe/transform.py b/tensorflow/contrib/learn/python/learn/dataframe/transform.py index 745d556f929..bbb97d2f290 100644 --- a/tensorflow/contrib/learn/python/learn/dataframe/transform.py +++ b/tensorflow/contrib/learn/python/learn/dataframe/transform.py @@ -223,13 +223,14 @@ class Transform(object): # pylint: disable=not-callable return self.return_type(*output_series) - def build_transitive(self, input_series, cache=None): + def build_transitive(self, input_series, cache=None, **kwargs): """Apply this `Transform` to the provided `Series`, producing 'Tensor's. Args: input_series: None, a `Series`, or a list of input `Series`, acting as positional arguments. cache: a dict from Series reprs to Tensors. + **kwargs: Additional keyword arguments, unused here. Returns: A namedtuple of the output Tensors. @@ -244,7 +245,7 @@ class Transform(object): if len(input_series) != self.input_valency: raise ValueError("Expected %s input Series but received %s." % (self.input_valency, len(input_series))) - input_tensors = [series.build(cache) for series in input_series] + input_tensors = [series.build(cache, **kwargs) for series in input_series] # Note we cache each output individually, not just the entire output # tuple. This allows using the graph as the cache, since it can sensibly @@ -254,7 +255,7 @@ class Transform(object): output_tensors = [cache.get(output_repr) for output_repr in output_reprs] if None in output_tensors: - result = self._apply_transform(input_tensors) + result = self._apply_transform(input_tensors, **kwargs) for output_name, output_repr in zip(self.output_names, output_reprs): cache[output_repr] = getattr(result, output_name) else: @@ -264,12 +265,13 @@ class Transform(object): return result @abstractmethod - def _apply_transform(self, input_tensors): + def _apply_transform(self, input_tensors, **kwargs): """Applies the transformation to the `transform_input`. Args: - input_tensors: a list of Tensors representing the input to + input_tensors: a list of Tensors representing the input to the Transform. + **kwargs: Additional keyword arguments, unused here. Returns: A namedtuple of Tensors representing the transformed output. diff --git a/tensorflow/contrib/learn/python/learn/dataframe/transforms/batch.py b/tensorflow/contrib/learn/python/learn/dataframe/transforms/batch.py index 352a028ee33..cf1585634ca 100644 --- a/tensorflow/contrib/learn/python/learn/dataframe/transforms/batch.py +++ b/tensorflow/contrib/learn/python/learn/dataframe/transforms/batch.py @@ -72,7 +72,7 @@ class Batch(AbstractBatchTransform): def name(self): return "Batch" - def _apply_transform(self, transform_input): + def _apply_transform(self, transform_input, **kwargs): batched = input_ops.batch(transform_input, batch_size=self.batch_size, num_threads=self.num_threads, @@ -121,7 +121,7 @@ class ShuffleBatch(AbstractBatchTransform): def seed(self): return self._seed - def _apply_transform(self, transform_input): + def _apply_transform(self, transform_input, **kwargs): batched = input_ops.shuffle_batch(transform_input, batch_size=self.batch_size, capacity=self.queue_capacity, diff --git a/tensorflow/contrib/learn/python/learn/dataframe/transforms/binary_transforms.py b/tensorflow/contrib/learn/python/learn/dataframe/transforms/binary_transforms.py index 7d46fb6d05e..78a21250c9c 100644 --- a/tensorflow/contrib/learn/python/learn/dataframe/transforms/binary_transforms.py +++ b/tensorflow/contrib/learn/python/learn/dataframe/transforms/binary_transforms.py @@ -1,4 +1,4 @@ -# Copyright 2016 Google Inc. All Rights Reserved. +# Copyright 2016 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. @@ -53,7 +53,7 @@ class SeriesBinaryTransform(transform.Transform): def _output_names(self): return "output", - def _apply_transform(self, input_tensors): + def _apply_transform(self, input_tensors, **kwargs): # TODO(jamieas): consider supporting sparse inputs. if isinstance(input_tensors[0], ops.SparseTensor) or isinstance( input_tensors[1], ops.SparseTensor): @@ -87,7 +87,7 @@ class ScalarBinaryTransform(transform.Transform): def _output_names(self): return "output", - def _apply_transform(self, input_tensors): + def _apply_transform(self, input_tensors, **kwargs): input_tensor = input_tensors[0] if isinstance(input_tensor, ops.SparseTensor): result = ops.SparseTensor(input_tensor.indices, diff --git a/tensorflow/contrib/learn/python/learn/dataframe/transforms/boolean_mask.py b/tensorflow/contrib/learn/python/learn/dataframe/transforms/boolean_mask.py index f572cf137f7..758de866e21 100644 --- a/tensorflow/contrib/learn/python/learn/dataframe/transforms/boolean_mask.py +++ b/tensorflow/contrib/learn/python/learn/dataframe/transforms/boolean_mask.py @@ -77,12 +77,13 @@ class BooleanMask(transform.Transform): def _output_names(self): return "output", - def _apply_transform(self, input_tensors): + def _apply_transform(self, input_tensors, **kwargs): """Applies the transformation to the `transform_input`. Args: - input_tensors: a list of Tensors representing the input to + input_tensors: a list of Tensors representing the input to the Transform. + **kwargs: Additional keyword arguments, unused here. Returns: A namedtuple of Tensors representing the transformed output. diff --git a/tensorflow/contrib/learn/python/learn/dataframe/transforms/csv_parser.py b/tensorflow/contrib/learn/python/learn/dataframe/transforms/csv_parser.py index caa83f5a966..d78b5652d6e 100644 --- a/tensorflow/contrib/learn/python/learn/dataframe/transforms/csv_parser.py +++ b/tensorflow/contrib/learn/python/learn/dataframe/transforms/csv_parser.py @@ -58,7 +58,7 @@ class CSVParser(transform.Transform): def default_values(self): return self._default_values - def _apply_transform(self, input_tensors): + def _apply_transform(self, input_tensors, **kwargs): default_consts = [constant_op.constant(d, shape=[1]) for d in self._default_values] parsed_values = parsing_ops.decode_csv(input_tensors[0], diff --git a/tensorflow/contrib/learn/python/learn/dataframe/transforms/densify.py b/tensorflow/contrib/learn/python/learn/dataframe/transforms/densify.py index 2f389153178..0f0c1a08911 100644 --- a/tensorflow/contrib/learn/python/learn/dataframe/transforms/densify.py +++ b/tensorflow/contrib/learn/python/learn/dataframe/transforms/densify.py @@ -47,12 +47,13 @@ class Densify(transform.Transform): def _output_names(self): return "output", - def _apply_transform(self, input_tensors): + def _apply_transform(self, input_tensors, **kwargs): """Applies the transformation to the `transform_input`. Args: - input_tensors: a list of Tensors representing the input to + input_tensors: a list of Tensors representing the input to the Transform. + **kwargs: Additional keyword arguments, unused here. Returns: A namedtuple of Tensors representing the transformed output. diff --git a/tensorflow/contrib/learn/python/learn/dataframe/transforms/difference.py b/tensorflow/contrib/learn/python/learn/dataframe/transforms/difference.py index d4e6c10094b..b585fceeb63 100644 --- a/tensorflow/contrib/learn/python/learn/dataframe/transforms/difference.py +++ b/tensorflow/contrib/learn/python/learn/dataframe/transforms/difference.py @@ -1,4 +1,4 @@ -# Copyright 2016 Google Inc. All Rights Reserved. +# Copyright 2016 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. @@ -50,7 +50,7 @@ class Difference(transform.Transform): def _output_names(self): return "output", - def _apply_transform(self, input_tensors): + def _apply_transform(self, input_tensors, **kwargs): pair_sparsity = (isinstance(input_tensors[0], ops.SparseTensor), isinstance(input_tensors[1], ops.SparseTensor)) diff --git a/tensorflow/contrib/learn/python/learn/dataframe/transforms/example_parser.py b/tensorflow/contrib/learn/python/learn/dataframe/transforms/example_parser.py index e22ef740ed9..c2c5e0cbed5 100644 --- a/tensorflow/contrib/learn/python/learn/dataframe/transforms/example_parser.py +++ b/tensorflow/contrib/learn/python/learn/dataframe/transforms/example_parser.py @@ -61,7 +61,7 @@ class ExampleParser(transform.Transform): def feature_definitions(self): return self._ordered_features - def _apply_transform(self, input_tensors): + def _apply_transform(self, input_tensors, **kwargs): parsed_values = parsing_ops.parse_example(input_tensors[0], features=self._ordered_features) # pylint: disable=not-callable diff --git a/tensorflow/contrib/learn/python/learn/dataframe/transforms/in_memory_source.py b/tensorflow/contrib/learn/python/learn/dataframe/transforms/in_memory_source.py index 97453c30325..d96d53468a5 100644 --- a/tensorflow/contrib/learn/python/learn/dataframe/transforms/in_memory_source.py +++ b/tensorflow/contrib/learn/python/learn/dataframe/transforms/in_memory_source.py @@ -89,7 +89,7 @@ class BaseInMemorySource(transform.Transform): def input_valency(self): return 0 - def _apply_transform(self, transform_input): + def _apply_transform(self, transform_input, **kwargs): queue = feeding_functions.enqueue_data(self.data, self.queue_capacity, self.shuffle, diff --git a/tensorflow/contrib/learn/python/learn/dataframe/transforms/reader_source.py b/tensorflow/contrib/learn/python/learn/dataframe/transforms/reader_source.py index 23556c40657..ddb2d321d1c 100644 --- a/tensorflow/contrib/learn/python/learn/dataframe/transforms/reader_source.py +++ b/tensorflow/contrib/learn/python/learn/dataframe/transforms/reader_source.py @@ -32,7 +32,6 @@ class ReaderSource(transform.Transform): reader_kwargs=None, enqueue_size=None, batch_size=1, - num_epochs=None, queue_capacity=None, shuffle=False, min_after_dequeue=None, @@ -49,9 +48,6 @@ class ReaderSource(transform.Transform): is constructed. enqueue_size: block size for each read operation. batch_size: The desired batch size of output. Defaults to 1. - num_epochs: the number of times that the reader should loop through all - the file names. If set to `None`, then the reader will continue - indefinitely. queue_capacity: Capacity of the queue. Defaults to 10 * `batch_size`. shuffle: Whether records will be shuffled before returning. Defaults to false. @@ -73,7 +69,6 @@ class ReaderSource(transform.Transform): self._batch_size = batch_size self._queue_capacity = (batch_size * 10 if queue_capacity is None else queue_capacity) - self._num_epochs = num_epochs self._shuffle = shuffle self._min_after_dequeue = int(self.queue_capacity / 4 if min_after_dequeue is None else min_after_dequeue) @@ -100,10 +95,6 @@ class ReaderSource(transform.Transform): def batch_size(self): return self._batch_size - @transform.parameter - def num_epochs(self): - return self._num_epochs - @transform.parameter def queue_capacity(self): return self._queue_capacity @@ -136,11 +127,12 @@ class ReaderSource(transform.Transform): def _output_names(self): return ("index", "value") - def _apply_transform(self, transform_input): - filename_queue = input_ops.string_input_producer(self.work_units, - num_epochs=self.num_epochs, - shuffle=self.shuffle, - seed=self.seed) + def _apply_transform(self, transform_input, **kwargs): + filename_queue = input_ops.string_input_producer( + self.work_units, + num_epochs=kwargs.get("num_epochs"), + shuffle=self.shuffle, + seed=self.seed) reader_ops = [] for _ in range(self.num_threads): reader = self._reader_cls(**self._reader_kwargs) @@ -174,7 +166,6 @@ def TextFileSource(file_names, reader_kwargs=None, enqueue_size=1, batch_size=1, - num_epochs=None, queue_capacity=None, shuffle=False, min_after_dequeue=None, @@ -185,7 +176,6 @@ def TextFileSource(file_names, reader_kwargs=reader_kwargs, enqueue_size=enqueue_size, batch_size=batch_size, - num_epochs=num_epochs, queue_capacity=queue_capacity, shuffle=shuffle, min_after_dequeue=min_after_dequeue, @@ -197,7 +187,6 @@ def TFRecordSource(file_names, reader_kwargs=None, enqueue_size=1, batch_size=1, - num_epochs=None, queue_capacity=None, shuffle=False, min_after_dequeue=None, @@ -208,7 +197,6 @@ def TFRecordSource(file_names, reader_kwargs=reader_kwargs, enqueue_size=enqueue_size, batch_size=batch_size, - num_epochs=num_epochs, queue_capacity=queue_capacity, shuffle=shuffle, min_after_dequeue=min_after_dequeue, diff --git a/tensorflow/contrib/learn/python/learn/dataframe/transforms/sparsify.py b/tensorflow/contrib/learn/python/learn/dataframe/transforms/sparsify.py index 552012ea330..f3447c5d940 100644 --- a/tensorflow/contrib/learn/python/learn/dataframe/transforms/sparsify.py +++ b/tensorflow/contrib/learn/python/learn/dataframe/transforms/sparsify.py @@ -52,12 +52,13 @@ class Sparsify(transform.Transform): def _output_names(self): return "output", - def _apply_transform(self, input_tensors): + def _apply_transform(self, input_tensors, **kwargs): """Applies the transformation to the `transform_input`. Args: - input_tensors: a list of Tensors representing the input to + input_tensors: a list of Tensors representing the input to the Transform. + **kwargs: Additional keyword arguments, unused here. Returns: A namedtuple of Tensors representing the transformed output. diff --git a/tensorflow/contrib/learn/python/learn/dataframe/transforms/sum.py b/tensorflow/contrib/learn/python/learn/dataframe/transforms/sum.py index 6b04166e09c..878b08f4b0a 100644 --- a/tensorflow/contrib/learn/python/learn/dataframe/transforms/sum.py +++ b/tensorflow/contrib/learn/python/learn/dataframe/transforms/sum.py @@ -1,4 +1,4 @@ -# Copyright 2016 Google Inc. All Rights Reserved. +# Copyright 2016 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. @@ -44,7 +44,7 @@ class Sum(transform.Transform): def _output_names(self): return "output", - def _apply_transform(self, input_tensors): + def _apply_transform(self, input_tensors, **kwargs): pair_sparsity = (isinstance(input_tensors[0], ops.SparseTensor), isinstance(input_tensors[1], ops.SparseTensor)) diff --git a/tensorflow/contrib/learn/python/learn/dataframe/transforms/unary_transforms.py b/tensorflow/contrib/learn/python/learn/dataframe/transforms/unary_transforms.py index 3fd8c2a6a90..058ce1ed248 100644 --- a/tensorflow/contrib/learn/python/learn/dataframe/transforms/unary_transforms.py +++ b/tensorflow/contrib/learn/python/learn/dataframe/transforms/unary_transforms.py @@ -1,4 +1,4 @@ -# Copyright 2016 Google Inc. All Rights Reserved. +# Copyright 2016 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. @@ -78,7 +78,7 @@ def register_unary_op(registered_name, operation): def _output_names(self): return "output" - def _apply_transform(self, input_tensors): + def _apply_transform(self, input_tensors, **kwargs): input_tensor = input_tensors[0] if isinstance(input_tensor, ops.SparseTensor): result = ops.SparseTensor(input_tensor.indices, diff --git a/tensorflow/contrib/learn/python/learn/tests/dataframe/tensorflow_dataframe_test.py b/tensorflow/contrib/learn/python/learn/tests/dataframe/tensorflow_dataframe_test.py index 14e283cb791..7e233f33849 100644 --- a/tensorflow/contrib/learn/python/learn/tests/dataframe/tensorflow_dataframe_test.py +++ b/tensorflow/contrib/learn/python/learn/tests/dataframe/tensorflow_dataframe_test.py @@ -208,10 +208,9 @@ class TensorFlowDataFrameTestCase(tf.test.TestCase): tensorflow_df = df.TensorFlowDataFrame.from_csv( [data_path], batch_size=batch_size, - num_epochs=num_epochs, shuffle=False, default_values=default_values) - actual_num_batches = len(list(tensorflow_df.run())) + actual_num_batches = len(list(tensorflow_df.run(num_epochs=num_epochs))) self.assertEqual(expected_num_batches, actual_num_batches) def testFromCSVWithFeatureSpec(self): From c0944a38a40956466f3e9b3a297c9994f7a2b7e6 Mon Sep 17 00:00:00 2001 From: "A. Unique TensorFlower" Date: Mon, 1 Aug 2016 08:08:26 -0800 Subject: [PATCH 007/134] Add an op for singular value decomposition (SVD) of a dense matrix or batches of dense matrices. This calls Eigen::JacobiSVD which is known to be rather slow. This change is primarily intended to get the TensorFlow interfaces and functionality in place. We intend to swap out the "backend" with a higher performance algorithm implementation in the future. This CL also contains a small refactoring of the LinearAlgebraOp base class: 1. I moved the initial processing of inputs and outputs into separate helper functions so Compute() is not so long. 2. The derived classes are now allowed to return fewer output matrix shapes (n) than the number of op outputs (m) in which case empty (shape[0]) tensors are returned for the last m-n outputs. Fixed a few Python linter errors that were blocking presubmit. Change: 128990912 --- tensorflow/core/kernels/BUILD | 1 + tensorflow/core/kernels/linalg_ops_common.cc | 146 +++++++++-------- tensorflow/core/kernels/linalg_ops_common.h | 36 +++-- tensorflow/core/kernels/svd_op.cc | 105 ++++++++++++ tensorflow/core/ops/linalg_ops.cc | 106 ++++++++++-- tensorflow/python/kernel_tests/BUILD | 1 + tensorflow/python/kernel_tests/svd_op_test.py | 112 +++++++++++++ tensorflow/python/ops/linalg_grad.py | 4 + tensorflow/python/ops/linalg_ops.py | 151 ++++++++++++++++++ tensorflow/python/ops/math_ops.py | 143 +++++++++-------- third_party/eigen3/BUILD | 1 + third_party/eigen3/Eigen/SVD | 38 +---- 12 files changed, 651 insertions(+), 193 deletions(-) create mode 100644 tensorflow/core/kernels/svd_op.cc create mode 100644 tensorflow/python/kernel_tests/svd_op_test.py diff --git a/tensorflow/core/kernels/BUILD b/tensorflow/core/kernels/BUILD index a078488dd18..f0cb90053e4 100644 --- a/tensorflow/core/kernels/BUILD +++ b/tensorflow/core/kernels/BUILD @@ -1023,6 +1023,7 @@ tf_kernel_libraries( "matrix_solve_ls_op", "matrix_solve_op", "matrix_triangular_solve_op", + "svd_op", ], deps = [ ":linalg_ops_common", diff --git a/tensorflow/core/kernels/linalg_ops_common.cc b/tensorflow/core/kernels/linalg_ops_common.cc index 9fbb6db9cf0..575c7e2e7c2 100644 --- a/tensorflow/core/kernels/linalg_ops_common.cc +++ b/tensorflow/core/kernels/linalg_ops_common.cc @@ -90,19 +90,35 @@ void LinearAlgebraOp::Compute( TensorInputs inputs; TensorShapes input_matrix_shapes; TensorShape batch_shape; + AnalyzeInputs(context, &inputs, &input_matrix_shapes, &batch_shape); + + TensorShapes output_matrix_shapes; + TensorOutputs outputs; + PrepareOutputs(context, input_matrix_shapes, batch_shape, &outputs, + &output_matrix_shapes); + + // Process the individual matrix problems in parallel using a threadpool. + auto shard = [this, &inputs, &input_matrix_shapes, &outputs, + &output_matrix_shapes, context](int64 begin, int64 end) { + for (int64 i = begin; i < end; ++i) { + ComputeTensorSlice(context, i, inputs, input_matrix_shapes, outputs, + output_matrix_shapes); + } + }; + auto worker_threads = *(context->device()->tensorflow_cpu_worker_threads()); + Shard(worker_threads.num_threads, worker_threads.workers, + batch_shape.num_elements(), GetCostPerUnit(input_matrix_shapes), shard); +} + +template +void LinearAlgebraOp::AnalyzeInputs( + OpKernelContext* context, TensorInputs* inputs, + TensorShapes* input_matrix_shapes, TensorShape* batch_shape) { int input_rank = -1; - int num_batch_matrices = 1; for (int i = 0; i < NumMatrixInputs(context); ++i) { const Tensor& in = context->input(i); if (i == 0) { - // If the tensor rank is greater than 2, we consider the inner-most - // dimensions as matrices, and loop over all the other outer ("batch") - // dimensions to compute the results. input_rank = in.dims(); - for (int dim = 0; dim < input_rank - 2; ++dim) { - num_batch_matrices *= in.dim_size(dim); - batch_shape.AddDim(in.dim_size(dim)); - } if (SupportsBatchOperation) { OP_REQUIRES( context, input_rank >= 2, @@ -114,6 +130,13 @@ void LinearAlgebraOp::Compute( errors::InvalidArgument("Input tensor ", i, " must have rank == 2, got", input_rank)); } + + // If the tensor rank is greater than 2, we consider the inner-most + // dimensions as matrices, and loop over all the other outer ("batch") + // dimensions to compute the results. + for (int dim = 0; dim < input_rank - 2; ++dim) { + batch_shape->AddDim(in.dim_size(dim)); + } } else { // Make sure that all inputs have the same rank and outer dimensions. OP_REQUIRES(context, input_rank == in.dims(), @@ -121,7 +144,7 @@ void LinearAlgebraOp::Compute( "All input tensors must have the same rank.")); for (int dim = 0; dim < input_rank - 2; ++dim) { OP_REQUIRES( - context, in.dim_size(dim) == batch_shape.dim_size(dim), + context, in.dim_size(dim) == batch_shape->dim_size(dim), errors::InvalidArgument( "All input tensors must have the same outer dimensions.")); } @@ -131,64 +154,59 @@ void LinearAlgebraOp::Compute( const int col_dimension = input_rank - 1; const int64 num_rows = in.dim_size(row_dimension); const int64 num_cols = in.dim_size(col_dimension); - input_matrix_shapes.push_back(TensorShape({num_rows, num_cols})); - inputs.push_back(in); + // TODO(rmlarsen): Use emplace_back when it is added to InlinedVector. Same + // in several places below. + input_matrix_shapes->push_back(TensorShape({num_rows, num_cols})); + inputs->push_back(in); } // Have the derived class validate that the inputs are as expected. - ValidateInputMatrixShapes(context, input_matrix_shapes); - - // Get shape for each of the matrix outputs. - const TensorShapes output_matrix_shapes = - GetOutputMatrixShapes(input_matrix_shapes); - // Make sure the number of outputs is what the derived class expects. - OP_REQUIRES( - context, output_matrix_shapes.size() == context->num_outputs(), - errors::Internal( - "Derived class expected (%d) output matrices for op, got (%d).", - output_matrix_shapes.size(), context->num_outputs())); - - // Allocate outputs. - TensorShapes output_shapes; - TensorOutputs outputs; - for (int i = 0; i < context->num_outputs(); ++i) { - OP_REQUIRES(context, output_matrix_shapes[i].dims() <= 2, - errors::InvalidArgument( - "Rank of matrix output no. %d must be 0, 1 or 2, got %d.", - i, output_matrix_shapes[i].dims())); - - // The final output has the shape of the outer batch dimensions concatenated - // with the output_matrix_shape (if the output is not scalar). - TensorShape output_shape; - if (input_rank == 2) { - output_shape = output_matrix_shapes[i]; - } else { - output_shape = batch_shape; - // Add the inner dimensions that depend on the operation implemented by - // the derived class. - for (int dim = 0; dim < output_matrix_shapes[i].dims(); ++dim) { - output_shape.AddDim(output_matrix_shapes[i].dim_size(dim)); - } - } - output_shapes.push_back(output_shape); - Tensor* out = nullptr; - OP_REQUIRES_OK(context, context->allocate_output(i, output_shape, &out)); - outputs.push_back(out); - } - - auto shard = [this, &inputs, &input_matrix_shapes, &outputs, - &output_matrix_shapes, context](int64 begin, int64 end) { - for (int64 i = begin; i < end; ++i) { - ComputeTensorSlice(context, i, inputs, input_matrix_shapes, outputs, - output_matrix_shapes); - } - }; - auto worker_threads = *(context->device()->tensorflow_cpu_worker_threads()); - Shard(worker_threads.num_threads, worker_threads.workers, num_batch_matrices, - GetCostPerUnit(input_matrix_shapes), shard); + ValidateInputMatrixShapes(context, *input_matrix_shapes); } -template -void LinearAlgebraOp::ComputeTensorSlice( +template +void LinearAlgebraOp::PrepareOutputs( + OpKernelContext* context, const TensorShapes& input_matrix_shapes, + const TensorShape& batch_shape, TensorOutputs* outputs, + TensorShapes* output_matrix_shapes) { + // Get shape for each of the matrix outputs produced by the derived class. + *output_matrix_shapes = GetOutputMatrixShapes(input_matrix_shapes); + const int num_outputs = output_matrix_shapes->size(); + + // Make sure the number of op outputs is what the derived class expects. + OP_REQUIRES( + context, num_outputs <= context->num_outputs(), + errors::Internal( + "Derived class expected more outputs (%d) that the op has (%d).", + num_outputs, context->num_outputs())); + + // Allocate outputs. + for (int i = 0; i < context->num_outputs(); ++i) { + TensorShape output_tensor_shape({0}); + if (i < num_outputs) { + // This output is used, set up output shape and allocate it. + const TensorShape& output_matrix_shape = output_matrix_shapes->at(i); + OP_REQUIRES(context, output_matrix_shape.dims() <= 2, + errors::InvalidArgument( + "Rank of matrix output no. %d must be 0, 1 or 2, got %d.", + i, output_matrix_shape.dims())); + + // The final output has the shape of the outer batch dimensions + // concatenated with the output_matrix_shape (if the output is not + // scalar). + output_tensor_shape = batch_shape; + for (int dim = 0; dim < output_matrix_shape.dims(); ++dim) { + output_tensor_shape.AddDim(output_matrix_shape.dim_size(dim)); + } + } + Tensor* out = nullptr; + OP_REQUIRES_OK(context, + context->allocate_output(i, output_tensor_shape, &out)); + outputs->push_back(out); + } +} + +template +void LinearAlgebraOp::ComputeTensorSlice( OpKernelContext* context, int64 matrix_index, const TensorInputs& inputs, const TensorShapes& input_matrix_shapes, const TensorOutputs& outputs, const TensorShapes& output_matrix_shapes) { @@ -204,7 +222,7 @@ void LinearAlgebraOp::ComputeTensorSlice( } MatrixMaps matrix_outputs; - for (int i = 0; i < outputs.size(); ++i) { + for (int i = 0; i < output_matrix_shapes.size(); ++i) { // The output matrix shape may not be a matrix. int num_output_rows = output_matrix_shapes[i].dims() >= 1 ? output_matrix_shapes[i].dim_size(0) diff --git a/tensorflow/core/kernels/linalg_ops_common.h b/tensorflow/core/kernels/linalg_ops_common.h index dda83ad2d12..3be9853c6cf 100644 --- a/tensorflow/core/kernels/linalg_ops_common.h +++ b/tensorflow/core/kernels/linalg_ops_common.h @@ -43,7 +43,7 @@ template class LinearAlgebraOp : public OpKernel { public: explicit LinearAlgebraOp(OpKernelConstruction* context) : OpKernel(context) {} - ~LinearAlgebraOp() override {} + void Compute(OpKernelContext* context) override; protected: @@ -80,19 +80,26 @@ class LinearAlgebraOp : public OpKernel { const TensorShapes& input_matrix_shapes); // Returns the output shapes of each individual matrix operation. Output - // matrices shapes must be rank 0, 1, or 2. Scalar outputs are rank 0. - // For many ops the output dimensions are the same as the input dimensions, + // matrices shapes must be rank 0, 1, or 2. Scalar outputs are rank 0. + // + // The derived class may return a number of shapes (N) less than + // context->num_outputs() (M) to indicate that a only leading subset of + // the outputs will be populated. In this case, a dummy scalar tensor with + // value zero will be return for the last M-N outputs. + // + // For many ops, the output dimensions are the same as the input dimensions, // so we provide that as a default implementation for convenience. virtual TensorShapes GetOutputMatrixShapes( const TensorShapes& input_matrix_shapes) const { return input_matrix_shapes; } - // Returns the cost per matrix operation. Cost per unit is assumed to be - // roughly 1ns, based on comments in core/util/work_sharder.cc. - // Many linear algebra ops take roughly max(m,n) * min(m,n)^2, where the first - // input matrix is m-by-n. We provide that as a default implementation for - // convenience. + // Returns the cost per matrix operation. This is used to determine the + // number of threads to use for parallelizing calls to ComputeMatrix in + // batch mode. Cost per unit is assumed to be roughly 1ns, based on comments + // in core/util/work_sharder.cc. Many linear algebra ops take roughly max(m,n) + // * min(m,n)^2, where the first input matrix is m-by-n. We provide that as a + // default implementation for convenience. virtual int64 GetCostPerUnit(const TensorShapes& input_matrix_shapes) const { double m = static_cast(input_matrix_shapes[0].dim_size(0)); double n = static_cast(input_matrix_shapes[0].dim_size(1)); @@ -111,7 +118,9 @@ class LinearAlgebraOp : public OpKernel { // Performs a single matrix computation given input matrices, and // stores the result in outputs. For batch operations, this will be called // repeatedly for a single call to Compute() when multiple matrices exist in - // input Tensors with rank > 2. + // input Tensors with rank > 2. In this case the calls to ComputeMatrix are + // parallelized. The number of threads used is determined by a cost model from + // the value returned by GetCostPerUnit(). virtual void ComputeMatrix(OpKernelContext* context, const ConstMatrixMaps& inputs, MatrixMaps* outputs) = 0; @@ -142,6 +151,15 @@ class LinearAlgebraOp : public OpKernel { const TensorShapes& input_matrix_shapes, const TensorOutputs& outputs, const TensorShapes& output_matrix_shapes); + + void AnalyzeInputs(OpKernelContext* context, TensorInputs* inputs, + TensorShapes* input_matrix_shapes, + TensorShape* batch_shape); + + void PrepareOutputs(OpKernelContext* context, + const TensorShapes& input_matrix_shapes, + const TensorShape& batch_shape, TensorOutputs* outputs, + TensorShapes* output_matrix_shapes); }; // Declare that LinearAlgebraOp is explicitly instantiated in diff --git a/tensorflow/core/kernels/svd_op.cc b/tensorflow/core/kernels/svd_op.cc new file mode 100644 index 00000000000..c3686947dda --- /dev/null +++ b/tensorflow/core/kernels/svd_op.cc @@ -0,0 +1,105 @@ +/* Copyright 2016 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. +==============================================================================*/ + +// See docs in ../ops/linalg_ops.cc. +#include + +#include "third_party/eigen3/Eigen/SVD" +#include "tensorflow/core/framework/kernel_def_builder.h" +#include "tensorflow/core/framework/op_kernel.h" +#include "tensorflow/core/framework/tensor_shape.h" +#include "tensorflow/core/kernels/linalg_ops_common.h" +#include "tensorflow/core/lib/core/errors.h" +#include "tensorflow/core/platform/logging.h" +#include "tensorflow/core/platform/macros.h" +#include "tensorflow/core/platform/types.h" + +namespace tensorflow { + +template +class SvdOp : public LinearAlgebraOp { + public: + typedef LinearAlgebraOp Base; + + explicit SvdOp(OpKernelConstruction* context) : Base(context) { + OP_REQUIRES_OK(context, context->GetAttr("compute_uv", &compute_uv_)); + OP_REQUIRES_OK(context, context->GetAttr("full_matrices", &full_matrices_)); + } + + using TensorShapes = typename Base::TensorShapes; + + void ValidateInputMatrixShapes( + OpKernelContext* context, + const TensorShapes& input_matrix_shapes) const final { + Base::ValidateSingleMatrix(context, input_matrix_shapes); + } + + TensorShapes GetOutputMatrixShapes( + const TensorShapes& input_matrix_shapes) const final { + int64 m = input_matrix_shapes[0].dim_size(0); + int64 n = input_matrix_shapes[0].dim_size(1); + int64 min_size = std::min(m, n); + if (compute_uv_) { + return TensorShapes({TensorShape({min_size}), + TensorShape({m, full_matrices_ ? m : min_size}), + TensorShape({n, full_matrices_ ? n : min_size})}); + } else { + return TensorShapes({TensorShape({min_size})}); + } + } + + // TODO(rmlarsen): This should depend on compute_uv. See b/30409375. + int64 GetCostPerUnit(const TensorShapes& input_matrix_shapes) const final { + double m = static_cast(input_matrix_shapes[0].dim_size(0)); + double n = static_cast(input_matrix_shapes[0].dim_size(1)); + double cost = 12 * std::max(m, n) * std::min(m, n) * std::min(m, n); + return cost >= static_cast(kint64max) ? kint64max + : static_cast(cost); + } + + using Matrix = typename Base::Matrix; + using MatrixMaps = typename Base::MatrixMaps; + using ConstMatrixMap = typename Base::ConstMatrixMap; + using ConstMatrixMaps = typename Base::ConstMatrixMaps; + + void ComputeMatrix(OpKernelContext* context, const ConstMatrixMaps& inputs, + MatrixMaps* outputs) final { + Eigen::JacobiSVD svd; + if (compute_uv_) { + svd.compute(inputs[0], + (full_matrices_ ? Eigen::ComputeFullU | Eigen::ComputeFullV + : Eigen::ComputeThinU | Eigen::ComputeThinV)); + outputs->at(0) = svd.singularValues(); + outputs->at(1) = svd.matrixU(); + outputs->at(2) = svd.matrixV(); + } else { + svd.compute(inputs[0]); + outputs->at(0) = svd.singularValues(); + } + } + + private: + bool compute_uv_; + bool full_matrices_; + + TF_DISALLOW_COPY_AND_ASSIGN(SvdOp); +}; + +REGISTER_LINALG_OP("Svd", (SvdOp), float); +REGISTER_LINALG_OP("Svd", (SvdOp), double); +REGISTER_LINALG_OP("BatchSvd", (SvdOp), float); +REGISTER_LINALG_OP("BatchSvd", (SvdOp), double); + +} // namespace tensorflow diff --git a/tensorflow/core/ops/linalg_ops.cc b/tensorflow/core/ops/linalg_ops.cc index ab4b2644b24..0ea31ddca33 100644 --- a/tensorflow/core/ops/linalg_ops.cc +++ b/tensorflow/core/ops/linalg_ops.cc @@ -128,7 +128,7 @@ REGISTER_OP("MatrixDeterminant") return Status::OK(); }) .Doc(R"doc( -Calculates the determinant of a square matrix. +Computes the determinant of a square matrix. input: A tensor of shape `[M, M]`. output: A scalar, equal to the determinant of the input. @@ -152,7 +152,7 @@ REGISTER_OP("BatchMatrixDeterminant") return Status::OK(); }) .Doc(R"doc( -Calculates the determinants for a batch of square matrices. +Computes the determinants for a batch of square matrices. The input is a tensor of shape `[..., M, M]` whose inner-most 2 dimensions form square matrices. The output is a tensor containing the determinants @@ -169,7 +169,7 @@ REGISTER_OP("MatrixInverse") .Attr("T: {double, float}") .SetShapeFn(UnchangedSquareShapeFn) .Doc(R"doc( -Calculates the inverse of a square invertible matrix or its adjoint (conjugate +Computes the inverse of a square invertible matrix or its adjoint (conjugate transpose). The op uses LU decomposition with partial pivoting to compute the inverse. @@ -191,7 +191,7 @@ REGISTER_OP("BatchMatrixInverse") .Attr("T: {double, float}") .SetShapeFn(BatchUnchangedSquareShapeFn) .Doc(R"doc( -Calculates the inverse of square invertible matrices or their adjoints +Computes the inverse of square invertible matrices or their adjoints (conjugate transposes). The input is a tensor of shape `[..., M, M]` whose inner-most 2 dimensions @@ -214,7 +214,7 @@ REGISTER_OP("Cholesky") .Attr("T: {double, float}") .SetShapeFn(UnchangedSquareShapeFn) .Doc(R"doc( -Calculates the Cholesky decomposition of a square matrix. +Computes the Cholesky decomposition of a square matrix. The input has to be symmetric and positive definite. Only the lower-triangular part of the input will be used for this operation. The upper-triangular part @@ -233,7 +233,7 @@ REGISTER_OP("BatchCholesky") .Attr("T: {double, float}") .SetShapeFn(BatchUnchangedSquareShapeFn) .Doc(R"doc( -Calculates the Cholesky decomposition of a batch of square matrices. +Computes the Cholesky decomposition of a batch of square matrices. The input is a tensor of shape `[..., M, M]` whose inner-most 2 dimensions form square matrices, with the same constraints as the single matrix Cholesky @@ -251,7 +251,7 @@ REGISTER_OP("CholeskyGrad") .Attr("T: {float, double}") .SetShapeFn(UnchangedSquareShapeFn) .Doc(R"doc( -Calculates the reverse mode backpropagated gradient of the Cholesky algorithm. +Computes the reverse mode backpropagated gradient of the Cholesky algorithm. For an explanation see "Differentiation of the Cholesky algorithm" by Iain Murray http://arxiv.org/abs/1602.07527. @@ -270,7 +270,7 @@ REGISTER_OP("BatchCholeskyGrad") .Attr("T: {float, double}") .SetShapeFn(BatchUnchangedSquareShapeFn) .Doc(R"doc( -Calculates the reverse mode backpropagated gradient of the Cholesky algorithm. +Computes the reverse mode backpropagated gradient of the Cholesky algorithm. For an explanation see "Differentiation of the Cholesky algorithm" by Iain Murray http://arxiv.org/abs/1602.07527. @@ -299,7 +299,7 @@ REGISTER_OP("SelfAdjointEig") return Status::OK(); }) .Doc(R"doc( -Calculates the Eigen Decomposition of a square Self-Adjoint matrix. +Computes the Eigen Decomposition of a square Self-Adjoint matrix. Only the lower-triangular part of the input will be used in this case. The upper-triangular part will not be read. @@ -330,7 +330,7 @@ REGISTER_OP("BatchSelfAdjointEig") return Status::OK(); }) .Doc(R"doc( -Calculates the Eigen Decomposition of a batch of square self-adjoint matrices. +Computes the Eigen Decomposition of a batch of square self-adjoint matrices. The input is a tensor of shape `[..., M, M]` whose inner-most 2 dimensions form square matrices, with the same constraints as the single matrix @@ -526,10 +526,10 @@ REGISTER_OP("BatchMatrixSolveLs") Solves multiple linear least-squares problems. `matrix` is a tensor of shape `[..., M, N]` whose inner-most 2 dimensions -form square matrices. Rhs is a tensor of shape `[..., M, K]`. The output -is a tensor shape `[..., N, K]` where each output matrix solves each of -the equations matrix[..., :, :] * output[..., :, :] = rhs[..., :, :] in the -least squares sense. +form matrices of size `[M, N]`. Rhs is a tensor of shape `[..., M, K]`. +The output is a tensor shape `[..., N, K]` where each output matrix solves +each of the equations matrix[..., :, :] * output[..., :, :] = rhs[..., :, :] +in the least squares sense. Below we will use the following notation for each pair of matrix and right-hand sides in the batch: @@ -563,4 +563,82 @@ rhs: Shape is `[..., M, K]`. output: Shape is `[..., N, K]`. )doc"); +REGISTER_OP("Svd") + .Input("input: T") + .Output("s: T") + .Output("u: T") + .Output("v: T") + .Attr("compute_uv: bool = False") + .Attr("full_matrices: bool = False") + .Attr("T: {double, float}") + .Doc(R"doc( +Computes the singular value decomposition of a matrix. + +Computes the SVD of if `input` such that `input = u * diag(s) * transpose(v)` + +```prettyprint +# a is a matrix. +# s is a vector of singular values. +# u is the matrix of left singular vectors. +# v is a matrix of right singular vectors. +s, _, _ = svd(a, compute_uv=False) +s, u, v = svd(a, compute_uv=True) +``` + +input: Shape is `[M, N]`. Let `P` be the minimum of `M` and `N`. +s: Singular values. Shape is `[P]`. +u: Left singular vectors; if `full_matrices` is `False` then shape is `[M, M]`. + If `full_matrices` is `True` then shape is `[M, P]`. + Undefined if `compute_uv` is `False`. +v: Left singular vectors. If `full_matrices` is `False` then shape is `[N, N]`. + If `full_matrices` is `True` then shape is `[N, P]`. + Undefined if `compute_uv` is false. +compute_uv: If true, left and right singular vectors will be + computed and returned in `u` and `v`, respectively. + If false, `u` and `v` are not set and should never referenced. +full_matrices: If true, compute full-sized `u` and `v`. If false + (the default), compute only the leading `P` singular vectors. + Ignored if `compute_uv` is `False`. +)doc"); + +REGISTER_OP("BatchSvd") + .Input("input: T") + .Output("s: T") + .Output("u: T") + .Output("v: T") + .Attr("compute_uv: bool = False") + .Attr("full_matrices: bool = False") + .Attr("T: {double, float}") + .Doc(R"doc( +Computes the singular value decompositions of a batch of matrices. + +Computes the SVD of each inner matrix in `input` such that +`input[..., :, :] = u[..., :, :] * diag(s[..., :, :]) * transpose(v[..., :, :])` + +```prettyprint +# a is a tensor containing a batch of matrices. +# s is a tensor of singular values for each matrix. +# u is the tensor containing of left singular vectors for each matrix. +# v is the tensor containing of right singular vectors for each matrix. +s, _, _ = batch_svd(a, compute_uv=False) +s, u, v = batch_svd(a, compute_uv=True) +``` + +input: A tensor of shape `[..., M, N]` whose inner-most 2 dimensions + form matrices of size `[M, N]`. Let `P` be the minimum of `M` and `N`. +s: Singular values. Shape is `[..., P]`. +u: Left singular vectors. If `full_matrices` is `False` then shape is + `[..., M, M]`; if `full_matrices` is `True` then shape is + `[..., M, P]`. Undefined if `compute_uv` is `False`. +v: Left singular vectors. If `full_matrices` is `False` then shape is + `[..., N, N]`. If `full_matrices` is `True` then shape is `[..., N, P]`. + Undefined if `compute_uv` is false. +compute_uv: If true, left and right singular vectors will be + computed and returned in `u` and `v`, respectively. + If false, `u` and `v` are not set and should never referenced. +full_matrices: If true, compute full-sized `u` and `v`. If false + (the default), compute only the leading `P` singular vectors. + Ignored if `compute_uv` is `False`. +)doc"); + } // namespace tensorflow diff --git a/tensorflow/python/kernel_tests/BUILD b/tensorflow/python/kernel_tests/BUILD index 7e11f17211b..16c260f154b 100644 --- a/tensorflow/python/kernel_tests/BUILD +++ b/tensorflow/python/kernel_tests/BUILD @@ -209,6 +209,7 @@ cuda_py_tests( "cwise_ops_test.py", "embedding_ops_test.py", "linalg_grad_test.py", + "svd_op_test.py", ], shard_count = 50, tags = ["notap"], # b/30226163 diff --git a/tensorflow/python/kernel_tests/svd_op_test.py b/tensorflow/python/kernel_tests/svd_op_test.py new file mode 100644 index 00000000000..6c2d8369799 --- /dev/null +++ b/tensorflow/python/kernel_tests/svd_op_test.py @@ -0,0 +1,112 @@ +# Copyright 2016 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. +# ============================================================================== +"""Tests for tensorflow.ops.math_ops.matrix_inverse.""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import numpy as np +import tensorflow as tf + + +class SvdOpTest(tf.test.TestCase): + + def testWrongDimensions(self): + # The input to svd should be 2-dimensional tensor. + scalar = tf.constant(1.) + with self.assertRaises(ValueError): + tf.svd(scalar) + vector = tf.constant([1., 2.]) + with self.assertRaises(ValueError): + tf.svd(vector) + tensor = tf.constant([[[1., 2.], [3., 4.]], [[1., 2.], [3., 4.]]]) + with self.assertRaises(ValueError): + tf.svd(tensor) + + # The input to batch_svd should be a tensor of at least rank 2. + scalar = tf.constant(1.) + with self.assertRaises(ValueError): + tf.batch_svd(scalar) + vector = tf.constant([1., 2.]) + with self.assertRaises(ValueError): + tf.batch_svd(vector) + + +def _GetSvdOpTest(dtype_, shape_): + + def _CompareSingularVectors(self, x, y, atol): + # Singular vectors are only unique up to sign (complex phase factor for + # complex matrices), so we normalize the signs first. + signs = np.sign(np.sum(np.divide(x, y), -2, keepdims=True)) + x *= signs + self.assertAllClose(x, y, atol=atol) + + def Test(self): + np.random.seed(1) + x = np.random.uniform( + low=-1.0, high=1.0, size=np.prod(shape_)).reshape(shape_).astype(dtype_) + if dtype_ == np.float32: + atol = 1e-4 + else: + atol = 1e-14 + for compute_uv in False, True: + for full_matrices in False, True: + with self.test_session(): + if x.ndim == 2: + if compute_uv: + tf_s, tf_u, tf_v = tf.svd(tf.constant(x), + compute_uv=compute_uv, + full_matrices=full_matrices) + else: + tf_s = tf.svd(tf.constant(x), + compute_uv=compute_uv, + full_matrices=full_matrices) + else: + if compute_uv: + tf_s, tf_u, tf_v = tf.batch_svd( + tf.constant(x), + compute_uv=compute_uv, + full_matrices=full_matrices) + else: + tf_s = tf.batch_svd( + tf.constant(x), + compute_uv=compute_uv, + full_matrices=full_matrices) + if compute_uv: + np_u, np_s, np_v = np.linalg.svd(x, + compute_uv=compute_uv, + full_matrices=full_matrices) + else: + np_s = np.linalg.svd(x, + compute_uv=compute_uv, + full_matrices=full_matrices) + self.assertAllClose(np_s, tf_s.eval(), atol=atol) + if compute_uv: + _CompareSingularVectors(self, np_u, tf_u.eval(), atol) + _CompareSingularVectors(self, np.swapaxes(np_v, -2, -1), + tf_v.eval(), atol) + + return Test + + +if __name__ == '__main__': + for dtype in np.float32, np.float64: + for m in 1, 2, 5, 10: + for n in 1, 2, 5, 10: + for batch_dims in [(), (3,)] + [(3, 2)] * (max(m, n) < 10): + shape = batch_dims + (m, n) + name = '%s_%s' % (dtype.__name__, '_'.join(map(str, shape))) + setattr(SvdOpTest, 'testSvd_' + name, _GetSvdOpTest(dtype, shape)) + tf.test.main() diff --git a/tensorflow/python/ops/linalg_grad.py b/tensorflow/python/ops/linalg_grad.py index 67fadc12cdc..908e04df7c8 100644 --- a/tensorflow/python/ops/linalg_grad.py +++ b/tensorflow/python/ops/linalg_grad.py @@ -32,6 +32,10 @@ from tensorflow.python.ops import math_ops ops.NoGradient("CholeskyGrad") ops.NoGradient("BatchCholeskyGrad") +ops.NoGradient("SelfAdjointEig") +ops.NoGradient("BatchSelfAdjointEig") +ops.NoGradient("Svd") +ops.NoGradient("BatchSvd") @ops.RegisterGradient("MatrixInverse") diff --git a/tensorflow/python/ops/linalg_ops.py b/tensorflow/python/ops/linalg_ops.py index 0e76f772caf..60707800207 100644 --- a/tensorflow/python/ops/linalg_ops.py +++ b/tensorflow/python/ops/linalg_ops.py @@ -31,6 +31,7 @@ from tensorflow.python.ops.gen_linalg_ops import * @ops.RegisterShape("CholeskyGrad") @ops.RegisterShape("MatrixInverse") def _UnchangedSquare(op): + """Shape function for matrix ops with output equal to input shape.""" input_shape = op.inputs[0].get_shape().with_rank(2) # The matrix must be square. input_shape[0].assert_is_compatible_with(input_shape[1]) @@ -41,6 +42,7 @@ def _UnchangedSquare(op): @ops.RegisterShape("BatchCholeskyGrad") @ops.RegisterShape("BatchMatrixInverse") def _BatchUnchangedSquare(op): + """Shape function for batch matrix ops with output equal to input shape.""" input_shape = op.inputs[0].get_shape().with_rank_at_least(2) # The matrices in the batch must be square. input_shape[-1].assert_is_compatible_with(input_shape[-2]) @@ -48,6 +50,7 @@ def _BatchUnchangedSquare(op): @ops.RegisterShape("MatrixDeterminant") def _MatrixDeterminantShape(op): + """Shape function for determinant op.""" input_shape = op.inputs[0].get_shape().with_rank(2) # The matrix must be square. input_shape[0].assert_is_compatible_with(input_shape[1]) @@ -59,6 +62,7 @@ def _MatrixDeterminantShape(op): @ops.RegisterShape("BatchMatrixDeterminant") def _BatchMatrixDeterminantShape(op): + """Shape function for batch determinant op.""" input_shape = op.inputs[0].get_shape().with_rank_at_least(2) # The matrices in the batch must be square. input_shape[-1].assert_is_compatible_with(input_shape[-2]) @@ -70,6 +74,7 @@ def _BatchMatrixDeterminantShape(op): @ops.RegisterShape("SelfAdjointEig") def _SelfAdjointEigShape(op): + """Shape function for self-adjoint eigensolver op.""" input_shape = op.inputs[0].get_shape().with_rank(2) # The matrix must be square. input_shape[0].assert_is_compatible_with(input_shape[1]) @@ -80,6 +85,7 @@ def _SelfAdjointEigShape(op): @ops.RegisterShape("BatchSelfAdjointEig") def _BatchSelfAdjointEigShape(op): + """Shape function for batch self-adjoint eigensolver op.""" input_shape = op.inputs[0].get_shape().with_rank_at_least(2) # The matrices in the batch must be square. input_shape[-1].assert_is_compatible_with(input_shape[-2]) @@ -89,9 +95,63 @@ def _BatchSelfAdjointEigShape(op): return [out_shape] +@ops.RegisterShape("Svd") +def _SvdShape(op): + """Shape function for SVD op.""" + input_shape = op.inputs[0].get_shape().with_rank(2) + unknown = tensor_shape.unknown_shape() + compute_uv = op.get_attr("compute_uv") + if input_shape.ndims is not None: + return [unknown, unknown, unknown] + full_matrices = op.get_attr("full_matrices") + m = input_shape.dims[0] + n = input_shape.dims[1] + p = min(m, n) + s_shape = tensor_shape.TensorShape([p]) + if compute_uv: + if full_matrices: + u_shape = tensor_shape.TensorShape([m, m]) + v_shape = tensor_shape.TensorShape([n, n]) + else: + u_shape = tensor_shape.TensorShape([m, p]) + v_shape = tensor_shape.TensorShape([n, p]) + else: + u_shape = [0] + v_shape = [0] + return [s_shape, u_shape, v_shape] + + +@ops.RegisterShape("BatchSvd") +def _BatchSvdShape(op): + """Shape function for batch SVD op.""" + input_shape = op.inputs[0].get_shape().with_rank_at_least(2) + unknown = tensor_shape.unknown_shape() + if input_shape.ndims is not None: + return [unknown, unknown, unknown] + compute_uv = op.get_attr("compute_uv") + full_matrices = op.get_attr("full_matrices") + m = input_shape.dims[-2] + n = input_shape.dims[-1] + p = min(m, n) + batch_shape = input_shape.dims[:-2] + s_shape = batch_shape.concatenate([p]) + if compute_uv: + if full_matrices: + u_shape = batch_shape.concatenate([m, m]) + v_shape = batch_shape.concatenate([n, n]) + else: + u_shape = batch_shape.concatenate([m, p]) + v_shape = batch_shape.concatenate([n, p]) + else: + u_shape = [0] + v_shape = [0] + return [s_shape, u_shape, v_shape] + + @ops.RegisterShape("MatrixSolve") @ops.RegisterShape("MatrixTriangularSolve") def _SquareMatrixSolveShape(op): + """Shape function for square matrix solver ops.""" lhs_shape = op.inputs[0].get_shape().with_rank(2) rhs_shape = op.inputs[1].get_shape().with_rank(2) # The matrix must be square. @@ -104,6 +164,7 @@ def _SquareMatrixSolveShape(op): @ops.RegisterShape("BatchMatrixSolve") @ops.RegisterShape("BatchMatrixTriangularSolve") def _BatchSquareMatrixSolveShape(op): + """Shape function for batch square matrix solver ops.""" lhs_shape = op.inputs[0].get_shape().with_rank_at_least(2) rhs_shape = op.inputs[1].get_shape().with_rank_at_least(2) # The matrices must be square. @@ -116,6 +177,7 @@ def _BatchSquareMatrixSolveShape(op): @ops.RegisterShape("MatrixSolveLs") def _MatrixSolveLsShape(op): + """Shape function for least-squares matrix solver op.""" lhs_shape = op.inputs[0].get_shape().with_rank(2) rhs_shape = op.inputs[1].get_shape().with_rank(2) # The matrix and right-hand side must have the same number of rows. @@ -125,6 +187,7 @@ def _MatrixSolveLsShape(op): @ops.RegisterShape("BatchMatrixSolveLs") def _BatchMatrixSolveLsShape(op): + """Shape function for batch least-squares matrix solver op.""" lhs_shape = op.inputs[0].get_shape().with_rank_at_least(2) rhs_shape = op.inputs[1].get_shape().with_rank_at_least(2) # The matrices and right-hand sides in the batch must have the same number of @@ -331,4 +394,92 @@ def batch_matrix_solve_ls(matrix, fast=fast, name=name) + +def svd(matrix, compute_uv=False, full_matrices=False, name=None): + """Computes the singular value decomposition of a matrix. + + Computes the SVD of if `matrix` such that `matrix = u * diag(s) * + transpose(v)` + + ```prettyprint + # a is a matrix. + # s is a vector of singular values. + # u is the matrix of left singular vectors. + # v is a matrix of right singular vectors. + s = svd(a, compute_uv=False) + s, u, v = svd(a, compute_uv=True) + ``` + + Args: + matrix: `Tensor` of shape `[M, N]`. Let `P` be the minimum of `M` and `N`. + compute_uv: If `True` then left and right singular vectors will be + computed and returned in `u` and `v`, respectively. Otherwise, only the + singular values will be computed. + full_matrices: If true, compute full-sized `u` and `v`. If false + (the default), compute only the leading `P` singular vectors. + Ignored if `compute_uv` is `False`. + name: string, optional name of the operation. + + Returns: + s: Singular values. Shape is `[P]`. + u: Right singular vectors. If `full_matrices` is `False` (default) then + shape is `[M, P]`; if `full_matrices` is `True` then shape is + `[M, M]`. Not returned if `compute_uv` is `False`. + v: Left singular vectors. If `full_matrices` is `False` (default) then + shape is `[N, P]`. If `full_matrices` is `True` then shape is + `[N, N]`. Not returned if `compute_uv` is `False`. + """ + s, u, v = gen_linalg_ops.svd(matrix, + compute_uv=compute_uv, + full_matrices=full_matrices) + if compute_uv: + return s, u, v + else: + return s + + +def batch_svd(tensor, compute_uv=False, full_matrices=False, name=None): + """Computes the singular value decompositions of a batch of matrices. + + Computes the SVD of each inner matrix in `tensor` such that + `tensor[..., :, :] = u[..., :, :] * diag(s[..., :, :]) * transpose(v[..., :, + :])` + + ```prettyprint + # a is a tensor. + # s is a tensor of singular values. + # u is a tensor of left singular vectors. + # v is a tensor of right singular vectors. + s = batch_svd(a, compute_uv=False) + s, u, v = batch_svd(a, compute_uv=True) + ``` + + Args: + matrix: `Tensor` of shape `[..., M, N]`. Let `P` be the minimum of `M` and + `N`. + compute_uv: If `True` then left and right singular vectors will be + computed and returned in `u` and `v`, respectively. Otherwise, only the + singular values will be computed. + full_matrices: If true, compute full-sized `u` and `v`. If false + (the default), compute only the leading `P` singular vectors. + Ignored if `compute_uv` is `False`. + name: string, optional name of the operation. + + Returns: + s: Singular values. Shape is `[..., P]`. + u: Right singular vectors. If `full_matrices` is `False` (default) then + shape is `[..., M, P]`; if `full_matrices` is `True` then shape is + `[..., M, M]`. Not returned if `compute_uv` is `False`. + v: Left singular vectors. If `full_matrices` is `False` (default) then + shape is `[..., N, P]`. If `full_matrices` is `True` then shape is + `[..., N, N]`. Not returned if `compute_uv` is `False`. + """ + s, u, v = gen_linalg_ops.batch_svd( + tensor, compute_uv=compute_uv, full_matrices=full_matrices) + if compute_uv: + return s, u, v + else: + return s + + # pylint: enable=invalid-name diff --git a/tensorflow/python/ops/math_ops.py b/tensorflow/python/ops/math_ops.py index cd7e92401d2..981a951e662 100644 --- a/tensorflow/python/ops/math_ops.py +++ b/tensorflow/python/ops/math_ops.py @@ -98,9 +98,6 @@ functions on matrices to your graph. @@cholesky_solve @@batch_cholesky_solve -@@self_adjoint_eig -@@batch_self_adjoint_eig - @@matrix_solve @@batch_matrix_solve @@ -110,6 +107,12 @@ functions on matrices to your graph. @@matrix_solve_ls @@batch_matrix_solve_ls +@@self_adjoint_eig +@@batch_self_adjoint_eig + +@@svd +@@batch_svd + ## Complex Number Functions TensorFlow provides several operations that you can use to add complex number @@ -1598,91 +1601,93 @@ def tanh(x, name=None): def cumsum(x, axis=0, exclusive=False, reverse=False, name=None): - """Compute the cumulative sum of the tensor `x` along `axis`. + """Compute the cumulative sum of the tensor `x` along `axis`. - By default, this op performs an inclusive cumsum, which means that the first - element of the input is identical to the first element of the output: - ```prettyprint - tf.cumsum([a, b, c]) ==> [a, a + b, a + b + c] - ``` + By default, this op performs an inclusive cumsum, which means that the first + element of the input is identical to the first element of the output: + ```prettyprint + tf.cumsum([a, b, c]) ==> [a, a + b, a + b + c] + ``` - By setting the `exclusive` kwarg to `True`, an exclusive cumsum is performed - instead: - ```prettyprint - tf.cumsum([a, b, c], exclusive=True) ==> [0, a, a + b] - ``` + By setting the `exclusive` kwarg to `True`, an exclusive cumsum is performed + instead: + ```prettyprint + tf.cumsum([a, b, c], exclusive=True) ==> [0, a, a + b] + ``` - By setting the `reverse` kwarg to `True`, the cumsum is performed in the - opposite direction: - ```prettyprint - tf.cumsum([a, b, c], reverse=True) ==> [a + b + c, b + c, c] - ``` - This is more efficient than using separate `tf.reverse` ops. + By setting the `reverse` kwarg to `True`, the cumsum is performed in the + opposite direction: + ```prettyprint + tf.cumsum([a, b, c], reverse=True) ==> [a + b + c, b + c, c] + ``` + This is more efficient than using separate `tf.reverse` ops. - The `reverse` and `exclusive` kwargs can also be combined: - ```prettyprint - tf.cumsum([a, b, c], exclusive=True, reverse=True) ==> [b + c, c, 0] - ``` + The `reverse` and `exclusive` kwargs can also be combined: + ```prettyprint + tf.cumsum([a, b, c], exclusive=True, reverse=True) ==> [b + c, c, 0] + ``` - Args: - x: A `Tensor`. Must be one of the following types: `float32`, `float64`, + Args: + x: A `Tensor`. Must be one of the following types: `float32`, `float64`, `int64`, `int32`, `uint8`, `uint16`, `int16`, `int8`, `complex64`, `complex128`, `qint8`, `quint8`, `qint32`, `half`. - axis: A `Tensor` of type `int32` (default: 0). - reverse: A `bool` (default: False). - name: A name for the operation (optional). + axis: A `Tensor` of type `int32` (default: 0). + reverse: A `bool` (default: False). + name: A name for the operation (optional). - Returns: - A `Tensor`. Has the same type as `x`. - """ - with ops.op_scope([x], name, "Cumsum") as name: - x = ops.convert_to_tensor(x, name="x") - return gen_math_ops.cumsum(x, axis, exclusive=exclusive, - reverse=reverse, name=name) + Returns: + A `Tensor`. Has the same type as `x`. + """ + with ops.op_scope([x], name, "Cumsum") as name: + x = ops.convert_to_tensor(x, name="x") + return gen_math_ops.cumsum( + x, axis, exclusive=exclusive, reverse=reverse, name=name) def cumprod(x, axis=0, exclusive=False, reverse=False, name=None): - """Compute the cumulative product of the tensor `x` along `axis`. + """Compute the cumulative product of the tensor `x` along `axis`. - By default, this op performs an inclusive cumprod, which means that the first - element of the input is identical to the first element of the output: - ```prettyprint - tf.cumprod([a, b, c]) ==> [a, a * b, a * b * c] - ``` + By default, this op performs an inclusive cumprod, which means that the + first + element of the input is identical to the first element of the output: + ```prettyprint + tf.cumprod([a, b, c]) ==> [a, a * b, a * b * c] + ``` - By setting the `exclusive` kwarg to `True`, an exclusive cumprod is performed - instead: - ```prettyprint - tf.cumprod([a, b, c], exclusive=True) ==> [0, a, a * b] - ``` + By setting the `exclusive` kwarg to `True`, an exclusive cumprod is + performed + instead: + ```prettyprint + tf.cumprod([a, b, c], exclusive=True) ==> [0, a, a * b] + ``` - By setting the `reverse` kwarg to `True`, the cumprod is performed in the - opposite direction: - ```prettyprint - tf.cumprod([a, b, c], reverse=True) ==> [a * b * c, b * c, c] - ``` - This is more efficient than using separate `tf.reverse` ops. + By setting the `reverse` kwarg to `True`, the cumprod is performed in the + opposite direction: + ```prettyprint + tf.cumprod([a, b, c], reverse=True) ==> [a * b * c, b * c, c] + ``` + This is more efficient than using separate `tf.reverse` ops. - The `reverse` and `exclusive` kwargs can also be combined: - ```prettyprint - tf.cumprod([a, b, c], exclusive=True, reverse=True) ==> [b * c, c, 0] - ``` + The `reverse` and `exclusive` kwargs can also be combined: + ```prettyprint + tf.cumprod([a, b, c], exclusive=True, reverse=True) ==> [b * c, c, 0] + ``` - Args: - x: A `Tensor`. Must be one of the following types: `float32`, `float64`, + Args: + x: A `Tensor`. Must be one of the following types: `float32`, `float64`, `int64`, `int32`, `uint8`, `uint16`, `int16`, `int8`, `complex64`, `complex128`, `qint8`, `quint8`, `qint32`, `half`. - axis: A `Tensor` of type `int32` (default: 0). - reverse: A `bool` (default: False). - name: A name for the operation (optional). + axis: A `Tensor` of type `int32` (default: 0). + reverse: A `bool` (default: False). + name: A name for the operation (optional). - Returns: - A `Tensor`. Has the same type as `x`. - """ - with ops.op_scope([x], name, "Cumprod") as name: - x = ops.convert_to_tensor(x, name="x") - return gen_math_ops.cumprod(x, axis, exclusive=exclusive, - reverse=reverse, name=name) + Returns: + A `Tensor`. Has the same type as `x`. + """ + with ops.op_scope([x], name, "Cumprod") as name: + x = ops.convert_to_tensor(x, name="x") + return gen_math_ops.cumprod( + x, axis, exclusive=exclusive, reverse=reverse, name=name) ops.RegisterShape("Abs")(common_shapes.unchanged_shape) diff --git a/third_party/eigen3/BUILD b/third_party/eigen3/BUILD index 9062ed2ec0d..15534fa9612 100644 --- a/third_party/eigen3/BUILD +++ b/third_party/eigen3/BUILD @@ -8,6 +8,7 @@ cc_library( "Eigen/Cholesky", "Eigen/Eigenvalues", "Eigen/QR", + "Eigen/SVD", "unsupported/Eigen/SpecialFunctions", "unsupported/Eigen/CXX11/Tensor", "unsupported/Eigen/CXX11/FixedPoint", diff --git a/third_party/eigen3/Eigen/SVD b/third_party/eigen3/Eigen/SVD index fd310017ad1..eecf47c1031 100644 --- a/third_party/eigen3/Eigen/SVD +++ b/third_party/eigen3/Eigen/SVD @@ -1,37 +1 @@ -#ifndef EIGEN_SVD_MODULE_H -#define EIGEN_SVD_MODULE_H - -#include "QR" -#include "Householder" -#include "Jacobi" - -#include "src/Core/util/DisableStupidWarnings.h" - -/** \defgroup SVD_Module SVD module - * - * - * - * This module provides SVD decomposition for matrices (both real and complex). - * This decomposition is accessible via the following MatrixBase method: - * - MatrixBase::jacobiSvd() - * - * \code - * #include - * \endcode - */ - -#include "src/misc/Solve.h" -#include "src/SVD/JacobiSVD.h" -#if defined(EIGEN_USE_LAPACKE) && !defined(EIGEN_USE_LAPACKE_STRICT) -#include "src/SVD/JacobiSVD_MKL.h" -#endif -#include "src/SVD/UpperBidiagonalization.h" - -#ifdef EIGEN2_SUPPORT -#include "src/Eigen2Support/SVD.h" -#endif - -#include "src/Core/util/ReenableStupidWarnings.h" - -#endif // EIGEN_SVD_MODULE_H -/* vim: set filetype=cpp et sw=2 ts=2 ai: */ +#include "Eigen/SVD" From 3b90f469f46b9bc0afc81c053e290ce44c8a13ed Mon Sep 17 00:00:00 2001 From: "A. Unique TensorFlower" Date: Mon, 1 Aug 2016 08:13:33 -0800 Subject: [PATCH 008/134] Add an 'extras' argument to run_op_benchmark. Change: 128991279 --- tensorflow/python/platform/benchmark.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tensorflow/python/platform/benchmark.py b/tensorflow/python/platform/benchmark.py index 1ba89db5628..23c03c38b13 100644 --- a/tensorflow/python/platform/benchmark.py +++ b/tensorflow/python/platform/benchmark.py @@ -164,6 +164,7 @@ class Benchmark(six.with_metaclass(_BenchmarkRegistrar, object)): wall_time: (optional) Total wall time in seconds throughput: (optional) Throughput (in MB/s) extras: (optional) Dict mapping string keys to additional benchmark info. + Values may be either floats or values that are convertible to strings. name: (optional) Override the BenchmarkEntry name with `name`. Otherwise it is inferred from the top-level method name. """ @@ -189,7 +190,8 @@ class TensorFlowBenchmark(Benchmark): burn_iters=2, min_iters=10, store_trace=False, - name=None): + name=None, + extras=None): """Run an op or tensor in the given session. Report the results. Args: @@ -205,6 +207,8 @@ class TensorFlowBenchmark(Benchmark): in the extras field "full_trace_chrome_format". name: (optional) Override the BenchmarkEntry name with `name`. Otherwise it is inferred from the top-level method name. + extras: (optional) Dict mapping string keys to additional benchmark info. + Values may be either floats or values that are convertible to strings. """ for _ in range(burn_iters): sess.run(op_or_tensor, feed_dict=feed_dict) @@ -218,7 +222,7 @@ class TensorFlowBenchmark(Benchmark): delta = end_time - start_time deltas[i] = delta - extras = {} + extras = extras if extras is not None else {} if store_trace: run_options = config_pb2.RunOptions( trace_level=config_pb2.RunOptions.FULL_TRACE) From 18060bb9960a8c74338f1ff0918f029eef36ab92 Mon Sep 17 00:00:00 2001 From: "A. Unique TensorFlower" Date: Mon, 1 Aug 2016 08:17:05 -0800 Subject: [PATCH 009/134] Update ops-related pbtxt files. Change: 128991563 --- .../core/ops/compat/ops_history.v0.pbtxt | 86 ++++++++++++ tensorflow/core/ops/ops.pbtxt | 124 ++++++++++++++++-- 2 files changed, 199 insertions(+), 11 deletions(-) diff --git a/tensorflow/core/ops/compat/ops_history.v0.pbtxt b/tensorflow/core/ops/compat/ops_history.v0.pbtxt index 6c7556076a9..282f5a907a0 100644 --- a/tensorflow/core/ops/compat/ops_history.v0.pbtxt +++ b/tensorflow/core/ops/compat/ops_history.v0.pbtxt @@ -5246,6 +5246,49 @@ op { } } } +op { + name: "BatchSvd" + input_arg { + name: "input" + type_attr: "T" + } + output_arg { + name: "s" + type_attr: "T" + } + output_arg { + name: "u" + type_attr: "T" + } + output_arg { + name: "v" + type_attr: "T" + } + attr { + name: "compute_uv" + type: "bool" + default_value { + b: false + } + } + attr { + name: "full_matrices" + type: "bool" + default_value { + b: false + } + } + attr { + name: "T" + type: "type" + allowed_values { + list { + type: DT_DOUBLE + type: DT_FLOAT + } + } + } +} op { name: "BatchToSpace" input_arg { @@ -25183,6 +25226,49 @@ op { } } } +op { + name: "Svd" + input_arg { + name: "input" + type_attr: "T" + } + output_arg { + name: "s" + type_attr: "T" + } + output_arg { + name: "u" + type_attr: "T" + } + output_arg { + name: "v" + type_attr: "T" + } + attr { + name: "compute_uv" + type: "bool" + default_value { + b: false + } + } + attr { + name: "full_matrices" + type: "bool" + default_value { + b: false + } + } + attr { + name: "T" + type: "type" + allowed_values { + list { + type: DT_DOUBLE + type: DT_FLOAT + } + } + } +} op { name: "Switch" input_arg { diff --git a/tensorflow/core/ops/ops.pbtxt b/tensorflow/core/ops/ops.pbtxt index 046923bdb46..722cceccd4a 100644 --- a/tensorflow/core/ops/ops.pbtxt +++ b/tensorflow/core/ops/ops.pbtxt @@ -1886,7 +1886,7 @@ op { } } } - summary: "Calculates the Cholesky decomposition of a batch of square matrices." + summary: "Computes the Cholesky decomposition of a batch of square matrices." description: "The input is a tensor of shape `[..., M, M]` whose inner-most 2 dimensions\nform square matrices, with the same constraints as the single matrix Cholesky\ndecomposition above. The output is a tensor of the same shape as the input\ncontaining the Cholesky decompositions for all input submatrices `[..., :, :]`." } op { @@ -1916,7 +1916,7 @@ op { } } } - summary: "Calculates the reverse mode backpropagated gradient of the Cholesky algorithm." + summary: "Computes the reverse mode backpropagated gradient of the Cholesky algorithm." description: "For an explanation see \"Differentiation of the Cholesky algorithm\" by\nIain Murray http://arxiv.org/abs/1602.07527." } op { @@ -2110,7 +2110,7 @@ op { } } } - summary: "Calculates the determinants for a batch of square matrices." + summary: "Computes the determinants for a batch of square matrices." description: "The input is a tensor of shape `[..., M, M]` whose inner-most 2 dimensions\nform square matrices. The output is a tensor containing the determinants\nfor all input submatrices `[..., :, :]`." } op { @@ -2180,7 +2180,7 @@ op { } } } - summary: "Calculates the inverse of square invertible matrices or their adjoints" + summary: "Computes the inverse of square invertible matrices or their adjoints" description: "(conjugate transposes).\n\nThe input is a tensor of shape `[..., M, M]` whose inner-most 2 dimensions\nform square matrices. The output is a tensor of the same shape as the input\ncontaining the inverse for all input submatrices `[..., :, :]`.\n\nThe op uses LU decomposition with partial pivoting to compute the inverses.\n\nIf a matrix is not invertible there is no guarantee what the op does. It\nmay detect the condition and raise an exception or it may simply return a\ngarbage result." } op { @@ -2284,7 +2284,7 @@ op { } } summary: "Solves multiple linear least-squares problems." - description: "`matrix` is a tensor of shape `[..., M, N]` whose inner-most 2 dimensions\nform square matrices. Rhs is a tensor of shape `[..., M, K]`. The output\nis a tensor shape `[..., N, K]` where each output matrix solves each of\nthe equations matrix[..., :, :] * output[..., :, :] = rhs[..., :, :] in the\nleast squares sense.\n\nBelow we will use the following notation for each pair of\nmatrix and right-hand sides in the batch:\n\n`matrix`=\\\\(A \\in \\Re^{m \\times n}\\\\),\n`rhs`=\\\\(B \\in \\Re^{m \\times k}\\\\),\n`output`=\\\\(X \\in \\Re^{n \\times k}\\\\),\n`l2_regularizer`=\\\\(\\lambda\\\\).\n\nIf `fast` is `True`, then the solution is computed by solving the normal\nequations using Cholesky decomposition. Specifically, if \\\\(m \\ge n\\\\) then\n\\\\(X = (A^T A + \\lambda I)^{-1} A^T B\\\\), which solves the least-squares\nproblem \\\\(X = \\mathrm{argmin}_{Z \\in \\Re^{n \\times k}} ||A Z - B||_F^2 +\n\\lambda ||Z||_F^2\\\\). If \\\\(m \\lt n\\\\) then `output` is computed as\n\\\\(X = A^T (A A^T + \\lambda I)^{-1} B\\\\), which (for \\\\(\\lambda = 0\\\\)) is the\nminimum-norm solution to the under-determined linear system, i.e.\n\\\\(X = \\mathrm{argmin}_{Z \\in \\Re^{n \\times k}} ||Z||_F^2 \\\\), subject to\n\\\\(A Z = B\\\\). Notice that the fast path is only numerically stable when\n\\\\(A\\\\) is numerically full rank and has a condition number\n\\\\(\\mathrm{cond}(A) \\lt \\frac{1}{\\sqrt{\\epsilon_{mach}}}\\\\) or\\\\(\\lambda\\\\) is\nsufficiently large.\n\nIf `fast` is `False` an algorithm based on the numerically robust complete\northogonal decomposition is used. This computes the minimum-norm\nleast-squares solution, even when \\\\(A\\\\) is rank deficient. This path is\ntypically 6-7 times slower than the fast path. If `fast` is `False` then\n`l2_regularizer` is ignored." + description: "`matrix` is a tensor of shape `[..., M, N]` whose inner-most 2 dimensions\nform matrices of size `[M, N]`. Rhs is a tensor of shape `[..., M, K]`.\nThe output is a tensor shape `[..., N, K]` where each output matrix solves\neach of the equations matrix[..., :, :] * output[..., :, :] = rhs[..., :, :]\nin the least squares sense.\n\nBelow we will use the following notation for each pair of\nmatrix and right-hand sides in the batch:\n\n`matrix`=\\\\(A \\in \\Re^{m \\times n}\\\\),\n`rhs`=\\\\(B \\in \\Re^{m \\times k}\\\\),\n`output`=\\\\(X \\in \\Re^{n \\times k}\\\\),\n`l2_regularizer`=\\\\(\\lambda\\\\).\n\nIf `fast` is `True`, then the solution is computed by solving the normal\nequations using Cholesky decomposition. Specifically, if \\\\(m \\ge n\\\\) then\n\\\\(X = (A^T A + \\lambda I)^{-1} A^T B\\\\), which solves the least-squares\nproblem \\\\(X = \\mathrm{argmin}_{Z \\in \\Re^{n \\times k}} ||A Z - B||_F^2 +\n\\lambda ||Z||_F^2\\\\). If \\\\(m \\lt n\\\\) then `output` is computed as\n\\\\(X = A^T (A A^T + \\lambda I)^{-1} B\\\\), which (for \\\\(\\lambda = 0\\\\)) is the\nminimum-norm solution to the under-determined linear system, i.e.\n\\\\(X = \\mathrm{argmin}_{Z \\in \\Re^{n \\times k}} ||Z||_F^2 \\\\), subject to\n\\\\(A Z = B\\\\). Notice that the fast path is only numerically stable when\n\\\\(A\\\\) is numerically full rank and has a condition number\n\\\\(\\mathrm{cond}(A) \\lt \\frac{1}{\\sqrt{\\epsilon_{mach}}}\\\\) or\\\\(\\lambda\\\\) is\nsufficiently large.\n\nIf `fast` is `False` an algorithm based on the numerically robust complete\northogonal decomposition is used. This computes the minimum-norm\nleast-squares solution, even when \\\\(A\\\\) is rank deficient. This path is\ntypically 6-7 times slower than the fast path. If `fast` is `False` then\n`l2_regularizer` is ignored." } op { name: "BatchMatrixTriangularSolve" @@ -2515,9 +2515,60 @@ op { } } } - summary: "Calculates the Eigen Decomposition of a batch of square self-adjoint matrices." + summary: "Computes the Eigen Decomposition of a batch of square self-adjoint matrices." description: "The input is a tensor of shape `[..., M, M]` whose inner-most 2 dimensions\nform square matrices, with the same constraints as the single matrix\nSelfAdjointEig.\n\nThe result is a \'[..., M+1, M] matrix with [..., 0,:] containing the\neigenvalues, and subsequent [...,1:, :] containing the eigenvectors." } +op { + name: "BatchSvd" + input_arg { + name: "input" + description: "A tensor of shape `[..., M, N]` whose inner-most 2 dimensions\nform matrices of size `[M, N]`. Let `P` be the minimum of `M` and `N`." + type_attr: "T" + } + output_arg { + name: "s" + description: "Singular values. Shape is `[..., P]`." + type_attr: "T" + } + output_arg { + name: "u" + description: "Left singular vectors. If `full_matrices` is `False` then shape is\n`[..., M, M]`; if `full_matrices` is `True` then shape is\n`[..., M, P]`. Undefined if `compute_uv` is `False`." + type_attr: "T" + } + output_arg { + name: "v" + description: "Left singular vectors. If `full_matrices` is `False` then shape is\n`[..., N, N]`. If `full_matrices` is `True` then shape is `[..., N, P]`.\nUndefined if `compute_uv` is false." + type_attr: "T" + } + attr { + name: "compute_uv" + type: "bool" + default_value { + b: false + } + description: "If true, left and right singular vectors will be\ncomputed and returned in `u` and `v`, respectively.\nIf false, `u` and `v` are not set and should never referenced." + } + attr { + name: "full_matrices" + type: "bool" + default_value { + b: false + } + description: "If true, compute full-sized `u` and `v`. If false\n(the default), compute only the leading `P` singular vectors.\nIgnored if `compute_uv` is `False`." + } + attr { + name: "T" + type: "type" + allowed_values { + list { + type: DT_DOUBLE + type: DT_FLOAT + } + } + } + summary: "Computes the singular value decompositions of a batch of matrices." + description: "Computes the SVD of each inner matrix in `input` such that\n`input[..., :, :] = u[..., :, :] * diag(s[..., :, :]) * transpose(v[..., :, :])`\n\n```prettyprint\n# a is a tensor containing a batch of matrices.\n# s is a tensor of singular values for each matrix.\n# u is the tensor containing of left singular vectors for each matrix.\n# v is the tensor containing of right singular vectors for each matrix.\ns, _, _ = batch_svd(a, compute_uv=False)\ns, u, v = batch_svd(a, compute_uv=True)\n```" +} op { name: "BatchToSpace" input_arg { @@ -3023,7 +3074,7 @@ op { } } } - summary: "Calculates the Cholesky decomposition of a square matrix." + summary: "Computes the Cholesky decomposition of a square matrix." description: "The input has to be symmetric and positive definite. Only the lower-triangular\npart of the input will be used for this operation. The upper-triangular part\nwill not be read.\n\nThe result is the lower-triangular matrix of the Cholesky decomposition of the\ninput, `L`, so that `input = L L^*`." } op { @@ -3053,7 +3104,7 @@ op { } } } - summary: "Calculates the reverse mode backpropagated gradient of the Cholesky algorithm." + summary: "Computes the reverse mode backpropagated gradient of the Cholesky algorithm." description: "For an explanation see \"Differentiation of the Cholesky algorithm\" by\nIain Murray http://arxiv.org/abs/1602.07527." } op { @@ -7566,7 +7617,7 @@ op { } } } - summary: "Calculates the determinant of a square matrix." + summary: "Computes the determinant of a square matrix." } op { name: "MatrixInverse" @@ -7597,7 +7648,7 @@ op { } } } - summary: "Calculates the inverse of a square invertible matrix or its adjoint (conjugate" + summary: "Computes the inverse of a square invertible matrix or its adjoint (conjugate" description: "transpose).\n\nThe op uses LU decomposition with partial pivoting to compute the inverse.\n\nIf the matrix is not invertible there is no guarantee what the op does. It\nmay detect the condition and raise an exception or it may simply return a\ngarbage result." } op { @@ -12090,7 +12141,7 @@ op { } } } - summary: "Calculates the Eigen Decomposition of a square Self-Adjoint matrix." + summary: "Computes the Eigen Decomposition of a square Self-Adjoint matrix." description: "Only the lower-triangular part of the input will be used in this case. The\nupper-triangular part will not be read.\n\nThe result is a M+1 x M matrix whose first row is the eigenvalues, and\nsubsequent rows are eigenvectors." } op { @@ -15124,6 +15175,57 @@ op { summary: "Computes the sum of elements across dimensions of a tensor." description: "Reduces `input` along the dimensions given in `reduction_indices`. Unless\n`keep_dims` is true, the rank of the tensor is reduced by 1 for each entry in\n`reduction_indices`. If `keep_dims` is true, the reduced dimensions are\nretained with length 1." } +op { + name: "Svd" + input_arg { + name: "input" + description: "Shape is `[M, N]`. Let `P` be the minimum of `M` and `N`." + type_attr: "T" + } + output_arg { + name: "s" + description: "Singular values. Shape is `[P]`." + type_attr: "T" + } + output_arg { + name: "u" + description: "Left singular vectors; if `full_matrices` is `False` then shape is `[M, M]`.\nIf `full_matrices` is `True` then shape is `[M, P]`.\nUndefined if `compute_uv` is `False`." + type_attr: "T" + } + output_arg { + name: "v" + description: "Left singular vectors. If `full_matrices` is `False` then shape is `[N, N]`.\nIf `full_matrices` is `True` then shape is `[N, P]`.\nUndefined if `compute_uv` is false." + type_attr: "T" + } + attr { + name: "compute_uv" + type: "bool" + default_value { + b: false + } + description: "If true, left and right singular vectors will be\ncomputed and returned in `u` and `v`, respectively.\nIf false, `u` and `v` are not set and should never referenced." + } + attr { + name: "full_matrices" + type: "bool" + default_value { + b: false + } + description: "If true, compute full-sized `u` and `v`. If false\n(the default), compute only the leading `P` singular vectors.\nIgnored if `compute_uv` is `False`." + } + attr { + name: "T" + type: "type" + allowed_values { + list { + type: DT_DOUBLE + type: DT_FLOAT + } + } + } + summary: "Computes the singular value decomposition of a matrix." + description: "Computes the SVD of if `input` such that `input = u * diag(s) * transpose(v)`\n\n```prettyprint\n# a is a matrix.\n# s is a vector of singular values.\n# u is the matrix of left singular vectors.\n# v is a matrix of right singular vectors.\ns, _, _ = svd(a, compute_uv=False)\ns, u, v = svd(a, compute_uv=True)\n```" +} op { name: "Switch" input_arg { From ab3a01247eda7a5edb69b0fc7df5eea096a96aad Mon Sep 17 00:00:00 2001 From: "A. Unique TensorFlower" Date: Mon, 1 Aug 2016 08:19:18 -0800 Subject: [PATCH 010/134] Update generated Python Op docs. Change: 128991814 --- .../shard0/tf.cholesky.md | 2 +- .../shard0/tf.cumprod.md | 10 +- .../shard1/tf.batch_matrix_inverse.md | 2 +- .../shard2/tf.batch_matrix_determinant.md | 2 +- .../shard3/tf.batch_self_adjoint_eig.md | 2 +- .../functions_and_classes/shard3/tf.svd.md | 39 ++++ .../shard4/tf.batch_svd.md | 41 ++++ .../functions_and_classes/shard6/tf.cumsum.md | 4 +- .../shard6/tf.self_adjoint_eig.md | 2 +- .../shard7/tf.batch_cholesky.md | 2 +- .../shard8/tf.matrix_inverse.md | 2 +- .../shard9/tf.matrix_determinant.md | 2 +- tensorflow/g3doc/api_docs/python/index.md | 2 + tensorflow/g3doc/api_docs/python/math_ops.md | 213 +++++++++++++----- 14 files changed, 249 insertions(+), 76 deletions(-) create mode 100644 tensorflow/g3doc/api_docs/python/functions_and_classes/shard3/tf.svd.md create mode 100644 tensorflow/g3doc/api_docs/python/functions_and_classes/shard4/tf.batch_svd.md diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.cholesky.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.cholesky.md index 4032b80d8e0..61e781319d8 100644 --- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.cholesky.md +++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.cholesky.md @@ -1,6 +1,6 @@ ### `tf.cholesky(input, name=None)` {#cholesky} -Calculates the Cholesky decomposition of a square matrix. +Computes the Cholesky decomposition of a square matrix. The input has to be symmetric and positive definite. Only the lower-triangular part of the input will be used for this operation. The upper-triangular part diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.cumprod.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.cumprod.md index a226ce07373..7381350be38 100644 --- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.cumprod.md +++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard0/tf.cumprod.md @@ -2,13 +2,15 @@ Compute the cumulative product of the tensor `x` along `axis`. -By default, this op performs an inclusive cumprod, which means that the first +By default, this op performs an inclusive cumprod, which means that the +first element of the input is identical to the first element of the output: ```prettyprint tf.cumprod([a, b, c]) ==> [a, a * b, a * b * c] ``` -By setting the `exclusive` kwarg to `True`, an exclusive cumprod is performed +By setting the `exclusive` kwarg to `True`, an exclusive cumprod is +performed instead: ```prettyprint tf.cumprod([a, b, c], exclusive=True) ==> [0, a, a * b] @@ -30,8 +32,8 @@ tf.cumprod([a, b, c], exclusive=True, reverse=True) ==> [b * c, c, 0] * `x`: A `Tensor`. Must be one of the following types: `float32`, `float64`, - `int64`, `int32`, `uint8`, `uint16`, `int16`, `int8`, `complex64`, - `complex128`, `qint8`, `quint8`, `qint32`, `half`. + `int64`, `int32`, `uint8`, `uint16`, `int16`, `int8`, `complex64`, + `complex128`, `qint8`, `quint8`, `qint32`, `half`. * `axis`: A `Tensor` of type `int32` (default: 0). * `reverse`: A `bool` (default: False). * `name`: A name for the operation (optional). diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard1/tf.batch_matrix_inverse.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard1/tf.batch_matrix_inverse.md index 231056a05c2..6b51df6aec7 100644 --- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard1/tf.batch_matrix_inverse.md +++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard1/tf.batch_matrix_inverse.md @@ -1,6 +1,6 @@ ### `tf.batch_matrix_inverse(input, adjoint=None, name=None)` {#batch_matrix_inverse} -Calculates the inverse of square invertible matrices or their adjoints +Computes the inverse of square invertible matrices or their adjoints (conjugate transposes). diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard2/tf.batch_matrix_determinant.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard2/tf.batch_matrix_determinant.md index d55bf96f187..a30b74e35cc 100644 --- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard2/tf.batch_matrix_determinant.md +++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard2/tf.batch_matrix_determinant.md @@ -1,6 +1,6 @@ ### `tf.batch_matrix_determinant(input, name=None)` {#batch_matrix_determinant} -Calculates the determinants for a batch of square matrices. +Computes the determinants for a batch of square matrices. The input is a tensor of shape `[..., M, M]` whose inner-most 2 dimensions form square matrices. The output is a tensor containing the determinants diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard3/tf.batch_self_adjoint_eig.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard3/tf.batch_self_adjoint_eig.md index 19d6c5319f0..1b58772074f 100644 --- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard3/tf.batch_self_adjoint_eig.md +++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard3/tf.batch_self_adjoint_eig.md @@ -1,6 +1,6 @@ ### `tf.batch_self_adjoint_eig(input, name=None)` {#batch_self_adjoint_eig} -Calculates the Eigen Decomposition of a batch of square self-adjoint matrices. +Computes the Eigen Decomposition of a batch of square self-adjoint matrices. The input is a tensor of shape `[..., M, M]` whose inner-most 2 dimensions form square matrices, with the same constraints as the single matrix diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard3/tf.svd.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard3/tf.svd.md new file mode 100644 index 00000000000..09f7edecbcd --- /dev/null +++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard3/tf.svd.md @@ -0,0 +1,39 @@ +### `tf.svd(matrix, compute_uv=False, full_matrices=False, name=None)` {#svd} + +Computes the singular value decomposition of a matrix. + +Computes the SVD of if `matrix` such that `matrix = u * diag(s) * +transpose(v)` + +```prettyprint +# a is a matrix. +# s is a vector of singular values. +# u is the matrix of left singular vectors. +# v is a matrix of right singular vectors. +s = svd(a, compute_uv=False) +s, u, v = svd(a, compute_uv=True) +``` + +##### Args: + + +* `matrix`: `Tensor` of shape `[M, N]`. Let `P` be the minimum of `M` and `N`. +* `compute_uv`: If `True` then left and right singular vectors will be + computed and returned in `u` and `v`, respectively. Otherwise, only the + singular values will be computed. +* `full_matrices`: If true, compute full-sized `u` and `v`. If false + (the default), compute only the leading `P` singular vectors. + Ignored if `compute_uv` is `False`. +* `name`: string, optional name of the operation. + +##### Returns: + + +* `s`: Singular values. Shape is `[P]`. +* `u`: Right singular vectors. If `full_matrices` is `False` (default) then + shape is `[M, P]`; if `full_matrices` is `True` then shape is + `[M, M]`. Not returned if `compute_uv` is `False`. +* `v`: Left singular vectors. If `full_matrices` is `False` (default) then + shape is `[N, P]`. If `full_matrices` is `True` then shape is + `[N, N]`. Not returned if `compute_uv` is `False`. + diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard4/tf.batch_svd.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard4/tf.batch_svd.md new file mode 100644 index 00000000000..97dd25d1819 --- /dev/null +++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard4/tf.batch_svd.md @@ -0,0 +1,41 @@ +### `tf.batch_svd(tensor, compute_uv=False, full_matrices=False, name=None)` {#batch_svd} + +Computes the singular value decompositions of a batch of matrices. + +Computes the SVD of each inner matrix in `tensor` such that +`tensor[..., :, :] = u[..., :, :] * diag(s[..., :, :]) * transpose(v[..., :, +:])` + +```prettyprint +# a is a tensor. +# s is a tensor of singular values. +# u is a tensor of left singular vectors. +# v is a tensor of right singular vectors. +s = batch_svd(a, compute_uv=False) +s, u, v = batch_svd(a, compute_uv=True) +``` + +##### Args: + + +* `matrix`: `Tensor` of shape `[..., M, N]`. Let `P` be the minimum of `M` and + `N`. +* `compute_uv`: If `True` then left and right singular vectors will be + computed and returned in `u` and `v`, respectively. Otherwise, only the + singular values will be computed. +* `full_matrices`: If true, compute full-sized `u` and `v`. If false + (the default), compute only the leading `P` singular vectors. + Ignored if `compute_uv` is `False`. +* `name`: string, optional name of the operation. + +##### Returns: + + +* `s`: Singular values. Shape is `[..., P]`. +* `u`: Right singular vectors. If `full_matrices` is `False` (default) then + shape is `[..., M, P]`; if `full_matrices` is `True` then shape is + `[..., M, M]`. Not returned if `compute_uv` is `False`. +* `v`: Left singular vectors. If `full_matrices` is `False` (default) then + shape is `[..., N, P]`. If `full_matrices` is `True` then shape is + `[..., N, N]`. Not returned if `compute_uv` is `False`. + diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard6/tf.cumsum.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard6/tf.cumsum.md index 64a8312fde0..baa00e57d53 100644 --- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard6/tf.cumsum.md +++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard6/tf.cumsum.md @@ -30,8 +30,8 @@ tf.cumsum([a, b, c], exclusive=True, reverse=True) ==> [b + c, c, 0] * `x`: A `Tensor`. Must be one of the following types: `float32`, `float64`, - `int64`, `int32`, `uint8`, `uint16`, `int16`, `int8`, `complex64`, - `complex128`, `qint8`, `quint8`, `qint32`, `half`. + `int64`, `int32`, `uint8`, `uint16`, `int16`, `int8`, `complex64`, + `complex128`, `qint8`, `quint8`, `qint32`, `half`. * `axis`: A `Tensor` of type `int32` (default: 0). * `reverse`: A `bool` (default: False). * `name`: A name for the operation (optional). diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard6/tf.self_adjoint_eig.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard6/tf.self_adjoint_eig.md index efbc0cd3be9..8254802a19d 100644 --- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard6/tf.self_adjoint_eig.md +++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard6/tf.self_adjoint_eig.md @@ -1,6 +1,6 @@ ### `tf.self_adjoint_eig(input, name=None)` {#self_adjoint_eig} -Calculates the Eigen Decomposition of a square Self-Adjoint matrix. +Computes the Eigen Decomposition of a square Self-Adjoint matrix. Only the lower-triangular part of the input will be used in this case. The upper-triangular part will not be read. diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard7/tf.batch_cholesky.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard7/tf.batch_cholesky.md index 487680f50b8..1ce7fca603d 100644 --- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard7/tf.batch_cholesky.md +++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard7/tf.batch_cholesky.md @@ -1,6 +1,6 @@ ### `tf.batch_cholesky(input, name=None)` {#batch_cholesky} -Calculates the Cholesky decomposition of a batch of square matrices. +Computes the Cholesky decomposition of a batch of square matrices. The input is a tensor of shape `[..., M, M]` whose inner-most 2 dimensions form square matrices, with the same constraints as the single matrix Cholesky diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard8/tf.matrix_inverse.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard8/tf.matrix_inverse.md index 4172badef50..1edc4a9ec9e 100644 --- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard8/tf.matrix_inverse.md +++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard8/tf.matrix_inverse.md @@ -1,6 +1,6 @@ ### `tf.matrix_inverse(input, adjoint=None, name=None)` {#matrix_inverse} -Calculates the inverse of a square invertible matrix or its adjoint (conjugate +Computes the inverse of a square invertible matrix or its adjoint (conjugate transpose). diff --git a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard9/tf.matrix_determinant.md b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard9/tf.matrix_determinant.md index a5cd5a7fe68..fcaa1b1c774 100644 --- a/tensorflow/g3doc/api_docs/python/functions_and_classes/shard9/tf.matrix_determinant.md +++ b/tensorflow/g3doc/api_docs/python/functions_and_classes/shard9/tf.matrix_determinant.md @@ -1,6 +1,6 @@ ### `tf.matrix_determinant(input, name=None)` {#matrix_determinant} -Calculates the determinant of a square matrix. +Computes the determinant of a square matrix. ##### Args: diff --git a/tensorflow/g3doc/api_docs/python/index.md b/tensorflow/g3doc/api_docs/python/index.md index 448a32d72a5..2856c13d319 100644 --- a/tensorflow/g3doc/api_docs/python/index.md +++ b/tensorflow/g3doc/api_docs/python/index.md @@ -186,6 +186,7 @@ * [`batch_matrix_transpose`](../../api_docs/python/math_ops.md#batch_matrix_transpose) * [`batch_matrix_triangular_solve`](../../api_docs/python/math_ops.md#batch_matrix_triangular_solve) * [`batch_self_adjoint_eig`](../../api_docs/python/math_ops.md#batch_self_adjoint_eig) + * [`batch_svd`](../../api_docs/python/math_ops.md#batch_svd) * [`ceil`](../../api_docs/python/math_ops.md#ceil) * [`cholesky`](../../api_docs/python/math_ops.md#cholesky) * [`cholesky_solve`](../../api_docs/python/math_ops.md#cholesky_solve) @@ -261,6 +262,7 @@ * [`square`](../../api_docs/python/math_ops.md#square) * [`squared_difference`](../../api_docs/python/math_ops.md#squared_difference) * [`sub`](../../api_docs/python/math_ops.md#sub) + * [`svd`](../../api_docs/python/math_ops.md#svd) * [`tan`](../../api_docs/python/math_ops.md#tan) * [`trace`](../../api_docs/python/math_ops.md#trace) * [`transpose`](../../api_docs/python/math_ops.md#transpose) diff --git a/tensorflow/g3doc/api_docs/python/math_ops.md b/tensorflow/g3doc/api_docs/python/math_ops.md index 05379613268..9d77a00f726 100644 --- a/tensorflow/g3doc/api_docs/python/math_ops.md +++ b/tensorflow/g3doc/api_docs/python/math_ops.md @@ -1387,7 +1387,7 @@ It is computed as: ### `tf.matrix_determinant(input, name=None)` {#matrix_determinant} -Calculates the determinant of a square matrix. +Computes the determinant of a square matrix. ##### Args: @@ -1406,7 +1406,7 @@ Calculates the determinant of a square matrix. ### `tf.batch_matrix_determinant(input, name=None)` {#batch_matrix_determinant} -Calculates the determinants for a batch of square matrices. +Computes the determinants for a batch of square matrices. The input is a tensor of shape `[..., M, M]` whose inner-most 2 dimensions form square matrices. The output is a tensor containing the determinants @@ -1429,7 +1429,7 @@ for all input submatrices `[..., :, :]`. ### `tf.matrix_inverse(input, adjoint=None, name=None)` {#matrix_inverse} -Calculates the inverse of a square invertible matrix or its adjoint (conjugate +Computes the inverse of a square invertible matrix or its adjoint (conjugate transpose). @@ -1459,7 +1459,7 @@ garbage result. ### `tf.batch_matrix_inverse(input, adjoint=None, name=None)` {#batch_matrix_inverse} -Calculates the inverse of square invertible matrices or their adjoints +Computes the inverse of square invertible matrices or their adjoints (conjugate transposes). @@ -1491,7 +1491,7 @@ garbage result. ### `tf.cholesky(input, name=None)` {#cholesky} -Calculates the Cholesky decomposition of a square matrix. +Computes the Cholesky decomposition of a square matrix. The input has to be symmetric and positive definite. Only the lower-triangular part of the input will be used for this operation. The upper-triangular part @@ -1516,7 +1516,7 @@ input, `L`, so that `input = L L^*`. ### `tf.batch_cholesky(input, name=None)` {#batch_cholesky} -Calculates the Cholesky decomposition of a batch of square matrices. +Computes the Cholesky decomposition of a batch of square matrices. The input is a tensor of shape `[..., M, M]` whose inner-most 2 dimensions form square matrices, with the same constraints as the single matrix Cholesky @@ -1612,56 +1612,6 @@ X[3, :, 2] # Solution to the linear system A[3, :, :] x = RHS[3, :, 2] -- - - - -### `tf.self_adjoint_eig(input, name=None)` {#self_adjoint_eig} - -Calculates the Eigen Decomposition of a square Self-Adjoint matrix. - -Only the lower-triangular part of the input will be used in this case. The -upper-triangular part will not be read. - -The result is a M+1 x M matrix whose first row is the eigenvalues, and -subsequent rows are eigenvectors. - -##### Args: - - -* `input`: A `Tensor`. Must be one of the following types: `float64`, `float32`. - Shape is `[M, M]`. -* `name`: A name for the operation (optional). - -##### Returns: - - A `Tensor`. Has the same type as `input`. Shape is `[M+1, M]`. - - -- - - - -### `tf.batch_self_adjoint_eig(input, name=None)` {#batch_self_adjoint_eig} - -Calculates the Eigen Decomposition of a batch of square self-adjoint matrices. - -The input is a tensor of shape `[..., M, M]` whose inner-most 2 dimensions -form square matrices, with the same constraints as the single matrix -SelfAdjointEig. - -The result is a '[..., M+1, M] matrix with [..., 0,:] containing the -eigenvalues, and subsequent [...,1:, :] containing the eigenvectors. - -##### Args: - - -* `input`: A `Tensor`. Must be one of the following types: `float64`, `float32`. - Shape is `[..., M, M]`. -* `name`: A name for the operation (optional). - -##### Returns: - - A `Tensor`. Has the same type as `input`. Shape is `[..., M+1, M]`. - - - - - - ### `tf.matrix_solve(matrix, rhs, adjoint=None, name=None)` {#matrix_solve} @@ -1908,6 +1858,143 @@ typically 6-7 times slower than the fast path. If `fast` is `False` then +- - - + +### `tf.self_adjoint_eig(input, name=None)` {#self_adjoint_eig} + +Computes the Eigen Decomposition of a square Self-Adjoint matrix. + +Only the lower-triangular part of the input will be used in this case. The +upper-triangular part will not be read. + +The result is a M+1 x M matrix whose first row is the eigenvalues, and +subsequent rows are eigenvectors. + +##### Args: + + +* `input`: A `Tensor`. Must be one of the following types: `float64`, `float32`. + Shape is `[M, M]`. +* `name`: A name for the operation (optional). + +##### Returns: + + A `Tensor`. Has the same type as `input`. Shape is `[M+1, M]`. + + +- - - + +### `tf.batch_self_adjoint_eig(input, name=None)` {#batch_self_adjoint_eig} + +Computes the Eigen Decomposition of a batch of square self-adjoint matrices. + +The input is a tensor of shape `[..., M, M]` whose inner-most 2 dimensions +form square matrices, with the same constraints as the single matrix +SelfAdjointEig. + +The result is a '[..., M+1, M] matrix with [..., 0,:] containing the +eigenvalues, and subsequent [...,1:, :] containing the eigenvectors. + +##### Args: + + +* `input`: A `Tensor`. Must be one of the following types: `float64`, `float32`. + Shape is `[..., M, M]`. +* `name`: A name for the operation (optional). + +##### Returns: + + A `Tensor`. Has the same type as `input`. Shape is `[..., M+1, M]`. + + + +- - - + +### `tf.svd(matrix, compute_uv=False, full_matrices=False, name=None)` {#svd} + +Computes the singular value decomposition of a matrix. + +Computes the SVD of if `matrix` such that `matrix = u * diag(s) * +transpose(v)` + +```prettyprint +# a is a matrix. +# s is a vector of singular values. +# u is the matrix of left singular vectors. +# v is a matrix of right singular vectors. +s = svd(a, compute_uv=False) +s, u, v = svd(a, compute_uv=True) +``` + +##### Args: + + +* `matrix`: `Tensor` of shape `[M, N]`. Let `P` be the minimum of `M` and `N`. +* `compute_uv`: If `True` then left and right singular vectors will be + computed and returned in `u` and `v`, respectively. Otherwise, only the + singular values will be computed. +* `full_matrices`: If true, compute full-sized `u` and `v`. If false + (the default), compute only the leading `P` singular vectors. + Ignored if `compute_uv` is `False`. +* `name`: string, optional name of the operation. + +##### Returns: + + +* `s`: Singular values. Shape is `[P]`. +* `u`: Right singular vectors. If `full_matrices` is `False` (default) then + shape is `[M, P]`; if `full_matrices` is `True` then shape is + `[M, M]`. Not returned if `compute_uv` is `False`. +* `v`: Left singular vectors. If `full_matrices` is `False` (default) then + shape is `[N, P]`. If `full_matrices` is `True` then shape is + `[N, N]`. Not returned if `compute_uv` is `False`. + + +- - - + +### `tf.batch_svd(tensor, compute_uv=False, full_matrices=False, name=None)` {#batch_svd} + +Computes the singular value decompositions of a batch of matrices. + +Computes the SVD of each inner matrix in `tensor` such that +`tensor[..., :, :] = u[..., :, :] * diag(s[..., :, :]) * transpose(v[..., :, +:])` + +```prettyprint +# a is a tensor. +# s is a tensor of singular values. +# u is a tensor of left singular vectors. +# v is a tensor of right singular vectors. +s = batch_svd(a, compute_uv=False) +s, u, v = batch_svd(a, compute_uv=True) +``` + +##### Args: + + +* `matrix`: `Tensor` of shape `[..., M, N]`. Let `P` be the minimum of `M` and + `N`. +* `compute_uv`: If `True` then left and right singular vectors will be + computed and returned in `u` and `v`, respectively. Otherwise, only the + singular values will be computed. +* `full_matrices`: If true, compute full-sized `u` and `v`. If false + (the default), compute only the leading `P` singular vectors. + Ignored if `compute_uv` is `False`. +* `name`: string, optional name of the operation. + +##### Returns: + + +* `s`: Singular values. Shape is `[..., P]`. +* `u`: Right singular vectors. If `full_matrices` is `False` (default) then + shape is `[..., M, P]`; if `full_matrices` is `True` then shape is + `[..., M, M]`. Not returned if `compute_uv` is `False`. +* `v`: Left singular vectors. If `full_matrices` is `False` (default) then + shape is `[..., N, P]`. If `full_matrices` is `True` then shape is + `[..., N, N]`. Not returned if `compute_uv` is `False`. + + + ## Complex Number Functions TensorFlow provides several operations that you can use to add complex number @@ -2625,8 +2712,8 @@ tf.cumsum([a, b, c], exclusive=True, reverse=True) ==> [b + c, c, 0] * `x`: A `Tensor`. Must be one of the following types: `float32`, `float64`, - `int64`, `int32`, `uint8`, `uint16`, `int16`, `int8`, `complex64`, - `complex128`, `qint8`, `quint8`, `qint32`, `half`. + `int64`, `int32`, `uint8`, `uint16`, `int16`, `int8`, `complex64`, + `complex128`, `qint8`, `quint8`, `qint32`, `half`. * `axis`: A `Tensor` of type `int32` (default: 0). * `reverse`: A `bool` (default: False). * `name`: A name for the operation (optional). @@ -2642,13 +2729,15 @@ tf.cumsum([a, b, c], exclusive=True, reverse=True) ==> [b + c, c, 0] Compute the cumulative product of the tensor `x` along `axis`. -By default, this op performs an inclusive cumprod, which means that the first +By default, this op performs an inclusive cumprod, which means that the +first element of the input is identical to the first element of the output: ```prettyprint tf.cumprod([a, b, c]) ==> [a, a * b, a * b * c] ``` -By setting the `exclusive` kwarg to `True`, an exclusive cumprod is performed +By setting the `exclusive` kwarg to `True`, an exclusive cumprod is +performed instead: ```prettyprint tf.cumprod([a, b, c], exclusive=True) ==> [0, a, a * b] @@ -2670,8 +2759,8 @@ tf.cumprod([a, b, c], exclusive=True, reverse=True) ==> [b * c, c, 0] * `x`: A `Tensor`. Must be one of the following types: `float32`, `float64`, - `int64`, `int32`, `uint8`, `uint16`, `int16`, `int8`, `complex64`, - `complex128`, `qint8`, `quint8`, `qint32`, `half`. + `int64`, `int32`, `uint8`, `uint16`, `int16`, `int8`, `complex64`, + `complex128`, `qint8`, `quint8`, `qint32`, `half`. * `axis`: A `Tensor` of type `int32` (default: 0). * `reverse`: A `bool` (default: False). * `name`: A name for the operation (optional). From cf8d866b3f2f76b349432ac197a62ca11dac6ceb Mon Sep 17 00:00:00 2001 From: Yuan Yu Date: Mon, 1 Aug 2016 08:33:31 -0800 Subject: [PATCH 011/134] Fix a bug in distributed execution of while loop. When a while loop is partitioned on multiple devices, control edges are added to control the recv nodes. There are two partitioning phases, one at the worker level and the other at the device level within a worker. We didn't handle properly when an op has two remote inputs, one on a different worker and the other on a different device of the same worker. Change: 128993033 --- tensorflow/core/graph/graph_partition.cc | 34 +++++++++++-------- .../kernel_tests/control_flow_ops_py_test.py | 7 ++-- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/tensorflow/core/graph/graph_partition.cc b/tensorflow/core/graph/graph_partition.cc index 7cf25ba48f4..7098bed572f 100644 --- a/tensorflow/core/graph/graph_partition.cc +++ b/tensorflow/core/graph/graph_partition.cc @@ -935,13 +935,15 @@ Status Partition(const PartitionOptions& opts, Graph* g, ref_recvs.clear(); ref_control_inputs.clear(); const Edge* control_flow_edge = nullptr; + int32 num_control_flow_edges = 0; for (const Edge* edge : dst->in_edges()) { if (edge->IsControlEdge()) { if (IsMerge(edge->src()) && IsControlLoop(edge->src())) { // This is one of the control edges added for control flow. There // can be multiple such edges as the dest node may have multiple - // remote inputs. We will just take one and ignore the others. + // remote inputs. We keep track of the number of such edges. control_flow_edge = edge; + ++num_control_flow_edges; } else { inputs.push_back(edge); } @@ -953,7 +955,6 @@ Status Partition(const PartitionOptions& opts, Graph* g, // Process in order so that all data edges are added as inputs to // dst in Edge::dst_input() order. - bool recv_added = false; for (const Edge* edge : inputs) { const Node* src = edge->src(); if (!src->IsOp()) continue; // Skip Sink/Source nodes. @@ -1041,21 +1042,21 @@ Status Partition(const PartitionOptions& opts, Graph* g, AddRecv(opts, g_info, dst_graph, edge, &real_recv, &status); if (!status.ok()) return status; - // Fix up the control flow edge. Redirect it to the recv. + // Fix up the control flow edge. // NOTE(yuanbyu): 'real_recv' must be the real recv node. - recv_added = true; - if (control_flow_edge != nullptr) { + if (src_graph == dst_graph) { + // For same device send/recv, add a control edge from send to recv. + // This prevents the asynchronous recv kernel from being scheduled + // before the data is available. + AddInput(real_recv, send->name(), Graph::kControlSlot); + } else if (control_flow_edge != nullptr) { + // Redirect control edge to the real recv since this is not a same + // device send/recv. + --num_control_flow_edges; AddInput(real_recv, control_flow_edge->src()->name(), Graph::kControlSlot); } - // For same device send/recv, add a control edge from send to recv. - // This prevents the asynchronous recv kernel from being scheduled - // immediately. - if (src_graph == dst_graph) { - AddInput(real_recv, send->name(), Graph::kControlSlot); - } - if (!edge->IsControlEdge() && IsRefType(src->output_type(edge->src_output()))) { AddNodeAttr("_start_time", recv_start_time, recv); @@ -1092,9 +1093,12 @@ Status Partition(const PartitionOptions& opts, Graph* g, // execution of recvs until all the other inputs become available. AddReadControl(ref_recvs, ref_control_inputs); - // Add back this control edge for control flow if not used. - if (!recv_added && (control_flow_edge != nullptr)) { - AddInput(dst_def, control_flow_edge->src()->name(), Graph::kControlSlot); + // Add back the control edges for control flow that are not used. + if (control_flow_edge != nullptr) { + for (int i = 0; i < num_control_flow_edges; ++i) { + AddInput(dst_def, control_flow_edge->src()->name(), + Graph::kControlSlot); + } } } diff --git a/tensorflow/python/kernel_tests/control_flow_ops_py_test.py b/tensorflow/python/kernel_tests/control_flow_ops_py_test.py index 00372831df6..879064d978b 100644 --- a/tensorflow/python/kernel_tests/control_flow_ops_py_test.py +++ b/tensorflow/python/kernel_tests/control_flow_ops_py_test.py @@ -716,10 +716,11 @@ class ControlFlowTest(tf.test.TestCase): def testWhileWithControl_3(self): with self.test_session() as sess: b = tf.placeholder(tf.bool) - c = tf.constant(0) + c = tf.constant(1) + x0 = tf.constant(0) with tf.control_dependencies([b]): - c = tf.while_loop(lambda x: x < 10, lambda x: x + 1, [c]) - self.assertEqual(10, sess.run(c, {b: True})) + r = tf.while_loop(lambda x: x < 10, lambda x: x + c, [x0]) + self.assertEqual(10, sess.run(r, {b: True})) def testWhileWithControl_4(self): with self.test_session() as sess: From 8ca0466448d06f5f89e255ce5697b4f161f06f60 Mon Sep 17 00:00:00 2001 From: Jonathan Hseu Date: Mon, 1 Aug 2016 08:53:53 -0800 Subject: [PATCH 012/134] Make default construction of Tasks cheaper. Change: 128995077 --- tensorflow/core/lib/core/threadpool.cc | 2 +- tensorflow/core/platform/context.h | 7 +++++++ tensorflow/core/platform/default/context.h | 3 +++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/tensorflow/core/lib/core/threadpool.cc b/tensorflow/core/lib/core/threadpool.cc index 59225049fa7..35c657265ff 100644 --- a/tensorflow/core/lib/core/threadpool.cc +++ b/tensorflow/core/lib/core/threadpool.cc @@ -58,7 +58,7 @@ struct EigenEnvironment { port::Tracing::RecordEvent(port::Tracing::EventCategory::kScheduleClosure, id); } - return Task{std::move(f), Context(), id}; + return Task{std::move(f), Context(ContextKind::kThread), id}; } void ExecuteTask(const Task& t) { diff --git a/tensorflow/core/platform/context.h b/tensorflow/core/platform/context.h index e6555029fd8..728ef916312 100644 --- a/tensorflow/core/platform/context.h +++ b/tensorflow/core/platform/context.h @@ -18,6 +18,13 @@ limitations under the License. namespace tensorflow { +enum class ContextKind { + // Initial state with default (empty) values. + kDefault, + // Initial state inherited from the creating or scheduling thread. + kThread, +}; + // Context is a container for request-specific information that should be passed // to threads that perform related work. The default constructor should capture // all relevant context. diff --git a/tensorflow/core/platform/default/context.h b/tensorflow/core/platform/default/context.h index 5d261ea9fbf..d8afeb47a9c 100644 --- a/tensorflow/core/platform/default/context.h +++ b/tensorflow/core/platform/default/context.h @@ -19,6 +19,9 @@ limitations under the License. namespace tensorflow { class Context { + public: + Context() {} + Context(const ContextKind kind) {} }; class WithContext { From b1b9c4c0e1ab453e8b9663295f6c0a29ec550ed1 Mon Sep 17 00:00:00 2001 From: Suharsh Sivakumar Date: Mon, 1 Aug 2016 09:40:54 -0800 Subject: [PATCH 013/134] TensorArray ops C++ shape inferece. Change: 129000884 --- tensorflow/core/ops/data_flow_ops.cc | 89 ++++++++++++++++++++++++++-- 1 file changed, 83 insertions(+), 6 deletions(-) diff --git a/tensorflow/core/ops/data_flow_ops.cc b/tensorflow/core/ops/data_flow_ops.cc index 0a0aa4ef7bd..1866bce47f7 100644 --- a/tensorflow/core/ops/data_flow_ops.cc +++ b/tensorflow/core/ops/data_flow_ops.cc @@ -465,9 +465,7 @@ elem: The tensor that is popped from the top of the stack. elem_type: The type of the elem that is popped. )doc"); -REGISTER_OP("StackClose") - .Input("handle: Ref(string)") - .Doc(R"doc( +REGISTER_OP("StackClose").Input("handle: Ref(string)").Doc(R"doc( Delete the stack from its resource container. handle: The handle to a stack. @@ -483,6 +481,12 @@ REGISTER_OP("TensorArray") .Attr("tensor_array_name: string = ''") .Output("handle: Ref(string)") .SetIsStateful() + .SetShapeFn([](InferenceContext* c) { + const Shape* unused; + TF_RETURN_IF_ERROR(c->WithRank(c->input(0), 0, &unused)); + c->set_output(0, c->Vector(2)); + return Status::OK(); + }) .Doc(R"doc( An array of Tensors of given size, with data written via Write and read via Read or Pack. @@ -506,6 +510,14 @@ REGISTER_OP("TensorArrayGrad") .Output("grad_handle: Ref(string)") .Attr("source: string") .SetIsStateful() + .SetShapeFn([](InferenceContext* c) { + const Shape* unused; + const Dimension* unused_dim; + TF_RETURN_IF_ERROR(c->WithRank(c->input(0), 1, &unused)); + TF_RETURN_IF_ERROR(c->WithValue(c->Dim(c->input(0), 0), 2, &unused_dim)); + c->set_output(0, c->Vector(2)); + return Status::OK(); + }) .Doc(R"doc( Creates a TensorArray for storing the gradients of values in the given handle. @@ -559,6 +571,15 @@ REGISTER_OP("TensorArrayWrite") .Input("flow_in: float") .Output("flow_out: float") .Attr("T: type") + .SetShapeFn([](InferenceContext* c) { + const Shape* unused; + const Dimension* unused_dim; + TF_RETURN_IF_ERROR(c->WithRank(c->input(0), 1, &unused)); + TF_RETURN_IF_ERROR(c->WithValue(c->Dim(c->input(0), 0), 2, &unused_dim)); + TF_RETURN_IF_ERROR(c->WithRank(c->input(1), 0, &unused)); + TF_RETURN_IF_ERROR(c->WithRank(c->input(3), 0, &unused)); + return shape_inference::ScalarShape(c); + }) .Doc(R"doc( Push an element onto the tensor_array. @@ -575,6 +596,15 @@ REGISTER_OP("TensorArrayRead") .Input("flow_in: float") .Output("value: dtype") .Attr("dtype: type") + .SetShapeFn([](InferenceContext* c) { + const Shape* unused; + const Dimension* unused_dim; + TF_RETURN_IF_ERROR(c->WithRank(c->input(0), 1, &unused)); + TF_RETURN_IF_ERROR(c->WithValue(c->Dim(c->input(0), 0), 2, &unused_dim)); + TF_RETURN_IF_ERROR(c->WithRank(c->input(1), 0, &unused)); + TF_RETURN_IF_ERROR(c->WithRank(c->input(2), 0, &unused)); + return shape_inference::UnknownShape(c); + }) .Doc(R"doc( Read an element from the TensorArray into output `value`. @@ -590,6 +620,14 @@ REGISTER_OP("TensorArrayPack") .Output("value: dtype") .Attr("dtype: type") .Attr("element_shape: shape = { unknown_rank: true }") + .SetShapeFn([](InferenceContext* c) { + const Shape* unused; + const Dimension* unused_dim; + TF_RETURN_IF_ERROR(c->WithRank(c->input(0), 1, &unused)); + TF_RETURN_IF_ERROR(c->WithValue(c->Dim(c->input(0), 0), 2, &unused_dim)); + TF_RETURN_IF_ERROR(c->WithRank(c->input(1), 0, &unused)); + return shape_inference::UnknownShape(c); + }) .Doc(R"doc( Pack the elements from the TensorArray into output `value`. @@ -611,6 +649,14 @@ REGISTER_OP("TensorArrayUnpack") .Input("flow_in: float") .Output("flow_out: float") .Attr("T: type") + .SetShapeFn([](InferenceContext* c) { + const Shape* unused; + const Dimension* unused_dim; + TF_RETURN_IF_ERROR(c->WithRank(c->input(0), 1, &unused)); + TF_RETURN_IF_ERROR(c->WithValue(c->Dim(c->input(0), 0), 2, &unused_dim)); + TF_RETURN_IF_ERROR(c->WithRank(c->input(2), 0, &unused)); + return shape_inference::ScalarShape(c); + }) .Doc(R"doc( Unpack the data from the input value into TensorArray elements. @@ -627,6 +673,16 @@ REGISTER_OP("TensorArrayConcat") .Output("lengths: int64") .Attr("dtype: type") .Attr("element_shape_except0: shape = { unknown_rank: true }") + .SetShapeFn([](InferenceContext* c) { + const Shape* unused; + const Dimension* unused_dim; + TF_RETURN_IF_ERROR(c->WithRank(c->input(0), 1, &unused)); + TF_RETURN_IF_ERROR(c->WithValue(c->Dim(c->input(0), 0), 2, &unused_dim)); + TF_RETURN_IF_ERROR(c->WithRank(c->input(1), 0, &unused)); + c->set_output(0, c->UnknownShape()); + c->set_output(1, c->Vector(c->UnknownDim())); + return Status::OK(); + }) .Doc(R"doc( Concat the elements from the TensorArray into value `value`. @@ -663,6 +719,15 @@ REGISTER_OP("TensorArraySplit") .Input("flow_in: float") .Output("flow_out: float") .Attr("T: type") + .SetShapeFn([](InferenceContext* c) { + const Shape* unused; + const Dimension* unused_dim; + TF_RETURN_IF_ERROR(c->WithRank(c->input(0), 1, &unused)); + TF_RETURN_IF_ERROR(c->WithValue(c->Dim(c->input(0), 0), 2, &unused_dim)); + TF_RETURN_IF_ERROR(c->WithRank(c->input(2), 1, &unused)); + TF_RETURN_IF_ERROR(c->WithRank(c->input(3), 0, &unused)); + return shape_inference::ScalarShape(c); + }) .Doc(R"doc( Split the data from the input value into TensorArray elements. @@ -696,6 +761,13 @@ REGISTER_OP("TensorArraySize") .Input("handle: Ref(string)") .Input("flow_in: float") .Output("size: int32") + .SetShapeFn([](InferenceContext* c) { + const Shape* unused; + const Dimension* unused_dim; + TF_RETURN_IF_ERROR(c->WithRank(c->input(0), 1, &unused)); + TF_RETURN_IF_ERROR(c->WithValue(c->Dim(c->input(0), 0), 2, &unused_dim)); + return shape_inference::ScalarShape(c); + }) .Doc(R"doc( Get the current size of the TensorArray. @@ -706,6 +778,13 @@ size: The current size of the TensorArray. REGISTER_OP("TensorArrayClose") .Input("handle: Ref(string)") + .SetShapeFn([](InferenceContext* c) { + const Shape* unused; + const Dimension* unused_dim; + TF_RETURN_IF_ERROR(c->WithRank(c->input(0), 1, &unused)); + TF_RETURN_IF_ERROR(c->WithValue(c->Dim(c->input(0), 0), 2, &unused_dim)); + return Status::OK(); + }) .Doc(R"doc( Delete the TensorArray from its resource container. This enables the user to close and release the resource in the middle of a step/run. @@ -1100,9 +1179,7 @@ value: The tensor for the given handle. dtype: The type of the output value. )doc"); -REGISTER_OP("DeleteSessionTensor") - .Input("handle: string") - .Doc(R"doc( +REGISTER_OP("DeleteSessionTensor").Input("handle: string").Doc(R"doc( Delete the tensor specified by its handle in the session. handle: The handle for a tensor stored in the session state. From d55d69a633af9d0e38726e2cdf2504b9e269a3f8 Mon Sep 17 00:00:00 2001 From: Suharsh Sivakumar Date: Mon, 1 Aug 2016 09:50:05 -0800 Subject: [PATCH 014/134] C++ shape inference for some image ops. Change: 129002019 --- tensorflow/core/ops/image_ops.cc | 40 +++++++++++++++++++++++++++ tensorflow/core/ops/image_ops_test.cc | 33 ++++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/tensorflow/core/ops/image_ops.cc b/tensorflow/core/ops/image_ops.cc index 18869205971..5a55493517b 100644 --- a/tensorflow/core/ops/image_ops.cc +++ b/tensorflow/core/ops/image_ops.cc @@ -177,6 +177,10 @@ REGISTER_OP("ResizeBilinearGrad") .Output("output: T") .Attr("T: {float, half, double}") .Attr("align_corners: bool = false") + .SetShapeFn([](InferenceContext* c) { + c->set_output(0, c->input(1)); + return Status::OK(); + }) .Doc(R"doc( Computes the gradient of bilinear interpolation. @@ -219,6 +223,27 @@ REGISTER_OP("ResizeNearestNeighborGrad") .Output("output: T") .Attr("T: {uint8, int8, int32, half, float, double}") .Attr("align_corners: bool = false") + .SetShapeFn([](InferenceContext* c) { + const Shape* input; + TF_RETURN_IF_ERROR(c->WithRank(c->input(0), 4, &input)); + const Shape* unused; + const Dimension* unused_dim; + TF_RETURN_IF_ERROR(c->WithRank(c->input(1), 1, &unused)); + TF_RETURN_IF_ERROR(c->WithValue(c->Dim(unused, 0), 2, &unused_dim)); + const Tensor* size = c->input_tensor(1); + if (size == nullptr) { + TF_RETURN_IF_ERROR(c->ReplaceDim(input, 1, c->UnknownDim(), &input)); + TF_RETURN_IF_ERROR(c->ReplaceDim(input, 2, c->UnknownDim(), &input)); + } else { + auto size_vec = size->vec(); + TF_RETURN_IF_ERROR( + c->ReplaceDim(input, 1, c->MakeDim(size_vec(0)), &input)); + TF_RETURN_IF_ERROR( + c->ReplaceDim(input, 2, c->MakeDim(size_vec(1)), &input)); + } + c->set_output(0, input); + return Status::OK(); + }) .Doc(R"doc( Computes the gradient of nearest neighbor interpolation. @@ -771,6 +796,13 @@ REGISTER_OP("CropAndResizeGradImage") .Output("output: T") .Attr("T: {float, half, double}") .Attr("method: {'bilinear'} = 'bilinear'") + .SetShapeFn([](InferenceContext* c) { + const Shape* out; + TF_RETURN_IF_ERROR(c->MakeShapeFromShapeTensor(3, &out)); + TF_RETURN_IF_ERROR(c->WithRank(out, 4, &out)); + c->set_output(0, out); + return Status::OK(); + }) .Doc(R"doc( Computes the gradient of the crop_and_resize op wrt the input image tensor. @@ -803,6 +835,10 @@ REGISTER_OP("CropAndResizeGradBoxes") .Output("output: float") .Attr("T: {uint8, int8, int16, int32, int64, half, float, double}") .Attr("method: {'bilinear'} = 'bilinear'") + .SetShapeFn([](InferenceContext* c) { + c->set_output(0, c->input(2)); + return Status::OK(); + }) .Doc(R"doc( Computes the gradient of the crop_and_resize op wrt the input boxes tensor. @@ -834,6 +870,10 @@ REGISTER_OP("NonMaxSuppression") .Input("max_output_size: int32") .Output("selected_indices: int32") .Attr("iou_threshold: float = 0.5") + .SetShapeFn([](InferenceContext* c) { + c->set_output(0, c->Vector(c->UnknownDim())); + return Status::OK(); + }) .Doc(R"doc( Greedily selects a subset of bounding boxes in descending order of score, pruning away boxes that have high intersection-over-union (IOU) overlap diff --git a/tensorflow/core/ops/image_ops_test.cc b/tensorflow/core/ops/image_ops_test.cc index 3cb33fe889b..fc9640ffb40 100644 --- a/tensorflow/core/ops/image_ops_test.cc +++ b/tensorflow/core/ops/image_ops_test.cc @@ -160,4 +160,37 @@ TEST(ImageOpsTest, CropAndResize_ShapeFn) { INFER_ERROR("Dimension must be 4 but is 3", op, "?;[?,3];?;?"); } +TEST(ImageOpsTest, ResizeNearestNeighborGrad_ShapeFn) { + ShapeInferenceTestOp op("ResizeNearestNeighborGrad"); + op.input_tensors.resize(2); + + // Rank and size checks. + INFER_ERROR("Shape must be rank 4 but is rank 3", op, "[1,2,3];?"); + INFER_ERROR("Shape must be rank 1 but is rank 2", op, "?;[1,2]") + INFER_ERROR("Dimension must be 2 but is 1", op, "?;[1]"); + + // When the size tensor is not a constant, the middle dims are unknown. + INFER_OK(op, "[1,?,3,?];[2]", "[d0_0,?,?,d0_3]"); + + Tensor size_tensor = test::AsTensor({20, 30}); + op.input_tensors[1] = &size_tensor; + INFER_OK(op, "[1,?,3,?];[2]", "[d0_0,20,30,d0_3]"); +} + +TEST(ImageOpsTest, CropAndResizeGradImage_ShapeFn) { + ShapeInferenceTestOp op("CropAndResizeGradImage"); + op.input_tensors.resize(4); + + // Rank checks. + INFER_ERROR("Shape must be rank 1 but is rank 2", op, "?;?;?;[1,2]"); + + // Unknown image_size should result in output of rank 4 with unknown dims. + INFER_OK(op, "?;?;?;?", "[?,?,?,?]"); + + // Known image_size should result in full shape information. + Tensor image_size = test::AsTensor({10, 20, 30, 40}); + op.input_tensors[3] = &image_size; + INFER_OK(op, "?;?;?;[1]", "[10, 20, 30, 40]"); +} + } // end namespace tensorflow From bbfe8e6e6ec13aae8cb3d00ce1d6ae49f4697600 Mon Sep 17 00:00:00 2001 From: Zongheng Yang Date: Mon, 1 Aug 2016 09:53:10 -0800 Subject: [PATCH 015/134] Replace a minomer: s/SaveRestoreHelper/Saver. Change: 129002390 --- tensorflow/core/protobuf/saver.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tensorflow/core/protobuf/saver.proto b/tensorflow/core/protobuf/saver.proto index b130c7343b4..c6b5e1c938a 100644 --- a/tensorflow/core/protobuf/saver.proto +++ b/tensorflow/core/protobuf/saver.proto @@ -6,7 +6,7 @@ option java_outer_classname = "SaverProtos"; option java_multiple_files = true; option java_package = "org.tensorflow.util"; -// Protocol buffer representing the configuration of a SaveRestoreHelper. +// Protocol buffer representing the configuration of a Saver. message SaverDef { // The name of the tensor in which to specify the filename when saving or // restoring a model checkpoint. From 9d7c9498ab82ce2f570dde4804336220a6687b29 Mon Sep 17 00:00:00 2001 From: Yuan Yu Date: Mon, 1 Aug 2016 10:24:29 -0800 Subject: [PATCH 016/134] Don't consider control inputs in gradient backprop graph construction. I added it as a conservative implementation, and always wanted to remove it. It could introduce unnecessary overhead/complexity, as shown in testWhileGrad_OneOutputWithControlDependencyOnSecond. Change: 129006471 --- .../kernel_tests/control_flow_ops_py_test.py | 21 +++++++++++++++++++ tensorflow/python/ops/control_flow_ops.py | 6 ++++-- tensorflow/python/ops/gradients.py | 8 +------ 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/tensorflow/python/kernel_tests/control_flow_ops_py_test.py b/tensorflow/python/kernel_tests/control_flow_ops_py_test.py index 879064d978b..159305f78bb 100644 --- a/tensorflow/python/kernel_tests/control_flow_ops_py_test.py +++ b/tensorflow/python/kernel_tests/control_flow_ops_py_test.py @@ -1246,6 +1246,27 @@ class ControlFlowTest(tf.test.TestCase): r = tf.gradients([rx], x) self.assertAllClose(64.0, r[0].eval()) + def testWhileGrad_OneOutputWithControlDependencyOnSecond(self): + with self.test_session(): + i = tf.constant(0, name="i") + x = tf.constant(1.0, name="x") + y = tf.constant(1.0, name="y") + c = lambda i, *_: tf.less(i, 1, name="cond_less") + def b(i, xi, yi): + # return (i + 1, xi, xi + yi) + return (tf.add(i, 1, name="inc"), + tf.identity(xi, name="xi"), + tf.add(xi, yi, name="xi_plus_yi")) + + _, x_f, y_f = tf.while_loop(c, b, [i, x, y]) + with tf.control_dependencies([x_f]): + y_f_d = tf.identity(y_f, name="y_f_d") + + self.assertAllClose(2.0, y_f_d.eval()) # y_f_d = 1.0 + 1.0 + g = tf.gradients([y_f_d], [x])[0] + self.assertTrue(g is not None) + self.assertAllClose(1.0, g.eval()) # y_f_d = x + 1.0, dy_f_d/dx = 1.0 + def _testNestedWhileGrad_Simple(self, use_gpu): with self.test_session(use_gpu=use_gpu): v = tf.constant(1.0) diff --git a/tensorflow/python/ops/control_flow_ops.py b/tensorflow/python/ops/control_flow_ops.py index eee3b3e2d4e..ae3770416f3 100644 --- a/tensorflow/python/ops/control_flow_ops.py +++ b/tensorflow/python/ops/control_flow_ops.py @@ -348,9 +348,11 @@ def merge(inputs, name=None): A tuple containing the chosen input tensor and its index in `inputs`. Raises: - ValueError: If inputs are IndexedSlices and some but not all have a - dense_shape property. + ValueError: If any of the inputs is None, or inputs are IndexedSlices and + some but not all have a dense_shape property. """ + if any([inp is None for inp in inputs]): + raise ValueError("At least one of the merge inputs is None: %s" % inputs) with ops.op_scope(inputs, name, "Merge") as name: inputs = [ops.convert_to_tensor_or_indexed_slices(inp, as_ref=True) for inp in inputs] diff --git a/tensorflow/python/ops/gradients.py b/tensorflow/python/ops/gradients.py index efd0826e566..27b7f044039 100644 --- a/tensorflow/python/ops/gradients.py +++ b/tensorflow/python/ops/gradients.py @@ -192,9 +192,6 @@ def _PendingCount(graph, to_ops, from_ops, colocate_gradients_with_ops): for x in op.inputs: if between_ops[x.op._id]: pending_count[x.op._id] += 1 - for x in op.control_inputs: - if between_ops[x._id]: - pending_count[x._id] += 1 return pending_count, loop_state @@ -361,6 +358,7 @@ def gradients(ys, grad_ys = [None] * len(ys) else: grad_ys = _AsList(grad_ys) + with ops.op_scope(ys + xs + grad_ys, name, "gradients"): ys = ops.convert_n_to_tensor_or_indexed_slices(ys, name="y") xs = ops.convert_n_to_tensor_or_indexed_slices(xs, name="x") @@ -512,10 +510,6 @@ def gradients(ys, control_flow_ops.IsLoopSwitch(x.op)) if ready: queue.append(x.op) - for x in op.control_inputs: - pending_count[x._id] -= 1 - if pending_count[x._id] is 0: - queue.append(x) # pylint: enable=protected-access if loop_state: From 5d3973adcf304376a69875c4290505bc24d38163 Mon Sep 17 00:00:00 2001 From: "A. Unique TensorFlower" Date: Mon, 1 Aug 2016 10:27:57 -0800 Subject: [PATCH 017/134] Adding documentation for slim/data. Change: 129006903 --- .../contrib/slim/python/slim/data/README.md | 153 ++++++++++++++++++ .../python/slim/data/tfexample_decoder.py | 10 +- 2 files changed, 158 insertions(+), 5 deletions(-) create mode 100644 tensorflow/contrib/slim/python/slim/data/README.md diff --git a/tensorflow/contrib/slim/python/slim/data/README.md b/tensorflow/contrib/slim/python/slim/data/README.md new file mode 100644 index 00000000000..858c6949902 --- /dev/null +++ b/tensorflow/contrib/slim/python/slim/data/README.md @@ -0,0 +1,153 @@ +# TensorFlow-Slim Data + +TF-Slim provides a data loading library for facilitating the reading of data +from various formats. TF-Slim's data modules are composed of several layers of +abstraction to make it flexible enough to support multiple file storage types, +such as TFRecords or Text files, data encoding and features naming schemes. + +# Overview + +The task of loading data has two main components: (1) specification of how +a dataset is represented so it can be read and interpreted and (2) instruction +for providing the data to consumers of the dataset. + +Secondly, one must specify instructions for how +the data is actually provided and housed in memory. For example, if the data is +sharded over many sources, should it be read in parallel from these sources? +Should it be read serially? Should the data be shuffled in memory? + +# Dataset Specification + +TF-Slim defines a dataset to be a set of files (that may or may not be encoded) +representing a finite set of samples, and which can be read to provide a +predefined set of entities or `items`. For example, a dataset might be stored +over thousands of files or a single file. The files might store the data in +clear text or some advanced encoding scheme. It might provide a single `item`, +like an image, or several `items`, like an image, a class label and a scene +label. + +More concretely, TF-Slim's +[dataset](https://www.tensorflow.org/code/tensorflow/contrib/slim/python/slim/data/dataset.py) +is a tuple that encapsulates the following elements of a dataset specification: + +* `data_sources`: A list of file paths that together make up the dataset +* `reader`: A TensorFlow +[Reader](https://www.tensorflow.org/api_docs/python/io_ops.html#ReaderBase) +appropriate for the file type in `data_sources`. +* `decoder`: A TF-Slim +[data_decoder](https://www.tensorflow.org/code/tensorflow/contrib/slim/python/slim/data/data_decoder.py) +class which is used to decode the content of the read dataset files. +* `num_samples`: The number of samples in the dataset. +* `items_to_descriptions`: A map from the items provided by the dataset to +descriptions of each. + +In a nutshell, a dataset is read by (a) opening the files specified by +`data_sources` using the given `reader` class (b) decoding the files using +the given `decoder` and (c) allowing the user to request a list of `items` to +be returned as `Tensors`. + +## Data Decoders + +A +[data_decoder](https://www.tensorflow.org/code/tensorflow/contrib/slim/python/slim/data/data_decoder.py) +is a class which is given some (possibly serialized/encoded) data and returns a +list of `Tensors`. In particular, a given data decoder is able to decode a +predefined list of `items` and can return a subset or all of them, when +requested: + +```python +# Load the data +my_encoded_data = ... +data_decoder = MyDataDecoder() + +# Decode the inputs and labels: +decoded_input, decoded_labels = data_decoder.Decode(data, ['input', 'labels']) + +# Decode just the inputs: +decoded_input = data_decoder.Decode(data, ['input']) + +# Check which items a data decoder knows how to decode: +for item in data_decoder.list_items(): + print(item) +``` + +## Example: TFExampleDataDecoder + +The +[tfexample_data_decoder.py](https://www.tensorflow.org/code/tensorflow/contrib/slim/python/slim/data/tfexample_data_decoder.py) +is a data decoder which decodes serialized `TFExample` protocol buffers. A +`TFExample` protocol buffer is a map from keys (strings) to either a +`tf.FixedLenFeature` or `tf.VarLenFeature`. Consequently, to decode a +`TFExample`, one must provide a mapping from one or more `TFExample` fields +to each of the `items` that the `tfexample_data_decoder` can provide. For +example, a dataset of `TFExamples` might store images in various formats and +each `TFExample` might contain an `encoding` key and a `format` key which can +be used to decode the image using the appropriate decoder (jpg, png, etc). + +To make this possible, the `tfexample_data_decoder` is constructed by specifying +the a map of `TFExample` keys to either `tf.FixedLenFeature` or +`tf.VarLenFeature` as well as a set of `ItemHandlers`. An `ItemHandler` +provides a mapping from `TFExample` keys to the item being provided. Because a +`tfexample_data_decoder` might return multiple `items`, one often constructs a +`tfexample_data_decoder` using multiple `ItemHandlers`. + +`tfexample_data_decoder` provides some predefined `ItemHandlers` which take care +of the common cases of mapping `TFExamples` to images, `Tensors` and +`SparseTensors`. For example, the following specification might be +used to decode a dataset of images: + +```python +keys_to_features = { + 'image/encoded': tf.FixedLenFeature((), tf.string, default_value=''), + 'image/format': tf.FixedLenFeature((), tf.string, default_value='raw'), + 'image/class/label': tf.FixedLenFeature( + [1], tf.int64, default_value=tf.zeros([1], dtype=tf.int64)), +} + +items_to_handlers = { + 'image': tfexample_decoder.Image( + image_key = 'image/encoded', + format_key = 'image/format', + shape=[28, 28], + channels=1), + 'label': tfexample_decoder.Tensor('image/class/label'), +} + +decoder = tfexample_decoder.TFExampleDecoder( + keys_to_features, items_to_handlers) +``` + +Notice that the TFExample is parsed using three keys: `image/encoded`, +`image/format` and `image/class/label`. Additionally, the first two keys are +mapped to a single `item` named 'image'. As defined, this `data_decoder` +provides two `items` named 'image' and 'label'. + +# Data Provision + +A +[data_provider](https://www.tensorflow.org/code/tensorflow/contrib/slim/python/slim/data/data_provider.py) +is a class which provides `Tensors` for each item requested: + +```python +my_data_provider = ... +image, class_label, bounding_box = my_data_provider.get( + ['image', 'label', 'bb']) +``` + +The +[dataset_data_provider](https://www.tensorflow.org/code/tensorflow/contrib/slim/python/slim/data/dataset_data_provider.py) +is a `data_provider` that provides data from a given `dataset` specification: + +```python +dataset = GetDataset(...) +data_provider = dataset_data_provider.DatasetDataProvider( + dataset, common_queue_capacity=32, common_queue_min=8) +``` + +The `dataset_data_provider` enables control over several elements of data +provision: + +* How many concurrent readers are used. +* Whether the data is shuffled as its loaded into its queue +* Whether to take a single pass over the data or read data indefinitely. + diff --git a/tensorflow/contrib/slim/python/slim/data/tfexample_decoder.py b/tensorflow/contrib/slim/python/slim/data/tfexample_decoder.py index cd052576044..627564cde7d 100644 --- a/tensorflow/contrib/slim/python/slim/data/tfexample_decoder.py +++ b/tensorflow/contrib/slim/python/slim/data/tfexample_decoder.py @@ -1,4 +1,4 @@ -# Copyright 2016 Google Inc. All Rights Reserved. +# Copyright 2016 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. @@ -97,7 +97,7 @@ class ItemHandlerCallback(ItemHandler): class Tensor(ItemHandler): - """An ItemHandler that returns a parsed Tensor or SparseTensor.""" + """An ItemHandler that returns a parsed Tensor.""" def __init__(self, tensor_key, shape_key=None, shape=None, default_value=0): """Initializes the Tensor handler. @@ -114,10 +114,10 @@ class Tensor(ItemHandler): tensor_key: the name of the `TFExample` feature to read the tensor from. shape_key: Optional name of the TF-Example feature in which the tensor shape is stored. - shape: Optional output shape of the Tensor. If provided, the `Tensor` is + shape: Optional output shape of the `Tensor`. If provided, the `Tensor` is reshaped accordingly. - default_value: Scalar value to set when making dense for indices not - specified in the `SparseTensor`. + default_value: The value used when the `tensor_key` is not found in a + particular `TFExample`. Raises: ValueError: if both `shape_key` and `shape` are specified. From b1d9ef53ad6fbf1d98374471456040aecc0b4799 Mon Sep 17 00:00:00 2001 From: "A. Unique TensorFlower" Date: Mon, 1 Aug 2016 10:57:02 -0800 Subject: [PATCH 018/134] Simplify tf.nn.sufficient_statistics. Change: 129010238 --- tensorflow/python/ops/nn.py | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/tensorflow/python/ops/nn.py b/tensorflow/python/ops/nn.py index a69a72564b2..9ed801dcc5a 100644 --- a/tensorflow/python/ops/nn.py +++ b/tensorflow/python/ops/nn.py @@ -749,27 +749,19 @@ def sufficient_statistics(x, axes, shift=None, keep_dims=False, name=None): * the (possibly shifted) sum of squares of the elements in the array. * the shift by which the mean must be corrected or None if `shift` is None. """ - with ops.op_scope([x, axes, shift], name, "sufficient_statistics"): + axes = list(set(axes)) + with ops.op_scope([x, shift], name, "sufficient_statistics"): x = ops.convert_to_tensor(x, name="x") x_shape = x.get_shape() if x_shape.is_fully_defined(): counts = 1 - m_shape = [] - for d in xrange(x_shape.ndims): - dim = x_shape[d].value - if d in set(axes): - counts *= dim - dim = 1 - m_shape.append(dim) + for d in axes: + counts *= x_shape[d].value counts = constant_op.constant(counts, dtype=x.dtype) else: # shape needs to be inferred at runtime. - x_shape = array_ops.shape(x) - select_axes = sparse_ops.sparse_to_dense(axes, array_ops.shape(x_shape), - True, False) - m_shape = math_ops.select(select_axes, array_ops.ones_like(x_shape), - x_shape) + x_dims = array_ops.gather(array_ops.shape(x), axes) counts = math_ops.cast( - math_ops.reduce_prod(x_shape / m_shape), x.dtype, name="count") + math_ops.reduce_prod(x_dims), x.dtype, name="count") if shift is not None: shift = ops.convert_to_tensor(shift, name="shift") m_ss = math_ops.sub(x, shift) From 19ad04564a70ae0134c044666460f47714e287f1 Mon Sep 17 00:00:00 2001 From: Vijay Vasudevan Date: Mon, 1 Aug 2016 11:08:01 -0800 Subject: [PATCH 019/134] TensorFlow: Add Conv3D/MaxPool3D/AvgPool3D C++ shape inference functions . Change: 129011665 --- tensorflow/core/framework/common_shape_fns.cc | 141 ++++++++++++++++++ tensorflow/core/framework/common_shape_fns.h | 6 + .../core/framework/common_shape_fns_test.cc | 69 +++++++++ tensorflow/core/ops/nn_ops.cc | 3 + 4 files changed, 219 insertions(+) diff --git a/tensorflow/core/framework/common_shape_fns.cc b/tensorflow/core/framework/common_shape_fns.cc index eea3112b3fa..65cfb1a90e6 100644 --- a/tensorflow/core/framework/common_shape_fns.cc +++ b/tensorflow/core/framework/common_shape_fns.cc @@ -263,6 +263,75 @@ Status Conv2DShape(shape_inference::InferenceContext* c) { return Status::OK(); } +Status Conv3DShape(shape_inference::InferenceContext* c) { + const Shape* input_shape; + TF_RETURN_IF_ERROR(c->WithRank(c->input(0), 5, &input_shape)); + const Shape* filter_shape; + TF_RETURN_IF_ERROR(c->WithRank(c->input(1), 5, &filter_shape)); + + std::vector strides; + TF_RETURN_IF_ERROR(c->GetAttr("strides", &strides)); + if (strides.size() != 5) { + return errors::InvalidArgument( + "Conv3D requires the stride attribute to contain 5 values, but got: ", + strides.size()); + } + + int32 stride_planes = strides[1]; + int32 stride_rows = strides[2]; + int32 stride_cols = strides[3]; + + const Dimension* batch_size_dim = c->Dim(input_shape, 0); + const Dimension* in_planes_dim = c->Dim(input_shape, 1); + const Dimension* in_rows_dim = c->Dim(input_shape, 2); + const Dimension* in_cols_dim = c->Dim(input_shape, 3); + + const Dimension* filter_planes_dim = c->Dim(filter_shape, 0); + const Dimension* filter_rows_dim = c->Dim(filter_shape, 1); + const Dimension* filter_cols_dim = c->Dim(filter_shape, 2); + const Dimension* output_depth_dim = c->Dim(filter_shape, 4); + + // At the moment we need to know the values of several fields. + TF_RETURN_IF_ERROR(CheckKnownDim(c, in_planes_dim, "in_planes")); + TF_RETURN_IF_ERROR(CheckKnownDim(c, in_rows_dim, "in_rows")); + TF_RETURN_IF_ERROR(CheckKnownDim(c, in_cols_dim, "in_cols")); + TF_RETURN_IF_ERROR(CheckKnownDim(c, filter_planes_dim, "filter_planes")); + TF_RETURN_IF_ERROR(CheckKnownDim(c, filter_rows_dim, "filter_rows")); + TF_RETURN_IF_ERROR(CheckKnownDim(c, filter_cols_dim, "filter_cols")); + + auto in_planes = c->Value(in_planes_dim); + auto in_rows = c->Value(in_rows_dim); + auto in_cols = c->Value(in_cols_dim); + auto filter_planes = c->Value(filter_planes_dim); + auto filter_rows = c->Value(filter_rows_dim); + auto filter_cols = c->Value(filter_cols_dim); + + const Dimension* unused; + TF_RETURN_IF_ERROR( + c->Merge(c->Dim(input_shape, 4), c->Dim(filter_shape, 3), &unused)); + + Padding padding; + TF_RETURN_IF_ERROR(c->GetAttr("padding", &padding)); + + int64 output_planes, output_rows, output_cols; + int64 padding_before, padding_after; + TF_RETURN_IF_ERROR(GetWindowedOutputSizeVerbose( + in_planes, filter_planes, stride_planes, padding, &output_planes, + &padding_before, &padding_after)); + TF_RETURN_IF_ERROR(GetWindowedOutputSizeVerbose( + in_rows, filter_rows, stride_rows, padding, &output_rows, &padding_before, + &padding_after)); + TF_RETURN_IF_ERROR(GetWindowedOutputSizeVerbose( + in_cols, filter_cols, stride_cols, padding, &output_cols, &padding_before, + &padding_after)); + + const Shape* output_shape = + c->MakeShape({batch_size_dim, output_planes, output_rows, output_cols, + output_depth_dim}); + c->set_output(0, output_shape); + return Status::OK(); +} + Status DepthwiseConv2DNativeShape(shape_inference::InferenceContext* c) { const Shape* input_shape; TF_RETURN_IF_ERROR(c->WithRank(c->input(0), 4, &input_shape)); @@ -507,6 +576,78 @@ Status MaxPoolShape(shape_inference::InferenceContext* c) { return Status::OK(); } +Status Pool3DShape(shape_inference::InferenceContext* c) { + const Shape* input_shape; + TF_RETURN_IF_ERROR(c->WithRank(c->input(0), 5, &input_shape)); + + std::vector strides; + TF_RETURN_IF_ERROR(c->GetAttr("strides", &strides)); + if (strides.size() != 5) { + return errors::InvalidArgument( + "Pool3D ops require the stride attribute to contain 5 values, but " + "got: ", + strides.size()); + } + + std::vector kernel_sizes; + TF_RETURN_IF_ERROR(c->GetAttr("ksize", &kernel_sizes)); + if (kernel_sizes.size() != 5) { + return errors::InvalidArgument( + "Pool3D requires the ksize attribute to contain 5 values, but got: ", + kernel_sizes.size()); + } + + int32 stride_planes, stride_rows, stride_cols; + int32 kernel_planes, kernel_rows, kernel_cols; + + stride_planes = strides[1]; + stride_rows = strides[2]; + stride_cols = strides[3]; + kernel_planes = kernel_sizes[1]; + kernel_rows = kernel_sizes[2]; + kernel_cols = kernel_sizes[3]; + + const Dimension* batch_size_dim = c->Dim(input_shape, 0); + const Dimension* in_planes_dim = c->Dim(input_shape, 1); + const Dimension* in_rows_dim = c->Dim(input_shape, 2); + const Dimension* in_cols_dim = c->Dim(input_shape, 3); + const Dimension* output_depth_dim = c->Dim(input_shape, 4); + + // At the moment we need to know the values of several fields. + TF_RETURN_IF_ERROR(CheckKnownDim(c, in_planes_dim, "in_planes")); + TF_RETURN_IF_ERROR(CheckKnownDim(c, in_rows_dim, "in_rows")); + TF_RETURN_IF_ERROR(CheckKnownDim(c, in_cols_dim, "in_cols")); + + Padding padding; + TF_RETURN_IF_ERROR(c->GetAttr("padding", &padding)); + + // TODO(mrry,shlens): Raise an error if the stride would cause + // information in the input to be ignored. This will require a change + // in the kernel implementation. + auto in_planes = c->Value(in_planes_dim); + auto in_rows = c->Value(in_rows_dim); + auto in_cols = c->Value(in_cols_dim); + + int64 output_planes, output_rows, output_cols; + int64 padding_before, padding_after; + TF_RETURN_IF_ERROR(GetWindowedOutputSizeVerbose( + in_planes, kernel_planes, stride_planes, padding, &output_planes, + &padding_before, &padding_after)); + TF_RETURN_IF_ERROR(GetWindowedOutputSizeVerbose( + in_rows, kernel_rows, stride_rows, padding, &output_rows, &padding_before, + &padding_after)); + TF_RETURN_IF_ERROR(GetWindowedOutputSizeVerbose( + in_cols, kernel_cols, stride_cols, padding, &output_cols, &padding_before, + &padding_after)); + + const Shape* output_shape = + c->MakeShape({batch_size_dim, output_planes, output_rows, output_cols, + output_depth_dim}); + + c->set_output(0, output_shape); + return Status::OK(); +} + Status UnknownShape(shape_inference::InferenceContext* c) { for (int i = 0; i < c->num_outputs(); ++i) { c->set_output(i, c->UnknownShape()); diff --git a/tensorflow/core/framework/common_shape_fns.h b/tensorflow/core/framework/common_shape_fns.h index f1bdd5ee8d1..0ca64990365 100644 --- a/tensorflow/core/framework/common_shape_fns.h +++ b/tensorflow/core/framework/common_shape_fns.h @@ -157,6 +157,9 @@ Status BiasAddGradShape(shape_inference::InferenceContext* c); // Shape function for Conv2D-like operations. Status Conv2DShape(shape_inference::InferenceContext* c); +// Shape function for Conv3D-like operations. +Status Conv3DShape(shape_inference::InferenceContext* c); + // Shape function for DepthwiseConv2D-like operations. Status DepthwiseConv2DNativeShape(shape_inference::InferenceContext* c); @@ -166,6 +169,9 @@ Status AvgPoolShape(shape_inference::InferenceContext* c); // Shape function for MaxPool-like operations. Status MaxPoolShape(shape_inference::InferenceContext* c); +// Shape function for 3D Pooling operations. +Status Pool3DShape(shape_inference::InferenceContext* c); + // Shape function for use with ops whose output shapes are unknown. Status UnknownShape(shape_inference::InferenceContext* c); diff --git a/tensorflow/core/framework/common_shape_fns_test.cc b/tensorflow/core/framework/common_shape_fns_test.cc index eada469b17a..6e0dd7f742d 100644 --- a/tensorflow/core/framework/common_shape_fns_test.cc +++ b/tensorflow/core/framework/common_shape_fns_test.cc @@ -419,6 +419,55 @@ TEST(CommonShapeFnsTest, Conv2DShapeTest) { INFER_OK(op, "[1,4,4,1];[2,2,1,1]", "[d0_0,4,4,d1_3]"); } +TEST(CommonShapeFnsTest, Conv3DShapeTest) { + ShapeInferenceTestOp op("Conv3D"); + auto set_op = [&op](const std::vector& strides, + const string& padding) { + TF_CHECK_OK(NodeDefBuilder("test", "Conv3D") + .Input("input", 0, DT_FLOAT) + .Input("filter", 0, DT_FLOAT) + .Attr("strides", strides) + .Attr("padding", padding) + .Finalize(&op.node_def)); + }; + + // 1x1x1 filter + set_op({{1, 1, 1, 1, 1}}, "VALID"); + INFER_OK(op, "[1,2,2,2,1];[1,1,1,1,1]", "[d0_0,2,2,2,d1_4]"); + + // Invalid rank for input + INFER_ERROR("must be rank 5", op, "[4,4];[2,1,1,1]"); + // Invalid rank for filter + INFER_ERROR("must be rank 5", op, "[1,4,4,1];[2,1,1]"); + + // No unknown dims in the critical fields. + INFER_ERROR("is not known", op, "[1,?,2,2,1];[1,1,1,1,1]"); + INFER_ERROR("is not known", op, "[1,2,?,2,1];[1,1,1,1,1]"); + INFER_ERROR("is not known", op, "[1,2,2,?,1];[1,1,1,1,1]"); + INFER_ERROR("is not known", op, "[1,2,2,2,1];[?,1,1,1,1]"); + INFER_ERROR("is not known", op, "[1,2,2,2,1];[1,?,1,1,1]"); + + // input depths must match. + INFER_ERROR("Dimensions must be equal, but are 10 and 10000", op, + "[1,2,2,2,10];[1,1,1,10000,20]"); + + // 2x2x2 filter + set_op({{1, 1, 1, 1, 1}}, "VALID"); + INFER_OK(op, "[1,2,2,2,1];[2,2,2,1,1]", "[d0_0,1,1,1,d1_4]"); + + // 3x3 input, 1x1 filter, 2x2 stride + set_op({{1, 2, 2, 2, 1}}, "VALID"); + INFER_OK(op, "[1,3,3,3,1];[1,1,1,1,1]", "[d0_0,2,2,2,d1_4]"); + + // 3x3 input, 1x1 filter, 2x1x1 stride + set_op({{1, 2, 1, 1, 1}}, "VALID"); + INFER_OK(op, "[1,3,3,3,1];[1,1,1,1,1]", "[d0_0,2,3,3,d1_4]"); + + // 4x4 input, 2x2 filter, 1x1 stride + set_op({{1, 1, 1, 1, 1}}, "SAME"); + INFER_OK(op, "[1,4,4,4,1];[2,2,2,1,1]", "[d0_0,4,4,4,d1_4]"); +} + TEST(CommonShapeFnsTest, DepthwiseConv2DShapeTest) { ShapeInferenceTestOp op("DepthwiseConv2dNative"); std::vector strides = {{1, 1, 1, 1}}; @@ -512,6 +561,26 @@ TEST(CommonShapeFnsTest, MaxPool2DShapeTest) { INFER_OK(op, "[1,7,5,5]", "[d0_0,3,5,5]"); } +TEST(CommonShapeFnsTest, Pool3DShapeTest) { + ShapeInferenceTestOp op("MaxPool3D"); + auto set_op = [&op](const std::vector& strides, + const std::vector& ksizes, const string& padding) { + TF_CHECK_OK(NodeDefBuilder("test", "MaxPool3D") + .Input("input", 0, DT_FLOAT) + .Attr("strides", strides) + .Attr("ksize", ksizes) + .Attr("padding", padding) + .Finalize(&op.node_def)); + }; + + // Most of the functionality is tested by conv-like shapes, + // so we check that we handle the extra dimension properly. + + // 2x3x4 stride, 1x1x1 filter. + set_op({1, 2, 3, 4, 1}, {1, 1, 1, 1, 1}, "VALID"); + INFER_OK(op, "[1,24,24,24,1]", "[d0_0,12,8,6,d0_4]"); +} + TEST(CommonShapeFnsTest, UnknownShapeTest) { { // Single output diff --git a/tensorflow/core/ops/nn_ops.cc b/tensorflow/core/ops/nn_ops.cc index 03ada875112..3a2c02bd858 100644 --- a/tensorflow/core/ops/nn_ops.cc +++ b/tensorflow/core/ops/nn_ops.cc @@ -533,6 +533,7 @@ REGISTER_OP("Conv3D") .Attr("T: numbertype") .Attr("strides: list(int) >= 5") .Attr(GetPaddingAttrString()) + .SetShapeFn(shape_inference::Conv3DShape) .Doc(R"doc( Computes a 3-D convolution given 5-D `input` and `filter` tensors. @@ -677,6 +678,7 @@ REGISTER_OP("AvgPool3D") .Attr("strides: list(int) >= 5") .Attr(GetPaddingAttrString()) .Attr("T: numbertype") + .SetShapeFn(shape_inference::Pool3DShape) .Doc(R"doc( Performs 3D average pooling on the input. @@ -726,6 +728,7 @@ REGISTER_OP("MaxPool3D") .Attr("strides: list(int) >= 5") .Attr(GetPaddingAttrString()) .Attr("T: numbertype") + .SetShapeFn(shape_inference::Pool3DShape) .Doc(R"doc( Performs 3D max pooling on the input. From 0691f0a94f04d8b81c1435de689e3d2056847bb8 Mon Sep 17 00:00:00 2001 From: Rohan Jain Date: Mon, 1 Aug 2016 11:12:11 -0800 Subject: [PATCH 020/134] Adding list_directory and walk functions to the File IO API. Change: 129012063 --- tensorflow/python/lib/io/file_io.i | 5 +- tensorflow/python/lib/io/file_io.py | 82 +++++++++++++++-- tensorflow/python/lib/io/file_io_test.py | 111 ++++++++++++++++++++++- 3 files changed, 184 insertions(+), 14 deletions(-) diff --git a/tensorflow/python/lib/io/file_io.i b/tensorflow/python/lib/io/file_io.i index 12ab8566e96..13ae0d1b363 100644 --- a/tensorflow/python/lib/io/file_io.i +++ b/tensorflow/python/lib/io/file_io.i @@ -21,6 +21,7 @@ limitations under the License. #include "tensorflow/core/framework/types.h" #include "tensorflow/core/lib/core/status.h" #include "tensorflow/core/lib/core/stringpiece.h" +#include "tensorflow/core/lib/io/path.h" #include "tensorflow/core/lib/io/match.h" #include "tensorflow/core/platform/env.h" #include "tensorflow/core/protobuf/meta_graph.pb.h" @@ -82,7 +83,7 @@ void CreateDir(const string& dirname, TF_Status* out_status) { void CopyFile(const string& oldpath, const string& newpath, bool overwrite, TF_Status* out_status) { - // If overwrite is false and the newpath file exists then its an error. + // If overwrite is false and the newpath file exists then it's an error. if (!overwrite && FileExists(newpath)) { TF_SetStatus(out_status, TF_ALREADY_EXISTS, "file already exists"); return; @@ -159,3 +160,5 @@ void RenameFile(const string& oldname, const string& newname, bool overwrite, TF_Status* out_status); void DeleteRecursively(const string& dirname, TF_Status* out_status); bool IsDirectory(const string& dirname, TF_Status* out_status); + +%include "tensorflow/core/lib/io/path.h" diff --git a/tensorflow/python/lib/io/file_io.py b/tensorflow/python/lib/io/file_io.py index a0ec199d3a0..4a6dc9f6181 100644 --- a/tensorflow/python/lib/io/file_io.py +++ b/tensorflow/python/lib/io/file_io.py @@ -12,7 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== - """File IO methods that wrap the C++ FileSystem API. The C++ FileSystem API is SWIG wrapped in file_io.i. These functions call those @@ -22,6 +21,8 @@ from __future__ import absolute_import from __future__ import division from __future__ import print_function +import os + from tensorflow.python import pywrap_tensorflow from tensorflow.python.framework import errors from tensorflow.python.util import compat @@ -43,8 +44,8 @@ def read_file_to_string(filename): def write_string_to_file(filename, file_content): with errors.raise_exception_on_not_ok_status() as status: - pywrap_tensorflow.WriteStringToFile(compat.as_bytes(filename), - compat.as_bytes(file_content), status) + pywrap_tensorflow.WriteStringToFile( + compat.as_bytes(filename), compat.as_bytes(file_content), status) def get_matching_files(filename): @@ -61,22 +62,21 @@ def recursive_create_dir(dirname): with errors.raise_exception_on_not_ok_status() as status: dirs = dirname.split('/') for i in range(len(dirs)): - partial_dir = '/'.join(dirs[0:i+1]) + partial_dir = '/'.join(dirs[0:i + 1]) if partial_dir and not file_exists(partial_dir): pywrap_tensorflow.CreateDir(compat.as_bytes(partial_dir), status) def copy(oldpath, newpath, overwrite=False): with errors.raise_exception_on_not_ok_status() as status: - pywrap_tensorflow.CopyFile(compat.as_bytes(oldpath), - compat.as_bytes(newpath), overwrite, status) + pywrap_tensorflow.CopyFile( + compat.as_bytes(oldpath), compat.as_bytes(newpath), overwrite, status) def rename(oldname, newname, overwrite=False): with errors.raise_exception_on_not_ok_status() as status: - return pywrap_tensorflow.RenameFile(compat.as_bytes(oldname), - compat.as_bytes(newname), overwrite, - status) + return pywrap_tensorflow.RenameFile( + compat.as_bytes(oldname), compat.as_bytes(newname), overwrite, status) def delete_recursively(dirname): @@ -87,3 +87,67 @@ def delete_recursively(dirname): def is_directory(dirname): with errors.raise_exception_on_not_ok_status() as status: return pywrap_tensorflow.IsDirectory(compat.as_bytes(dirname), status) + + +def list_directory(dirname): + """Returns a list of entries contained within a directory. + + The list is in arbitrary order. It does not contain the special entries "." + and "..". + + Args: + dirname: string, path to a directory + + Raises: + NotFoundError if directory doesn't exist + + Returns: + [filename1, filename2, ... filenameN] + """ + if not is_directory(dirname): + raise errors.NotFoundError(None, None, 'Could not find directory') + file_list = get_matching_files(os.path.join(compat.as_str_any(dirname), '*')) + return [compat.as_bytes(pywrap_tensorflow.Basename(compat.as_bytes(filename))) + for filename in file_list] + + +def walk(top, in_order=True): + """Recursive directory tree generator for directories. + + Args: + top: string, a Directory name + in_order: bool, Traverse in order if True, post order if False. + + Errors that happen while listing directories are ignored. + + Yields: + # Each yield is a 3-tuple: the pathname of a directory, followed + # by lists of all its subdirectories and leaf files. + (dirname, [subdirname, subdirname, ...], [filename, filename, ...]) + """ + top = compat.as_bytes(top) + try: + listing = list_directory(top) + except errors.NotFoundError: + return + + files = [] + subdirs = [] + for item in listing: + full_path = os.path.join(top, item) + if is_directory(full_path): + subdirs.append(item) + else: + files.append(item) + + here = (top, subdirs, files) + + if in_order: + yield here + + for subdir in subdirs: + for subitem in walk(os.path.join(top, subdir), in_order): + yield subitem + + if not in_order: + yield here diff --git a/tensorflow/python/lib/io/file_io_test.py b/tensorflow/python/lib/io/file_io_test.py index b47b687a2ac..fc702de4ad7 100644 --- a/tensorflow/python/lib/io/file_io_test.py +++ b/tensorflow/python/lib/io/file_io_test.py @@ -12,7 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================= - """Testing File IO operations in file_io.py.""" from __future__ import absolute_import from __future__ import division @@ -24,6 +23,7 @@ import tensorflow as tf from tensorflow.python.framework import errors from tensorflow.python.lib.io import file_io +from tensorflow.python.util import compat class FileIoTest(tf.test.TestCase): @@ -60,9 +60,9 @@ class FileIoTest(tf.test.TestCase): file_path = os.path.join(dir_path, name) file_io.write_string_to_file(file_path, "testing") expected_match = [os.path.join(dir_path, name) for name in files] - self.assertItemsEqual(file_io.get_matching_files(os.path.join(dir_path, - "file*.txt")), - expected_match) + self.assertItemsEqual( + file_io.get_matching_files(os.path.join(dir_path, "file*.txt")), + expected_match) file_io.delete_recursively(dir_path) self.assertFalse(file_io.file_exists(os.path.join(dir_path, "file3.txt"))) @@ -144,5 +144,108 @@ class FileIoTest(tf.test.TestCase): # False for a file. self.assertFalse(file_io.is_directory(file_path)) + def testListDirectory(self): + dir_path = os.path.join(self._base_dir, "test_dir") + file_io.create_dir(dir_path) + files = [b"file1.txt", b"file2.txt", b"file3.txt"] + for name in files: + file_path = os.path.join(dir_path, compat.as_str_any(name)) + file_io.write_string_to_file(file_path, "testing") + subdir_path = os.path.join(dir_path, "sub_dir") + file_io.create_dir(subdir_path) + subdir_file_path = os.path.join(subdir_path, "file4.txt") + file_io.write_string_to_file(subdir_file_path, "testing") + dir_list = file_io.list_directory(dir_path) + self.assertItemsEqual(files + [b"sub_dir"], dir_list) + + def testListDirectoryFailure(self): + dir_path = os.path.join(self._base_dir, "test_dir") + with self.assertRaises(errors.NotFoundError): + file_io.list_directory(dir_path) + + def _setupWalkDirectories(self, dir_path): + # Creating a file structure as follows + # test_dir -> file: file1.txt; dirs: subdir1_1, subdir1_2, subdir1_3 + # subdir1_1 -> file: file3.txt + # subdir1_2 -> dir: subdir2 + file_io.create_dir(dir_path) + file_io.write_string_to_file(os.path.join(dir_path, "file1.txt"), "testing") + sub_dirs1 = ["subdir1_1", "subdir1_2", "subdir1_3"] + for name in sub_dirs1: + file_io.create_dir(os.path.join(dir_path, name)) + file_io.write_string_to_file( + os.path.join(dir_path, "subdir1_1/file2.txt"), "testing") + file_io.create_dir(os.path.join(dir_path, "subdir1_2/subdir2")) + + def testWalkInOrder(self): + dir_path = os.path.join(self._base_dir, "test_dir") + self._setupWalkDirectories(dir_path) + # Now test the walk (in_order = True) + all_dirs = [] + all_subdirs = [] + all_files = [] + for (w_dir, w_subdirs, w_files) in file_io.walk(dir_path, in_order=True): + all_dirs.append(w_dir) + all_subdirs.append(w_subdirs) + all_files.append(w_files) + self.assertItemsEqual(all_dirs, [compat.as_bytes(dir_path)] + [ + compat.as_bytes(os.path.join(dir_path, item)) + for item in ["subdir1_1", "subdir1_2", "subdir1_2/subdir2", "subdir1_3"] + ]) + self.assertEqual(compat.as_bytes(dir_path), all_dirs[0]) + self.assertLess( + all_dirs.index(compat.as_bytes(os.path.join(dir_path, "subdir1_2"))), + all_dirs.index( + compat.as_bytes(os.path.join(dir_path, "subdir1_2/subdir2")))) + self.assertItemsEqual(all_subdirs[1:5], [[], [b"subdir2"], [], []]) + self.assertItemsEqual(all_subdirs[0], + [b"subdir1_1", b"subdir1_2", b"subdir1_3"]) + self.assertItemsEqual(all_files, [[b"file1.txt"], [b"file2.txt"], [], [], + []]) + self.assertLess( + all_files.index([b"file1.txt"]), all_files.index([b"file2.txt"])) + + def testWalkPostOrder(self): + dir_path = os.path.join(self._base_dir, "test_dir") + self._setupWalkDirectories(dir_path) + # Now test the walk (in_order = False) + all_dirs = [] + all_subdirs = [] + all_files = [] + for (w_dir, w_subdirs, w_files) in file_io.walk(dir_path, in_order=False): + all_dirs.append(w_dir) + all_subdirs.append(w_subdirs) + all_files.append(w_files) + self.assertItemsEqual(all_dirs, [ + compat.as_bytes(os.path.join(dir_path, item)) + for item in ["subdir1_1", "subdir1_2/subdir2", "subdir1_2", "subdir1_3"] + ] + [compat.as_bytes(dir_path)]) + self.assertEqual(compat.as_bytes(dir_path), all_dirs[4]) + self.assertLess( + all_dirs.index( + compat.as_bytes(os.path.join(dir_path, "subdir1_2/subdir2"))), + all_dirs.index(compat.as_bytes(os.path.join(dir_path, "subdir1_2")))) + self.assertItemsEqual(all_subdirs[0:4], [[], [], [b"subdir2"], []]) + self.assertItemsEqual(all_subdirs[4], + [b"subdir1_1", b"subdir1_2", b"subdir1_3"]) + self.assertItemsEqual(all_files, [[b"file2.txt"], [], [], [], + [b"file1.txt"]]) + self.assertLess( + all_files.index([b"file2.txt"]), all_files.index([b"file1.txt"])) + + def testWalkFailure(self): + dir_path = os.path.join(self._base_dir, "test_dir") + # Try walking a directory that wasn't created. + all_dirs = [] + all_subdirs = [] + all_files = [] + for (w_dir, w_subdirs, w_files) in file_io.walk(dir_path, in_order=False): + all_dirs.append(w_dir) + all_subdirs.append(w_subdirs) + all_files.append(w_files) + self.assertItemsEqual(all_dirs, []) + self.assertItemsEqual(all_subdirs, []) + self.assertItemsEqual(all_files, []) + if __name__ == "__main__": tf.test.main() From 01336ac3293445d08b1c237310ef0a5da13ad763 Mon Sep 17 00:00:00 2001 From: Renato Utsch Date: Mon, 1 Aug 2016 11:35:20 -0800 Subject: [PATCH 021/134] Fix the scrollbar behavior, they are appearing when they are not needed on firefox, making the pages look weird. Change: 129014158 --- .../components/tf-audio-dashboard/tf-audio-dashboard.html | 2 -- .../components/tf-audio-dashboard/tf-audio-grid.html | 2 +- .../components/tf-dashboard-common/tf-dashboard-layout.html | 2 +- .../components/tf-image-dashboard/tf-image-dashboard.html | 2 -- .../components/tf-image-dashboard/tf-image-grid.html | 2 +- .../components/tf-multi-checkbox/tf-multi-checkbox.html | 2 +- 6 files changed, 4 insertions(+), 8 deletions(-) diff --git a/tensorflow/tensorboard/components/tf-audio-dashboard/tf-audio-dashboard.html b/tensorflow/tensorboard/components/tf-audio-dashboard/tf-audio-dashboard.html index 3c803247ac8..6b7ccb0f27c 100644 --- a/tensorflow/tensorboard/components/tf-audio-dashboard/tf-audio-dashboard.html +++ b/tensorflow/tensorboard/components/tf-audio-dashboard/tf-audio-dashboard.html @@ -25,8 +25,6 @@ tf-audio-dashboard displays a dashboard that loads audio from a TensorFlow run.