From 8d579aacb836e4061632268401ff5052b8ff7d9b Mon Sep 17 00:00:00 2001 From: klessard Date: Sun, 25 Apr 2021 22:09:16 -0400 Subject: [PATCH 01/63] Move NdArray library to subfolder --- ndarray/pom.xml | 68 + .../tensorflow/ndarray/BooleanNdArray.java | 108 + .../org/tensorflow/ndarray/ByteNdArray.java | 108 + .../org/tensorflow/ndarray/DoubleNdArray.java | 108 + .../org/tensorflow/ndarray/FloatNdArray.java | 108 + .../ndarray/IllegalRankException.java | 27 + .../org/tensorflow/ndarray/IntNdArray.java | 108 + .../org/tensorflow/ndarray/LongNdArray.java | 108 + .../java/org/tensorflow/ndarray/NdArray.java | 302 ++ .../tensorflow/ndarray/NdArraySequence.java | 67 + .../java/org/tensorflow/ndarray/NdArrays.java | 495 +++ .../java/org/tensorflow/ndarray/Shape.java | 447 ++ .../java/org/tensorflow/ndarray/Shaped.java | 51 + .../org/tensorflow/ndarray/ShortNdArray.java | 108 + .../org/tensorflow/ndarray/StdArrays.java | 3809 +++++++++++++++++ .../ndarray/buffer/BooleanDataBuffer.java | 165 + .../ndarray/buffer/ByteDataBuffer.java | 232 + .../tensorflow/ndarray/buffer/DataBuffer.java | 324 ++ .../ndarray/buffer/DataBufferWindow.java | 93 + .../ndarray/buffer/DataBuffers.java | 457 ++ .../ndarray/buffer/DataStorageVisitor.java | 147 + .../ndarray/buffer/DoubleDataBuffer.java | 165 + .../ndarray/buffer/FloatDataBuffer.java | 165 + .../ndarray/buffer/IntDataBuffer.java | 165 + .../ndarray/buffer/LongDataBuffer.java | 165 + .../ndarray/buffer/ShortDataBuffer.java | 165 + .../buffer/layout/BooleanDataLayout.java | 65 + .../ndarray/buffer/layout/ByteDataLayout.java | 65 + .../ndarray/buffer/layout/DataLayout.java | 129 + .../ndarray/buffer/layout/DataLayouts.java | 96 + .../buffer/layout/DoubleDataLayout.java | 65 + .../buffer/layout/FloatDataLayout.java | 65 + .../ndarray/buffer/layout/IntDataLayout.java | 66 + .../ndarray/buffer/layout/LongDataLayout.java | 65 + .../buffer/layout/ShortDataLayout.java | 65 + .../ndarray/impl/AbstractNdArray.java | 92 + .../tensorflow/ndarray/impl/Validator.java | 55 + .../impl/buffer/AbstractDataBuffer.java | 182 + .../impl/buffer/AbstractDataBufferWindow.java | 48 + .../ndarray/impl/buffer/Validator.java | 132 + .../adapter/AbstractDataBufferAdapter.java | 68 + .../adapter/BooleanDataBufferAdapter.java | 116 + .../buffer/adapter/ByteDataBufferAdapter.java | 135 + .../buffer/adapter/DataBufferAdapter.java | 47 + .../adapter/DataBufferAdapterFactory.java | 142 + .../adapter/DoubleDataBufferAdapter.java | 116 + .../adapter/FloatDataBufferAdapter.java | 116 + .../buffer/adapter/IntDataBufferAdapter.java | 116 + .../buffer/adapter/LongDataBufferAdapter.java | 116 + .../adapter/ShortDataBufferAdapter.java | 116 + .../impl/buffer/layout/Bfloat16Layout.java | 54 + .../impl/buffer/layout/BoolLayout.java | 47 + .../impl/buffer/layout/Float16Layout.java | 119 + .../impl/buffer/layout/StringLayout.java | 48 + .../impl/buffer/misc/ArrayDataBuffer.java | 126 + .../impl/buffer/misc/BitSetDataBuffer.java | 183 + .../buffer/misc/BooleanArrayDataBuffer.java | 176 + .../buffer/misc/MiscDataBufferFactory.java | 40 + .../buffer/nio/AbstractNioDataBuffer.java | 41 + .../impl/buffer/nio/ByteNioDataBuffer.java | 185 + .../impl/buffer/nio/DoubleNioDataBuffer.java | 147 + .../impl/buffer/nio/FloatNioDataBuffer.java | 147 + .../impl/buffer/nio/IntNioDataBuffer.java | 147 + .../impl/buffer/nio/LongNioDataBuffer.java | 147 + .../impl/buffer/nio/NioDataBufferFactory.java | 61 + .../impl/buffer/nio/ShortNioDataBuffer.java | 147 + .../buffer/raw/AbstractRawDataBuffer.java | 94 + .../impl/buffer/raw/BooleanRawDataBuffer.java | 146 + .../impl/buffer/raw/ByteRawDataBuffer.java | 185 + .../impl/buffer/raw/DoubleRawDataBuffer.java | 149 + .../impl/buffer/raw/FloatRawDataBuffer.java | 150 + .../impl/buffer/raw/IntRawDataBuffer.java | 149 + .../impl/buffer/raw/LongRawDataBuffer.java | 149 + .../impl/buffer/raw/RawDataBufferFactory.java | 148 + .../impl/buffer/raw/RawDataBufferWindow.java | 19 + .../impl/buffer/raw/ShortRawDataBuffer.java | 149 + .../impl/buffer/raw/UnsafeMemoryHandle.java | 195 + .../impl/buffer/raw/UnsafeReference.java | 64 + .../impl/dense/AbstractDenseNdArray.java | 163 + .../impl/dense/BooleanDenseNdArray.java | 91 + .../ndarray/impl/dense/ByteDenseNdArray.java | 91 + .../ndarray/impl/dense/DataTransfer.java | 136 + .../ndarray/impl/dense/DenseNdArray.java | 63 + .../impl/dense/DoubleDenseNdArray.java | 91 + .../ndarray/impl/dense/FloatDenseNdArray.java | 91 + .../ndarray/impl/dense/IntDenseNdArray.java | 91 + .../ndarray/impl/dense/LongDenseNdArray.java | 91 + .../ndarray/impl/dense/ShortDenseNdArray.java | 91 + .../ndarray/impl/dense/Validator.java | 49 + .../impl/dimension/AbstractDimension.java | 45 + .../ndarray/impl/dimension/Axis.java | 61 + .../ndarray/impl/dimension/Dimension.java | 36 + .../impl/dimension/DimensionalSpace.java | 224 + .../impl/dimension/IndexedDimension.java | 69 + .../impl/dimension/ReducedDimension.java | 62 + .../dimension/RelativeDimensionalSpace.java | 32 + .../impl/sequence/CoordinatesIncrementor.java | 38 + .../impl/sequence/FastElementSequence.java | 81 + .../sequence/IndexedPositionIterator.java | 28 + .../IndexedSequentialPositionIterator.java | 51 + .../impl/sequence/NdPositionIterator.java | 70 + .../impl/sequence/PositionIterator.java | 42 + .../sequence/SequentialPositionIterator.java | 55 + .../impl/sequence/SingleElementSequence.java | 71 + .../impl/sequence/SlicingElementSequence.java | 77 + .../org/tensorflow/ndarray/index/All.java | 57 + .../java/org/tensorflow/ndarray/index/At.java | 74 + .../tensorflow/ndarray/index/Ellipsis.java | 48 + .../tensorflow/ndarray/index/Hyperslab.java | 90 + .../org/tensorflow/ndarray/index/Index.java | 131 + .../org/tensorflow/ndarray/index/Indices.java | 363 ++ .../org/tensorflow/ndarray/index/NewAxis.java | 53 + .../tensorflow/ndarray/index/Sequence.java | 52 + .../org/tensorflow/ndarray/index/Slice.java | 89 + .../tensorflow/ndarray/index/SliceFrom.java | 86 + .../org/tensorflow/ndarray/index/SliceTo.java | 86 + .../org/tensorflow/ndarray/index/Step.java | 83 + .../ndarray/BooleanNdArrayTestBase.java | 57 + .../ndarray/ByteNdArrayTestBase.java | 55 + .../ndarray/DoubleNdArrayTestBase.java | 55 + .../ndarray/FloatNdArrayTestBase.java | 55 + .../org/tensorflow/ndarray/IndexTest.java | 205 + .../ndarray/IntNdArrayTestBase.java | 55 + .../ndarray/LongNdArrayTestBase.java | 55 + .../tensorflow/ndarray/NdArrayTestBase.java | 338 ++ .../org/tensorflow/ndarray/ShapeTest.java | 170 + .../ndarray/ShortNdArrayTestBase.java | 55 + .../org/tensorflow/ndarray/StdArraysTest.java | 211 + .../ndarray/benchmark/NdArrayBenchmark.java | 163 + .../buffer/BooleanDataBufferTestBase.java | 142 + .../buffer/ByteDataBufferTestBase.java | 145 + .../ndarray/buffer/DataBufferTestBase.java | 293 ++ .../buffer/DoubleDataBufferTestBase.java | 135 + .../buffer/FloatDataBufferTestBase.java | 135 + .../ndarray/buffer/IntDataBufferTestBase.java | 135 + .../buffer/LongDataBufferTestBase.java | 135 + .../buffer/ShortDataBufferTestBase.java | 135 + .../BigIntegerDataBufferAdapterTest.java | 67 + .../adapter/BooleanDataBufferAdapterTest.java | 45 + .../adapter/ByteDataBufferAdapterTest.java | 27 + .../adapter/DoubleDataBufferAdapterTest.java | 61 + .../adapter/FloatDataBufferAdapterTest.java | 52 + .../adapter/IntDataBufferAdapterTest.java | 51 + .../adapter/LongDataBufferAdapterTest.java | 60 + .../adapter/ShortDataBufferAdapterTest.java | 45 + .../buffer/layout/Bfloat16LayoutTest.java | 84 + .../impl/buffer/layout/BoolLayoutTest.java | 42 + .../impl/buffer/layout/Float16LayoutTest.java | 90 + .../impl/buffer/misc/ArrayDataBufferTest.java | 265 ++ .../buffer/misc/BitSetDataBufferTest.java | 34 + .../misc/StringArrayDataBufferTest.java | 33 + .../buffer/nio/ByteNioDataBufferTest.java | 29 + .../buffer/nio/DoubleNioDataBufferTest.java | 29 + .../buffer/nio/FloatNioDataBufferTest.java | 29 + .../impl/buffer/nio/IntNioDataBufferTest.java | 29 + .../buffer/nio/LongNioDataBufferTest.java | 29 + .../buffer/nio/ShortNioDataBufferTest.java | 29 + .../buffer/raw/BooleanRawDataBufferTest.java | 28 + .../buffer/raw/ByteRawDataBufferTest.java | 28 + .../buffer/raw/DoubleRawDataBufferTest.java | 28 + .../buffer/raw/FloatRawDataBufferTest.java | 28 + .../impl/buffer/raw/IntRawDataBufferTest.java | 28 + .../buffer/raw/LongRawDataBufferTest.java | 28 + .../buffer/raw/ShortRawDataBufferTest.java | 28 + .../impl/dense/BooleanDenseNdArrayTest.java | 35 + .../impl/dense/ByteDenseNdArrayTest.java | 35 + .../ndarray/impl/dense/DenseNdArrayTest.java | 51 + .../impl/dense/DoubleDenseNdArrayTest.java | 35 + .../impl/dense/FloatDenseNdArrayTest.java | 35 + .../impl/dense/IntDenseNdArrayTest.java | 35 + .../impl/dense/LongDenseNdArrayTest.java | 35 + .../impl/dense/ShortDenseNdArrayTest.java | 35 + .../impl/dense/StringDenseNdArrayTest.java | 43 + .../impl/sequence/ElementSequenceTest.java | 145 + ndarray/src/test/resources/COPYRIGHT.txt | 1 + ndarray/src/test/resources/castle.jpg | Bin 0 -> 436164 bytes 176 files changed, 21797 insertions(+) create mode 100644 ndarray/pom.xml create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/BooleanNdArray.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/ByteNdArray.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/DoubleNdArray.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/FloatNdArray.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/IllegalRankException.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/IntNdArray.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/LongNdArray.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/NdArray.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/NdArraySequence.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/NdArrays.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/Shape.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/Shaped.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/ShortNdArray.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/StdArrays.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/buffer/BooleanDataBuffer.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/buffer/ByteDataBuffer.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/buffer/DataBuffer.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/buffer/DataBufferWindow.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/buffer/DataBuffers.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/buffer/DataStorageVisitor.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/buffer/DoubleDataBuffer.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/buffer/FloatDataBuffer.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/buffer/IntDataBuffer.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/buffer/LongDataBuffer.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/buffer/ShortDataBuffer.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/BooleanDataLayout.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/ByteDataLayout.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/DataLayout.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/DataLayouts.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/DoubleDataLayout.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/FloatDataLayout.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/IntDataLayout.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/LongDataLayout.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/ShortDataLayout.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/AbstractNdArray.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/Validator.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/AbstractDataBuffer.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/AbstractDataBufferWindow.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/Validator.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/AbstractDataBufferAdapter.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/BooleanDataBufferAdapter.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/ByteDataBufferAdapter.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/DataBufferAdapter.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/DataBufferAdapterFactory.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/DoubleDataBufferAdapter.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/FloatDataBufferAdapter.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/IntDataBufferAdapter.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/LongDataBufferAdapter.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/ShortDataBufferAdapter.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/layout/Bfloat16Layout.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/layout/BoolLayout.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/layout/Float16Layout.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/layout/StringLayout.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/misc/ArrayDataBuffer.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/misc/BitSetDataBuffer.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/misc/BooleanArrayDataBuffer.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/misc/MiscDataBufferFactory.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/nio/AbstractNioDataBuffer.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/nio/ByteNioDataBuffer.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/nio/DoubleNioDataBuffer.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/nio/FloatNioDataBuffer.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/nio/IntNioDataBuffer.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/nio/LongNioDataBuffer.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/nio/NioDataBufferFactory.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/nio/ShortNioDataBuffer.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/AbstractRawDataBuffer.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/BooleanRawDataBuffer.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/ByteRawDataBuffer.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/DoubleRawDataBuffer.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/FloatRawDataBuffer.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/IntRawDataBuffer.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/LongRawDataBuffer.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/RawDataBufferFactory.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/RawDataBufferWindow.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/ShortRawDataBuffer.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/UnsafeMemoryHandle.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/UnsafeReference.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/AbstractDenseNdArray.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/BooleanDenseNdArray.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/ByteDenseNdArray.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/DataTransfer.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/DenseNdArray.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/DoubleDenseNdArray.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/FloatDenseNdArray.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/IntDenseNdArray.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/LongDenseNdArray.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/ShortDenseNdArray.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/Validator.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/dimension/AbstractDimension.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/dimension/Axis.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/dimension/Dimension.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/dimension/DimensionalSpace.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/dimension/IndexedDimension.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/dimension/ReducedDimension.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/dimension/RelativeDimensionalSpace.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/CoordinatesIncrementor.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/FastElementSequence.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/IndexedPositionIterator.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/IndexedSequentialPositionIterator.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/NdPositionIterator.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/PositionIterator.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/SequentialPositionIterator.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/SingleElementSequence.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/SlicingElementSequence.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/index/All.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/index/At.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/index/Ellipsis.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/index/Hyperslab.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/index/Index.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/index/Indices.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/index/NewAxis.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/index/Sequence.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/index/Slice.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/index/SliceFrom.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/index/SliceTo.java create mode 100644 ndarray/src/main/java/org/tensorflow/ndarray/index/Step.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/BooleanNdArrayTestBase.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/ByteNdArrayTestBase.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/DoubleNdArrayTestBase.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/FloatNdArrayTestBase.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/IndexTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/IntNdArrayTestBase.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/LongNdArrayTestBase.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/NdArrayTestBase.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/ShapeTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/ShortNdArrayTestBase.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/StdArraysTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/benchmark/NdArrayBenchmark.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/buffer/BooleanDataBufferTestBase.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/buffer/ByteDataBufferTestBase.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/buffer/DataBufferTestBase.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/buffer/DoubleDataBufferTestBase.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/buffer/FloatDataBufferTestBase.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/buffer/IntDataBufferTestBase.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/buffer/LongDataBufferTestBase.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/buffer/ShortDataBufferTestBase.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/adapter/BigIntegerDataBufferAdapterTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/adapter/BooleanDataBufferAdapterTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/adapter/ByteDataBufferAdapterTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/adapter/DoubleDataBufferAdapterTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/adapter/FloatDataBufferAdapterTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/adapter/IntDataBufferAdapterTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/adapter/LongDataBufferAdapterTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/adapter/ShortDataBufferAdapterTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/layout/Bfloat16LayoutTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/layout/BoolLayoutTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/layout/Float16LayoutTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/misc/ArrayDataBufferTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/misc/BitSetDataBufferTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/misc/StringArrayDataBufferTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/nio/ByteNioDataBufferTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/nio/DoubleNioDataBufferTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/nio/FloatNioDataBufferTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/nio/IntNioDataBufferTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/nio/LongNioDataBufferTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/nio/ShortNioDataBufferTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/raw/BooleanRawDataBufferTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/raw/ByteRawDataBufferTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/raw/DoubleRawDataBufferTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/raw/FloatRawDataBufferTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/raw/IntRawDataBufferTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/raw/LongRawDataBufferTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/raw/ShortRawDataBufferTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/BooleanDenseNdArrayTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/ByteDenseNdArrayTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/DenseNdArrayTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/DoubleDenseNdArrayTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/FloatDenseNdArrayTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/IntDenseNdArrayTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/LongDenseNdArrayTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/ShortDenseNdArrayTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/StringDenseNdArrayTest.java create mode 100644 ndarray/src/test/java/org/tensorflow/ndarray/impl/sequence/ElementSequenceTest.java create mode 100644 ndarray/src/test/resources/COPYRIGHT.txt create mode 100644 ndarray/src/test/resources/castle.jpg diff --git a/ndarray/pom.xml b/ndarray/pom.xml new file mode 100644 index 00000000000..d852f9bcd32 --- /dev/null +++ b/ndarray/pom.xml @@ -0,0 +1,68 @@ + + + 4.0.0 + + + org.tensorflow + tensorflow-java-ndarray + 0.4.0-SNAPSHOT + + ndarray + jar + + Java NdArray Library + + Utility library for N-dimensional data I/O operations in Java. + + + + org.tensorflow.ndarray + + + + + + maven-jar-plugin + 3.2.0 + + + + ${java.module.name} + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.2 + + 1 + false + -Xmx2G -XX:MaxPermSize=256m + + **/*Test.java + + + + + + + diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/BooleanNdArray.java b/ndarray/src/main/java/org/tensorflow/ndarray/BooleanNdArray.java new file mode 100644 index 00000000000..5b4bedb1c84 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/BooleanNdArray.java @@ -0,0 +1,108 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray; + +import org.tensorflow.ndarray.buffer.BooleanDataBuffer; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.index.Index; + +/** + * An {@link NdArray} of booleans. + */ +public interface BooleanNdArray extends NdArray { + + /** + * Returns the boolean value of the scalar found at the given coordinates. + * + *

To access the scalar element, the number of coordinates provided must be equal to the number + * of dimensions of this array (i.e. its rank). For example: + *

{@code
+   *  BooleanNdArray matrix = NdArrays.ofBooleans(shape(2, 2));  // matrix rank = 2
+   *  matrix.getBoolean(0, 1);  // succeeds, returns false
+   *  matrix.getBoolean(0);  // throws IllegalRankException
+   *
+   *  BooleanNdArray scalar = matrix.get(0, 1);  // scalar rank = 0
+   *  scalar.getBoolean();  // succeeds, returns false
+   * }
+ * + * @param coordinates coordinates of the scalar to resolve + * @return value of that scalar + * @throws IndexOutOfBoundsException if some coordinates are outside the limits of their respective dimension + * @throws IllegalRankException if number of coordinates is not sufficient to access a scalar element + */ + boolean getBoolean(long... coordinates); + + /** + * Assigns the boolean value of the scalar found at the given coordinates. + * + *

To access the scalar element, the number of coordinates provided must be equal to the number + * of dimensions of this array (i.e. its rank). For example: + *

{@code
+   *  BooleanNdArray matrix = NdArrays.ofBooleans(shape(2, 2));  // matrix rank = 2
+   *  matrix.setBoolean(true, 0, 1);  // succeeds
+   *  matrix.setBoolean(true, 0);  // throws IllegalRankException
+   *
+   *  BooleanNdArray scalar = matrix.get(0, 1);  // scalar rank = 0
+   *  scalar.setBoolean(true);  // succeeds
+   * }
+ * + * @param value the value to assign + * @param coordinates coordinates of the scalar to assign + * @return this array + * @throws IndexOutOfBoundsException if some coordinates are outside the limits of their respective dimension + * @throws IllegalRankException if number of coordinates is not sufficient to access a scalar element + */ + BooleanNdArray setBoolean(boolean value, long... coordinates); + + @Override + BooleanNdArray slice(Index... indices); + + @Override + BooleanNdArray get(long... coordinates); + + @Override + BooleanNdArray set(NdArray src, long... coordinates); + + @Override + default Boolean getObject(long... coordinates) { + return getBoolean(coordinates); + } + + @Override + default BooleanNdArray setObject(Boolean value, long... coordinates) { + return setBoolean(value, coordinates); + } + + @Override + NdArraySequence elements(int dimensionIdx); + + @Override + NdArraySequence scalars(); + + @Override + BooleanNdArray copyTo(NdArray dst); + + @Override + BooleanNdArray read(DataBuffer dst); + + BooleanNdArray read(BooleanDataBuffer dst); + + @Override + BooleanNdArray write(DataBuffer src); + + BooleanNdArray write(BooleanDataBuffer src); +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/ByteNdArray.java b/ndarray/src/main/java/org/tensorflow/ndarray/ByteNdArray.java new file mode 100644 index 00000000000..0e6f118f5ef --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/ByteNdArray.java @@ -0,0 +1,108 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray; + +import org.tensorflow.ndarray.buffer.ByteDataBuffer; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.index.Index; + +/** + * An {@link NdArray} of bytes. + */ +public interface ByteNdArray extends NdArray { + + /** + * Returns the byte value of the scalar found at the given coordinates. + * + *

To access the scalar element, the number of coordinates provided must be equal to the number + * of dimensions of this array (i.e. its rank). For example: + *

{@code
+   *  ByteNdArray matrix = NdArrays.ofBytes(shape(2, 2));  // matrix rank = 2
+   *  matrix.getByte(0, 1);  // succeeds, returns 0
+   *  matrix.getByte(0);  // throws IllegalRankException
+   *
+   *  ByteNdArray scalar = matrix.get(0, 1);  // scalar rank = 0
+   *  scalar.getByte();  // succeeds, returns 0
+   * }
+ * + * @param coordinates coordinates of the scalar to resolve + * @return value of that scalar + * @throws IndexOutOfBoundsException if some coordinates are outside the limits of their respective dimension + * @throws IllegalRankException if number of coordinates is not sufficient to access a scalar element + */ + byte getByte(long... coordinates); + + /** + * Assigns the byte value of the scalar found at the given coordinates. + * + *

To access the scalar element, the number of coordinates provided must be equal to the number + * of dimensions of this array (i.e. its rank). For example: + *

{@code
+   *  ByteNdArray matrix = NdArrays.ofBytes(shape(2, 2));  // matrix rank = 2
+   *  matrix.setByte(10, 0, 1);  // succeeds
+   *  matrix.setByte(10, 0);  // throws IllegalRankException
+   *
+   *  ByteNdArray scalar = matrix.get(0, 1);  // scalar rank = 0
+   *  scalar.setByte(10);  // succeeds
+   * }
+ * + * @param value the value to assign + * @param coordinates coordinates of the scalar to assign + * @return this array + * @throws IndexOutOfBoundsException if some coordinates are outside the limits of their respective dimension + * @throws IllegalRankException if number of coordinates is not sufficient to access a scalar element + */ + ByteNdArray setByte(byte value, long... coordinates); + + @Override + ByteNdArray slice(Index... indices); + + @Override + ByteNdArray get(long... coordinates); + + @Override + ByteNdArray set(NdArray src, long... coordinates); + + @Override + default Byte getObject(long... coordinates) { + return getByte(coordinates); + } + + @Override + default ByteNdArray setObject(Byte value, long... coordinates) { + return setByte(value, coordinates); + } + + @Override + NdArraySequence elements(int dimensionIdx); + + @Override + NdArraySequence scalars(); + + @Override + ByteNdArray copyTo(NdArray dst); + + @Override + ByteNdArray read(DataBuffer dst); + + ByteNdArray read(ByteDataBuffer dst); + + @Override + ByteNdArray write(DataBuffer src); + + ByteNdArray write(ByteDataBuffer src); +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/DoubleNdArray.java b/ndarray/src/main/java/org/tensorflow/ndarray/DoubleNdArray.java new file mode 100644 index 00000000000..80e99b01877 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/DoubleNdArray.java @@ -0,0 +1,108 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray; + +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DoubleDataBuffer; +import org.tensorflow.ndarray.index.Index; + +/** + * An {@link NdArray} of doubles. + */ +public interface DoubleNdArray extends NdArray { + + /** + * Returns the double value of the scalar found at the given coordinates. + * + *

To access the scalar element, the number of coordinates provided must be equal to the number + * of dimensions of this array (i.e. its rank). For example: + *

{@code
+   *  DoubleNdArray matrix = NdArrays.ofDoubles(shape(2, 2));  // matrix rank = 2
+   *  matrix.getDouble(0, 1);  // succeeds, returns 0.0
+   *  matrix.getDouble(0);  // throws IllegalRankException
+   *
+   *  DoubleNdArray scalar = matrix.get(0, 1);  // scalar rank = 0
+   *  scalar.getDouble();  // succeeds, returns 0.0
+   * }
+ * + * @param coordinates coordinates of the scalar to resolve + * @return value of that scalar + * @throws IndexOutOfBoundsException if some coordinates are outside the limits of their respective dimension + * @throws IllegalRankException if number of coordinates is not sufficient to access a scalar element + */ + double getDouble(long... coordinates); + + /** + * Assigns the double value of the scalar found at the given coordinates. + * + *

To access the scalar element, the number of coordinates provided must be equal to the number + * of dimensions of this array (i.e. its rank). For example: + *

{@code
+   *  DoubleNdArray matrix = NdArrays.ofDoubles(shape(2, 2));  // matrix rank = 2
+   *  matrix.setDouble(10.0, 0, 1);  // succeeds
+   *  matrix.setDouble(10.0, 0);  // throws IllegalRankException
+   *
+   *  DoubleNdArray scalar = matrix.get(0, 1);  // scalar rank = 0
+   *  scalar.setDouble(10.0);  // succeeds
+   * }
+ * + * @param value value to assign + * @param coordinates coordinates of the scalar to assign + * @return this array + * @throws IndexOutOfBoundsException if some coordinates are outside the limits of their respective dimension + * @throws IllegalRankException if number of coordinates is not sufficient to access a scalar element + */ + DoubleNdArray setDouble(double value, long... coordinates); + + @Override + DoubleNdArray slice(Index... indices); + + @Override + DoubleNdArray get(long... coordinates); + + @Override + DoubleNdArray set(NdArray src, long... coordinates); + + @Override + default Double getObject(long... coordinates) { + return getDouble(coordinates); + } + + @Override + default DoubleNdArray setObject(Double value, long... coordinates) { + return setDouble(value, coordinates); + } + + @Override + NdArraySequence elements(int dimensionIdx); + + @Override + NdArraySequence scalars(); + + @Override + DoubleNdArray copyTo(NdArray dst); + + @Override + DoubleNdArray read(DataBuffer dst); + + DoubleNdArray read(DoubleDataBuffer dst); + + @Override + DoubleNdArray write(DataBuffer src); + + DoubleNdArray write(DoubleDataBuffer src); +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/FloatNdArray.java b/ndarray/src/main/java/org/tensorflow/ndarray/FloatNdArray.java new file mode 100644 index 00000000000..8d4fbf5c1ed --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/FloatNdArray.java @@ -0,0 +1,108 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray; + +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.FloatDataBuffer; +import org.tensorflow.ndarray.index.Index; + +/** + * An {@link NdArray} of floats. + */ +public interface FloatNdArray extends NdArray { + + /** + * Returns the float value of the scalar found at the given coordinates. + * + *

To access the scalar element, the number of coordinates provided must be equal to the number + * of dimensions of this array (i.e. its rank). For example: + *

{@code
+   *  FloatNdArray matrix = NdArrays.ofFloats(shape(2, 2));  // matrix rank = 2
+   *  matrix.getFloat(0, 1);  // succeeds, returns 0.0f
+   *  matrix.getFloat(0);  // throws IllegalRankException
+   *
+   *  FloatNdArray scalar = matrix.get(0, 1);  // scalar rank = 0
+   *  scalar.getFloat();  // succeeds, returns 0.0f
+   * }
+ * + * @param coordinates coordinates of the scalar to resolve + * @return value of that scalar + * @throws IndexOutOfBoundsException if some coordinates are outside the limits of their respective dimension + * @throws IllegalRankException if number of coordinates is not sufficient to access a scalar element + */ + float getFloat(long... coordinates); + + /** + * Assigns the float value of the scalar found at the given coordinates. + * + *

To access the scalar element, the number of coordinates provided must be equal to the number + * of dimensions of this array (i.e. its rank). For example: + *

{@code
+   *  FloatNdArray matrix = NdArrays.ofFloats(shape(2, 2));  // matrix rank = 2
+   *  matrix.setFloat(10.0f, 0, 1);  // succeeds
+   *  matrix.setFloat(10.0f, 0);  // throws IllegalRankException
+   *
+   *  FloatNdArray scalar = matrix.get(0, 1);  // scalar rank = 0
+   *  scalar.setFloat(10.0f);  // succeeds
+   * }
+ * + * @param value value to assign + * @param coordinates coordinates of the scalar to assign + * @return this array + * @throws IndexOutOfBoundsException if some coordinates are outside the limits of their respective dimension + * @throws IllegalRankException if number of coordinates is not sufficient to access a scalar element + */ + FloatNdArray setFloat(float value, long... coordinates); + + @Override + FloatNdArray slice(Index... coordinates); + + @Override + FloatNdArray get(long... coordinates); + + @Override + FloatNdArray set(NdArray src, long... coordinates); + + @Override + default Float getObject(long... coordinates) { + return getFloat(coordinates); + } + + @Override + default FloatNdArray setObject(Float value, long... coordinates) { + return setFloat(value, coordinates); + } + + @Override + NdArraySequence elements(int dimensionIdx); + + @Override + NdArraySequence scalars(); + + @Override + FloatNdArray copyTo(NdArray dst); + + @Override + FloatNdArray read(DataBuffer dst); + + FloatNdArray read(FloatDataBuffer dst); + + @Override + FloatNdArray write(DataBuffer src); + + FloatNdArray write(FloatDataBuffer src); +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/IllegalRankException.java b/ndarray/src/main/java/org/tensorflow/ndarray/IllegalRankException.java new file mode 100644 index 00000000000..b816d338d7e --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/IllegalRankException.java @@ -0,0 +1,27 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray; + +/** + * Exception thrown when an operation cannot be completed because of the rank of the targeted array. + */ +public class IllegalRankException extends IllegalArgumentException { + + public IllegalRankException(String message) { + super(message); + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/IntNdArray.java b/ndarray/src/main/java/org/tensorflow/ndarray/IntNdArray.java new file mode 100644 index 00000000000..aa2cc652d69 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/IntNdArray.java @@ -0,0 +1,108 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray; + +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.IntDataBuffer; +import org.tensorflow.ndarray.index.Index; + +/** + * An {@link NdArray} of integers. + */ +public interface IntNdArray extends NdArray { + + /** + * Returns the integer value of the scalar found at the given coordinates. + * + *

To access the scalar element, the number of coordinates provided must be equal to the number + * of dimensions of this array (i.e. its rank). For example: + *

{@code
+   *  IntNdArray matrix = NdArrays.ofInts(shape(2, 2));  // matrix rank = 2
+   *  matrix.getInt(0, 1);  // succeeds, returns 0
+   *  matrix.getInt(0);  // throws IllegalRankException
+   *
+   *  IntNdArray scalar = matrix.get(0, 1);  // scalar rank = 0
+   *  scalar.getInt();  // succeeds, returns 0
+   * }
+ * + * @param coordinates coordinates of the scalar to resolve + * @return value of that scalar + * @throws IndexOutOfBoundsException if some coordinates are outside the limits of their respective dimension + * @throws IllegalRankException if number of coordinates is not sufficient to access a scalar element + */ + int getInt(long... coordinates); + + /** + * Assigns the integer value of the scalar found at the given coordinates. + * + *

To access the scalar element, the number of coordinates provided must be equal to the number + * of dimensions of this array (i.e. its rank). For example: + *

{@code
+   *  IntNdArray matrix = NdArrays.ofInts(shape(2, 2));  // matrix rank = 2
+   *  matrix.setInt(10, 0, 1);  // succeeds
+   *  matrix.setInt(10, 0);  // throws IllegalRankException
+   *
+   *  IntNdArray scalar = matrix.get(0, 1);  // scalar rank = 0
+   *  scalar.setInt(10);  // succeeds
+   * }
+ * + * @param value value to assign + * @param coordinates coordinates of the scalar to assign + * @return this array + * @throws IndexOutOfBoundsException if some coordinates are outside the limits of their respective dimension + * @throws IllegalRankException if number of coordinates is not sufficient to access a scalar element + */ + IntNdArray setInt(int value, long... coordinates); + + @Override + IntNdArray slice(Index... indices); + + @Override + IntNdArray get(long... coordinates); + + @Override + IntNdArray set(NdArray src, long... coordinates); + + @Override + default Integer getObject(long... coordinates) { + return getInt(coordinates); + } + + @Override + default IntNdArray setObject(Integer value, long... coordinates) { + return setInt(value, coordinates); + } + + @Override + NdArraySequence elements(int dimensionIdx); + + @Override + NdArraySequence scalars(); + + @Override + IntNdArray copyTo(NdArray dst); + + @Override + IntNdArray read(DataBuffer dst); + + IntNdArray read(IntDataBuffer dst); + + @Override + IntNdArray write(DataBuffer src); + + IntNdArray write(IntDataBuffer src); +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/LongNdArray.java b/ndarray/src/main/java/org/tensorflow/ndarray/LongNdArray.java new file mode 100644 index 00000000000..3e5be6dc7ec --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/LongNdArray.java @@ -0,0 +1,108 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray; + +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.LongDataBuffer; +import org.tensorflow.ndarray.index.Index; + +/** + * An {@link NdArray} of longs. + */ +public interface LongNdArray extends NdArray { + + /** + * Returns the long value of the scalar found at the given coordinates. + * + *

To access the scalar element, the number of coordinates provided must be equal to the number + * of dimensions of this array (i.e. its rank). For example: + *

{@code
+   *  LongNdArray matrix = NdArrays.ofLongs(shape(2, 2));  // matrix rank = 2
+   *  matrix.getLong(0, 1);  // succeeds, returns 0L
+   *  matrix.getLong(0);  // throws IllegalRankException
+   *
+   *  LongNdArray scalar = matrix.get(0, 1);  // scalar rank = 0
+   *  scalar.getLong();  // succeeds, returns 0L
+   * }
+ * + * @param coordinates coordinates of the scalar to resolve + * @return value of that scalar + * @throws IndexOutOfBoundsException if some coordinates are outside the limits of their respective dimension + * @throws IllegalRankException if number of coordinates is not sufficient to access a scalar element + */ + long getLong(long... coordinates); + + /** + * Assigns the long value of the scalar found at the given coordinates. + * + *

To access the scalar element, the number of coordinates provided must be equal to the number + * of dimensions of this array (i.e. its rank). For example: + *

{@code
+   *  LongNdArray matrix = NdArrays.ofLongs(shape(2, 2));  // matrix rank = 2
+   *  matrix.setLong(10L, 0, 1);  // succeeds
+   *  matrix.setLong(10L, 0);  // throws IllegalRankException
+   *
+   *  LongNdArray scalar = matrix.get(0, 1);  // scalar rank = 0
+   *  scalar.setLong(10L);  // succeeds
+   * }
+ * + * @param value value to assign + * @param coordinates coordinates of the scalar to assign + * @return this array + * @throws IndexOutOfBoundsException if some coordinates are outside the limits of their respective dimension + * @throws IllegalRankException if number of coordinates is not sufficient to access a scalar element + */ + LongNdArray setLong(long value, long... coordinates); + + @Override + LongNdArray slice(Index... indices); + + @Override + LongNdArray get(long... coordinates); + + @Override + LongNdArray set(NdArray src, long... coordinates); + + @Override + default Long getObject(long... coordinates) { + return getLong(coordinates); + } + + @Override + default LongNdArray setObject(Long value, long... coordinates) { + return setLong(value, coordinates); + } + + @Override + NdArraySequence elements(int dimensionIdx); + + @Override + NdArraySequence scalars(); + + @Override + LongNdArray copyTo(NdArray dst); + + @Override + LongNdArray read(DataBuffer dst); + + LongNdArray read(LongDataBuffer dst); + + @Override + LongNdArray write(DataBuffer src); + + LongNdArray write(LongDataBuffer src); +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/NdArray.java b/ndarray/src/main/java/org/tensorflow/ndarray/NdArray.java new file mode 100644 index 00000000000..6686abd9148 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/NdArray.java @@ -0,0 +1,302 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray; + +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.index.Index; + +/** + * A data structure of N-dimensions. + * + *

The `NdArray` interface creates an abstraction between the physical storage of a data record, + * which can be linear or segmented, and its logical representation. In general, they achieve + * better performances than standard multi-dimensional arrays in Java by mapping directly linear + * data segments in memory. + * + *

Like {@link DataBuffer}, {@code NdArray} instances support 64-bits indexing so they can be + * used to map very large data records. They also support special coordinates that allow traversing + * their values in any direction or to select only a subset of them. + * + *

Example of usage: + *

{@code
+ *    // Creates a 2x3x2 matrix (of rank 3)
+ *    FloatNdArray matrix3d = NdArrays.ofFloats(shape(2, 3, 2));
+ *
+ *    // Initialize sub-matrices data with vectors
+ *    matrix.set(NdArrays.vectorOf(1.0f, 2.0f), 0, 0)
+ *          .set(NdArrays.vectorOf(3.0f, 4.0f), 0, 1)
+ *          .set(NdArrays.vectorOf(5.0f, 6.0f), 0, 2)
+ *          .set(NdArrays.vectorOf(7.0f, 8.0f), 1, 0)
+ *          .set(NdArrays.vectorOf(9.0f, 10.0f), 1, 1)
+ *          .set(NdArrays.vectorOf(11.0f, 12.0f), 1, 2);
+ *
+ *    // Access the second 3x2 matrix (of rank 2)
+ *    FloatNdArray matrix = matrix3d.get(1);
+ *
+ *    // Access directly the float value at (1, 0) from the second matrix
+ *    assertEquals(9.0f, matrix.getFloat(1, 0));
+ * }
+ * + * @param the type of values to be mapped + */ +public interface NdArray extends Shaped { + + /** + * Returns a sequence of all elements at a given dimension. + * + *

Logically, the N-dimensional array can be flatten in a single vector, where the scalars of + * the {@code (n - 1)}th element precedes those of the {@code (n)}th element, for a total of + * {@link #size()} values. + * + *

For example, given a {@code n x m} matrix on the {@code [x, y]} axes, elements are iterated in + * the following order: + *

x0y0, x0y1, ..., x0ym-1, x1y0, x1y1, ..., xn-1ym-1 + * + *

The returned sequence can then be iterated to visit each elements, either by calling + * {@link NdArraySequence#forEach(Consumer)} or {@link NdArraySequence#forEachIndexed(BiConsumer)}. + *

{@code
+   *    // Iterate matrix for initializing each of its vectors
+   *    matrixOfFloats.elements(0).forEach(v -> {
+   *      v.set(vector(1.0f, 2.0f, 3.0f));
+   *    });
+   *
+   *    // Iterate a vector for reading each of its scalar
+   *    vectorOfFloats.scalars().forEachIdx((coords, s) -> {
+   *      System.out.println("Value " + s.getFloat() + " found at " + coords);
+   *    });
+   * }
+ * + * @param dimensionIdx index of the dimension + * @return an {@code NdArray} sequence + * @throws IllegalArgumentException if {@code dimensionIdx} is greater or equal to the total + * number of dimensions of this array + */ + NdArraySequence> elements(int dimensionIdx); + + /** + * Returns a sequence of all scalars in this array. + * + *

This is equivalent to call {@code elements(shape().numDimensions() - 1)} + * + * @return an {@code NdArray} sequence + */ + NdArraySequence> scalars(); + + /** + * Creates a multi-dimensional view (or slice) of this array by mapping one or more dimensions + * to the given index selectors. + * + *

Slices allow to traverse an N-dimensional array in any of its axis and/or to filter only + * elements of interest. For example, for a given matrix on the {@code [x, y]} axes, it is + * possible to iterate elements at {@code y=0} for all {@code x}. + * + *

Any changes applied to the returned slice affect the data of this array as well, as there + * is no copy involved. + * + *

Example of usage: + *

{@code
+   *    FloatNdArray matrix3d = NdArrays.ofFloats(shape(3, 2, 4));  // with [x, y, z] axes
+   *
+   *    // Iterates elements on the x axis by preserving only the 3rd value on the z axis,
+   *    // (i.e. [x, y, 2])
+   *    matrix3d.slice(all(), all(), at(2)).elements(0).forEach(m -> {
+   *      assertEquals(shape(2), m); // y=2, z=0 (scalar)
+   *    });
+   *
+   *    // Creates a slice that contains only the last element of the y axis and elements with an
+   *    // odd `z` coordinate.
+   *    FloatNdArray slice = matrix3d.slice(all(), at(1), odd());
+   *    assertEquals(shape(3, 2), slice.shape());  // x=3, y=0 (scalar), z=2 (odd coordinates)
+   *
+   *    // Iterates backward the elements on the x axis
+   *    matrix3d.slice(flip()).elements(0).forEach(m -> {
+   *      assertEquals(shape(2, 4), m);  // y=2, z=4
+   *    });
+   * }
+ * + * @param indices index selectors per dimensions, starting from dimension 0 of this array. + * @return the element resulting of the index selection + * @throws IndexOutOfBoundsException if some coordinates are outside the limits of their + * respective dimension + */ + NdArray slice(Index... indices); + + /** + * Returns the N-dimensional element of this array at the given coordinates. + * + *

Elements of any of the dimensions of this array can be retrieved. For example, if the number + * of coordinates is equal to the number of dimensions of this array, then a rank-0 (scalar) array + * is returned, which value can then be obtained by calling `array.getObject()`. + * + *

Any changes applied to the returned elements affect the data of this array as well, as there + * is no copy involved. + * + *

Note that invoking this method is an equivalent and more efficient way to slice this array + * on single scalar, i.e. {@code array.get(x, y, z)} is equal to + * {@code array.slice(at(x), at(y), at(z))} + * + * @param coordinates coordinates of the element to access, none will return this array + * @return the element at this index + * @throws IndexOutOfBoundsException if some coordinates are outside the limits of their + * respective dimension + */ + NdArray get(long... coordinates); + + /** + * Assigns the value of the N-dimensional element found at the given coordinates. + * + *

The number of coordinates provided can be anywhere between 0 and rank - 1. For example: + *

{@code
+   *  FloatNdArray matrix = NdArrays.ofFloats(shape(2, 2));  // matrix rank = 2
+   *  matrix.set(vector(10.0f, 20.0f), 0);  // success
+   *  matrix.set(scalar(10.0f), 1, 0); // success
+   * }
+ * + * @param src an array of the values to assign + * @param coordinates coordinates of the element to assign + * @return this array + * @throws IndexOutOfBoundsException if some coordinates are outside the limits of their + * respective dimension + */ + NdArray set(NdArray src, long... coordinates); + + /** + * Returns the value of the scalar found at the given coordinates. + * + *

To access the scalar element, the number of coordinates provided must be equal to the number + * of dimensions of this array (i.e. its rank). For example: + *

{@code
+   *  FloatNdArray matrix = NdArrays.ofFloats(shape(2, 2));  // matrix rank = 2
+   *  matrix.getObject(0, 1);  // succeeds, returns 0.0f
+   *  matrix.getObject(0);  // throws IllegalRankException
+   *
+   *  FloatNdArray scalar = matrix.get(0, 1);  // scalar rank = 0
+   *  scalar.getObject();  // succeeds, returns 0.0f
+   * }
+ * + * Note: if this array stores values of a primitive type, prefer the usage of the specialized + * method in the subclass for that type. For example, {@code floatArray.getFloat(0); }. + * + * @param coordinates coordinates of the scalar to resolve + * @return value of that scalar + * @throws IndexOutOfBoundsException if some coordinates are outside the limits of their + * respective dimension + * @throws IllegalRankException if number of coordinates is not sufficient to access a scalar + * element + */ + T getObject(long... coordinates); + + /** + * Assigns the value of the scalar found at the given coordinates. + * + *

To access the scalar element, the number of coordinates provided must be equal to the number + * of dimensions of this array (i.e. its rank). For example: + *

{@code
+   *  FloatNdArray matrix = NdArrays.ofFloats(shape(2, 2));  // matrix rank = 2
+   *  matrix.setObject(10.0f, 0, 1);  // succeeds
+   *  matrix.setObject(10.0f, 0);  // throws IllegalRankException
+   *
+   *  FloatNdArray scalar = matrix.get(0, 1);  // scalar rank = 0
+   *  scalar.setObject(10.0f);  // succeeds
+   * }
+ * + * Note: if this array stores values of a primitive type, prefer the usage of the specialized + * method in the subclass for that type. For example, {@code floatArray.setFloat(10.0f, 0); } + * + * @param value the value to assign + * @param coordinates coordinates of the scalar to assign + * @return this array + * @throws IndexOutOfBoundsException if some coordinates are outside the limits of their + * respective dimension + * @throws IllegalRankException if number of coordinates is not sufficient to access a scalar + * element + */ + NdArray setObject(T value, long... coordinates); + + /** + * Copy the content of this array to the destination array. + * + *

The {@link #shape()} of the destination array must be equal to the shape of this array, or + * an exception is thrown. After the copy, the content of both arrays can be altered + * independently, without affecting each other. + * + * @param dst array to receive a copy of the content of this array + * @return this array + * @throws IllegalArgumentException if the shape of {@code dst} is not equal to the shape of this + * array + */ + NdArray copyTo(NdArray dst); + + /** + * Read the content of this N-dimensional array into the destination buffer. + * + *

The size of the buffer must be equal or greater to the {@link #size()} of this + * array, or an exception is thrown. After the copy, content of the buffer and of the array can be + * altered independently, without affecting each other. + * + * @param dst the destination buffer + * @return this array + * @throws java.nio.BufferOverflowException if the buffer cannot hold the content of this array + * @see DataBuffer#size() + */ + NdArray read(DataBuffer dst); + + /** + * Write the content of this N-dimensional array from the source buffer. + * + *

The size of the buffer must be equal or greater to the {@link #size()} of this + * array, or an exception is thrown. After the copy, content of the buffer and of the array can be + * altered independently, without affecting each other. + * + * @param src the source buffer + * @return this array + * @throws java.nio.BufferUnderflowException if the buffer has not enough remaining data to write + * into this array + * @see DataBuffer#size() + */ + NdArray write(DataBuffer src); + + /** + * Checks equality between n-dimensional arrays. + * + *

An array is equal to another object if this object is another {@link NdArray} of the + * same shape, type and the elements are equal and in the same order. For example: + * + *

{@code
+   * IntNdArray array = NdArrays.ofInts(Shape.of(2, 2))
+   *    .set(NdArrays.vectorOf(1, 2), 0)
+   *    .set(NdArrays.vectorOf(3, 4), 1);
+   *
+   * assertEquals(array, StdArrays.ndCopyOf(new int[][] {{1, 2}, {3, 4}}));  // true
+   * assertEquals(array, StdArrays.ndCopyOf(new Integer[][] {{1, 2}, {3, 4}}));  // true, as Integers are equal to ints
+   * assertNotEquals(array, NdArrays.vectorOf(1, 2, 3, 4));  // false, different shapes
+   * assertNotEquals(array, StdArrays.ndCopyOf(new int[][] {{3, 4}, {1, 2}}));  // false, different order
+   * assertNotEquals(array, StdArrays.ndCopyOf(new long[][] {{1L, 2L}, {3L, 4L}}));  // false, different types
+   * }
+ * + *

Note that the computation required to verify equality between two arrays can be expensive + * in some cases and therefore, it is recommended to not use this method in a critical path + * where performances matter. + * + * @param obj object to compare this array with + * @return true if this array is equal to the provided object + */ + @Override + boolean equals(Object obj); +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/NdArraySequence.java b/ndarray/src/main/java/org/tensorflow/ndarray/NdArraySequence.java new file mode 100644 index 00000000000..afb930e278b --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/NdArraySequence.java @@ -0,0 +1,67 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray; + +import java.util.function.BiConsumer; +import org.tensorflow.ndarray.buffer.DataBufferWindow; + +/** + * A sequence of elements of an N-dimensional array. + * + *

An {@code NdArraySequence} is used to traverse an {@code NdArray} in a given dimension + * and visit each of its elements. For example, given a {@code n x m} matrix on the {@code [x, y]} axes, + * elements are iterated in the following order: + *

x0y0, x0y1, ..., x0ym-1, x1y0, x1y1, ..., xn-1ym-1 + * + * @param data type of the array being iterated + */ +public interface NdArraySequence> extends Iterable { + + /** + * Visit each elements of this iteration and their respective coordinates. + * + *

Important: the consumer method should not keep a reference to the coordinates + * as they might be mutable and reused during the iteration to improve performance. + * + * @param consumer method to invoke for each elements + */ + void forEachIndexed(BiConsumer consumer); + + /** + * Returns each element as a new slice. + * + *

Unlike conventional Java collections, elements of a {@code NdArraySequence} are transient, i.e. new {@code NdArray} + * instances are allocated for each iteration. To improve performance, the same instance can be recycled to view + * all elements of this sequence, using a {@link DataBufferWindow}. + * + *

In some cases though, it might be preferable to disable such optimizations to ensure that each element returned is a + * new slice of the original array. For example, if one or more elements visited must live beyond the scope of the sequence + * iteration, {@code asSlices()} makes sure that all elements returned by the sequence are unique instances. + * + *

{@code
+   *     final List vectors = new ArrayList<>();
+   *     IntNdArray matrix = NdArrays.ofInts(Shape.of(6, 6));
+   *     ndArray.elements(0).forEach(e -> vectors::add);  // Not safe, as `e` might always be the same recycled instance
+   *     ndArray.elements(0).asSlices().forEach(e -> vectors::add);  // Safe, each `e` is a distinct NdArray instance
+   * }
+ * + * @return a sequence that returns each elements iterated as a new slice + * @see DataBufferWindow + */ + NdArraySequence asSlices(); +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/NdArrays.java b/ndarray/src/main/java/org/tensorflow/ndarray/NdArrays.java new file mode 100644 index 00000000000..8ad55cae7ed --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/NdArrays.java @@ -0,0 +1,495 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray; + +import org.tensorflow.ndarray.impl.dense.DenseNdArray; +import org.tensorflow.ndarray.impl.dense.IntDenseNdArray; +import org.tensorflow.ndarray.buffer.BooleanDataBuffer; +import org.tensorflow.ndarray.buffer.ByteDataBuffer; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DataBuffers; +import org.tensorflow.ndarray.buffer.DoubleDataBuffer; +import org.tensorflow.ndarray.buffer.FloatDataBuffer; +import org.tensorflow.ndarray.buffer.IntDataBuffer; +import org.tensorflow.ndarray.buffer.LongDataBuffer; +import org.tensorflow.ndarray.buffer.ShortDataBuffer; +import org.tensorflow.ndarray.impl.dense.BooleanDenseNdArray; +import org.tensorflow.ndarray.impl.dense.ByteDenseNdArray; +import org.tensorflow.ndarray.impl.dense.DoubleDenseNdArray; +import org.tensorflow.ndarray.impl.dense.FloatDenseNdArray; +import org.tensorflow.ndarray.impl.dense.LongDenseNdArray; +import org.tensorflow.ndarray.impl.dense.ShortDenseNdArray; + +/** + * Utility class for instantiating {@link NdArray} objects. + */ +public final class NdArrays { + + // BYTE ARRAYS + + /** + * Creates byte scalar (rank 0) initialized with the given value. + * + * @param value scalar value + * @return new byte scalar + */ + public static ByteNdArray scalarOf(byte value) { + return ofBytes(Shape.scalar()).setByte(value); + } + + /** + * Creates a byte vector (rank 1) initialized with the given values. + * + *

Modifying the data of the returned vector will also impact the values in the array + * passed in parameter. + * + * @param values vector values + * @return new byte vector + * @throws IllegalArgumentException if values is null + */ + public static ByteNdArray vectorOf(byte... values) { + if (values == null) { + throw new IllegalArgumentException("Values cannot be null"); + } + return wrap(Shape.of(values.length), DataBuffers.of(values, false, false)); + } + + /** + * Creates an N-dimensional array of bytes of the given shape. + * + *

All values are initialized to zeros. + * + * @param shape shape of the array + * @return new byte N-dimensional array + * @throws IllegalArgumentException if shape is null or has unknown dimensions + */ + public static ByteNdArray ofBytes(Shape shape) { + if (shape == null) { + throw new IllegalArgumentException("Shape cannot be null"); + } + return wrap(shape, DataBuffers.ofBytes(shape.size())); + } + + /** + * Wraps a buffer in a byte N-dimensional array of a given shape. + * + * @param shape shape of the array + * @param buffer buffer to wrap + * @return new byte N-dimensional array + * @throws IllegalArgumentException if shape is null, has unknown dimensions or has size bigger + * in the buffer size + */ + public static ByteNdArray wrap(Shape shape, ByteDataBuffer buffer) { + return ByteDenseNdArray.create(buffer, shape); + } + + // LONG ARRAYS + + /** + * Creates long scalar (rank 0) initialized with the given value. + * + * @param value scalar value + * @return new long scalar + */ + public static LongNdArray scalarOf(long value) { + return ofLongs(Shape.scalar()).setLong(value); + } + + /** + * Creates a long vector (rank 1) initialized with the given values. + * + *

Modifying the data of the returned vector will also impact the values in the array + * passed in parameter. + * + * @param values vector values + * @return new long vector + * @throws IllegalArgumentException if values is null + */ + public static LongNdArray vectorOf(long... values) { + if (values == null) { + throw new IllegalArgumentException(); + } + return wrap(Shape.of(values.length), DataBuffers.of(values, false, false)); + } + + /** + * Creates an N-dimensional array of longs of the given shape. + * + *

All values are initialized to zeros. + * + * @param shape shape of the array + * @return new long N-dimensional array + * @throws IllegalArgumentException if shape is null or has unknown dimensions + */ + public static LongNdArray ofLongs(Shape shape) { + return wrap(shape, DataBuffers.ofLongs(shape.size())); + } + + /** + * Wraps a buffer in a long N-dimensional array of a given shape. + * + * @param shape shape of the array + * @param buffer buffer to wrap + * @return new long N-dimensional array + * @throws IllegalArgumentException if shape is null, has unknown dimensions or has size bigger + * in the buffer size + */ + public static LongNdArray wrap(Shape shape, LongDataBuffer buffer) { + return LongDenseNdArray.create(buffer, shape); + } + + // INT ARRAYS + + /** + * Creates long scalar (rank 0) initialized with the given value. + * + * @param value scalar value + * @return new long scalar + */ + public static IntNdArray scalarOf(int value) { + return ofInts(Shape.scalar()).setInt(value); + } + + /** + * Creates a int vector (rank 1) initialized with the given values. + * + *

Modifying the data of the returned vector will also impact the values in the array + * passed in parameter. + * + * @param values vector values + * @return new int vector + * @throws IllegalArgumentException if values is null + */ + public static IntNdArray vectorOf(int... values) { + if (values == null) { + throw new IllegalArgumentException(); + } + return wrap(Shape.of(values.length), DataBuffers.of(values, false, false)); + } + + /** + * Creates an N-dimensional array of ints of the given shape. + * + *

All values are initialized to zeros. + * + * @param shape shape of the array + * @return new int N-dimensional array + * @throws IllegalArgumentException if shape is null or has unknown dimensions + */ + public static IntNdArray ofInts(Shape shape) { + return wrap(shape, DataBuffers.ofInts(shape.size())); + } + + /** + * Wraps a buffer in an int N-dimensional array of a given shape. + * + * @param shape shape of the array + * @param buffer buffer to wrap + * @return new int N-dimensional array + * @throws IllegalArgumentException if shape is null, has unknown dimensions or has size bigger + * in the buffer size + */ + public static IntNdArray wrap(Shape shape, IntDataBuffer buffer) { + return IntDenseNdArray.create(buffer, shape); + } + + // SHORT ARRAYS + + /** + * Creates short scalar (rank 0) initialized with the given value. + * + * @param value scalar value + * @return new short scalar + */ + public static ShortNdArray scalarOf(short value) { + return ofShorts(Shape.scalar()).setShort(value); + } + + /** + * Creates a short vector (rank 1) initialized with the given values. + * + *

Modifying the data of the returned vector will also impact the values in the array + * passed in parameter. + * + * @param values vector values + * @return new short vector + * @throws IllegalArgumentException if values is null + */ + public static ShortNdArray vectorOf(short... values) { + if (values == null) { + throw new IllegalArgumentException(); + } + return wrap(Shape.of(values.length), DataBuffers.of(values, false, false)); + } + + /** + * Creates an N-dimensional array of shorts of the given shape. + * + *

All values are initialized to zeros. + * + * @param shape shape of the array + * @return new short N-dimensional array + * @throws IllegalArgumentException if shape is null or has unknown dimensions + */ + public static ShortNdArray ofShorts(Shape shape) { + return wrap(shape, DataBuffers.ofShorts(shape.size())); + } + + /** + * Wraps a buffer in a short N-dimensional array of a given shape. + * + * @param shape shape of the array + * @param buffer buffer to wrap + * @return new short N-dimensional array + * @throws IllegalArgumentException if shape is null, has unknown dimensions or has size bigger + * in the buffer size + */ + public static ShortNdArray wrap(Shape shape, ShortDataBuffer buffer) { + return ShortDenseNdArray.create(buffer, shape); + } + + // FLOAT ARRAYS + + /** + * Creates float scalar (rank 0) initialized with the given value. + * + * @param value scalar value + * @return new float scalar + */ + public static FloatNdArray scalarOf(float value) { + return ofFloats(Shape.scalar()).setFloat(value); + } + + /** + * Creates a float vector (rank 1) initialized with the given values. + * + *

Modifying the data of the returned vector will also impact the values in the array + * passed in parameter. + * + * @param values vector values + * @return new float vector + * @throws IllegalArgumentException if values is null + */ + public static FloatNdArray vectorOf(float... values) { + if (values == null) { + throw new IllegalArgumentException(); + } + return wrap(Shape.of(values.length), DataBuffers.of(values, false, false)); + } + + /** + * Creates an N-dimensional array of floats of the given shape. + * + *

All values are initialized to zeros. + * + * @param shape shape of the array + * @return new float N-dimensional array + * @throws IllegalArgumentException if shape is null or has unknown dimensions + */ + public static FloatNdArray ofFloats(Shape shape) { + return wrap(shape, DataBuffers.ofFloats(shape.size())); + } + + /** + * Wraps a buffer in a float N-dimensional array of a given shape. + * + * @param shape shape of the array + * @param buffer buffer to wrap + * @return new float N-dimensional array + * @throws IllegalArgumentException if shape is null, has unknown dimensions or has size bigger + * in the buffer size + */ + public static FloatNdArray wrap(Shape shape, FloatDataBuffer buffer) { + return FloatDenseNdArray.create(buffer, shape); + } + + // DOUBLE ARRAYS + + /** + * Creates double scalar (rank 0) initialized with the given value. + * + * @param value scalar value + * @return new double scalar + */ + public static DoubleNdArray scalarOf(double value) { + return ofDoubles(Shape.scalar()).setDouble(value); + } + + /** + * Creates a double vector (rank 1) initialized with the given values. + * + *

Modifying the data of the returned vector will also impact the values in the array + * passed in parameter. + * + * @param values vector values + * @return new double vector + * @throws IllegalArgumentException if values is null + */ + public static DoubleNdArray vectorOf(double... values) { + if (values == null) { + throw new IllegalArgumentException(); + } + return wrap(Shape.of(values.length), DataBuffers.of(values, false, false)); + } + + /** + * Creates an N-dimensional array of doubles of the given shape. + * + *

All values are initialized to zeros. + * + * @param shape shape of the array + * @return new double N-dimensional array + * @throws IllegalArgumentException if shape is null or has unknown dimensions + */ + public static DoubleNdArray ofDoubles(Shape shape) { + return wrap(shape, DataBuffers.ofDoubles(shape.size())); + } + + /** + * Wraps a buffer in a double N-dimensional array of a given shape. + * + * @param shape shape of the array + * @param buffer buffer to wrap + * @return new double N-dimensional array + * @throws IllegalArgumentException if shape is null, has unknown dimensions or has size bigger + * in the buffer size + */ + public static DoubleNdArray wrap(Shape shape, DoubleDataBuffer buffer) { + return DoubleDenseNdArray.create(buffer, shape); + } + + // BOOLEAN ARRAYS + + /** + * Creates boolean scalar (rank 0) initialized with the given value. + * + * @param value scalar value + * @return new boolean scalar + */ + public static BooleanNdArray scalarOf(boolean value) { + return ofBooleans(Shape.scalar()).setBoolean(value); + } + + /** + * Creates a boolean vector (rank 1) initialized with the given values. + * + *

Modifying the data of the returned vector will also impact the values in the array + * passed in parameter. + * + * @param values vector values + * @return new boolean vector + * @throws IllegalArgumentException if values is null + */ + public static BooleanNdArray vectorOf(boolean... values) { + if (values == null) { + throw new IllegalArgumentException(); + } + return wrap(Shape.of(values.length), DataBuffers.of(values, false, false)); + } + + /** + * Creates an N-dimensional array of booleans of the given shape. + * + *

All values are initialized to zeros. + * + * @param shape shape of the array + * @return new boolean N-dimensional array + * @throws IllegalArgumentException if shape is null or has unknown dimensions + */ + public static BooleanNdArray ofBooleans(Shape shape) { + return wrap(shape, DataBuffers.ofBooleans(shape.size())); + } + + /** + * Wraps a buffer in a boolean N-dimensional array of a given shape. + * + * @param shape shape of the array + * @param buffer buffer to wrap + * @return new boolean N-dimensional array + * @throws IllegalArgumentException if shape is null, has unknown dimensions or has size bigger + * in the buffer size + */ + public static BooleanNdArray wrap(Shape shape, BooleanDataBuffer buffer) { + return BooleanDenseNdArray.create(buffer, shape); + } + + // OBJECT ARRAYS + + /** + * Creates scalar (rank 0) initialized with the given value. + * + * @param value scalar value + * @param the data type + * @return new scalar + */ + @SuppressWarnings("unchecked") + public static NdArray scalarOfObject(T value) { + if (value == null) { + throw new IllegalArgumentException(); + } + return ofObjects((Class)value.getClass(), Shape.scalar()).setObject(value); + } + + /** + * Creates a vector (rank 1) initialized with the given values. + * + *

Modifying the data of the returned vector will also impact the values in the array + * passed in parameter. + * + * @param values vector values + * @param the data type + * @return new vector + * @throws IllegalArgumentException if values is null + */ + @SafeVarargs + public static NdArray vectorOfObjects(T... values) { + if (values == null || values.length == 0) { + throw new IllegalArgumentException("Null or zero length input supplied to vectorOfObjects."); + } + return wrap(Shape.of(values.length), DataBuffers.of(values, false, false)); + } + + /** + * Creates an N-dimensional array of the given shape. + * + *

All values are initialized to zeros. + * + * @param clazz class of the data to be stored in this array + * @param shape shape of the array + * @param the data type + * @return new N-dimensional array + * @throws IllegalArgumentException if shape is null or has unknown dimensions + */ + public static NdArray ofObjects(Class clazz, Shape shape) { + return wrap(shape, DataBuffers.ofObjects(clazz, shape.size())); + } + + /** + * Wraps a buffer in an N-dimensional array of a given shape. + * + * @param shape shape of the array + * @param buffer buffer to wrap + * @param the data type + * @return new N-dimensional array + * @throws IllegalArgumentException if shape is null, has unknown dimensions or has size bigger + * in the buffer size + */ + public static NdArray wrap(Shape shape, DataBuffer buffer) { + return DenseNdArray.wrap(buffer, shape); + } +} + diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/Shape.java b/ndarray/src/main/java/org/tensorflow/ndarray/Shape.java new file mode 100644 index 00000000000..85a905408c7 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/Shape.java @@ -0,0 +1,447 @@ +/* +Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +======================================================================= +*/ + +package org.tensorflow.ndarray; + +import java.util.Arrays; + +/** + * The shape of a Tensor or {@link NdArray}. + * + *

A {@code Shape} defines sizes along its axes. It may contain an unknown size for one of the + * axes or may be totally unknown, in which case not even the number of axes is known. If the size + * of an axis is unknown, {@link Shape#UNKNOWN_SIZE} should be used as its size. + */ +public final class Shape { + + /** The size of an unknown axis or the total unknown size for an unknown Shape. */ + public static long UNKNOWN_SIZE = -1L; + + /** + * Creates a Shape representing an unknown number of dimensions. + * + * @return A Shape for which {@link Shape#isUnknown()} is true, never null. + */ + public static Shape unknown() { + return new Shape(null); + } + + /** + * Creates a Shape representing a scalar value. + * + * @return A Shape without dimensions for which {@link Shape#isScalar()} is true, never null. + */ + public static Shape scalar() { + return new Shape(new long[0]); + } + + /** + * Create a Shape representing a scalar or an N-dimensional value. + * + *

Creates a Shape representing a scalar or an N-dimensional value (N being at least 1), with + * the provided size for each dimension. A -1 indicates that the size of the corresponding + * dimension is unknown. If no sizes are provided, a Shape representing a scalar is created. For + * example: + * + *

{@code
+   * // A 2-element vector.
+   * Shape vector = Shape.of(2);
+   *
+   * // A 2x3 matrix.
+   * Shape matrix = Shape.of(2, 3);
+   *
+   * // A matrix with 4 columns but an unknown number of rows.
+   * // This is typically used to indicate the shape of tensors that represent
+   * // a variable-sized batch of values. The Shape below might represent a
+   * // variable-sized batch of 4-element vectors.
+   * Shape batch = Shape.of(-1, 4);
+   *
+   * // A scalar. For readability, you should prefer calling Shape.scalar()
+   * Shape scalar = Shape.of()
+   * }
+ * + * @param dimensionSizes number of elements in each dimension of this shape, if any, or + * {@link Shape#UNKNOWN_SIZE} if unknown. + * @return a new shape + */ + public static Shape of(long... dimensionSizes) { + if (dimensionSizes == null || dimensionSizes.length == 0) { + return scalar(); + } + return new Shape(dimensionSizes); + } + + /** + * Returns the total number of elements a Tensor with this Shape would have. + * + *

If {@link Shape#isUnknown()} is true or {@link Shape#hasUnknownDimension()} is true, {@link + * Shape#UNKNOWN_SIZE} is returned. + * + * @return The total number of elements a Tensor with this shape would have if it can be + * calculated, else {@link Shape#UNKNOWN_SIZE}. + */ + public long size() { + if (size == null) { + size = computeSize(dimensionSizes); + } + return size; + } + + /** + * The size of the dimension with the given index. + * + *

If {@link Shape#isUnknown()} is true or the size of the dimension with the given index has + * an unknown size, {@link Shape#UNKNOWN_SIZE} is returned. + * + * @param i the index of the dimension to get the size for. If this Shape has a known number of + * dimensions, it must be < {@link Shape#numDimensions()}. The index may be negative, in which + * case the position is counted from the end of the shape. E.g.: {@code size(-1)} returns the + * size of the last dimension, {@code size(-2)} the size of the second to last dimension etc. + * @return The size of the dimension with the given index if known, {@link Shape#UNKNOWN_SIZE} + * otherwise. + */ + public long size(int i) { + if (dimensionSizes == null) { + return UNKNOWN_SIZE; + } else if (i >= 0) { + return dimensionSizes[i]; + } else { + return dimensionSizes[dimensionSizes.length + i]; + } + } + + /** + * Returns the number of dimensions of this Shape. -1 if unknown, 0 for a scalar, 1 for a vector, + * 2 for a matrix etc. + */ + public int numDimensions() { + return dimensionSizes != null ? dimensionSizes.length : -1; + } + + /** Returns whether one or more dimensions of this Shape have an unknown size. */ + public boolean hasUnknownDimension() { + if (dimensionSizes == null) { + return true; + } + for (long dimSize : dimensionSizes) { + if (dimSize == UNKNOWN_SIZE) { + return true; + } + } + return false; + } + + /** Returns whether this Shape represents a scalar. */ + public boolean isScalar() { + return dimensionSizes != null && dimensionSizes.length == 0; + } + + /** Returns whether this Shape is the shape of a vector. */ + public boolean isVector() { + return dimensionSizes != null && dimensionSizes.length == 1; + } + + /** Returns whether this Shape is the shape of a matrix */ + public boolean isMatrix() { + return dimensionSizes != null && dimensionSizes.length == 2; + } + + /** Returns whether the number of dimensions of this Shape is unknown. */ + public boolean isUnknown() { + return dimensionSizes == null; + } + + /** + * Returns a defensive copy of the this Shape's axes. Changes to the returned array to not change + * this Shape's state. Returns null if {@link Shape#isUnknown()} is true. + */ + public long[] asArray() { + if (this.dimensionSizes == null) { + return null; + } else { + return Arrays.copyOf(dimensionSizes, dimensionSizes.length); + } + } + + @Override + public int hashCode() { + return dimensionSizes != null ? Arrays.hashCode(dimensionSizes) : super.hashCode(); + } + + /** + * Equals implementation for Shapes. Two Shapes are considered equal iff: + * + *

+ *

    + *
  • the number of dimensions is defined and equal for both + *
  • the size of each dimension is defined and equal for both + *
+ * + *

If either Shape has unknown dimensions (even if they are the same in both) or if either + * shape has an unknown number of dimensions (even if both return {@code true} for {@link + * Shape#isUnknown()}), they are not considered equal! However, a shape will always equal itself, + * even if it is unknown or contains unknown dimensions. + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + // Shapes are equivalent if all of their dimensions are equals + if (obj instanceof Shape) { + Shape otherShape = (Shape) obj; + if (otherShape.hasUnknownDimension()) { + return false; + } + return Arrays.equals(dimensionSizes, otherShape.dimensionSizes); + } + return false; + } + + /** Succinct description of the Shape meant for debugging. */ + @Override + public String toString() { + return Arrays.toString(dimensionSizes); + } + + private Shape(long[] dimensionSizes) { + this.dimensionSizes = dimensionSizes; + } + + private final long[] dimensionSizes; + private Long size; + + /** + * Returns a 1-dimensional Shape with first dimension matching the first dimension of this Shape. + */ + public Shape head() { + return take(1); + } + + /** + * Returns an n-dimensional Shape with the dimensions matching the first n dimensions of this + * shape + * + * @param n the number of leading dimensions to get, must be <= than {@link Shape#numDimensions()} + * @return an n-dimensional Shape with the first n dimensions matching the first n dimensions of + * this Shape + */ + public Shape take(int n) { + if (n > numDimensions()) { + throw new ArrayIndexOutOfBoundsException( + "Cannot take " + n + " dimensions, shape has only " + numDimensions() + "."); + } + long[] newDimensions = new long[n]; + System.arraycopy(dimensionSizes, 0, newDimensions, 0, n); + return Shape.of(newDimensions); + } + + /** Returns a new Shape, with this Shape's first dimension removed. */ + public Shape tail() { + if (dimensionSizes.length < 2) return Shape.of(); + return Shape.of(Arrays.copyOfRange(dimensionSizes, 1, dimensionSizes.length)); + } + + /** + * Returns an n-dimensional Shape with the dimensions matching the last n dimensions of this + * Shape. + * + * @param n the number of trailing dimensions to get, must be <= than {@link + * Shape#numDimensions()} + * @return an n-dimensional shape with the dimensions matching the last n dimensions of this + * Shape, never null + */ + public Shape takeLast(int n) { + if (n > numDimensions()) { + throw new ArrayIndexOutOfBoundsException( + "Cannot take last " + n + " dimensions, shape has only " + numDimensions() + "."); + } + long[] newDimensions = new long[n]; + System.arraycopy(dimensionSizes, numDimensions() - n, newDimensions, 0, n); + return Shape.of(newDimensions); + } + + /** + * Return a {@code end - begin} dimensional shape with dimensions matching this Shape from {@code begin} to {@code end}. + * @param begin Where to start the sub-shape. + * @param end Where to end the sub-shape, exclusive. + * @return the sub-shape bounded by begin and end. + */ + public Shape subShape(int begin, int end){ + if (end > numDimensions()) { + throw new ArrayIndexOutOfBoundsException( + "End index " + end + " out of bounds: shape only has " + numDimensions() + " dimensions."); + } + if (begin < 0) { + throw new ArrayIndexOutOfBoundsException( + "Begin index " + begin + " out of bounds: cannot be less than 0."); + } + + long[] newDimensions = new long[end - begin]; + System.arraycopy(dimensionSizes, begin, newDimensions, 0, end - begin); + return Shape.of(newDimensions); + } + + /** + * Returns a new Shape, with a new first dimension added. In order for this call to succeed, + * {@link Shape#isUnknown()} must be {@code false}. + * + * @param firstDimension the dimension to prepend + * @return a new shape with the given dimension first, followed by this Shape's dimensions, never + * null + */ + public Shape prepend(long firstDimension) { + long[] newDimensions = new long[dimensionSizes.length + 1]; + newDimensions[0] = firstDimension; + System.arraycopy(dimensionSizes, 0, newDimensions, 1, dimensionSizes.length); + + return Shape.of(newDimensions); + } + + /** + * Returns a new Shape, with a new last dimension added. In order for this call to succeed, {@link + * Shape#isUnknown()} must be {@code false}. + * + * @param lastDimension the dimension to append + * @return a new Shape with this Shape's dimensions followed by the given dimension, never null + */ + public Shape append(long lastDimension) { + long[] newDimensions = new long[dimensionSizes.length + 1]; + newDimensions[newDimensions.length - 1] = lastDimension; + System.arraycopy(dimensionSizes, 0, newDimensions, 0, dimensionSizes.length); + + return Shape.of(newDimensions); + } + + /** + * Returns a new Shape, with another Shape's dimensions prepended. For both this Shape and the + * other Shape, {@link Shape#isUnknown()} must return false. E.g. {@code + * Shape.of(3,4).prepend(Shape.of(1,2)) => Shape.of(1,2,3,4) } + * + * @param other another Shape, must not be {@code null}, must not be unknown + * @return A new Shape consisting of the given Shape's dimensions followed by this Shape's + * dimensions, never null + */ + public Shape prepend(Shape other) { + long[] newDimensions = new long[other.dimensionSizes.length + dimensionSizes.length]; + System.arraycopy(other.dimensionSizes, 0, newDimensions, 0, other.dimensionSizes.length); + System.arraycopy( + dimensionSizes, 0, newDimensions, other.dimensionSizes.length, dimensionSizes.length); + return Shape.of(newDimensions); + } + + /** + * Returns a new Shape, with another Shapes' dimensions appended. For both this Shape and the + * other Shape, {@link Shape#isUnknown()} must return false. E.g. @code + * Shape.of(3,4).append(Shape.of(1,2)) => Shape.of(3,4,1,2) } + * + * @param other another Shape, must not be {@code null}, must not be unknown + * @return A new Shape consisting of this Shape's dimensions followed by the given Shape's + * dimensions + */ + public Shape append(Shape other) { + long[] newDimensions = new long[dimensionSizes.length + other.dimensionSizes.length]; + System.arraycopy(dimensionSizes, 0, newDimensions, 0, dimensionSizes.length); + System.arraycopy( + other.dimensionSizes, 0, newDimensions, dimensionSizes.length, other.dimensionSizes.length); + return Shape.of(newDimensions); + } + + private static long computeSize(long[] dimensionSizes) { + if (dimensionSizes == null) { + return UNKNOWN_SIZE; + } + long computedSize = 1L; + for (long dimensionSize : dimensionSizes) { + if (dimensionSize == UNKNOWN_SIZE) { + return UNKNOWN_SIZE; + } + computedSize *= dimensionSize; + } + return computedSize; + } + + /** + * Determines whether another shape is compatible with this one. + * + *

+ * + *

Two possibly-partially-defined shapes are compatible if there exists a fully-defined shape + * that both shapes can represent. Thus, compatibility allows the shape inference code to reason + * about partially-defined shapes. For example: + * + *

    + *
  • Shape.unknown() is compatible with all shapes. + *
  • Shape(UNKNOWN_SIZE, UNKNOWN_SIZE) is compatible with all two-dimensional + * shapes, such as Shape(32, 784), and also Shape.unknown(). It is + * not compatible with, for example, Shape(UNKNOWN_SIZE) or + * Shape(UNKNOWN_SIZE, UNKNOWN_SIZE, UNKNOWN_SIZE). + *
  • Shape(32, UNKNOWN_SIZE) is compatible with all two-dimensional shapes with + * size 32 in the 0th dimension, and also Shape(UNKNOWN_SIZE, UNKNOWN_SIZE) and + * Shape.unknown(). It is not compatible with, for example, Shape(32) + * , Shape(32, UNKNOWN_SIZE, 1) or Shape(64, UNKNOWN_SIZE). + *
  • Shape(32, 784) is compatible with itself, and also + * Shape(32, UNKNOWN_SIZE), Shape(UNKNOWN_SIZE, 784), + * Shape(UNKNOWN_SIZE, UNKNOWN_SIZE) and Shape.unknown(). It is not + * compatible with, for example, Shape(32, 1, 784) or Shape(UNKNOWN_SIZE) + * . + *
+ * + *

The compatibility relation is reflexive and symmetric, but not transitive. For example, + * Shape(32, 784) is compatible with Shape.unknown(), and + * Shape.unknown() is compatible with Shape(4, 4), but Shape(32, 784) + * is not compatible with Shape(4, 4). + * + *

Compatibility is not the same as broadcasting. Compatible shapes must have the same number + * of dimensions and for each dimension pair, one dimension has to equal the other dimensions or + * at least one of the dimensions in the pair has to be UNKNOWN_SIZE. + * + *

Broadcasting allows different dimensions, but paired dimensions have to either be equal, or + * one dimension must be 1. If one shape has less dimensions than another shape, the smaller shape + * is "stretched" with dimensions of 1. + * + * @param shape The other shape + * @return true, if the two shapes are compatible. + */ + public boolean isCompatibleWith(Shape shape) { + if (!this.isUnknown() && !shape.isUnknown()) { + if (numDimensions() != shape.numDimensions()) { + return false; + } + for (int i = 0; i < numDimensions(); i++) { + if (!isCompatible(size(i), shape.size(i))) { + return false; + } + } + } + return true; + } + + /** + * Test to see if two shape dimensions are compatible. + * + *

The dimensions are compatible if either dimension is Shape.UNKNOWN_SIZE or both + * dimensions are equal + * + * @param dim the first dimension + * @param otherDim the second dimension + * @return true, if both dimensions are compatible + */ + public static boolean isCompatible(long dim, long otherDim) { + return dim == Shape.UNKNOWN_SIZE || otherDim == Shape.UNKNOWN_SIZE || dim == otherDim; + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/Shaped.java b/ndarray/src/main/java/org/tensorflow/ndarray/Shaped.java new file mode 100644 index 00000000000..fbe19d75623 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/Shaped.java @@ -0,0 +1,51 @@ +/* + Copyright 2020 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray; + +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.index.Index; + +/** + * Any data container with a given {@link Shape}. + */ +public interface Shaped { + + /** + * @return the shape of this container + */ + Shape shape(); + + /** + * @return the rank of this container + */ + default int rank() { + return shape().numDimensions(); + } + + /** + * Computes and returns the total size of this container, in number of values. + * + *

For example, given a 3x3x2 matrix, the return value will be 18. + * + * @return number of values in this element + */ + default long size() { + return shape().size(); + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/ShortNdArray.java b/ndarray/src/main/java/org/tensorflow/ndarray/ShortNdArray.java new file mode 100644 index 00000000000..f9335b4d5d2 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/ShortNdArray.java @@ -0,0 +1,108 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray; + +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.ShortDataBuffer; +import org.tensorflow.ndarray.index.Index; + +/** + * An {@link NdArray} of shorts. + */ +public interface ShortNdArray extends NdArray { + + /** + * Returns the short value of the scalar found at the given coordinates. + * + *

To access the scalar element, the number of coordinates provided must be equal to the number + * of dimensions of this array (i.e. its rank). For example: + *

{@code
+   *  ShortNdArray matrix = NdArrays.ofShorts(shape(2, 2));  // matrix rank = 2
+   *  matrix.getShort(0, 1);  // succeeds, returns 0.0f
+   *  matrix.getShort(0);  // throws IllegalRankException
+   *
+   *  ShortNdArray scalar = matrix.get(0, 1);  // scalar rank = 0
+   *  scalar.getShort();  // succeeds, returns 0.0f
+   * }
+ * + * @param coordinates coordinates of the scalar to resolve + * @return value of that scalar + * @throws IndexOutOfBoundsException if some coordinates are outside the limits of their respective dimension + * @throws IllegalRankException if number of coordinates is not sufficient to access a scalar element + */ + short getShort(long... coordinates); + + /** + * Assigns the short value of the scalar found at the given coordinates. + * + *

To access the scalar element, the number of coordinates provided must be equal to the number + * of dimensions of this array (i.e. its rank). For example: + *

{@code
+   *  ShortNdArray matrix = NdArrays.ofShorts(shape(2, 2));  // matrix rank = 2
+   *  matrix.setShort(10.0f, 0, 1);  // succeeds
+   *  matrix.setShort(10.0f, 0);  // throws IllegalRankException
+   *
+   *  ShortNdArray scalar = matrix.get(0, 1);  // scalar rank = 0
+   *  scalar.setShort(10.0f);  // succeeds
+   * }
+ * + * @param value value to assign + * @param coordinates coordinates of the scalar to assign + * @return this array + * @throws IndexOutOfBoundsException if some coordinates are outside the limits of their respective dimension + * @throws IllegalRankException if number of coordinates is not sufficient to access a scalar element + */ + ShortNdArray setShort(short value, long... coordinates); + + @Override + ShortNdArray slice(Index... coordinates); + + @Override + ShortNdArray get(long... coordinates); + + @Override + ShortNdArray set(NdArray src, long... coordinates); + + @Override + default Short getObject(long... coordinates) { + return getShort(coordinates); + } + + @Override + default ShortNdArray setObject(Short value, long... coordinates) { + return setShort(value, coordinates); + } + + @Override + NdArraySequence elements(int dimensionIdx); + + @Override + NdArraySequence scalars(); + + @Override + ShortNdArray copyTo(NdArray dst); + + @Override + ShortNdArray read(DataBuffer dst); + + ShortNdArray read(ShortDataBuffer dst); + + @Override + ShortNdArray write(DataBuffer src); + + ShortNdArray write(ShortDataBuffer src); +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/StdArrays.java b/ndarray/src/main/java/org/tensorflow/ndarray/StdArrays.java new file mode 100644 index 00000000000..7d847bd1a9c --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/StdArrays.java @@ -0,0 +1,3809 @@ +package org.tensorflow.ndarray; + +import static org.tensorflow.ndarray.NdArrays.vectorOf; + +import java.lang.reflect.Array; +import org.tensorflow.ndarray.buffer.DataBuffers; + +/** + * Utility class for working with {@link NdArray} instances mixed with standard Java arrays. + */ +public final class StdArrays { + + /** + * Copy an array of ints in a new {@link IntNdArray} + * + * @param array source array + * @return the {@code IntNdArray} copy + */ + public static IntNdArray ndCopyOf(int[] array) { + IntNdArray ndArray = NdArrays.ofInts(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 2-dimensional array of ints in a new {@link IntNdArray} + * + * @param array source array + * @return the {@code IntNdArray} copy + */ + public static IntNdArray ndCopyOf(int[][] array) { + IntNdArray ndArray = NdArrays.ofInts(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 3-dimensional array of ints in a new {@link IntNdArray} + * + * @param array source array + * @return the {@code IntNdArray} copy + */ + public static IntNdArray ndCopyOf(int[][][] array) { + IntNdArray ndArray = NdArrays.ofInts(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 4-dimensional array of ints in a new {@link IntNdArray} + * + * @param array source array + * @return the {@code IntNdArray} copy + */ + public static IntNdArray ndCopyOf(int[][][][] array) { + IntNdArray ndArray = NdArrays.ofInts(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 5-dimensional array of ints in a new {@link IntNdArray} + * + * @param array source array + * @return the {@code IntNdArray} copy + */ + public static IntNdArray ndCopyOf(int[][][][][] array) { + IntNdArray ndArray = NdArrays.ofInts(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 6-dimensional array of ints in a new {@link IntNdArray} + * + * @param array source array + * @return the {@code IntNdArray} copy + */ + public static IntNdArray ndCopyOf(int[][][][][][] array) { + IntNdArray ndArray = NdArrays.ofInts(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy an array of longs in a new {@link LongNdArray} + * + * @param array source array + * @return the {@code LongNdArray} copy + */ + public static LongNdArray ndCopyOf(long[] array) { + LongNdArray ndArray = NdArrays.ofLongs(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 2-dimensional array of longs in a new {@link LongNdArray} + * + * @param array source array + * @return the {@code LongNdArray} copy + */ + public static LongNdArray ndCopyOf(long[][] array) { + LongNdArray ndArray = NdArrays.ofLongs(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 3-dimensional array of longs in a new {@link LongNdArray} + * + * @param array source array + * @return the {@code LongNdArray} copy + */ + public static LongNdArray ndCopyOf(long[][][] array) { + LongNdArray ndArray = NdArrays.ofLongs(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 4-dimensional array of longs in a new {@link LongNdArray} + * + * @param array source array + * @return the {@code LongNdArray} copy + */ + public static LongNdArray ndCopyOf(long[][][][] array) { + LongNdArray ndArray = NdArrays.ofLongs(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 5-dimensional array of longs in a new {@link LongNdArray} + * + * @param array source array + * @return the {@code LongNdArray} copy + */ + public static LongNdArray ndCopyOf(long[][][][][] array) { + LongNdArray ndArray = NdArrays.ofLongs(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 6-dimensional array of longs in a new {@link LongNdArray} + * + * @param array source array + * @return the {@code LongNdArray} copy + */ + public static LongNdArray ndCopyOf(long[][][][][][] array) { + LongNdArray ndArray = NdArrays.ofLongs(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy an array of floats in a new {@link FloatNdArray} + * + * @param array source array + * @return the {@code FloatNdArray} copy + */ + public static FloatNdArray ndCopyOf(float[] array) { + FloatNdArray ndArray = NdArrays.ofFloats(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 2-dimensional array of floats in a new {@link FloatNdArray} + * + * @param array source array + * @return the {@code FloatNdArray} copy + */ + public static FloatNdArray ndCopyOf(float[][] array) { + FloatNdArray ndArray = NdArrays.ofFloats(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 3-dimensional array of floats in a new {@link FloatNdArray} + * + * @param array source array + * @return the {@code FloatNdArray} copy + */ + public static FloatNdArray ndCopyOf(float[][][] array) { + FloatNdArray ndArray = NdArrays.ofFloats(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 4-dimensional array of floats in a new {@link FloatNdArray} + * + * @param array source array + * @return the {@code FloatNdArray} copy + */ + public static FloatNdArray ndCopyOf(float[][][][] array) { + FloatNdArray ndArray = NdArrays.ofFloats(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 5-dimensional array of floats in a new {@link FloatNdArray} + * + * @param array source array + * @return the {@code FloatNdArray} copy + */ + public static FloatNdArray ndCopyOf(float[][][][][] array) { + FloatNdArray ndArray = NdArrays.ofFloats(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 6-dimensional array of floats in a new {@link FloatNdArray} + * + * @param array source array + * @return the {@code FloatNdArray} copy + */ + public static FloatNdArray ndCopyOf(float[][][][][][] array) { + FloatNdArray ndArray = NdArrays.ofFloats(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy an array of doubles in a new {@link DoubleNdArray} + * + * @param array source array + * @return the {@code DoubleNdArray} copy + */ + public static DoubleNdArray ndCopyOf(double[] array) { + DoubleNdArray ndArray = NdArrays.ofDoubles(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 2-dimensional array of doubles in a new {@link DoubleNdArray} + * + * @param array source array + * @return the {@code DoubleNdArray} copy + */ + public static DoubleNdArray ndCopyOf(double[][] array) { + DoubleNdArray ndArray = NdArrays.ofDoubles(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 3-dimensional array of doubles in a new {@link DoubleNdArray} + * + * @param array source array + * @return the {@code DoubleNdArray} copy + */ + public static DoubleNdArray ndCopyOf(double[][][] array) { + DoubleNdArray ndArray = NdArrays.ofDoubles(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 4-dimensional array of doubles in a new {@link DoubleNdArray} + * + * @param array source array + * @return the {@code DoubleNdArray} copy + */ + public static DoubleNdArray ndCopyOf(double[][][][] array) { + DoubleNdArray ndArray = NdArrays.ofDoubles(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 5-dimensional array of doubles in a new {@link DoubleNdArray} + * + * @param array source array + * @return the {@code DoubleNdArray} copy + */ + public static DoubleNdArray ndCopyOf(double[][][][][] array) { + DoubleNdArray ndArray = NdArrays.ofDoubles(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 6-dimensional array of doubles in a new {@link DoubleNdArray} + * + * @param array source array + * @return the {@code DoubleNdArray} copy + */ + public static DoubleNdArray ndCopyOf(double[][][][][][] array) { + DoubleNdArray ndArray = NdArrays.ofDoubles(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy an array of bytes in a new {@link ByteNdArray} + * + * @param array source array + * @return the {@code ByteNdArray} copy + */ + public static ByteNdArray ndCopyOf(byte[] array) { + ByteNdArray ndArray = NdArrays.ofBytes(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 2-dimensional array of bytes in a new {@link ByteNdArray} + * + * @param array source array + * @return the {@code ByteNdArray} copy + */ + public static ByteNdArray ndCopyOf(byte[][] array) { + ByteNdArray ndArray = NdArrays.ofBytes(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 3-dimensional array of bytes in a new {@link ByteNdArray} + * + * @param array source array + * @return the {@code ByteNdArray} copy + */ + public static ByteNdArray ndCopyOf(byte[][][] array) { + ByteNdArray ndArray = NdArrays.ofBytes(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 4-dimensional array of bytes in a new {@link ByteNdArray} + * + * @param array source array + * @return the {@code ByteNdArray} copy + */ + public static ByteNdArray ndCopyOf(byte[][][][] array) { + ByteNdArray ndArray = NdArrays.ofBytes(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 5-dimensional array of bytes in a new {@link ByteNdArray} + * + * @param array source array + * @return the {@code ByteNdArray} copy + */ + public static ByteNdArray ndCopyOf(byte[][][][][] array) { + ByteNdArray ndArray = NdArrays.ofBytes(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 6-dimensional array of bytes in a new {@link ByteNdArray} + * + * @param array source array + * @return the {@code ByteNdArray} copy + */ + public static ByteNdArray ndCopyOf(byte[][][][][][] array) { + ByteNdArray ndArray = NdArrays.ofBytes(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy an array of shorts in a new {@link ShortNdArray} + * + * @param array source array + * @return the {@code ShortNdArray} copy + */ + public static ShortNdArray ndCopyOf(short[] array) { + ShortNdArray ndArray = NdArrays.ofShorts(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 2-dimensional array of shorts in a new {@link ShortNdArray} + * + * @param array source array + * @return the {@code ShortNdArray} copy + */ + public static ShortNdArray ndCopyOf(short[][] array) { + ShortNdArray ndArray = NdArrays.ofShorts(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 3-dimensional array of shorts in a new {@link ShortNdArray} + * + * @param array source array + * @return the {@code ShortNdArray} copy + */ + public static ShortNdArray ndCopyOf(short[][][] array) { + ShortNdArray ndArray = NdArrays.ofShorts(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 4-dimensional array of shorts in a new {@link ShortNdArray} + * + * @param array source array + * @return the {@code ShortNdArray} copy + */ + public static ShortNdArray ndCopyOf(short[][][][] array) { + ShortNdArray ndArray = NdArrays.ofShorts(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 5-dimensional array of shorts in a new {@link ShortNdArray} + * + * @param array source array + * @return the {@code ShortNdArray} copy + */ + public static ShortNdArray ndCopyOf(short[][][][][] array) { + ShortNdArray ndArray = NdArrays.ofShorts(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 6-dimensional array of shorts in a new {@link ShortNdArray} + * + * @param array source array + * @return the {@code ShortNdArray} copy + */ + public static ShortNdArray ndCopyOf(short[][][][][][] array) { + ShortNdArray ndArray = NdArrays.ofShorts(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy an array of booleans in a new {@link BooleanNdArray} + * + * @param array source array + * @return the {@code BooleanNdArray} copy + */ + public static BooleanNdArray ndCopyOf(boolean[] array) { + BooleanNdArray ndArray = NdArrays.ofBooleans(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 2-dimensional array of booleans in a new {@link BooleanNdArray} + * + * @param array source array + * @return the {@code BooleanNdArray} copy + */ + public static BooleanNdArray ndCopyOf(boolean[][] array) { + BooleanNdArray ndArray = NdArrays.ofBooleans(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 3-dimensional array of booleans in a new {@link BooleanNdArray} + * + * @param array source array + * @return the {@code BooleanNdArray} copy + */ + public static BooleanNdArray ndCopyOf(boolean[][][] array) { + BooleanNdArray ndArray = NdArrays.ofBooleans(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 4-dimensional array of booleans in a new {@link BooleanNdArray} + * + * @param array source array + * @return the {@code BooleanNdArray} copy + */ + public static BooleanNdArray ndCopyOf(boolean[][][][] array) { + BooleanNdArray ndArray = NdArrays.ofBooleans(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 5-dimensional array of booleans in a new {@link BooleanNdArray} + * + * @param array source array + * @return the {@code BooleanNdArray} copy + */ + public static BooleanNdArray ndCopyOf(boolean[][][][][] array) { + BooleanNdArray ndArray = NdArrays.ofBooleans(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 6-dimensional array of booleans in a new {@link BooleanNdArray} + * + * @param array source array + * @return the {@code BooleanNdArray} copy + */ + public static BooleanNdArray ndCopyOf(boolean[][][][][][] array) { + BooleanNdArray ndArray = NdArrays.ofBooleans(shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy an array of objects in a new {@link NdArray} + * + * @param array source array + * @param data type + * @return the {@code NdArray} copy + */ + public static NdArray ndCopyOf(T[] array) { + @SuppressWarnings("unchecked") + NdArray ndArray = NdArrays.ofObjects(componentTypeOf(array), shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 2-dimensional array of objects in a new {@link NdArray} + * + * @param array source array + * @param data type + * @return the {@code NdArray} copy + */ + public static NdArray ndCopyOf(T[][] array) { + @SuppressWarnings("unchecked") + NdArrayndArray = NdArrays.ofObjects(componentTypeOf(array), shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 3-dimensional array of objects in a new {@link NdArray} + * + * @param array source array + * @param data type + * @return the {@code NdArray} copy + */ + public static NdArray ndCopyOf(T[][][] array) { + @SuppressWarnings("unchecked") + NdArrayndArray = NdArrays.ofObjects(componentTypeOf(array), shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 4-dimensional array of objects in a new {@link NdArray} + * + * @param array source array + * @param data type + * @return the {@code NdArray} copy + */ + public static NdArray ndCopyOf(T[][][][] array) { + @SuppressWarnings("unchecked") + NdArrayndArray = NdArrays.ofObjects(componentTypeOf(array), shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 5-dimensional array of objects in a new {@link NdArray} + * + * @param array source array + * @param data type + * @return the {@code NdArray} copy + */ + public static NdArray ndCopyOf(T[][][][][] array) { + @SuppressWarnings("unchecked") + NdArrayndArray = NdArrays.ofObjects(componentTypeOf(array), shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a 6-dimensional array of objects in a new {@link NdArray} + * + * @param array source array + * @param data type + * @return the {@code NdArray} copy + */ + public static NdArray ndCopyOf(T[][][][][][] array) { + @SuppressWarnings("unchecked") + NdArrayndArray = NdArrays.ofObjects(componentTypeOf(array), shapeOf(array)); + copyTo(array, ndArray); + return ndArray; + } + + /** + * Copy a {@link IntNdArray} in a new 1-dimension standard array of ints + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-1 or has a shape that + * exceeds standard arrays limits + */ + public static int[] array1dCopyOf(IntNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 1); + int[] array = new int[dims[0]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link IntNdArray} in a new 2-dimension standard array of ints + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-2 or has a shape that + * exceeds standard arrays limits + */ + public static int[][] array2dCopyOf(IntNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 2); + int[][] array = new int[dims[0]][dims[1]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link IntNdArray} in a new 3-dimension standard array of ints + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-3 or has a shape that + * exceeds standard arrays limits + */ + public static int[][][] array3dCopyOf(IntNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 3); + int[][][] array = new int[dims[0]][dims[1]][dims[2]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link IntNdArray} in a new 4-dimension standard array of ints + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-4 or has a shape that + * exceeds standard arrays limits + */ + public static int[][][][] array4dCopyOf(IntNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 4); + int[][][][] array = new int[dims[0]][dims[1]][dims[2]][dims[3]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link IntNdArray} in a new 5-dimension standard array of ints + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-5 or has a shape that + * exceeds standard arrays limits + */ + public static int[][][][][] array5dCopyOf(IntNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 5); + int[][][][][] array = new int[dims[0]][dims[1]][dims[2]][dims[3]][dims[4]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link IntNdArray} in a new 6-dimension standard array of ints + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-6 or has a shape that + * exceeds standard arrays limits + */ + public static int[][][][][][] array6dCopyOf(IntNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 6); + int[][][][][][] array = new int[dims[0]][dims[1]][dims[2]][dims[3]][dims[4]][dims[5]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link LongNdArray} in a new 1-dimension standard array of longs + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-1 or has a shape that + * exceeds standard arrays limits + */ + public static long[] array1dCopyOf(LongNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 1); + long[] array = new long[dims[0]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link LongNdArray} in a new 2-dimension standard array of longs + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-2 or has a shape that + * exceeds standard arrays limits + */ + public static long[][] array2dCopyOf(LongNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 2); + long[][] array = new long[dims[0]][dims[1]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link LongNdArray} in a new 3-dimension standard array of longs + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-3 or has a shape that + * exceeds standard arrays limits + */ + public static long[][][] array3dCopyOf(LongNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 3); + long[][][] array = new long[dims[0]][dims[1]][dims[2]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link LongNdArray} in a new 4-dimension standard array of longs + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-4 or has a shape that + * exceeds standard arrays limits + */ + public static long[][][][] array4dCopyOf(LongNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 4); + long[][][][] array = new long[dims[0]][dims[1]][dims[2]][dims[3]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link LongNdArray} in a new 5-dimension standard array of longs + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-5 or has a shape that + * exceeds standard arrays limits + */ + public static long[][][][][] array5dCopyOf(LongNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 5); + long[][][][][] array = new long[dims[0]][dims[1]][dims[2]][dims[3]][dims[4]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link LongNdArray} in a new 6-dimension standard array of longs + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-6 or has a shape that + * exceeds standard arrays limits + */ + public static long[][][][][][] array6dCopyOf(LongNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 6); + long[][][][][][] array = new long[dims[0]][dims[1]][dims[2]][dims[3]][dims[4]][dims[5]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link FloatNdArray} in a new 1-dimension standard array of floats + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-1 or has a shape that + * exceeds standard arrays limits + */ + public static float[] array1dCopyOf(FloatNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 1); + float[] array = new float[dims[0]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link FloatNdArray} in a new 2-dimension standard array of floats + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-2 or has a shape that + * exceeds standard arrays limits + */ + public static float[][] array2dCopyOf(FloatNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 2); + float[][] array = new float[dims[0]][dims[1]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link FloatNdArray} in a new 3-dimension standard array of floats + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-3 or has a shape that + * exceeds standard arrays limits + */ + public static float[][][] array3dCopyOf(FloatNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 3); + float[][][] array = new float[dims[0]][dims[1]][dims[2]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link FloatNdArray} in a new 4-dimension standard array of floats + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-4 or has a shape that + * exceeds standard arrays limits + */ + public static float[][][][] array4dCopyOf(FloatNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 4); + float[][][][] array = new float[dims[0]][dims[1]][dims[2]][dims[3]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link FloatNdArray} in a new 5-dimension standard array of floats + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-5 or has a shape that + * exceeds standard arrays limits + */ + public static float[][][][][] array5dCopyOf(FloatNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 5); + float[][][][][] array = new float[dims[0]][dims[1]][dims[2]][dims[3]][dims[4]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link FloatNdArray} in a new 6-dimension standard array of floats + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-6 or has a shape that + * exceeds standard arrays limits + */ + public static float[][][][][][] array6dCopyOf(FloatNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 6); + float[][][][][][] array = new float[dims[0]][dims[1]][dims[2]][dims[3]][dims[4]][dims[5]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link DoubleNdArray} in a new 1-dimension standard array of doubles + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-1 or has a shape that + * exceeds standard arrays limits + */ + public static double[] array1dCopyOf(DoubleNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 1); + double[] array = new double[dims[0]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link DoubleNdArray} in a new 2-dimension standard array of doubles + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-2 or has a shape that + * exceeds standard arrays limits + */ + public static double[][] array2dCopyOf(DoubleNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 2); + double[][] array = new double[dims[0]][dims[1]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link DoubleNdArray} in a new 3-dimension standard array of doubles + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-3 or has a shape that + * exceeds standard arrays limits + */ + public static double[][][] array3dCopyOf(DoubleNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 3); + double[][][] array = new double[dims[0]][dims[1]][dims[2]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link DoubleNdArray} in a new 4-dimension standard array of doubles + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-4 or has a shape that + * exceeds standard arrays limits + */ + public static double[][][][] array4dCopyOf(DoubleNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 4); + double[][][][] array = new double[dims[0]][dims[1]][dims[2]][dims[3]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link DoubleNdArray} in a new 5-dimension standard array of doubles + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-5 or has a shape that + * exceeds standard arrays limits + */ + public static double[][][][][] array5dCopyOf(DoubleNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 5); + double[][][][][] array = new double[dims[0]][dims[1]][dims[2]][dims[3]][dims[4]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link DoubleNdArray} in a new 6-dimension standard array of doubles + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-6 or has a shape that + * exceeds standard arrays limits + */ + public static double[][][][][][] array6dCopyOf(DoubleNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 6); + double[][][][][][] array = new double[dims[0]][dims[1]][dims[2]][dims[3]][dims[4]][dims[5]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link ByteNdArray} in a new 1-dimension standard array of bytes + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-1 or has a shape that + * exceeds standard arrays limits + */ + public static byte[] array1dCopyOf(ByteNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 1); + byte[] array = new byte[dims[0]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link ByteNdArray} in a new 2-dimension standard array of bytes + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-2 or has a shape that + * exceeds standard arrays limits + */ + public static byte[][] array2dCopyOf(ByteNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 2); + byte[][] array = new byte[dims[0]][dims[1]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link ByteNdArray} in a new 3-dimension standard array of bytes + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-3 or has a shape that + * exceeds standard arrays limits + */ + public static byte[][][] array3dCopyOf(ByteNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 3); + byte[][][] array = new byte[dims[0]][dims[1]][dims[2]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link ByteNdArray} in a new 4-dimension standard array of bytes + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-4 or has a shape that + * exceeds standard arrays limits + */ + public static byte[][][][] array4dCopyOf(ByteNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 4); + byte[][][][] array = new byte[dims[0]][dims[1]][dims[2]][dims[3]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link ByteNdArray} in a new 5-dimension standard array of bytes + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-5 or has a shape that + * exceeds standard arrays limits + */ + public static byte[][][][][] array5dCopyOf(ByteNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 5); + byte[][][][][] array = new byte[dims[0]][dims[1]][dims[2]][dims[3]][dims[4]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link ByteNdArray} in a new 6-dimension standard array of bytes + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-6 or has a shape that + * exceeds standard arrays limits + */ + public static byte[][][][][][] array6dCopyOf(ByteNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 6); + byte[][][][][][] array = new byte[dims[0]][dims[1]][dims[2]][dims[3]][dims[4]][dims[5]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link ShortNdArray} in a new 1-dimension standard array of shorts + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-1 or has a shape that + * exceeds standard arrays limits + */ + public static short[] array1dCopyOf(ShortNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 1); + short[] array = new short[dims[0]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link ShortNdArray} in a new 2-dimension standard array of shorts + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-2 or has a shape that + * exceeds standard arrays limits + */ + public static short[][] array2dCopyOf(ShortNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 2); + short[][] array = new short[dims[0]][dims[1]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link ShortNdArray} in a new 3-dimension standard array of shorts + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-3 or has a shape that + * exceeds standard arrays limits + */ + public static short[][][] array3dCopyOf(ShortNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 3); + short[][][] array = new short[dims[0]][dims[1]][dims[2]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link ShortNdArray} in a new 4-dimension standard array of shorts + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-4 or has a shape that + * exceeds standard arrays limits + */ + public static short[][][][] array4dCopyOf(ShortNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 4); + short[][][][] array = new short[dims[0]][dims[1]][dims[2]][dims[3]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link ShortNdArray} in a new 5-dimension standard array of shorts + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-5 or has a shape that + * exceeds standard arrays limits + */ + public static short[][][][][] array5dCopyOf(ShortNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 5); + short[][][][][] array = new short[dims[0]][dims[1]][dims[2]][dims[3]][dims[4]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link ShortNdArray} in a new 6-dimension standard array of shorts + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-6 or has a shape that + * exceeds standard arrays limits + */ + public static short[][][][][][] array6dCopyOf(ShortNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 6); + short[][][][][][] array = new short[dims[0]][dims[1]][dims[2]][dims[3]][dims[4]][dims[5]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link BooleanNdArray} in a new 1-dimension standard array of booleans + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-1 or has a shape that + * exceeds standard arrays limits + */ + public static boolean[] array1dCopyOf(BooleanNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 1); + boolean[] array = new boolean[dims[0]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link BooleanNdArray} in a new 2-dimension standard array of booleans + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-2 or has a shape that + * exceeds standard arrays limits + */ + public static boolean[][] array2dCopyOf(BooleanNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 2); + boolean[][] array = new boolean[dims[0]][dims[1]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link BooleanNdArray} in a new 3-dimension standard array of booleans + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-3 or has a shape that + * exceeds standard arrays limits + */ + public static boolean[][][] array3dCopyOf(BooleanNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 3); + boolean[][][] array = new boolean[dims[0]][dims[1]][dims[2]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link BooleanNdArray} in a new 4-dimension standard array of booleans + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-4 or has a shape that + * exceeds standard arrays limits + */ + public static boolean[][][][] array4dCopyOf(BooleanNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 4); + boolean[][][][] array = new boolean[dims[0]][dims[1]][dims[2]][dims[3]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link BooleanNdArray} in a new 5-dimension standard array of booleans + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-5 or has a shape that + * exceeds standard arrays limits + */ + public static boolean[][][][][] array5dCopyOf(BooleanNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 5); + boolean[][][][][] array = new boolean[dims[0]][dims[1]][dims[2]][dims[3]][dims[4]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link BooleanNdArray} in a new 6-dimension standard array of booleans + * + * @param ndArray source array + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-6 or has a shape that + * exceeds standard arrays limits + */ + public static boolean[][][][][][] array6dCopyOf(BooleanNdArray ndArray) { + int[] dims = computeArrayDims(ndArray, 6); + boolean[][][][][][] array = new boolean[dims[0]][dims[1]][dims[2]][dims[3]][dims[4]][dims[5]]; + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link NdArray NdArray<T>} in a new 1-dimension standard array of objects + * + * @param ndArray source array + * @param objectType type of object + * @param data type + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-1 or has a shape that + * exceeds standard arrays limits + */ + public static T[] array1dCopyOf(NdArray ndArray, Class objectType) { + int[] dims = computeArrayDims(ndArray, 1); + T[] array = (T[])Array.newInstance(objectType, dims[0]); + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link NdArray NdArray<T>} in a new 2-dimension standard array of objects + * + * @param ndArray source array + * @param objectType type of object + * @param data type + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-2 or has a shape that + * exceeds standard arrays limits + */ + public static T[][] array2dCopyOf(NdArray ndArray, Class objectType) { + int[] dims = computeArrayDims(ndArray, 2); + T[][] array = (T[][])Array.newInstance(objectType, dims[0], dims[1]); + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link NdArray NdArray<T>} in a new 3-dimension standard array of objects + * + * @param ndArray source array + * @param objectType type of object + * @param data type + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-3 or has a shape that + * exceeds standard arrays limits + */ + public static T[][][] array3dCopyOf(NdArray ndArray, Class objectType) { + int[] dims = computeArrayDims(ndArray, 3); + T[][][] array = (T[][][])Array.newInstance(objectType, dims[0], dims[1], dims[2]); + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link NdArray NdArray<T>} in a new 4-dimension standard array of objects + * + * @param ndArray source array + * @param objectType type of object + * @param data type + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-4 or has a shape that + * exceeds standard arrays limits + */ + public static T[][][][] array4dCopyOf(NdArray ndArray, Class objectType) { + int[] dims = computeArrayDims(ndArray, 4); + T[][][][] array = (T[][][][])Array.newInstance(objectType, dims[0], dims[1], dims[2], dims[3]); + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link NdArray NdArray<T>} in a new 5-dimension standard array of objects + * + * @param ndArray source array + * @param objectType type of object + * @param data type + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-5 or has a shape that + * exceeds standard arrays limits + */ + public static T[][][][][] array5dCopyOf(NdArray ndArray, Class objectType) { + int[] dims = computeArrayDims(ndArray, 5); + T[][][][][] array = + (T[][][][][])Array.newInstance(objectType, dims[0], dims[1], dims[2], dims[3], dims[4]); + copyFrom(ndArray, array); + return array; + } + + /** + * Copy a {@link NdArray NdArray<T>} in a new 6-dimension standard array of objects + * + * @param ndArray source array + * @param objectType type of object + * @param data type + * @return the array copy + * @throws IllegalArgumentException if {@code ndArray} is not of rank-6 or has a shape that + * exceeds standard arrays limits + */ + public static T[][][][][][] array6dCopyOf(NdArray ndArray, Class objectType) { + int[] dims = computeArrayDims(ndArray, 6); + T[][][][][][] array = + (T[][][][][][])Array.newInstance(objectType, dims[0], dims[1], dims[2], dims[3], dims[4], dims[5]); + copyFrom(ndArray, array); + return array; + } + + /** + * Copy an array of ints into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-1 array + * @throws IllegalArgumentException if {@code dst} is not of rank-1 or has an incompatible shape + * with the source array + */ + public static void copyTo(int[] src, IntNdArray dst) { + NdArrays.vectorOf(src).copyTo(dst); + } + + /** + * Copy a 2-dimensional array of ints into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-2 array + * @throws IllegalArgumentException if {@code dst} is not of rank-2 or has an incompatible shape + * with the source array + */ + public static void copyTo(int[][] src, IntNdArray dst) { + dst.elements(0).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]]).copyTo(e) + ); + } + + /** + * Copy a 3-dimensional array of ints into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-3 array + * @throws IllegalArgumentException if {@code dst} is not of rank-3 or has an incompatible shape + * with the source array + */ + public static void copyTo(int[][][] src, IntNdArray dst) { + dst.elements(1).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]][(int)idx[1]]).copyTo(e) + ); + } + + /** + * Copy a 4-dimensional array of ints into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-4 array + * @throws IllegalArgumentException if {@code dst} is not of rank-4 or has an incompatible shape + * with the source array + */ + public static void copyTo(int[][][][] src, IntNdArray dst) { + dst.elements(2).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]][(int)idx[1]][(int)idx[2]]).copyTo(e) + ); + } + + /** + * Copy a 5-dimensional array of ints into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-5 array + * @throws IllegalArgumentException if {@code dst} is not of rank-5 or has an incompatible shape + * with the source array + */ + public static void copyTo(int[][][][][] src, IntNdArray dst) { + dst.elements(3).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]][(int)idx[1]][(int)idx[2]][(int)idx[3]]).copyTo(e) + ); + } + + /** + * Copy a 6-dimensional array of ints into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-6 array + * @throws IllegalArgumentException if {@code dst} is not of rank-6 or has an incompatible shape + * with the source array + */ + public static void copyTo(int[][][][][][] src, IntNdArray dst) { + dst.elements(4).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]][(int)idx[1]][(int)idx[2]][(int)idx[3]][(int)idx[4]]).copyTo(e) + ); + } + + /** + * Copy an array of longs into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-1 array + * @throws IllegalArgumentException if {@code dst} is not of rank-1 or has an incompatible shape + * with the source array + */ + public static void copyTo(long[] src, LongNdArray dst) { + NdArrays.vectorOf(src).copyTo(dst); + } + + /** + * Copy a 2-dimensional array of longs into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-2 array + * @throws IllegalArgumentException if {@code dst} is not of rank-2 or has an incompatible shape + * with the source array + */ + public static void copyTo(long[][] src, LongNdArray dst) { + dst.elements(0).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]]).copyTo(e) + ); + } + + /** + * Copy a 3-dimensional array of longs into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-3 array + * @throws IllegalArgumentException if {@code dst} is not of rank-3 or has an incompatible shape + * with the source array + */ + public static void copyTo(long[][][] src, LongNdArray dst) { + dst.elements(1).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]][(int)idx[1]]).copyTo(e) + ); + } + + /** + * Copy a 4-dimensional array of longs into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-4 array + * @throws IllegalArgumentException if {@code dst} is not of rank-4 or has an incompatible shape + * with the source array + */ + public static void copyTo(long[][][][] src, LongNdArray dst) { + dst.elements(2).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]][(int)idx[1]][(int)idx[2]]).copyTo(e) + ); + } + + /** + * Copy a 5-dimensional array of longs into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-5 array + * @throws IllegalArgumentException if {@code dst} is not of rank-5 or has an incompatible shape + * with the source array + */ + public static void copyTo(long[][][][][] src, LongNdArray dst) { + dst.elements(3).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]][(int)idx[1]][(int)idx[2]][(int)idx[3]]).copyTo(e) + ); + } + + /** + * Copy a 6-dimensional array of longs into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-6 array + * @throws IllegalArgumentException if {@code dst} is not of rank-6 or has an incompatible shape + * with the source array + */ + public static void copyTo(long[][][][][][] src, LongNdArray dst) { + dst.elements(4).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]][(int)idx[1]][(int)idx[2]][(int)idx[3]][(int)idx[4]]).copyTo(e) + ); + } + + /** + * Copy an array of floats into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-1 array + * @throws IllegalArgumentException if {@code dst} is not of rank-1 or has an incompatible shape + * with the source array + */ + public static void copyTo(float[] src, FloatNdArray dst) { + NdArrays.vectorOf(src).copyTo(dst); + } + + /** + * Copy a 2-dimensional array of floats into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-2 array + * @throws IllegalArgumentException if {@code dst} is not of rank-2 or has an incompatible shape + * with the source array + */ + public static void copyTo(float[][] src, FloatNdArray dst) { + dst.elements(0).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]]).copyTo(e) + ); + } + + /** + * Copy a 3-dimensional array of floats into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-3 array + * @throws IllegalArgumentException if {@code dst} is not of rank-3 or has an incompatible shape + * with the source array + */ + public static void copyTo(float[][][] src, FloatNdArray dst) { + dst.elements(1).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]][(int)idx[1]]).copyTo(e) + ); + } + + /** + * Copy a 4-dimensional array of floats into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-4 array + * @throws IllegalArgumentException if {@code dst} is not of rank-4 or has an incompatible shape + * with the source array + */ + public static void copyTo(float[][][][] src, FloatNdArray dst) { + dst.elements(2).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]][(int)idx[1]][(int)idx[2]]).copyTo(e) + ); + } + + /** + * Copy a 5-dimensional array of floats into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-5 array + * @throws IllegalArgumentException if {@code dst} is not of rank-5 or has an incompatible shape + * with the source array + */ + public static void copyTo(float[][][][][] src, FloatNdArray dst) { + dst.elements(3).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]][(int)idx[1]][(int)idx[2]][(int)idx[3]]).copyTo(e) + ); + } + + /** + * Copy a 6-dimensional array of floats into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-6 array + * @throws IllegalArgumentException if {@code dst} is not of rank-6 or has an incompatible shape + * with the source array + */ + public static void copyTo(float[][][][][][] src, FloatNdArray dst) { + dst.elements(4).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]][(int)idx[1]][(int)idx[2]][(int)idx[3]][(int)idx[4]]).copyTo(e) + ); + } + + /** + * Copy an array of doubles into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-1 array + * @throws IllegalArgumentException if {@code dst} is not of rank-1 or has an incompatible shape + * with the source array + */ + public static void copyTo(double[] src, DoubleNdArray dst) { + NdArrays.vectorOf(src).copyTo(dst); + } + + /** + * Copy a 2-dimensional array of doubles into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-2 array + * @throws IllegalArgumentException if {@code dst} is not of rank-2 or has an incompatible shape + * with the source array + */ + public static void copyTo(double[][] src, DoubleNdArray dst) { + dst.elements(0).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]]).copyTo(e) + ); + } + + /** + * Copy a 3-dimensional array of doubles into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-3 array + * @throws IllegalArgumentException if {@code dst} is not of rank-3 or has an incompatible shape + * with the source array + */ + public static void copyTo(double[][][] src, DoubleNdArray dst) { + dst.elements(1).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]][(int)idx[1]]).copyTo(e) + ); + } + + /** + * Copy a 4-dimensional array of doubles into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-4 array + * @throws IllegalArgumentException if {@code dst} is not of rank-4 or has an incompatible shape + * with the source array + */ + public static void copyTo(double[][][][] src, DoubleNdArray dst) { + dst.elements(2).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]][(int)idx[1]][(int)idx[2]]).copyTo(e) + ); + } + + /** + * Copy a 5-dimensional array of doubles into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-5 array + * @throws IllegalArgumentException if {@code dst} is not of rank-5 or has an incompatible shape + * with the source array + */ + public static void copyTo(double[][][][][] src, DoubleNdArray dst) { + dst.elements(3).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]][(int)idx[1]][(int)idx[2]][(int)idx[3]]).copyTo(e) + ); + } + + /** + * Copy a 6-dimensional array of doubles into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-6 array + * @throws IllegalArgumentException if {@code dst} is not of rank-6 or has an incompatible shape + * with the source array + */ + public static void copyTo(double[][][][][][] src, DoubleNdArray dst) { + dst.elements(4).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]][(int)idx[1]][(int)idx[2]][(int)idx[3]][(int)idx[4]]).copyTo(e) + ); + } + + /** + * Copy an array of bytes into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-1 array + * @throws IllegalArgumentException if {@code dst} is not of rank-1 or has an incompatible shape + * with the source array + */ + public static void copyTo(byte[] src, ByteNdArray dst) { + NdArrays.vectorOf(src).copyTo(dst); + } + + /** + * Copy a 2-dimensional array of bytes into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-2 array + * @throws IllegalArgumentException if {@code dst} is not of rank-2 or has an incompatible shape + * with the source array + */ + public static void copyTo(byte[][] src, ByteNdArray dst) { + dst.elements(0).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]]).copyTo(e) + ); + } + + /** + * Copy a 3-dimensional array of bytes into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-3 array + * @throws IllegalArgumentException if {@code dst} is not of rank-3 or has an incompatible shape + * with the source array + */ + public static void copyTo(byte[][][] src, ByteNdArray dst) { + dst.elements(1).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]][(int)idx[1]]).copyTo(e) + ); + } + + /** + * Copy a 4-dimensional array of bytes into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-4 array + * @throws IllegalArgumentException if {@code dst} is not of rank-4 or has an incompatible shape + * with the source array + */ + public static void copyTo(byte[][][][] src, ByteNdArray dst) { + dst.elements(2).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]][(int)idx[1]][(int)idx[2]]).copyTo(e) + ); + } + + /** + * Copy a 5-dimensional array of bytes into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-5 array + * @throws IllegalArgumentException if {@code dst} is not of rank-5 or has an incompatible shape + * with the source array + */ + public static void copyTo(byte[][][][][] src, ByteNdArray dst) { + dst.elements(3).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]][(int)idx[1]][(int)idx[2]][(int)idx[3]]).copyTo(e) + ); + } + + /** + * Copy a 6-dimensional array of bytes into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-6 array + * @throws IllegalArgumentException if {@code dst} is not of rank-6 or has an incompatible shape + * with the source array + */ + public static void copyTo(byte[][][][][][] src, ByteNdArray dst) { + dst.elements(4).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]][(int)idx[1]][(int)idx[2]][(int)idx[3]][(int)idx[4]]).copyTo(e) + ); + } + + /** + * Copy an array of shorts into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-1 array + * @throws IllegalArgumentException if {@code dst} is not of rank-1 or has an incompatible shape + * with the source array + */ + public static void copyTo(short[] src, ShortNdArray dst) { + NdArrays.vectorOf(src).copyTo(dst); + } + + /** + * Copy a 2-dimensional array of shorts into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-2 array + * @throws IllegalArgumentException if {@code dst} is not of rank-2 or has an incompatible shape + * with the source array + */ + public static void copyTo(short[][] src, ShortNdArray dst) { + dst.elements(0).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]]).copyTo(e) + ); + } + + /** + * Copy a 3-dimensional array of shorts into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-3 array + * @throws IllegalArgumentException if {@code dst} is not of rank-3 or has an incompatible shape + * with the source array + */ + public static void copyTo(short[][][] src, ShortNdArray dst) { + dst.elements(1).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]][(int)idx[1]]).copyTo(e) + ); + } + + /** + * Copy a 4-dimensional array of shorts into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-4 array + * @throws IllegalArgumentException if {@code dst} is not of rank-4 or has an incompatible shape + * with the source array + */ + public static void copyTo(short[][][][] src, ShortNdArray dst) { + dst.elements(2).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]][(int)idx[1]][(int)idx[2]]).copyTo(e) + ); + } + + /** + * Copy a 5-dimensional array of shorts into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-5 array + * @throws IllegalArgumentException if {@code dst} is not of rank-5 or has an incompatible shape + * with the source array + */ + public static void copyTo(short[][][][][] src, ShortNdArray dst) { + dst.elements(3).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]][(int)idx[1]][(int)idx[2]][(int)idx[3]]).copyTo(e) + ); + } + + /** + * Copy a 6-dimensional array of shorts into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-6 array + * @throws IllegalArgumentException if {@code dst} is not of rank-6 or has an incompatible shape + * with the source array + */ + public static void copyTo(short[][][][][][] src, ShortNdArray dst) { + dst.elements(4).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]][(int)idx[1]][(int)idx[2]][(int)idx[3]][(int)idx[4]]).copyTo(e) + ); + } + + /** + * Copy an array of booleans into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-1 array + * @throws IllegalArgumentException if {@code dst} is not of rank-1 or has an incompatible shape + * with the source array + */ + public static void copyTo(boolean[] src, BooleanNdArray dst) { + NdArrays.vectorOf(src).copyTo(dst); + } + + /** + * Copy a 2-dimensional array of booleans into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-2 array + * @throws IllegalArgumentException if {@code dst} is not of rank-2 or has an incompatible shape + * with the source array + */ + public static void copyTo(boolean[][] src, BooleanNdArray dst) { + dst.elements(0).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]]).copyTo(e) + ); + } + + /** + * Copy a 3-dimensional array of booleans into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-3 array + * @throws IllegalArgumentException if {@code dst} is not of rank-3 or has an incompatible shape + * with the source array + */ + public static void copyTo(boolean[][][] src, BooleanNdArray dst) { + dst.elements(1).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]][(int)idx[1]]).copyTo(e) + ); + } + + /** + * Copy a 4-dimensional array of booleans into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-4 array + * @throws IllegalArgumentException if {@code dst} is not of rank-4 or has an incompatible shape + * with the source array + */ + public static void copyTo(boolean[][][][] src, BooleanNdArray dst) { + dst.elements(2).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]][(int)idx[1]][(int)idx[2]]).copyTo(e) + ); + } + + /** + * Copy a 5-dimensional array of booleans into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-5 array + * @throws IllegalArgumentException if {@code dst} is not of rank-5 or has an incompatible shape + * with the source array + */ + public static void copyTo(boolean[][][][][] src, BooleanNdArray dst) { + dst.elements(3).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]][(int)idx[1]][(int)idx[2]][(int)idx[3]]).copyTo(e) + ); + } + + /** + * Copy a 6-dimensional array of booleans into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-6 array + * @throws IllegalArgumentException if {@code dst} is not of rank-6 or has an incompatible shape + * with the source array + */ + public static void copyTo(boolean[][][][][][] src, BooleanNdArray dst) { + dst.elements(4).forEachIndexed((idx, e) -> + NdArrays.vectorOf(src[(int)idx[0]][(int)idx[1]][(int)idx[2]][(int)idx[3]][(int)idx[4]]).copyTo(e) + ); + } + + /** + * Copy an array of objects into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-1 array + * @param data type + * @throws IllegalArgumentException if {@code dst} is not of rank-1 or has an incompatible shape + * with the source array + */ + public static void copyTo(T[] src, NdArray dst) { + NdArrays.vectorOfObjects(src).copyTo(dst); + } + + /** + * Copy a 2-dimensional array of objects into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-2 array + * @param data type + * @throws IllegalArgumentException if {@code dst} is not of rank-2 or has an incompatible shape + * with the source array + */ + public static void copyTo(T[][] src, NdArray dst) { + dst.elements(0).forEachIndexed((idx, e) -> + NdArrays.vectorOfObjects(src[(int)idx[0]]).copyTo(e) + ); + } + + /** + * Copy a 3-dimensional array of objects into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-3 array + * @param data type + * @throws IllegalArgumentException if {@code dst} is not of rank-3 or has an incompatible shape + * with the source array + */ + public static void copyTo(T[][][] src, NdArray dst) { + dst.elements(1).forEachIndexed((idx, e) -> + NdArrays.vectorOfObjects(src[(int)idx[0]][(int)idx[1]]).copyTo(e) + ); + } + + /** + * Copy a 4-dimensional array of objects into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-4 array + * @param data type + * @throws IllegalArgumentException if {@code dst} is not of rank-4 or has an incompatible shape + * with the source array + */ + public static void copyTo(T[][][][] src, NdArray dst) { + dst.elements(2).forEachIndexed((idx, e) -> + NdArrays.vectorOfObjects(src[(int)idx[0]][(int)idx[1]][(int)idx[2]]).copyTo(e) + ); + } + + /** + * Copy a 5-dimensional array of objects into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-5 array + * @param data type + * @throws IllegalArgumentException if {@code dst} is not of rank-5 or has an incompatible shape + * with the source array + */ + public static void copyTo(T[][][][][] src, NdArray dst) { + dst.elements(3).forEachIndexed((idx, e) -> + NdArrays.vectorOfObjects(src[(int)idx[0]][(int)idx[1]][(int)idx[2]][(int)idx[3]]).copyTo(e) + ); + } + + /** + * Copy a 6-dimensional array of objects into the {@code dst} {@link NdArray} + * + * @param src source array + * @param dst destination rank-6 array + * @param data type + * @throws IllegalArgumentException if {@code dst} is not of rank-6 or has an incompatible shape + * with the source array + */ + public static void copyTo(T[][][][][][] src, NdArray dst) { + dst.elements(4).forEachIndexed((idx, e) -> + NdArrays.vectorOfObjects(src[(int)idx[0]][(int)idx[1]][(int)idx[2]][(int)idx[3]][(int)idx[4]]).copyTo(e) + ); + } + + + /** + * Copy a {@link NdArray} to an array of ints + * + * @param src source rank-1 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-1 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(IntNdArray src, int[] dst) { + if (src.rank() != 1) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + if (src.size() > dst.length) { + throw new ArrayIndexOutOfBoundsException(String.valueOf(src.size()) + " > " + dst.length); + } + src.read(DataBuffers.of(dst, false, false)); + } + + /** + * Copy a {@link NdArray} to a 2-dimensional array of ints + * + * @param src source rank-2 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-2 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(IntNdArray src, int[][] dst) { + if (src.rank() != 2) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(0).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]]) + ); + } + + /** + * Copy a {@link NdArray} to a 3-dimensional array of ints + * + * @param src source rank-3 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-3 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(IntNdArray src, int[][][] dst) { + if (src.rank() != 3) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(1).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]][(int)idx[1]]) + ); + } + + /** + * Copy a {@link NdArray} to a 4-dimensional array of ints + * + * @param src source rank-4 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-4 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(IntNdArray src, int[][][][] dst) { + if (src.rank() != 4) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(2).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]][(int)idx[1]][(int)idx[2]]) + ); + } + + /** + * Copy a {@link NdArray} to a 5-dimensional array of ints + * + * @param src source rank-5 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-5 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(IntNdArray src, int[][][][][] dst) { + if (src.rank() != 5) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(3).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]][(int)idx[1]][(int)idx[2]][(int)idx[3]]) + ); + } + + /** + * Copy a {@link NdArray} to a 6-dimensional array of ints + * + * @param src source rank-6 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-6 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(IntNdArray src, int[][][][][][] dst) { + if (src.rank() != 6) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(4).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]][(int)idx[1]][(int)idx[2]][(int)idx[3]][(int)idx[4]]) + ); + } + + /** + * Copy a {@link NdArray} to an array of longs + * + * @param src source rank-1 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-1 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(LongNdArray src, long[] dst) { + if (src.rank() != 1) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + if (src.size() > dst.length) { + throw new ArrayIndexOutOfBoundsException(String.valueOf(src.size()) + " > " + dst.length); + } + src.read(DataBuffers.of(dst, false, false)); + } + + /** + * Copy a {@link NdArray} to a 2-dimensional array of longs + * + * @param src source rank-2 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-2 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(LongNdArray src, long[][] dst) { + if (src.rank() != 2) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(0).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]]) + ); + } + + /** + * Copy a {@link NdArray} to a 3-dimensional array of longs + * + * @param src source rank-3 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-3 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(LongNdArray src, long[][][] dst) { + if (src.rank() != 3) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(1).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]][(int)idx[1]]) + ); + } + + /** + * Copy a {@link NdArray} to a 4-dimensional array of longs + * + * @param src source rank-4 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-4 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(LongNdArray src, long[][][][] dst) { + if (src.rank() != 4) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(2).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]][(int)idx[1]][(int)idx[2]]) + ); + } + + /** + * Copy a {@link NdArray} to a 5-dimensional array of longs + * + * @param src source rank-5 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-5 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(LongNdArray src, long[][][][][] dst) { + if (src.rank() != 5) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(3).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]][(int)idx[1]][(int)idx[2]][(int)idx[3]]) + ); + } + + /** + * Copy a {@link NdArray} to a 6-dimensional array of longs + * + * @param src source rank-6 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-6 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(LongNdArray src, long[][][][][][] dst) { + if (src.rank() != 6) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(4).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]][(int)idx[1]][(int)idx[2]][(int)idx[3]][(int)idx[4]]) + ); + } + + /** + * Copy a {@link NdArray} to an array of floats + * + * @param src source rank-1 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-1 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(FloatNdArray src, float[] dst) { + if (src.rank() != 1) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + if (src.size() > dst.length) { + throw new ArrayIndexOutOfBoundsException(String.valueOf(src.size()) + " > " + dst.length); + } + src.read(DataBuffers.of(dst, false, false)); + } + + /** + * Copy a {@link NdArray} to a 2-dimensional array of floats + * + * @param src source rank-2 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-2 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(FloatNdArray src, float[][] dst) { + if (src.rank() != 2) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(0).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]]) + ); + } + + /** + * Copy a {@link NdArray} to a 3-dimensional array of floats + * + * @param src source rank-3 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-3 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(FloatNdArray src, float[][][] dst) { + if (src.rank() != 3) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(1).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]][(int)idx[1]]) + ); + } + + /** + * Copy a {@link NdArray} to a 4-dimensional array of floats + * + * @param src source rank-4 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-4 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(FloatNdArray src, float[][][][] dst) { + if (src.rank() != 4) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(2).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]][(int)idx[1]][(int)idx[2]]) + ); + } + + /** + * Copy a {@link NdArray} to a 5-dimensional array of floats + * + * @param src source rank-5 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-5 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(FloatNdArray src, float[][][][][] dst) { + if (src.rank() != 5) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(3).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]][(int)idx[1]][(int)idx[2]][(int)idx[3]]) + ); + } + + /** + * Copy a {@link NdArray} to a 6-dimensional array of floats + * + * @param src source rank-6 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-6 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(FloatNdArray src, float[][][][][][] dst) { + if (src.rank() != 6) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(4).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]][(int)idx[1]][(int)idx[2]][(int)idx[3]][(int)idx[4]]) + ); + } + + /** + * Copy a {@link NdArray} to an array of doubles + * + * @param src source rank-1 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-1 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(DoubleNdArray src, double[] dst) { + if (src.rank() != 1) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + if (src.size() > dst.length) { + throw new ArrayIndexOutOfBoundsException(String.valueOf(src.size()) + " > " + dst.length); + } + src.read(DataBuffers.of(dst, false, false)); + } + + /** + * Copy a {@link NdArray} to a 2-dimensional array of doubles + * + * @param src source rank-2 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-2 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(DoubleNdArray src, double[][] dst) { + if (src.rank() != 2) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(0).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]]) + ); + } + + /** + * Copy a {@link NdArray} to a 3-dimensional array of doubles + * + * @param src source rank-3 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-3 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(DoubleNdArray src, double[][][] dst) { + if (src.rank() != 3) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(1).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]][(int)idx[1]]) + ); + } + + /** + * Copy a {@link NdArray} to a 4-dimensional array of doubles + * + * @param src source rank-4 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-4 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(DoubleNdArray src, double[][][][] dst) { + if (src.rank() != 4) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(2).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]][(int)idx[1]][(int)idx[2]]) + ); + } + + /** + * Copy a {@link NdArray} to a 5-dimensional array of doubles + * + * @param src source rank-5 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-5 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(DoubleNdArray src, double[][][][][] dst) { + if (src.rank() != 5) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(3).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]][(int)idx[1]][(int)idx[2]][(int)idx[3]]) + ); + } + + /** + * Copy a {@link NdArray} to a 6-dimensional array of doubles + * + * @param src source rank-6 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-6 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(DoubleNdArray src, double[][][][][][] dst) { + if (src.rank() != 6) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(4).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]][(int)idx[1]][(int)idx[2]][(int)idx[3]][(int)idx[4]]) + ); + } + + /** + * Copy a {@link NdArray} to an array of bytes + * + * @param src source rank-1 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-1 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(ByteNdArray src, byte[] dst) { + if (src.rank() != 1) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + if (src.size() > dst.length) { + throw new ArrayIndexOutOfBoundsException(String.valueOf(src.size()) + " > " + dst.length); + } + src.read(DataBuffers.of(dst, false, false)); + } + + /** + * Copy a {@link NdArray} to a 2-dimensional array of bytes + * + * @param src source rank-2 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-2 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(ByteNdArray src, byte[][] dst) { + if (src.rank() != 2) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(0).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]]) + ); + } + + /** + * Copy a {@link NdArray} to a 3-dimensional array of bytes + * + * @param src source rank-3 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-3 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(ByteNdArray src, byte[][][] dst) { + if (src.rank() != 3) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(1).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]][(int)idx[1]]) + ); + } + + /** + * Copy a {@link NdArray} to a 4-dimensional array of bytes + * + * @param src source rank-4 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-4 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(ByteNdArray src, byte[][][][] dst) { + if (src.rank() != 4) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(2).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]][(int)idx[1]][(int)idx[2]]) + ); + } + + /** + * Copy a {@link NdArray} to a 5-dimensional array of bytes + * + * @param src source rank-5 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-5 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(ByteNdArray src, byte[][][][][] dst) { + if (src.rank() != 5) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(3).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]][(int)idx[1]][(int)idx[2]][(int)idx[3]]) + ); + } + + /** + * Copy a {@link NdArray} to a 6-dimensional array of bytes + * + * @param src source rank-6 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-6 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(ByteNdArray src, byte[][][][][][] dst) { + if (src.rank() != 6) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(4).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]][(int)idx[1]][(int)idx[2]][(int)idx[3]][(int)idx[4]]) + ); + } + + /** + * Copy a {@link NdArray} to an array of shorts + * + * @param src source rank-1 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-1 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(ShortNdArray src, short[] dst) { + if (src.rank() != 1) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + if (src.size() > dst.length) { + throw new ArrayIndexOutOfBoundsException(String.valueOf(src.size()) + " > " + dst.length); + } + src.read(DataBuffers.of(dst, false, false)); + } + + /** + * Copy a {@link NdArray} to a 2-dimensional array of shorts + * + * @param src source rank-2 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-2 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(ShortNdArray src, short[][] dst) { + if (src.rank() != 2) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(0).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]]) + ); + } + + /** + * Copy a {@link NdArray} to a 3-dimensional array of shorts + * + * @param src source rank-3 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-3 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(ShortNdArray src, short[][][] dst) { + if (src.rank() != 3) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(1).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]][(int)idx[1]]) + ); + } + + /** + * Copy a {@link NdArray} to a 4-dimensional array of shorts + * + * @param src source rank-4 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-4 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(ShortNdArray src, short[][][][] dst) { + if (src.rank() != 4) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(2).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]][(int)idx[1]][(int)idx[2]]) + ); + } + + /** + * Copy a {@link NdArray} to a 5-dimensional array of shorts + * + * @param src source rank-5 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-5 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(ShortNdArray src, short[][][][][] dst) { + if (src.rank() != 5) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(3).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]][(int)idx[1]][(int)idx[2]][(int)idx[3]]) + ); + } + + /** + * Copy a {@link NdArray} to a 6-dimensional array of shorts + * + * @param src source rank-6 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-6 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(ShortNdArray src, short[][][][][][] dst) { + if (src.rank() != 6) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(4).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]][(int)idx[1]][(int)idx[2]][(int)idx[3]][(int)idx[4]]) + ); + } + + /** + * Copy a {@link NdArray} to an array of booleans. + * + * @param src source rank-1 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-1 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(BooleanNdArray src, boolean[] dst) { + if (src.rank() != 1) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + if (src.size() > dst.length) { + throw new ArrayIndexOutOfBoundsException(String.valueOf(src.size()) + " > " + dst.length); + } + src.read(DataBuffers.of(dst, false, false)); + } + + /** + * Copy a {@link NdArray} to a 2-dimensional array of booleans + * + * @param src source rank-2 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-2 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(BooleanNdArray src, boolean[][] dst) { + if (src.rank() != 2) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(0).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]]) + ); + } + + /** + * Copy a {@link NdArray} to a 3-dimensional array of booleans + * + * @param src source rank-3 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-3 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(BooleanNdArray src, boolean[][][] dst) { + if (src.rank() != 3) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(1).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]][(int)idx[1]]) + ); + } + + /** + * Copy a {@link NdArray} to a 4-dimensional array of booleans + * + * @param src source rank-4 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-4 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(BooleanNdArray src, boolean[][][][] dst) { + if (src.rank() != 4) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(2).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]][(int)idx[1]][(int)idx[2]]) + ); + } + + /** + * Copy a {@link NdArray} to a 5-dimensional array of booleans + * + * @param src source rank-5 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-5 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(BooleanNdArray src, boolean[][][][][] dst) { + if (src.rank() != 5) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(3).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]][(int)idx[1]][(int)idx[2]][(int)idx[3]]) + ); + } + + /** + * Copy a {@link NdArray} to a 6-dimensional array of booleans + * + * @param src source rank-6 array + * @param dst destination array + * @throws IllegalArgumentException if {@code src} is not of rank-6 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(BooleanNdArray src, boolean[][][][][][] dst) { + if (src.rank() != 6) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(4).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]][(int)idx[1]][(int)idx[2]][(int)idx[3]][(int)idx[4]]) + ); + } + + /** + * Copy a {@link NdArray} to an array of objects + * + * @param src source rank-1 array + * @param dst destination array + * @param data type + * @throws IllegalArgumentException if {@code src} is not of rank-1 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(NdArray src, T[] dst) { + if (src.rank() != 1) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + if (src.size() > dst.length) { + throw new ArrayIndexOutOfBoundsException(String.valueOf(src.size()) + " > " + dst.length); + } + src.read(DataBuffers.of(dst, false, false)); + } + + /** + * Copy a {@link NdArray} to a 2-dimensional array of objects + * + * @param src source rank-2 array + * @param dst destination array + * @param data type + * @throws IllegalArgumentException if {@code src} is not of rank-2 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(NdArray src, T[][] dst) { + if (src.rank() != 2) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(0).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]]) + ); + } + + /** + * Copy a {@link NdArray} to a 3-dimensional array of objects + * + * @param src source rank-3 array + * @param dst destination array + * @param data type + * @throws IllegalArgumentException if {@code src} is not of rank-3 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(NdArray src, T[][][] dst) { + if (src.rank() != 3) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(1).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]][(int)idx[1]]) + ); + } + + /** + * Copy a {@link NdArray} to a 4-dimensional array of objects + * + * @param src source rank-4 array + * @param dst destination array + * @param data type + * @throws IllegalArgumentException if {@code src} is not of rank-4 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(NdArray src, T[][][][] dst) { + if (src.rank() != 4) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(2).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]][(int)idx[1]][(int)idx[2]]) + ); + } + + /** + * Copy a {@link NdArray} to a 5-dimensional array of objects + * + * @param src source rank-5 array + * @param dst destination array + * @param data type + * @throws IllegalArgumentException if {@code src} is not of rank-5 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(NdArray src, T[][][][][] dst) { + if (src.rank() != 5) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(3).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]][(int)idx[1]][(int)idx[2]][(int)idx[3]]) + ); + } + + /** + * Copy a {@link NdArray} to a 6-dimensional array of objects + * + * @param src source rank-6 array + * @param dst destination array + * @param data type + * @throws IllegalArgumentException if {@code src} is not of rank-6 + * @throws ArrayIndexOutOfBoundsException if not all elements of {@code src} can fit it the destination array + */ + public static void copyFrom(NdArray src, T[][][][][][] dst) { + if (src.rank() != 6) { + throw new IllegalArgumentException("Array cannot be copied from NdArray of rank " + src.rank()); + } + src.elements(4).forEachIndexed((idx, e) -> + copyFrom(e, dst[(int)idx[0]][(int)idx[1]][(int)idx[2]][(int)idx[3]][(int)idx[4]]) + ); + } + + /** + * Compute the shape of an int array. + * + * @param array 1D array + * @return shape of the array + */ + public static Shape shapeOf(int[] array) { + return Shape.of(array.length); + } + + /** + * Compute the shape of a 2-dimensional int array. + * + * @param array 2D array + * @return shape of the array + */ + public static Shape shapeOf(int[][] array) { + return Shape.of(computeShape(array, new long[2])); + } + + /** + * Compute the shape of a 3-dimensional int array. + * + * @param array 3D array + * @return shape of the array + */ + public static Shape shapeOf(int[][][] array) { + return Shape.of(computeShape(array, new long[3])); + } + + /** + * Compute the shape of a 4-dimensional int array. + * + * @param array 4D array + * @return shape of the array + */ + public static Shape shapeOf(int[][][][] array) { + return Shape.of(computeShape(array, new long[4])); + } + + /** + * Compute the shape of a 5-dimensional int array. + * + * @param array 5D array + * @return shape of the array + */ + public static Shape shapeOf(int[][][][][] array) { + return Shape.of(computeShape(array, new long[5])); + } + + /** + * Compute the shape of a 6-dimensional int array. + * + * @param array 6D array + * @return shape of the array + */ + public static Shape shapeOf(int[][][][][][] array) { + return Shape.of(computeShape(array, new long[6])); + } + + /** + * Compute the shape of a long array. + * + * @param array 1D array + * @return shape of the array + */ + public static Shape shapeOf(long[] array) { + return Shape.of(array.length); + } + + /** + * Compute the shape of a 2-dimensional long array. + * + * @param array 2D array + * @return shape of the array + */ + public static Shape shapeOf(long[][] array) { + return Shape.of(computeShape(array, new long[2])); + } + + /** + * Compute the shape of a 3-dimensional long array. + * + * @param array 3D array + * @return shape of the array + */ + public static Shape shapeOf(long[][][] array) { + return Shape.of(computeShape(array, new long[3])); + } + + /** + * Compute the shape of a 4-dimensional long array. + * + * @param array 4D array + * @return shape of the array + */ + public static Shape shapeOf(long[][][][] array) { + return Shape.of(computeShape(array, new long[4])); + } + + /** + * Compute the shape of a 5-dimensional long array. + * + * @param array 5D array + * @return shape of the array + */ + public static Shape shapeOf(long[][][][][] array) { + return Shape.of(computeShape(array, new long[5])); + } + + /** + * Compute the shape of a 6-dimensional long array. + * + * @param array 6D array + * @return shape of the array + */ + public static Shape shapeOf(long[][][][][][] array) { + return Shape.of(computeShape(array, new long[6])); + } + + /** + * Compute the shape of a float array. + * + * @param array 1D array + * @return shape of the array + */ + public static Shape shapeOf(float[] array) { + return Shape.of(array.length); + } + + /** + * Compute the shape of a 2-dimensional float array. + * + * @param array 2D array + * @return shape of the array + */ + public static Shape shapeOf(float[][] array) { + return Shape.of(computeShape(array, new long[2])); + } + + /** + * Compute the shape of a 3-dimensional float array. + * + * @param array 3D array + * @return shape of the array + */ + public static Shape shapeOf(float[][][] array) { + return Shape.of(computeShape(array, new long[3])); + } + + /** + * Compute the shape of a 4-dimensional float array. + * + * @param array 4D array + * @return shape of the array + */ + public static Shape shapeOf(float[][][][] array) { + return Shape.of(computeShape(array, new long[4])); + } + + /** + * Compute the shape of a 5-dimensional float array. + * + * @param array 5D array + * @return shape of the array + */ + public static Shape shapeOf(float[][][][][] array) { + return Shape.of(computeShape(array, new long[5])); + } + + /** + * Compute the shape of a 6-dimensional float array. + * + * @param array 6D array + * @return shape of the array + */ + public static Shape shapeOf(float[][][][][][] array) { + return Shape.of(computeShape(array, new long[6])); + } + + /** + * Compute the shape of a double array. + * + * @param array 1D array + * @return shape of the array + */ + public static Shape shapeOf(double[] array) { + return Shape.of(array.length); + } + + /** + * Compute the shape of a 2-dimensional double array. + * + * @param array 2D array + * @return shape of the array + */ + public static Shape shapeOf(double[][] array) { + return Shape.of(computeShape(array, new long[2])); + } + + /** + * Compute the shape of a 3-dimensional double array. + * + * @param array 3D array + * @return shape of the array + */ + public static Shape shapeOf(double[][][] array) { + return Shape.of(computeShape(array, new long[3])); + } + + /** + * Compute the shape of a 4-dimensional double array. + * + * @param array 4D array + * @return shape of the array + */ + public static Shape shapeOf(double[][][][] array) { + return Shape.of(computeShape(array, new long[4])); + } + + /** + * Compute the shape of a 5-dimensional double array. + * + * @param array 5D array + * @return shape of the array + */ + public static Shape shapeOf(double[][][][][] array) { + return Shape.of(computeShape(array, new long[5])); + } + + /** + * Compute the shape of a 6-dimensional double array. + * + * @param array 6D array + * @return shape of the array + */ + public static Shape shapeOf(double[][][][][][] array) { + return Shape.of(computeShape(array, new long[6])); + } + + /** + * Compute the shape of a byte array. + * + * @param array 1D array + * @return shape of the array + */ + public static Shape shapeOf(byte[] array) { + return Shape.of(array.length); + } + + /** + * Compute the shape of a 2-dimensional byte array. + * + * @param array 2D array + * @return shape of the array + */ + public static Shape shapeOf(byte[][] array) { + return Shape.of(computeShape(array, new long[2])); + } + + /** + * Compute the shape of a 3-dimensional byte array. + * + * @param array 3D array + * @return shape of the array + */ + public static Shape shapeOf(byte[][][] array) { + return Shape.of(computeShape(array, new long[3])); + } + + /** + * Compute the shape of a 4-dimensional byte array. + * + * @param array 4D array + * @return shape of the array + */ + public static Shape shapeOf(byte[][][][] array) { + return Shape.of(computeShape(array, new long[4])); + } + + /** + * Compute the shape of a 5-dimensional byte array. + * + * @param array 5D array + * @return shape of the array + */ + public static Shape shapeOf(byte[][][][][] array) { + return Shape.of(computeShape(array, new long[5])); + } + + /** + * Compute the shape of a 6-dimensional byte array. + * + * @param array 6D array + * @return shape of the array + */ + public static Shape shapeOf(byte[][][][][][] array) { + return Shape.of(computeShape(array, new long[6])); + } + + /** + * Compute the shape of a short array. + * + * @param array 1D array + * @return shape of the array + */ + public static Shape shapeOf(short[] array) { + return Shape.of(array.length); + } + + /** + * Compute the shape of a 2-dimensional short array. + * + * @param array 2D array + * @return shape of the array + */ + public static Shape shapeOf(short[][] array) { + return Shape.of(computeShape(array, new long[2])); + } + + /** + * Compute the shape of a 3-dimensional short array. + * + * @param array 3D array + * @return shape of the array + */ + public static Shape shapeOf(short[][][] array) { + return Shape.of(computeShape(array, new long[3])); + } + + /** + * Compute the shape of a 4-dimensional short array. + * + * @param array 4D array + * @return shape of the array + */ + public static Shape shapeOf(short[][][][] array) { + return Shape.of(computeShape(array, new long[4])); + } + + /** + * Compute the shape of a 5-dimensional short array. + * + * @param array 5D array + * @return shape of the array + */ + public static Shape shapeOf(short[][][][][] array) { + return Shape.of(computeShape(array, new long[5])); + } + + /** + * Compute the shape of a 6-dimensional short array. + * + * @param array 6D array + * @return shape of the array + */ + public static Shape shapeOf(short[][][][][][] array) { + return Shape.of(computeShape(array, new long[6])); + } + + /** + * Compute the shape of a boolean array. + * + * @param array 1D array + * @return shape of the array + */ + public static Shape shapeOf(boolean[] array) { + return Shape.of(array.length); + } + + /** + * Compute the shape of a 2-dimensional boolean array. + * + * @param array 2D array + * @return shape of the array + */ + public static Shape shapeOf(boolean[][] array) { + return Shape.of(computeShape(array, new long[2])); + } + + /** + * Compute the shape of a 3-dimensional boolean array. + * + * @param array 3D array + * @return shape of the array + */ + public static Shape shapeOf(boolean[][][] array) { + return Shape.of(computeShape(array, new long[3])); + } + + /** + * Compute the shape of a 4-dimensional boolean array. + * + * @param array 4D array + * @return shape of the array + */ + public static Shape shapeOf(boolean[][][][] array) { + return Shape.of(computeShape(array, new long[4])); + } + + /** + * Compute the shape of a 5-dimensional boolean array. + * + * @param array 5D array + * @return shape of the array + */ + public static Shape shapeOf(boolean[][][][][] array) { + return Shape.of(computeShape(array, new long[5])); + } + + /** + * Compute the shape of a 6-dimensional boolean array. + * + * @param array 6D array + * @return shape of the array + */ + public static Shape shapeOf(boolean[][][][][][] array) { + return Shape.of(computeShape(array, new long[6])); + } + + /** + * Compute the shape of an object array. + * + * @param array 1D array + * @param data type + * @return shape of the array + */ + public static Shape shapeOf(T[] array) { + return Shape.of(array.length); + } + + /** + * Compute the shape of a 2-dimensional object array. + * + * @param array 2D array + * @param data type + * @return shape of the array + */ + public static Shape shapeOf(T[][] array) { + return Shape.of(computeShape(array, new long[2])); + } + + /** + * Compute the shape of a 3-dimensional object array. + * + * @param array 3D array + * @param data type + * @return shape of the array + */ + public static Shape shapeOf(T[][][] array) { + return Shape.of(computeShape(array, new long[3])); + } + + /** + * Compute the shape of a 4-dimensional object array. + * + * @param array 4D array + * @param data type + * @return shape of the array + */ + public static Shape shapeOf(T[][][][] array) { + return Shape.of(computeShape(array, new long[4])); + } + + /** + * Compute the shape of a 5-dimensional object array. + * + * @param array 5D array + * @param data type + * @return shape of the array + */ + public static Shape shapeOf(T[][][][][] array) { + return Shape.of(computeShape(array, new long[5])); + } + + /** + * Compute the shape of a 6-dimensional object array. + * + * @param array 6D array + * @param data type + * @return shape of the array + */ + public static Shape shapeOf(T[][][][][][] array) { + return Shape.of(computeShape(array, new long[6])); + } + + private static void dimSize(int arrayLength, long[] shape, int dimIdx) { + if (shape[dimIdx] == 0) { + shape[dimIdx] = arrayLength; + } else if (shape[dimIdx] != arrayLength) { + shape[dimIdx] = Shape.UNKNOWN_SIZE; + } + } + + private static long[] computeShape(int[][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 2); + for (int i = 0; i < array.length; ++i) { + if (array[i] == null) { + throw new IllegalStateException("One of the subarray is null"); + } + dimSize(array[i].length, shape, shape.length - 1); + } + return shape; + } + + private static long[] computeShape(int[][][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 3); + for (int i = 0; i < array.length; ++i) { + computeShape(array[i], shape); + } + return shape; + } + + private static long[] computeShape(int[][][][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 4); + for (int i = 0; i < array.length; ++i) { + computeShape(array[i], shape); + } + return shape; + } + + private static long[] computeShape(int[][][][][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 5); + for (int i = 0; i < array.length; ++i) { + computeShape(array[i], shape); + } + return shape; + } + + private static long[] computeShape(int[][][][][][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 6); + for (int i = 0; i < array.length; ++i) { + computeShape(array[i], shape); + } + return shape; + } + + private static long[] computeShape(long[][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 2); + for (int i = 0; i < array.length; ++i) { + if (array[i] == null) { + throw new IllegalStateException("One of the subarray is null"); + } + dimSize(array[i].length, shape, shape.length - 1); + } + return shape; + } + + private static long[] computeShape(long[][][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 3); + for (int i = 0; i < array.length; ++i) { + computeShape(array[i], shape); + } + return shape; + } + + private static long[] computeShape(long[][][][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 4); + for (int i = 0; i < array.length; ++i) { + computeShape(array[i], shape); + } + return shape; + } + + private static long[] computeShape(long[][][][][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 5); + for (int i = 0; i < array.length; ++i) { + computeShape(array[i], shape); + } + return shape; + } + + private static long[] computeShape(long[][][][][][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 6); + for (int i = 0; i < array.length; ++i) { + computeShape(array[i], shape); + } + return shape; + } + + private static long[] computeShape(float[][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 2); + for (int i = 0; i < array.length; ++i) { + if (array[i] == null) { + throw new IllegalStateException("One of the subarray is null"); + } + dimSize(array[i].length, shape, shape.length - 1); + } + return shape; + } + + private static long[] computeShape(float[][][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 3); + for (int i = 0; i < array.length; ++i) { + computeShape(array[i], shape); + } + return shape; + } + + private static long[] computeShape(float[][][][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 4); + for (int i = 0; i < array.length; ++i) { + computeShape(array[i], shape); + } + return shape; + } + + private static long[] computeShape(float[][][][][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 5); + for (int i = 0; i < array.length; ++i) { + computeShape(array[i], shape); + } + return shape; + } + + private static long[] computeShape(float[][][][][][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 6); + for (int i = 0; i < array.length; ++i) { + computeShape(array[i], shape); + } + return shape; + } + + private static long[] computeShape(double[][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 2); + for (int i = 0; i < array.length; ++i) { + if (array[i] == null) { + throw new IllegalStateException("One of the subarray is null"); + } + dimSize(array[i].length, shape, shape.length - 1); + } + return shape; + } + + private static long[] computeShape(double[][][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 3); + for (int i = 0; i < array.length; ++i) { + computeShape(array[i], shape); + } + return shape; + } + + private static long[] computeShape(double[][][][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 4); + for (int i = 0; i < array.length; ++i) { + computeShape(array[i], shape); + } + return shape; + } + + private static long[] computeShape(double[][][][][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 5); + for (int i = 0; i < array.length; ++i) { + computeShape(array[i], shape); + } + return shape; + } + + private static long[] computeShape(double[][][][][][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 6); + for (int i = 0; i < array.length; ++i) { + computeShape(array[i], shape); + } + return shape; + } + + private static long[] computeShape(byte[][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 2); + for (int i = 0; i < array.length; ++i) { + if (array[i] == null) { + throw new IllegalStateException("One of the subarray is null"); + } + dimSize(array[i].length, shape, shape.length - 1); + } + return shape; + } + + private static long[] computeShape(byte[][][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 3); + for (int i = 0; i < array.length; ++i) { + computeShape(array[i], shape); + } + return shape; + } + + private static long[] computeShape(byte[][][][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 4); + for (int i = 0; i < array.length; ++i) { + computeShape(array[i], shape); + } + return shape; + } + + private static long[] computeShape(byte[][][][][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 5); + for (int i = 0; i < array.length; ++i) { + computeShape(array[i], shape); + } + return shape; + } + + private static long[] computeShape(byte[][][][][][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 6); + for (int i = 0; i < array.length; ++i) { + computeShape(array[i], shape); + } + return shape; + } + + private static long[] computeShape(short[][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 2); + for (int i = 0; i < array.length; ++i) { + if (array[i] == null) { + throw new IllegalStateException("One of the subarray is null"); + } + dimSize(array[i].length, shape, shape.length - 1); + } + return shape; + } + + private static long[] computeShape(short[][][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 3); + for (int i = 0; i < array.length; ++i) { + computeShape(array[i], shape); + } + return shape; + } + + private static long[] computeShape(short[][][][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 4); + for (int i = 0; i < array.length; ++i) { + computeShape(array[i], shape); + } + return shape; + } + + private static long[] computeShape(short[][][][][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 5); + for (int i = 0; i < array.length; ++i) { + computeShape(array[i], shape); + } + return shape; + } + + private static long[] computeShape(short[][][][][][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 6); + for (int i = 0; i < array.length; ++i) { + computeShape(array[i], shape); + } + return shape; + } + + private static long[] computeShape(boolean[][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 2); + for (int i = 0; i < array.length; ++i) { + if (array[i] == null) { + throw new IllegalStateException("One of the subarray is null"); + } + dimSize(array[i].length, shape, shape.length - 1); + } + return shape; + } + + private static long[] computeShape(boolean[][][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 3); + for (int i = 0; i < array.length; ++i) { + computeShape(array[i], shape); + } + return shape; + } + + private static long[] computeShape(boolean[][][][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 4); + for (int i = 0; i < array.length; ++i) { + computeShape(array[i], shape); + } + return shape; + } + + private static long[] computeShape(boolean[][][][][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 5); + for (int i = 0; i < array.length; ++i) { + computeShape(array[i], shape); + } + return shape; + } + + private static long[] computeShape(boolean[][][][][][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 6); + for (int i = 0; i < array.length; ++i) { + computeShape(array[i], shape); + } + return shape; + } + + private static long[] computeShape(T[][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 2); + for (int i = 0; i < array.length; ++i) { + if (array[i] == null) { + throw new IllegalStateException("One of the subarray is null"); + } + dimSize(array[i].length, shape, shape.length - 1); + } + return shape; + } + + private static long[] computeShape(T[][][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 3); + for (int i = 0; i < array.length; ++i) { + computeShape(array[i], shape); + } + return shape; + } + + private static long[] computeShape(T[][][][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 4); + for (int i = 0; i < array.length; ++i) { + computeShape(array[i], shape); + } + return shape; + } + + private static long[] computeShape(T[][][][][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 5); + for (int i = 0; i < array.length; ++i) { + computeShape(array[i], shape); + } + return shape; + } + + private static long[] computeShape(T[][][][][][] array, long[] shape) { + if (array == null) { + throw new IllegalStateException("The array or one of its subarray is null"); + } + dimSize(array.length, shape, shape.length - 6); + for (int i = 0; i < array.length; ++i) { + computeShape(array[i], shape); + } + return shape; + } + + private static Class componentTypeOf(Object array) { + Class componentType = array.getClass().getComponentType(); + while (componentType.isArray()) { + componentType = componentType.getComponentType(); + } + return (Class)componentType; + } + + private static int[] computeArrayDims(NdArray ndArray, int expectedRank) { + Shape shape = ndArray.shape(); + if (shape.numDimensions() != expectedRank) { + throw new IllegalArgumentException("NdArray must be of rank " + expectedRank); + } + int[] arrayShape = new int[expectedRank]; + for (int i = 0; i < expectedRank; ++i) { + long dimSize = shape.size(i); + if (dimSize > Integer.MAX_VALUE) { + throw new IllegalArgumentException("Dimension " + i + " is too large to fit in a standard array (" + shape.size(i) + ")"); + } + arrayShape[i] = (int)dimSize; + } + return arrayShape; + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/buffer/BooleanDataBuffer.java b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/BooleanDataBuffer.java new file mode 100644 index 00000000000..73a570d4fe8 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/BooleanDataBuffer.java @@ -0,0 +1,165 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.buffer; + +import java.nio.BufferOverflowException; +import java.nio.BufferUnderflowException; +import java.nio.ReadOnlyBufferException; + +/** + * A {@link DataBuffer} of booleans. + */ +public interface BooleanDataBuffer extends DataBuffer { + + /** + * Reads the boolean at the given index. + * + * @param index the index from which the float will be read + * @return the boolean at the given index + * @throws IndexOutOfBoundsException if index is negative or not smaller than the buffer size + */ + boolean getBoolean(long index); + + /** + * Writes the given boolean into this buffer at the given index. + * + * @param value the boolean to be written + * @param index the index at which the value will be written + * @return this buffer + * @throws IndexOutOfBoundsException if index is negative or not smaller than the buffer size + * @throws ReadOnlyBufferException if this buffer is read-only + */ + BooleanDataBuffer setBoolean(boolean value, long index); + + /** + * Bulk get method, using boolean arrays. + *

+ * This method transfers values from this buffer into the given destination array. If there are + * fewer values in the buffer than are required to satisfy the request, that is, if + * {@code dst.length > size()}, then no values are transferred and a + * BufferUnderflowException is thrown. + *

+ * Otherwise, this method copies {@code n = dst.length} values from this buffer into the given + * array. + * + * @param dst the array into which values are to be written + * @return this buffer + * @throws BufferUnderflowException if there are not enough values to copy from this buffer + */ + default BooleanDataBuffer read(boolean[] dst) { + return read(dst, 0, dst.length); + } + + /** + * Bulk get method, using boolean arrays. + *

+ * This method transfers values from this buffer into the given destination array. If there are + * fewer values in the buffer than are required to satisfy the request, that is, if + * {@code length > size()}, then no values are transferred and a + * BufferUnderflowException is thrown. + *

+ * Otherwise, this method copies {@code n = length} values from this buffer into the given array + * starting at the given offset. + * + * @param dst the array into which values are to be written + * @param offset the offset within the array of the first value to be written; must be + * non-negative and no larger than {@code dst.length} + * @param length the maximum number of values to be written to the given array; must be + * non-negative and no larger than {@code dst.length - offset} + * @return this buffer + * @throws BufferUnderflowException if there are fewer than length values remaining in this buffer + * @throws IndexOutOfBoundsException if the preconditions on the offset and length parameters do + * not hold + */ + BooleanDataBuffer read(boolean[] dst, int offset, int length); + + /** + * Bulk put method, using boolean arrays. + *

+ * This method transfers the values in the given source array into this buffer. If there are + * more values in the source array than in this buffer, that is, if + * {@code src.length > size()}, then no values are transferred and a + * BufferOverflowException is thrown. + *

+ * Otherwise, this method copies {@code n = src.length} values from the given array. + * + * @param src the source array from which values are to be read + * @return this buffer + * @throws BufferOverflowException if there is insufficient space in this buffer for the values in + * the source array + * @throws ReadOnlyBufferException if this buffer is read-only + */ + default BooleanDataBuffer write(boolean[] src) { + return write(src, 0, src.length); + } + + /** + * Bulk put method, using boolean arrays. + *

+ * This method transfers the values in the given source array into this buffer. If there are + * more values in the source array than in this buffer, that is, if + * {@code length > size()}, then no values are transferred and a + * BufferOverflowException is thrown. + *

+ * Otherwise, this method copies {@code n = length} values from the given array into this buffer, + * starting at the given offset. + * + * @param src the source array from which values are to be read + * @param offset the offset within the array of the first value to be read; must be non-negative + * and no larger than {@code src.length} + * @param length the number of values to be read from the given array; must be non-negative and no + * larger than {@code src.length - offset} + * @return this buffer + * @throws BufferOverflowException if there is insufficient space in this buffer for the values in + * the source array + * @throws IndexOutOfBoundsException if the preconditions on the offset and length parameters do + * not hold + * @throws ReadOnlyBufferException if this buffer is read-only + */ + BooleanDataBuffer write(boolean[] src, int offset, int length); + + @Override + default Boolean getObject(long index) { + return getBoolean(index); + } + + @Override + default BooleanDataBuffer setObject(Boolean value, long index) { + return setBoolean(value, index); + } + + @Override + BooleanDataBuffer copyTo(DataBuffer dst, long size); + + @Override + default BooleanDataBuffer offset(long index) { + return slice(index, size() - index); + } + + @Override + default BooleanDataBuffer narrow(long size) { + return slice(0, size); + } + + @Override + BooleanDataBuffer slice(long index, long size); + + @Override + default DataBufferWindow window(long size) { + throw new UnsupportedOperationException(); + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/buffer/ByteDataBuffer.java b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/ByteDataBuffer.java new file mode 100644 index 00000000000..b1cce441b13 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/ByteDataBuffer.java @@ -0,0 +1,232 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.buffer; + +import java.nio.BufferOverflowException; +import java.nio.BufferUnderflowException; +import java.nio.ReadOnlyBufferException; + +/** + * A {@link DataBuffer} of bytes. + */ +public interface ByteDataBuffer extends DataBuffer { + + /** + * Reads the byte at the given index. + * + * @param index the index from which the float will be read + * @return the byte at the given index + * @throws IndexOutOfBoundsException if index is negative or not smaller than the buffer size + */ + byte getByte(long index); + + /** + * Writes the given byte into this buffer at the given index. + * + * @param value the byte to be written + * @param index the index at which the value will be written + * @return this buffer + * @throws IndexOutOfBoundsException if index is negative or not smaller than the buffer size + * @throws ReadOnlyBufferException if this buffer is read-only + */ + ByteDataBuffer setByte(byte value, long index); + + /** + * Bulk get method, using byte arrays. + *

+ * This method transfers values from this buffer into the given destination array. If there are + * fewer values in the buffer than are required to satisfy the request, that is, if + * {@code dst.length > size()}, then no values are transferred and a + * BufferUnderflowException is thrown. + *

+ * Otherwise, this method copies {@code n = dst.length} values from this buffer into the given + * array. + * + * @param dst the array into which values are to be written + * @return this buffer + * @throws BufferUnderflowException if there are not enough values to copy from this buffer + */ + default ByteDataBuffer read(byte[] dst) { + return read(dst, 0, dst.length); + } + + /** + * Bulk get method, using byte arrays. + *

+ * This method transfers values from this buffer into the given destination array. If there are + * fewer values in the buffer than are required to satisfy the request, that is, if + * {@code length > size()}, then no values are transferred and a + * BufferUnderflowException is thrown. + *

+ * Otherwise, this method copies {@code n = length} values from this buffer into the given array + * starting at the given offset. + * + * @param dst the array into which values are to be written + * @param offset the offset within the array of the first value to be written; must be + * non-negative and no larger than {@code dst.length} + * @param length the maximum number of values to be written to the given array; must be + * non-negative and no larger than {@code dst.length - offset} + * @return this buffer + * @throws BufferUnderflowException if there are fewer than length values remaining in this buffer + * @throws IndexOutOfBoundsException if the preconditions on the offset and length parameters do + * not hold + */ + ByteDataBuffer read(byte[] dst, int offset, int length); + + /** + * Bulk put method, using byte arrays. + *

+ * This method transfers the values in the given source array into this buffer. If there are + * more values in the source array than in this buffer, that is, if + * {@code src.length > size()}, then no values are transferred and a + * BufferOverflowException is thrown. + *

+ * Otherwise, this method copies {@code n = src.length} values from the given array. + * + * @param src the source array from which values are to be read + * @return this buffer + * @throws BufferOverflowException if there is insufficient space in this buffer for the values in + * the source array + * @throws ReadOnlyBufferException if this buffer is read-only + */ + default ByteDataBuffer write(byte[] src) { + return write(src, 0, src.length); + } + + /** + * Bulk put method, using byte arrays. + *

+ * This method transfers the values in the given source array into this buffer. If there are + * more values in the source array than in this buffer, that is, if + * {@code length > size()}, then no values are transferred and a + * BufferOverflowException is thrown. + *

+ * Otherwise, this method copies {@code n = length} values from the given array into this buffer, + * starting at the given offset. + * + * @param src the source array from which values are to be read + * @param offset the offset within the array of the first value to be read; must be non-negative + * and no larger than {@code src.length} + * @param length the number of values to be read from the given array; must be non-negative and no + * larger than {@code src.length - offset} + * @return this buffer + * @throws BufferOverflowException if there is insufficient space in this buffer for the values in + * the source array + * @throws IndexOutOfBoundsException if the preconditions on the offset and length parameters do + * not hold + * @throws ReadOnlyBufferException if this buffer is read-only + */ + ByteDataBuffer write(byte[] src, int offset, int length); + + /** + * Return this byte buffer as a buffer of ints. + * + *

The returned buffer provides a different view on the same memory as the original byte buffer, + * meaning that changing a value in one will affect the other. + * + * @return this buffer as a {@link IntDataBuffer} + * @throws IllegalStateException if this buffer cannot be converted + */ + IntDataBuffer asInts(); + + /** + * Return this byte buffer as a buffer of shorts. + * + *

The returned buffer provides a different view on the same memory as the original byte buffer, + * meaning that changing a value in one will affect the other. + * + * @return this buffer as a {@link ShortDataBuffer} + * @throws IllegalStateException if this buffer cannot be converted + */ + ShortDataBuffer asShorts(); + + /** + * Return this byte buffer as a buffer of longs. + * + *

The returned buffer provides a different view on the same memory as the original byte buffer, + * meaning that changing a value in one will affect the other. + * + * @return this buffer as a {@link LongDataBuffer} + * @throws IllegalStateException if this buffer cannot be converted + */ + LongDataBuffer asLongs(); + + /** + * Return this byte buffer as a buffer of floats. + * + *

The returned buffer provides a different view on the same memory as the original byte buffer, + * meaning that changing a value in one will affect the other. + * + * @return this buffer as a {@link FloatDataBuffer} + * @throws IllegalStateException if this buffer cannot be converted + */ + FloatDataBuffer asFloats(); + + /** + * Return this byte buffer as a buffer of doubles. + * + *

The returned buffer provides a different view on the same memory as the original byte buffer, + * meaning that changing a value in one will affect the other. + * + * @return this buffer as a {@link DoubleDataBuffer} + * @throws IllegalStateException if this buffer cannot be converted + */ + DoubleDataBuffer asDoubles(); + + /** + * Return this byte buffer as a buffer of booleans. + * + *

The returned buffer provides a different view on the same memory as the original byte buffer, + * meaning that changing a value in one will affect the other. + * + * @return this buffer as a {@link BooleanDataBuffer} + * @throws IllegalStateException if this buffer cannot be converted + */ + BooleanDataBuffer asBooleans(); + + @Override + default Byte getObject(long index) { + return getByte(index); + } + + @Override + default ByteDataBuffer setObject(Byte value, long index) { + return setByte(value, index); + } + + @Override + ByteDataBuffer copyTo(DataBuffer dst, long size); + + + @Override + default ByteDataBuffer offset(long index) { + return slice(index, size() - index); + } + + @Override + default ByteDataBuffer narrow(long size) { + return slice(0, size); + } + + @Override + ByteDataBuffer slice(long index, long size); + + @Override + default DataBufferWindow window(long size) { + throw new UnsupportedOperationException(); + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/buffer/DataBuffer.java b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/DataBuffer.java new file mode 100644 index 00000000000..e62ba87ce6e --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/DataBuffer.java @@ -0,0 +1,324 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ + +package org.tensorflow.ndarray.buffer; + +import java.nio.BufferOverflowException; +import java.nio.BufferUnderflowException; +import java.nio.ReadOnlyBufferException; + +/** + * A container of data of a specific type. + * + *

Instances of {@code DataBuffer} map native or heap memory segments to a linear view that + * supports: + *

    + *
  • 64-bits indexing, allowing to work with buffer larger than 231 bytes
  • + *
  • Storage of object of any types and not only primitives
  • + *
  • Generic types allows to work directly with boxed types as well, which does not require + * explicit buffer types as with the standard JDK buffers. + *
+ * It is important to note that there is no guarantee the memory managed by a {@code DataBuffer} + * is linear, specially when dealing with non-primitive types or large buffers. + * + * @param type of data stored in this buffer + */ +public interface DataBuffer { + + /** + * Size of the buffer, in elements. + *

+ * For exemple, in case of a byte buffer, this value is equal to the number of bytes this buffer + * can hold. For an integer buffer, it is equal to the number of integers, therefore the size + * in bytes of this buffer is {@code size() * Integer.BYTES}. + * + * @return the buffer size + */ + long size(); + + /** + * Tells whether or not this buffer is backed by an accessible array. + * + * @return true if, and only if, this buffer is read-only + */ + boolean isReadOnly(); + + /** + * Reads the value at the given index. + * + * Important: Usage of this method should be limited to buffers of non-primitive types or + * when the data type is not deterministically known by the caller. In any other case, prefer + * the usage of its primitive variant which will significantly improve performances + * (e.g. {@code IntDataBuffer.getInt(idx)} + * + * @param index the index from which the float will be read + * @return the value at the given index + * @throws IndexOutOfBoundsException if index is negative or not smaller than the buffer size + */ + T getObject(long index); + + /** + * Writes the given value into this buffer at the given index. + * + * Important: Usage of this method should be limited to buffers of non-primitive types or + * when the data type is not deterministically known by the caller. In any other case, prefer + * the usage of its primitive variant which will significantly improve performances + * (e.g. {@code IntDataBuffer.setInt(idx)} + * + * @param value the value to be written + * @param index the index at which the value will be written + * @return this buffer + * @throws IndexOutOfBoundsException if index is negative or not smaller than the buffer size + * @throws ReadOnlyBufferException if this buffer is read-only + */ + DataBuffer setObject(T value, long index); + + /** + * Read the references of the objects in this buffer into the destination array. + *

+ * This method transfers values from this buffer into the given destination array. If there are + * fewer values in the buffer than are required to satisfy the request, that is, if + * {@code dst.length > size()}, then no values are transferred and a + * BufferUnderflowException is thrown. + *

+ * Otherwise, this method copies {@code n = dst.length} values from this buffer into the given + * array. + * + * @param dst the array into which values are to be written + * @return this buffer + * @throws BufferUnderflowException if there are not enough values to copy from this buffer + */ + default DataBuffer read(T[] dst) { + return read(dst, 0, dst.length); + } + + /** + * Read the references of the objects in this buffer into the destination array. + *

+ * This method transfers values from this buffer into the given destination array. If there are + * fewer values in the buffer than are required to satisfy the request, that is, if + * {@code length > size()}, then no values are transferred and a + * BufferUnderflowException is thrown. + *

+ * Otherwise, this method copies {@code n = length} values from this buffer into the given array + * starting at the given offset. + * + * @param dst the array into which values are to be written + * @param offset the offset within the array of the first value to be written; must be + * non-negative and no larger than {@code dst.length} + * @param length the maximum number of values to be written to the given array; must be + * non-negative and no larger than {@code dst.length - offset} + * @return this buffer + * @throws BufferUnderflowException if there are fewer than length values remaining in this buffer + * @throws IndexOutOfBoundsException if the preconditions on the offset and length parameters do + * not hold + */ + DataBuffer read(T[] dst, int offset, int length); + + /** + * Write the references of the objects in the source array into this buffer. + *

+ * This method transfers the values in the given source array into this buffer. If there are + * more values in the source array than in this buffer, that is, if + * {@code src.length > size()}, then no values are transferred and a + * BufferOverflowException is thrown. + *

+ * Otherwise, this method copies {@code n = src.length} values from the given array. + * + * @param src the source array from which values are to be read + * @return this buffer + * @throws BufferOverflowException if there is insufficient space in this buffer for the values in + * the source array + * @throws ReadOnlyBufferException if this buffer is read-only + */ + default DataBuffer write(T[] src) { + return write(src, 0, src.length); + } + + /** + * Bulk put method, using int arrays. + *

+ * This method transfers the values in the given source array into this buffer. If there are + * more values in the source array than in this buffer, that is, if + * {@code length > size()}, then no values are transferred and a + * BufferOverflowException is thrown. + *

+ * Otherwise, this method copies {@code n = length} values from the given array into this buffer, + * starting at the given offset. + * + * @param src the source array from which values are to be read + * @param offset the offset within the array of the first value to be read; must be non-negative + * and no larger than {@code src.length} + * @param length the number of values to be read from the given array; must be non-negative and no + * larger than {@code src.length - offset} + * @return this buffer + * @throws BufferOverflowException if there is insufficient space in this buffer for the values in + * the source array + * @throws IndexOutOfBoundsException if the preconditions on the offset and length parameters do + * not hold + * @throws ReadOnlyBufferException if this buffer is read-only + */ + DataBuffer write(T[] src, int offset, int length); + + /** + * Write the references of the objects in the source array into this buffer. + *

+ * If there are more values to copy than the destination buffer size, i.e. + * {@code size > dst.size()}, then no values are transferred and a + * BufferOverflowException is thrown. On the other hand, if there are more values to copy that + * the source buffer size, i.e. {@code > src.size()}, then a BufferUnderfloatException is thrown. + *

+ * Otherwise, this method copies {@code n = size} values from this buffer into + * the destination buffer. + * + * @param dst the destination buffer into which values are copied; must not be this buffer + * @param size number of values to copy to the destination buffer + * @return this buffer + * @throws IllegalArgumentException if the destination buffer is this buffer + * @throws ReadOnlyBufferException if the destination buffer is read-only + * @throws java.nio.BufferOverflowException if there is not enough space in destination buffer + * @throws java.nio.BufferUnderflowException if there are not enough values in the source buffer + */ + DataBuffer copyTo(DataBuffer dst, long size); + + /** + * Creates a new buffer whose content is a shared subsequence of this buffer's content, starting + * at the given index. + *

+ * The index must not be greater than this buffer size. Changes to this buffer's content will + * be visible in the new buffer and vice versa. The new buffer will be read-only if, and only if, + * this buffer is read-only. + *

+ * This call is equivalent to {@link #slice(long, long) slice(index, size() - index)} + * + * @param index index of the first value of the new buffer created, must not be greater than + * {@code size()} + * @return the new buffer + * @throws IllegalArgumentException if index do not pass validation checks + */ + default DataBuffer offset(long index) { + return slice(index, size() - index); + } + + /** + * Creates a new buffer whose content is a shared subsequence of this buffer's content, whose + * size is set to the given value. + *

+ * The new size must not be greater than this buffer size. Changes to this buffer's + * content will be visible in the new buffer and vice versa. The new buffer will be read-only if, + * and only if, this buffer is read-only. + *

+ * This call is equivalent to {@link #slice(long, long) slice(0, size)} + * + * @param size size of this new buffer + * @return the new buffer + * @throws IllegalArgumentException if index and/or size values do not pass validation checks + */ + default DataBuffer narrow(long size) { + return slice(0, size); + } + + /** + * Creates a new buffer whose content is a shared subsequence of this buffer's content, starting + * at the given index and of the given size. + *

+ * The index plus the new size must not be greater than this buffer size. Changes to this + * buffer's content will be visible in the new buffer and vice versa. The new buffer will be + * read-only if, and only if, this buffer is read-only. + * + * @param index index of the first value of the new buffer created + * @param size size of this new buffer, must not be greater than {@code size()} + * @return the new buffer + * @throws IllegalArgumentException if size value do not pass validation checks + */ + DataBuffer slice(long index, long size); + + /** + * Creates a {@link DataBufferWindow} that provides a partial view of this buffer. + * + *

The created window has a fixed size and can {@link DataBufferWindow#slide(long) "slide"} + * along this buffer to provide different views of the data without allocating a new buffer + * instance, like {@link #offset(long)} does. This improves overall performance when this + * operation is repeated frequently. For example: + * + *

{@code
+   * IntDataBuffer bufferA = DataBuffers.ofInts(1024);
+   * // ... init buffer data
+   * IntDataBuffer bufferB = DataBuffers.ofInts(1, 2, 3, 4);
+   *
+   * // Return the index of the first occurrence of bufferB in bufferA using a sliding window
+   * DataBufferWindow windowA = bufferA.window(4);
+   * for (int i = 0; i < bufferA.size() - bufferB.size(); ++i) {
+   *     if (windowA.slideTo(i).buffer().equals(bufferB)) {
+   *         return i;
+   *     }
+   * }
+   * }
+ * + *

The returned object is stateful and is not thread-safe. + * + * @param size size of the window + * @return a new window that starts at the index 0 of this buffer + * @throws UnsupportedOperationException if this type of buffer does not support buffer windows + */ + default DataBufferWindow> window(long size) { + throw new UnsupportedOperationException(); + } + + /** + * Visits the backing storage of this buffer. + * + *

The buffer implementation is responsible of passing back a reference to the actual data + * storage to the provided visitor. The visitor does not have to handle all possible types of + * data storage and can override only methods for storage it is actually interested in. For any + * other type of storage, this call will fallback to {@link DataStorageVisitor#fallback()} so the + * visitor can execute some generic routine if needed. + * + * @param visitor visits the data storage of this buffer + * @param type of value returned by the visitor + * @return the same value returned by the visitor + */ + default R accept(DataStorageVisitor visitor) { + return visitor.fallback(); + } + + /** + * Checks equality between data buffers. + * + *

A data buffer is equal to another object if this object is another {@link DataBuffer} of the + * same size, type and the elements are equal and in the same order. For example: + * + *

{@code
+   * IntDataBuffer buffer = DataBuffers.of(1, 2, 3);
+   *
+   * assertEquals(buffer, DataBuffers.of(1, 2, 3));  // true
+   * assertEquals(buffer, DataBuffers.ofObjects(1, 2, 3));  // true, as Integers are equal to ints
+   * assertNotEquals(buffer, DataBuffers.of(1, 2, 3, 0));  // false, different sizes
+   * assertNotEquals(buffer, DataBuffers.of(1, 3, 2));  // false, different order
+   * assertNotEquals(buffer, DataBuffers.of(1L, 2L, 3L));  // false, different types
+   * }
+ * + *

Note that the computation required to verify equality between two buffers can be expensive + * in some cases and therefore, it is recommended to not use this method in a critical path + * where performances matter. + * + * @param obj object to compare this buffer with + * @return true if this buffer is equal to the provided object + */ + @Override + boolean equals(Object obj); +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/buffer/DataBufferWindow.java b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/DataBufferWindow.java new file mode 100644 index 00000000000..85fc8c43d05 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/DataBufferWindow.java @@ -0,0 +1,93 @@ +package org.tensorflow.ndarray.buffer; + +/** + * A mutable container for viewing part of a {@link DataBuffer}. + * + *

Data buffer windows have a fixed size and can {@link DataBufferWindow#slide(long) "slide"} + * along a buffer to provide different views of the data without allocating a new buffer instance, + * like {@link DataBuffer#offset(long)} does. This improves overall performance when this operation + * is repeated frequently. For example: + * + *

{@code
+ * IntDataBuffer bufferA = DataBuffers.ofInts(1024);
+ * // ... init buffer data
+ * IntDataBuffer bufferB = DataBuffers.ofInts(1, 2, 3, 4);
+ *
+ * // Return the index of the first occurrence of bufferB in bufferA using a sliding window
+ * DataBufferWindow windowA = bufferA.window(4);
+ * for (int i = 0; i < bufferA.size() - bufferB.size(); ++i) {
+ *     if (windowA.slideTo(i).buffer().equals(bufferB)) {
+ *         return i;
+ *     }
+ * }
+ * }
+ * + *

{@code DataBufferWindow} instances are stateful and not thread-safe. + * + * @param the type of buffer being viewed + */ +public interface DataBufferWindow> { + + /** + * Returns the current offset of this window in the original buffer. + */ + long offset(); + + /** + * Returns the size of this buffer window. + */ + long size(); + + /** + * Moves the window at the given position in the original buffer. + * + *

The size of the window remains the same and its offset is set to {@code index}, so that + * accessing the value of {@link #buffer()} at index {@code x} will return the value at + * {@code index + x} in the original buffer. + * + * @param index new offset for this window + * @return this instance + * @throws IndexOutOfBoundsException if the window cannot be slid because it goes beyond + * the original buffer limits + */ + DataBufferWindow slideTo(long index); + + /** + * Moves the window of {@code step} elements in the original buffer. + * + *

The size of the window remains the same and its offset is set to {@code offset() + step}. + * If {@code step} is positive, then the window will slide forward. If it is negative, it will + * slide backward. + * + * @param step value to add to the current offset of this window + * @return this instance + * @throws IndexOutOfBoundsException if the window cannot be slid because it goes beyond + * the original buffer limits + */ + DataBufferWindow slide(long step); + + /** + * Returns the buffer backing this window. + * + *

Each window instance has it's own buffer providing a view onto the original + * {@link DataBuffer}. The buffers are mutated when the window slides to different offsets. + * For example: + * + *

{@code
+   * IntDataBuffer buffer = DataBuffers.of(0, 1, 2, 3);
+   * DataBufferWindow window = buffer.window(0, 2);
+   *
+   * IntDataBuffer windowBuffer = window.buffer();
+   * assertEquals(0, windowBuffer.getInt(0));
+   * assertEquals(1, windowBuffer.getInt(1));
+   *
+   * window.slideTo(2);
+   * assertEquals(2, windowBuffer.getInt(0));
+   * assertEquals(3, windowBuffer.getInt(1));
+   * assertSame(windowBuffer, window.buffer());
+   * }
+ * + * @return this window's buffer + */ + B buffer(); +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/buffer/DataBuffers.java b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/DataBuffers.java new file mode 100644 index 00000000000..a5feb2599d0 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/DataBuffers.java @@ -0,0 +1,457 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.buffer; + +import java.lang.reflect.Array; +import java.nio.ByteBuffer; +import java.nio.DoubleBuffer; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.nio.LongBuffer; +import java.nio.ShortBuffer; +import java.util.Arrays; +import java.util.BitSet; +import org.tensorflow.ndarray.impl.buffer.Validator; +import org.tensorflow.ndarray.impl.buffer.misc.MiscDataBufferFactory; +import org.tensorflow.ndarray.impl.buffer.nio.NioDataBufferFactory; +import org.tensorflow.ndarray.impl.buffer.raw.RawDataBufferFactory; + +/** + * Helper class for creating {@code DataBuffer} instances. + */ +public final class DataBuffers { + + /** + * Creates a buffer of bytes that can store up to {@code size} values + * + * @param size size of the buffer to allocate + * @return a new buffer + */ + public static ByteDataBuffer ofBytes(long size) { + Validator.createArgs(size, MAX_32BITS); + if (RawDataBufferFactory.canBeUsed()) { + return RawDataBufferFactory.create(new byte[(int)size], false); + } + return NioDataBufferFactory.create(ByteBuffer.allocate((int)size)); + } + + /** + * Creates a buffer of longs that can store up to {@code size} values + * + * @param size size of the buffer to allocate + * @return a new buffer + */ + public static LongDataBuffer ofLongs(long size) { + Validator.createArgs(size, MAX_32BITS); + if (RawDataBufferFactory.canBeUsed()) { + return RawDataBufferFactory.create(new long[(int)size], false); + } + return NioDataBufferFactory.create(LongBuffer.allocate((int)size)); + } + + /** + * Creates a buffer of integers that can store up to {@code size} values + * + * @param size size of the buffer to allocate + * @return a new buffer + */ + public static IntDataBuffer ofInts(long size) { + Validator.createArgs(size, MAX_32BITS); + if (RawDataBufferFactory.canBeUsed()) { + return RawDataBufferFactory.create(new int[(int)size], false); + } + return NioDataBufferFactory.create(IntBuffer.allocate((int)size)); + } + + /** + * Creates a buffer of shorts that can store up to {@code size} values + * + * @param size size of the buffer to allocate + * @return a new buffer + */ + public static ShortDataBuffer ofShorts(long size) { + Validator.createArgs(size, MAX_32BITS); + if (RawDataBufferFactory.canBeUsed()) { + return RawDataBufferFactory.create(new short[(int)size], false); + } + return NioDataBufferFactory.create(ShortBuffer.allocate((int)size)); + } + + /** + * Creates a buffer of doubles that can store up to {@code size} values + * + * @param size size of the buffer to allocate + * @return a new buffer + */ + public static DoubleDataBuffer ofDoubles(long size) { + Validator.createArgs(size, MAX_32BITS); + if (RawDataBufferFactory.canBeUsed()) { + return RawDataBufferFactory.create(new double[(int)size], false); + } + return NioDataBufferFactory.create(DoubleBuffer.allocate((int)size)); + } + + /** + * Creates a buffer of floats that can store up to {@code size} values + * + * @param size size of the buffer to allocate + * @return a new buffer + */ + public static FloatDataBuffer ofFloats(long size) { + Validator.createArgs(size, MAX_32BITS); + if (RawDataBufferFactory.canBeUsed()) { + return RawDataBufferFactory.create(new float[(int)size], false); + } + return NioDataBufferFactory.create(FloatBuffer.allocate((int)size)); + } + + /** + * Creates a buffer of booleans that can store up to {@code size} values + * + * @param size size of the buffer to allocate + * @return a new buffer + */ + public static BooleanDataBuffer ofBooleans(long size) { + Validator.createArgs(size, MAX_32BITS); + if (RawDataBufferFactory.canBeUsed()) { + return RawDataBufferFactory.create(new boolean[(int)size], false); + } + return MiscDataBufferFactory.create(new BitSet((int)size), size, false); + } + + /** + * Creates a buffer of references to objects of type {@code clazz` that can store up to `size} + * values. + * + * @param type the type of object stored in this buffer + * @param size size of the buffer to allocate + * @param data type + * @return a new buffer + */ + public static DataBuffer ofObjects(Class type, long size) { + Validator.createArgs(size, MAX_32BITS); + @SuppressWarnings("unchecked") + T[] array = (T[])Array.newInstance(type, (int)size); + return MiscDataBufferFactory.create(array, false); + } + + /** + * Create a buffer from an array of floats into a data buffer. + * + *

The returned buffer allows read and write operations and share the memory of the source + * array, which is equivalent to call {@link #of(float[], boolean, boolean) of(values, false, false}} + * + * @param values float values + * @return a new buffer + */ + public static FloatDataBuffer of(float... values) { + return of(values, false, false); + } + + /** + * Create a buffer from an array of bytes into a data buffer. + * + *

The returned buffer allows read and write operations and share the memory of the source + * array, which is equivalent to call {@link #of(byte[], boolean, boolean) of(values, false, false}} + * + * @param values byte values + * @return a new buffer + */ + public static ByteDataBuffer of(byte... values) { + return of(values, false, false); + } + + /** + * Create a buffer from an array of longs into a data buffer. + * + *

The returned buffer allows read and write operations and share the memory of the source + * array, which is equivalent to call {@link #of(long[], boolean, boolean) of(values, false, false}} + * + * @param values long values + * @return a new buffer + */ + public static LongDataBuffer of(long... values) { + return of(values, false, false); + } + + /** + * Create a buffer from an array of ints into a data buffer. + * + *

The returned buffer allows read and write operations and share the memory of the source + * array, which is equivalent to call {@link #of(int[], boolean, boolean) of(values, false, false}} + * + * @param values int values + * @return a new buffer + */ + public static IntDataBuffer of(int... values) { + return of(values, false, false); + } + + /** + * Create a buffer from an array of shorts into a data buffer. + * + *

The returned buffer allows read and write operations and share the memory of the source + * array, which is equivalent to call {@link #of(short[], boolean, boolean) of(values, false, false}} + * + * @param values short values + * @return a new buffer + */ + public static ShortDataBuffer of(short... values) { + return of(values, false, false); + } + + /** + * Create a buffer from an array of doubles into a data buffer. + * + *

The returned buffer allows read and write operations and share the memory of the source + * array, which is equivalent to call {@link #of(double[], boolean, boolean) of(array, false, false}} + * + * @param values double values + * @return a new buffer + */ + public static DoubleDataBuffer of(double... values) { + return of(values, false, false); + } + + /** + * Create a buffer from an array of booleans into a data buffer. + * + *

The returned buffer allows read and write operations and share the memory of the source + * array, which is equivalent to call {@link #of(boolean[], boolean, boolean) of(values, false, false}} + * + * @param values booleans values + * @return a new buffer + */ + public static BooleanDataBuffer of(boolean... values) { + return of(values, false, false); + } + + /** + * Create a buffer from an array of objects into a data buffer. + * + *

The returned buffer allows read and write operations and share the memory of the source + * array, which is equivalent to call {@link #of(Object[], boolean, boolean) of(values, false, false}} + * + * @param values objects values + * @param data type + * @return a new buffer + */ + @SafeVarargs + public static DataBuffer ofObjects(T... values) { + return of(values, false, false); + } + + /** + * Create a buffer from an array of floats into a data buffer. + * + * @param array array of floats + * @param readOnly true if the buffer created must be read-only + * @param makeCopy true if the array must be copied, false will wrap the provided array + * @return a new buffer + */ + public static FloatDataBuffer of(float[] array, boolean readOnly, boolean makeCopy) { + float[] bufferArray = makeCopy ? Arrays.copyOf(array, array.length) : array; + if (RawDataBufferFactory.canBeUsed()) { + return RawDataBufferFactory.create(bufferArray, readOnly); + } + FloatBuffer buf = FloatBuffer.wrap(bufferArray); + return NioDataBufferFactory.create(readOnly ? buf.asReadOnlyBuffer() : buf); + } + + /** + * Create a buffer from an array of bytes into a data buffer. + * + * @param array array of bytes + * @param readOnly true if the buffer created must be read-only + * @param makeCopy true if the array must be copied, false will wrap the provided array + * @return a new buffer + */ + public static ByteDataBuffer of(byte[] array, boolean readOnly, boolean makeCopy) { + byte[] bufferArray = makeCopy ? Arrays.copyOf(array, array.length) : array; + if (RawDataBufferFactory.canBeUsed()) { + return RawDataBufferFactory.create(bufferArray, readOnly); + } + ByteBuffer buf = ByteBuffer.wrap(bufferArray); + return NioDataBufferFactory.create(readOnly ? buf.asReadOnlyBuffer() : buf); + } + + /** + * Create a buffer from an array of longs into a data buffer. + * + * @param array array of longs + * @param readOnly true if the buffer created must be read-only + * @param makeCopy true if the array must be copied, false will wrap the provided array + * @return a new buffer + */ + public static LongDataBuffer of(long[] array, boolean readOnly, boolean makeCopy) { + long[] bufferArray = makeCopy ? Arrays.copyOf(array, array.length) : array; + if (RawDataBufferFactory.canBeUsed()) { + return RawDataBufferFactory.create(bufferArray, readOnly); + } + LongBuffer buf = LongBuffer.wrap(bufferArray); + return NioDataBufferFactory.create(readOnly ? buf.asReadOnlyBuffer() : buf); + } + + /** + * Create a buffer from an array of ints into a data buffer. + * + * @param array array of ints + * @param readOnly true if the buffer created must be read-only + * @param makeCopy true if the array must be copied, false will wrap the provided array + * @return a new buffer + */ + public static IntDataBuffer of(int[] array, boolean readOnly, boolean makeCopy) { + int[] bufferArray = makeCopy ? Arrays.copyOf(array, array.length) : array; + if (RawDataBufferFactory.canBeUsed()) { + return RawDataBufferFactory.create(bufferArray, readOnly); + } + IntBuffer buf = IntBuffer.wrap(bufferArray); + return NioDataBufferFactory.create(readOnly ? buf.asReadOnlyBuffer() : buf); + } + + /** + * Create a buffer from an array of shorts into a data buffer. + * + * @param array array of shorts + * @param readOnly true if the buffer created must be read-only + * @param makeCopy true if the array must be copied, false will wrap the provided array + * @return a new buffer + */ + public static ShortDataBuffer of(short[] array, boolean readOnly, boolean makeCopy) { + short[] bufferArray = makeCopy ? Arrays.copyOf(array, array.length) : array; + if (RawDataBufferFactory.canBeUsed()) { + return RawDataBufferFactory.create(bufferArray, readOnly); + } + ShortBuffer buf = ShortBuffer.wrap(bufferArray); + return NioDataBufferFactory.create(readOnly ? buf.asReadOnlyBuffer() : buf); + } + + /** + * Create a buffer from an array of doubles into a data buffer. + * + * @param array array of doubles + * @param readOnly true if the buffer created must be read-only + * @param makeCopy true if the array must be copied, false will wrap the provided array + * @return a new buffer + */ + public static DoubleDataBuffer of(double[] array, boolean readOnly, boolean makeCopy) { + double[] bufferArray = makeCopy ? Arrays.copyOf(array, array.length) : array; + if (RawDataBufferFactory.canBeUsed()) { + return RawDataBufferFactory.create(bufferArray, readOnly); + } + DoubleBuffer buf = DoubleBuffer.wrap(bufferArray); + return NioDataBufferFactory.create(readOnly ? buf.asReadOnlyBuffer() : buf); + } + + /** + * Create a buffer from an array of booleans into a data buffer. + * + * @param array array of booleans + * @param readOnly true if the buffer created must be read-only + * @param makeCopy true if the array must be copied, false will wrap the provided array + * @return a new buffer + */ + public static BooleanDataBuffer of(boolean[] array, boolean readOnly, boolean makeCopy) { + boolean[] bufferArray = makeCopy ? Arrays.copyOf(array, array.length) : array; + if (RawDataBufferFactory.canBeUsed()) { + return RawDataBufferFactory.create(bufferArray, readOnly); + } + return MiscDataBufferFactory.create(bufferArray, readOnly); + } + + /** + * Create a buffer from an array of objects into a data buffer. + * + * @param array array of objects + * @param readOnly true if the buffer created must be read-only + * @param makeCopy true if the array must be copied, false will wrap the provided array + * @param data type + * @return a new buffer + */ + public static DataBuffer of(T[] array, boolean readOnly, boolean makeCopy) { + T[] bufferArray = makeCopy ? Arrays.copyOf(array, array.length) : array; + return MiscDataBufferFactory.create(bufferArray, readOnly); + } + + /** + * Wraps a JDK NIO {@link ByteBuffer} into a data buffer. + * + * @param buf buffer to wrap + * @return a new buffer + */ + public static ByteDataBuffer of(ByteBuffer buf) { + return NioDataBufferFactory.create(buf.duplicate()); + } + + /** + * Wraps a JDK NIO {@link IntBuffer} into a data buffer. + * + * @param buf buffer to wrap + * @return a new buffer + */ + public static IntDataBuffer of(IntBuffer buf) { + return NioDataBufferFactory.create(buf.duplicate()); + } + + /** + * Wraps a JDK NIO {@link ShortBuffer} into a data buffer. + * + * @param buf buffer to wrap + * @return a new buffer + */ + public static ShortDataBuffer of(ShortBuffer buf) { + return NioDataBufferFactory.create(buf.duplicate()); + } + + /** + * Wraps a JDK NIO {@link LongBuffer} into a data buffer. + * + * @param buf buffer to wrap + * @return a new buffer + */ + public static LongDataBuffer of(LongBuffer buf) { + return NioDataBufferFactory.create(buf.duplicate()); + } + + /** + * Wraps a JDK NIO {@link FloatBuffer} into a data buffer. + * + * @param buf buffer to wrap + * @return a new buffer + */ + public static FloatDataBuffer of(FloatBuffer buf) { + return NioDataBufferFactory.create(buf.duplicate()); + } + + /** + * Wraps a JDK NIO {@link DoubleBuffer} into a data buffer. + * + * @param buf buffer to wrap + * @return a new buffer + */ + public static DoubleDataBuffer of(DoubleBuffer buf) { + return NioDataBufferFactory.create(buf.duplicate()); + } + + /* + * The maximum size for a buffer of this type, i.e. the maximum number of bytes it can store. + *

+ * As the maximum size may vary depending on the JVM implementation and on the platform, this + * property returns a value that is safe for most of them. + */ + static long MAX_32BITS = Integer.MAX_VALUE - 10; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/buffer/DataStorageVisitor.java b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/DataStorageVisitor.java new file mode 100644 index 00000000000..560320cd7eb --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/DataStorageVisitor.java @@ -0,0 +1,147 @@ +package org.tensorflow.ndarray.buffer; + +import java.nio.ByteBuffer; +import java.nio.DoubleBuffer; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.nio.LongBuffer; +import java.nio.ShortBuffer; +import java.util.BitSet; + +/** + * Visit the backing storage of {@link DataBuffer} instances. + * + * @param value type returned by the visitor + */ +public interface DataStorageVisitor { + + /** + * Visit the {@link ByteBuffer} backing a given instance of a {@link DataBuffer} + * + * @param buffer underlying buffer + * @return any value + * @see DataBuffer#accept(DataStorageVisitor) + */ + default R visit(ByteBuffer buffer) { + return fallback(); + } + + /** + * Visit the {@link ShortBuffer} backing a given instance of a {@link DataBuffer} + * + * @param buffer underlying buffer + * @return any value + * @see DataBuffer#accept(DataStorageVisitor) + */ + default R visit(ShortBuffer buffer) { + return fallback(); + } + + /** + * Visit the {@link IntBuffer} backing a given instance of a {@link DataBuffer} + * + * @param buffer underlying buffer + * @return any value + * @see DataBuffer#accept(DataStorageVisitor) + */ + default R visit(IntBuffer buffer) { + return fallback(); + } + + /** + * Visit the {@link LongBuffer} backing a given instance of a {@link DataBuffer} + * + * @param buffer underlying buffer + * @return any value + * @see DataBuffer#accept(DataStorageVisitor) + */ + default R visit(LongBuffer buffer) { + return fallback(); + } + + /** + * Visit the {@link FloatBuffer} backing a given instance of a {@link DataBuffer} + * + * @param buffer underlying buffer + * @return any value + * @see DataBuffer#accept(DataStorageVisitor) + */ + default R visit(FloatBuffer buffer) { + return fallback(); + } + + /** + * Visit the {@link DoubleBuffer} backing a given instance of a {@link DataBuffer} + * + * @param buffer underlying buffer + * @return any value + * @see DataBuffer#accept(DataStorageVisitor) + */ + default R visit(DoubleBuffer buffer) { + return fallback(); + } + + /** + * Visit the boolean array backing a given instance of a {@link DataBuffer} + * + * @param array underlying array + * @param offset offset of the buffer within the array + * @param length length of the buffer within the array + * @return any value + * @see DataBuffer#accept(DataStorageVisitor) + */ + default R visit(boolean[] array, int offset, int length) { + return fallback(); + } + + /** + * Visit the bit set backing a given instance of a {@link DataBuffer} + * + * @param bitSet underlying bit set + * @param offset offset of the buffer within the bit set + * @param numBits number of bits used to represent the buffer within the bit set + * @return any value + * @see DataBuffer#accept(DataStorageVisitor) + */ + default R visit(BitSet bitSet, int offset, long numBits) { + return fallback(); + } + + /** + * Visit the object array backing a given instance of a {@link DataBuffer} + * + * @param array underlying array + * @param offset offset of the buffer within the array + * @param length length of the buffer within the array + * @return any value + * @see DataBuffer#accept(DataStorageVisitor) + */ + default R visit(Object[] array, int offset, int length) { + return fallback(); + } + + /** + * Visit the raw memory segment of a given instance of a {@link DataBuffer} + * + * @param address native address of the buffer + * @param length length of the buffer + * @param scale number of bytes required to store a single value of this buffer + * @return any value + * @see DataBuffer#accept(DataStorageVisitor) + */ + default R visit(long address, long length, long scale) { + return fallback(); + } + + /** + * Fallback method called if the visitor implementation does not support the type of backing storage + * for a given {@link DataBuffer} + * + *

The implementor of this interface must override the {@code visit} methods for type of storage + * it supports. If {@link DataBuffer#accept(DataStorageVisitor)} is called on a buffer + * using a different type of storage, the invocation will fallback to this method. + * + * @return any value + */ + R fallback(); +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/buffer/DoubleDataBuffer.java b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/DoubleDataBuffer.java new file mode 100644 index 00000000000..f2db925eb78 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/DoubleDataBuffer.java @@ -0,0 +1,165 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.buffer; + +import java.nio.BufferOverflowException; +import java.nio.BufferUnderflowException; +import java.nio.ReadOnlyBufferException; + +/** + * A {@link DataBuffer} of doubles. + */ +public interface DoubleDataBuffer extends DataBuffer { + + /** + * Reads the double at the given index. + * + * @param index the index from which the float will be read + * @return the double at the given index + * @throws IndexOutOfBoundsException if index is negative or not smaller than the buffer size + */ + double getDouble(long index); + + /** + * Writes the given double into this buffer at the given index. + * + * @param value the double to be written + * @param index the index at which the value will be written + * @return this buffer + * @throws IndexOutOfBoundsException if index is negative or not smaller than the buffer size + * @throws ReadOnlyBufferException if this buffer is read-only + */ + DoubleDataBuffer setDouble(double value, long index); + + /** + * Bulk get method, using double arrays. + *

+ * This method transfers values from this buffer into the given destination array. If there are + * fewer values in the buffer than are required to satisfy the request, that is, if + * {@code dst.length > size()}, then no values are transferred and a + * BufferUnderflowException is thrown. + *

+ * Otherwise, this method copies {@code n = dst.length} values from this buffer into the given + * array. + * + * @param dst the array into which values are to be written + * @return this buffer + * @throws BufferUnderflowException if there are not enough values to copy from this buffer + */ + default DoubleDataBuffer read(double[] dst) { + return read(dst, 0, dst.length); + } + + /** + * Bulk get method, using double arrays. + *

+ * This method transfers values from this buffer into the given destination array. If there are + * fewer values in the buffer than are required to satisfy the request, that is, if + * {@code length > size()}, then no values are transferred and a + * BufferUnderflowException is thrown. + *

+ * Otherwise, this method copies {@code n = length} values from this buffer into the given array + * starting at the given offset. + * + * @param dst the array into which values are to be written + * @param offset the offset within the array of the first value to be written; must be + * non-negative and no larger than {@code dst.length} + * @param length the maximum number of values to be written to the given array; must be + * non-negative and no larger than {@code dst.length - offset} + * @return this buffer + * @throws BufferUnderflowException if there are fewer than length values remaining in this buffer + * @throws IndexOutOfBoundsException if the preconditions on the offset and length parameters do + * not hold + */ + DoubleDataBuffer read(double[] dst, int offset, int length); + + /** + * Bulk put method, using double arrays. + *

+ * This method transfers the values in the given source array into this buffer. If there are + * more values in the source array than in this buffer, that is, if + * {@code src.length > size()}, then no values are transferred and a + * BufferOverflowException is thrown. + *

+ * Otherwise, this method copies {@code n = src.length} values from the given array. + * + * @param src the source array from which values are to be read + * @return this buffer + * @throws BufferOverflowException if there is insufficient space in this buffer for the values in + * the source array + * @throws ReadOnlyBufferException if this buffer is read-only + */ + default DoubleDataBuffer write(double[] src) { + return write(src, 0, src.length); + } + + /** + * Bulk put method, using double arrays. + *

+ * This method transfers the values in the given source array into this buffer. If there are + * more values in the source array than in this buffer, that is, if + * {@code length > size()}, then no values are transferred and a + * BufferOverflowException is thrown. + *

+ * Otherwise, this method copies {@code n = length} values from the given array into this buffer, + * starting at the given offset. + * + * @param src the source array from which values are to be read + * @param offset the offset within the array of the first value to be read; must be non-negative + * and no larger than {@code src.length} + * @param length the number of values to be read from the given array; must be non-negative and no + * larger than {@code src.length - offset} + * @return this buffer + * @throws BufferOverflowException if there is insufficient space in this buffer for the values in + * the source array + * @throws IndexOutOfBoundsException if the preconditions on the offset and length parameters do + * not hold + * @throws ReadOnlyBufferException if this buffer is read-only + */ + DoubleDataBuffer write(double[] src, int offset, int length); + + @Override + default Double getObject(long index) { + return getDouble(index); + } + + @Override + default DoubleDataBuffer setObject(Double value, long index) { + return setDouble(value, index); + } + + @Override + DoubleDataBuffer copyTo(DataBuffer dst, long size); + + @Override + default DoubleDataBuffer offset(long index) { + return slice(index, size() - index); + } + + @Override + default DoubleDataBuffer narrow(long size) { + return slice(0, size); + } + + @Override + DoubleDataBuffer slice(long index, long size); + + @Override + default DataBufferWindow window(long size) { + throw new UnsupportedOperationException(); + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/buffer/FloatDataBuffer.java b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/FloatDataBuffer.java new file mode 100644 index 00000000000..4961c1b3445 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/FloatDataBuffer.java @@ -0,0 +1,165 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.buffer; + +import java.nio.BufferOverflowException; +import java.nio.BufferUnderflowException; +import java.nio.ReadOnlyBufferException; + +/** + * A {@link DataBuffer} of floats. + */ +public interface FloatDataBuffer extends DataBuffer { + + /** + * Reads the float at the given index. + * + * @param index the index from which the float will be read + * @return the float at the given index + * @throws IndexOutOfBoundsException if index is negative or not smaller than the buffer size + */ + float getFloat(long index); + + /** + * Writes the given float into this buffer at the given index. + * + * @param value the float to be written + * @param index the index at which the value will be written + * @return this buffer + * @throws IndexOutOfBoundsException if index is negative or not smaller than the buffer size + * @throws ReadOnlyBufferException if this buffer is read-only + */ + FloatDataBuffer setFloat(float value, long index); + + /** + * Bulk get method, using float arrays. + *

+ * This method transfers values from this buffer into the given destination array. If there are + * fewer values in the buffer than are required to satisfy the request, that is, if + * {@code dst.length > size()}, then no values are transferred and a + * BufferUnderflowException is thrown. + *

+ * Otherwise, this method copies {@code n = dst.length} values from this buffer into the given + * array. + * + * @param dst the array into which values are to be written + * @return this buffer + * @throws BufferUnderflowException if there are not enough values to copy from this buffer + */ + default FloatDataBuffer read(float[] dst) { + return read(dst, 0, dst.length); + } + + /** + * Bulk get method, using float arrays. + *

+ * This method transfers values from this buffer into the given destination array. If there are + * fewer values in the buffer than are required to satisfy the request, that is, if + * {@code length > size()}, then no values are transferred and a + * BufferUnderflowException is thrown. + *

+ * Otherwise, this method copies {@code n = length} values from this buffer into the given array + * starting at the given offset. + * + * @param dst the array into which values are to be written + * @param offset the offset within the array of the first value to be written; must be + * non-negative and no larger than {@code dst.length} + * @param length the maximum number of values to be written to the given array; must be + * non-negative and no larger than {@code dst.length - offset} + * @return this buffer + * @throws BufferUnderflowException if there are fewer than length values remaining in this buffer + * @throws IndexOutOfBoundsException if the preconditions on the offset and length parameters do + * not hold + */ + FloatDataBuffer read(float[] dst, int offset, int length); + + /** + * Bulk put method, using float arrays. + *

+ * This method transfers the values in the given source array into this buffer. If there are + * more values in the source array than in this buffer, that is, if + * {@code src.length > size()}, then no values are transferred and a + * BufferOverflowException is thrown. + *

+ * Otherwise, this method copies {@code n = src.length} values from the given array. + * + * @param src the source array from which values are to be read + * @return this buffer + * @throws BufferOverflowException if there is insufficient space in this buffer for the values in + * the source array + * @throws ReadOnlyBufferException if this buffer is read-only + */ + default FloatDataBuffer write(float[] src) { + return write(src, 0, src.length); + } + + /** + * Bulk put method, using float arrays. + *

+ * This method transfers the values in the given source array into this buffer. If there are + * more values in the source array than in this buffer, that is, if + * {@code length > size()}, then no values are transferred and a + * BufferOverflowException is thrown. + *

+ * Otherwise, this method copies {@code n = length} values from the given array into this buffer, + * starting at the given offset. + * + * @param src the source array from which values are to be read + * @param offset the offset within the array of the first value to be read; must be non-negative + * and no larger than {@code src.length} + * @param length the number of values to be read from the given array; must be non-negative and no + * larger than {@code src.length - offset} + * @return this buffer + * @throws BufferOverflowException if there is insufficient space in this buffer for the values in + * the source array + * @throws IndexOutOfBoundsException if the preconditions on the offset and length parameters do + * not hold + * @throws ReadOnlyBufferException if this buffer is read-only + */ + FloatDataBuffer write(float[] src, int offset, int length); + + @Override + default Float getObject(long index) { + return getFloat(index); + } + + @Override + default FloatDataBuffer setObject(Float value, long index) { + return setFloat(value, index); + } + + @Override + FloatDataBuffer copyTo(DataBuffer dst, long size); + + @Override + default FloatDataBuffer offset(long index) { + return slice(index, size() - index); + } + + @Override + default FloatDataBuffer narrow(long size) { + return slice(0, size); + } + + @Override + FloatDataBuffer slice(long index, long size); + + @Override + default DataBufferWindow window(long size) { + throw new UnsupportedOperationException(); + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/buffer/IntDataBuffer.java b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/IntDataBuffer.java new file mode 100644 index 00000000000..2d660756e09 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/IntDataBuffer.java @@ -0,0 +1,165 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.buffer; + +import java.nio.BufferOverflowException; +import java.nio.BufferUnderflowException; +import java.nio.ReadOnlyBufferException; + +/** + * A {@link DataBuffer} of ints. + */ +public interface IntDataBuffer extends DataBuffer { + + /** + * Reads the int at the given index. + * + * @param index the index from which the float will be read + * @return the int at the given index + * @throws IndexOutOfBoundsException if index is negative or not smaller than the buffer size + */ + int getInt(long index); + + /** + * Writes the given int into this buffer at the given index. + * + * @param value the int to be written + * @param index the index at which the value will be written + * @return this buffer + * @throws IndexOutOfBoundsException if index is negative or not smaller than the buffer size + * @throws ReadOnlyBufferException if this buffer is read-only + */ + IntDataBuffer setInt(int value, long index); + + /** + * Bulk get method, using int arrays. + *

+ * This method transfers values from this buffer into the given destination array. If there are + * fewer values in the buffer than are required to satisfy the request, that is, if + * {@code dst.length > size()}, then no values are transferred and a + * BufferUnderflowException is thrown. + *

+ * Otherwise, this method copies {@code n = dst.length} values from this buffer into the given + * array. + * + * @param dst the array into which values are to be written + * @return this buffer + * @throws BufferUnderflowException if there are not enough values to copy from this buffer + */ + default IntDataBuffer read(int[] dst) { + return read(dst, 0, dst.length); + } + + /** + * Bulk get method, using int arrays. + *

+ * This method transfers values from this buffer into the given destination array. If there are + * fewer values in the buffer than are required to satisfy the request, that is, if + * {@code length > size()}, then no values are transferred and a + * BufferUnderflowException is thrown. + *

+ * Otherwise, this method copies {@code n = length} values from this buffer into the given array + * starting at the given offset. + * + * @param dst the array into which values are to be written + * @param offset the offset within the array of the first value to be written; must be + * non-negative and no larger than {@code dst.length} + * @param length the maximum number of values to be written to the given array; must be + * non-negative and no larger than {@code dst.length - offset} + * @return this buffer + * @throws BufferUnderflowException if there are fewer than length values remaining in this buffer + * @throws IndexOutOfBoundsException if the preconditions on the offset and length parameters do + * not hold + */ + IntDataBuffer read(int[] dst, int offset, int length); + + /** + * Bulk put method, using int arrays. + *

+ * This method transfers the values in the given source array into this buffer. If there are + * more values in the source array than in this buffer, that is, if + * {@code src.length > size()}, then no values are transferred and a + * BufferOverflowException is thrown. + *

+ * Otherwise, this method copies {@code n = src.length} values from the given array. + * + * @param src the source array from which values are to be read + * @return this buffer + * @throws BufferOverflowException if there is insufficient space in this buffer for the values in + * the source array + * @throws ReadOnlyBufferException if this buffer is read-only + */ + default IntDataBuffer write(int[] src) { + return write(src, 0, src.length); + } + + /** + * Bulk put method, using int arrays. + *

+ * This method transfers the values in the given source array into this buffer. If there are + * more values in the source array than in this buffer, that is, if + * {@code length > size()}, then no values are transferred and a + * BufferOverflowException is thrown. + *

+ * Otherwise, this method copies {@code n = length} values from the given array into this buffer, + * starting at the given offset. + * + * @param src the source array from which values are to be read + * @param offset the offset within the array of the first value to be read; must be non-negative + * and no larger than {@code src.length} + * @param length the number of values to be read from the given array; must be non-negative and no + * larger than {@code src.length - offset} + * @return this buffer + * @throws BufferOverflowException if there is insufficient space in this buffer for the values in + * the source array + * @throws IndexOutOfBoundsException if the preconditions on the offset and length parameters do + * not hold + * @throws ReadOnlyBufferException if this buffer is read-only + */ + IntDataBuffer write(int[] src, int offset, int length); + + @Override + default Integer getObject(long index) { + return getInt(index); + } + + @Override + default IntDataBuffer setObject(Integer value, long index) { + return setInt(value, index); + } + + @Override + IntDataBuffer copyTo(DataBuffer dst, long size); + + @Override + default IntDataBuffer offset(long index) { + return slice(index, size() - index); + } + + @Override + default IntDataBuffer narrow(long size) { + return slice(0, size); + } + + @Override + IntDataBuffer slice(long index, long size); + + @Override + default DataBufferWindow window(long size) { + throw new UnsupportedOperationException(); + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/buffer/LongDataBuffer.java b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/LongDataBuffer.java new file mode 100644 index 00000000000..f88ae4a80b4 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/LongDataBuffer.java @@ -0,0 +1,165 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.buffer; + +import java.nio.BufferOverflowException; +import java.nio.BufferUnderflowException; +import java.nio.ReadOnlyBufferException; + +/** + * A {@link DataBuffer} of longs. + */ +public interface LongDataBuffer extends DataBuffer { + + /** + * Reads the long at the given index. + * + * @param index the index from which the float will be read + * @return the long at the given index + * @throws IndexOutOfBoundsException if index is negative or not smaller than the buffer size + */ + long getLong(long index); + + /** + * Writes the given long into this buffer at the given index. + * + * @param value the long to be written + * @param index the index at which the value will be written + * @return this buffer + * @throws IndexOutOfBoundsException if index is negative or not smaller than the buffer size + * @throws ReadOnlyBufferException if this buffer is read-only + */ + LongDataBuffer setLong(long value, long index); + + /** + * Bulk get method, using long arrays. + *

+ * This method transfers values from this buffer into the given destination array. If there are + * fewer values in the buffer than are required to satisfy the request, that is, if + * {@code dst.length > size()}, then no values are transferred and a + * BufferUnderflowException is thrown. + *

+ * Otherwise, this method copies {@code n = dst.length} values from this buffer into the given + * array. + * + * @param dst the array into which values are to be written + * @return this buffer + * @throws BufferUnderflowException if there are not enough values to copy from this buffer + */ + default LongDataBuffer read(long[] dst) { + return read(dst, 0, dst.length); + } + + /** + * Bulk get method, using long arrays. + *

+ * This method transfers values from this buffer into the given destination array. If there are + * fewer values in the buffer than are required to satisfy the request, that is, if + * {@code length > size()}, then no values are transferred and a + * BufferUnderflowException is thrown. + *

+ * Otherwise, this method copies {@code n = length} values from this buffer into the given array + * starting at the given offset. + * + * @param dst the array into which values are to be written + * @param offset the offset within the array of the first value to be written; must be + * non-negative and no larger than {@code dst.length} + * @param length the maximum number of values to be written to the given array; must be + * non-negative and no larger than {@code dst.length - offset} + * @return this buffer + * @throws BufferUnderflowException if there are fewer than length values remaining in this buffer + * @throws IndexOutOfBoundsException if the preconditions on the offset and length parameters do + * not hold + */ + LongDataBuffer read(long[] dst, int offset, int length); + + /** + * Bulk put method, using long arrays. + *

+ * This method transfers the values in the given source array into this buffer. If there are + * more values in the source array than in this buffer, that is, if + * {@code src.length > size()}, then no values are transferred and a + * BufferOverflowException is thrown. + *

+ * Otherwise, this method copies {@code n = src.length} values from the given array. + * + * @param src the source array from which values are to be read + * @return this buffer + * @throws BufferOverflowException if there is insufficient space in this buffer for the values in + * the source array + * @throws ReadOnlyBufferException if this buffer is read-only + */ + default LongDataBuffer write(long[] src) { + return write(src, 0, src.length); + } + + /** + * Bulk put method, using long arrays. + *

+ * This method transfers the values in the given source array into this buffer. If there are + * more values in the source array than in this buffer, that is, if + * {@code length > size()}, then no values are transferred and a + * BufferOverflowException is thrown. + *

+ * Otherwise, this method copies {@code n = length} values from the given array into this buffer, + * starting at the given offset. + * + * @param src the source array from which values are to be read + * @param offset the offset within the array of the first value to be read; must be non-negative + * and no larger than {@code src.length} + * @param length the number of values to be read from the given array; must be non-negative and no + * larger than {@code src.length - offset} + * @return this buffer + * @throws BufferOverflowException if there is insufficient space in this buffer for the values in + * the source array + * @throws IndexOutOfBoundsException if the preconditions on the offset and length parameters do + * not hold + * @throws ReadOnlyBufferException if this buffer is read-only + */ + LongDataBuffer write(long[] src, int offset, int length); + + @Override + default Long getObject(long index) { + return getLong(index); + } + + @Override + default LongDataBuffer setObject(Long value, long index) { + return setLong(value, index); + } + + @Override + LongDataBuffer copyTo(DataBuffer dst, long size); + + @Override + default LongDataBuffer offset(long index) { + return slice(index, size() - index); + } + + @Override + default LongDataBuffer narrow(long size) { + return slice(0, size); + } + + @Override + LongDataBuffer slice(long index, long size); + + @Override + default DataBufferWindow window(long size) { + throw new UnsupportedOperationException(); + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/buffer/ShortDataBuffer.java b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/ShortDataBuffer.java new file mode 100644 index 00000000000..290e2d57619 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/ShortDataBuffer.java @@ -0,0 +1,165 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.buffer; + +import java.nio.BufferOverflowException; +import java.nio.BufferUnderflowException; +import java.nio.ReadOnlyBufferException; + +/** + * A {@link DataBuffer} of shorts. + */ +public interface ShortDataBuffer extends DataBuffer { + + /** + * Reads the short at the given index. + * + * @param index the index from which the float will be read + * @return the short at the given index + * @throws IndexOutOfBoundsException if index is negative or not smaller than the buffer size + */ + short getShort(long index); + + /** + * Writes the given short into this buffer at the given index. + * + * @param value the short to be written + * @param index the index at which the value will be written + * @return this buffer + * @throws IndexOutOfBoundsException if index is negative or not smaller than the buffer size + * @throws ReadOnlyBufferException if this buffer is read-only + */ + ShortDataBuffer setShort(short value, long index); + + /** + * Bulk get method, using short arrays. + *

+ * This method transfers values from this buffer into the given destination array. If there are + * fewer values in the buffer than are required to satisfy the request, that is, if + * {@code dst.length > size()}, then no values are transferred and a + * BufferUnderflowException is thrown. + *

+ * Otherwise, this method copies {@code n = dst.length} values from this buffer into the given + * array. + * + * @param dst the array into which values are to be written + * @return this buffer + * @throws BufferUnderflowException if there are not enough values to copy from this buffer + */ + default ShortDataBuffer read(short[] dst) { + return read(dst, 0, dst.length); + } + + /** + * Bulk get method, using short arrays. + *

+ * This method transfers values from this buffer into the given destination array. If there are + * fewer values in the buffer than are required to satisfy the request, that is, if + * {@code length > size()}, then no values are transferred and a + * BufferUnderflowException is thrown. + *

+ * Otherwise, this method copies {@code n = length} values from this buffer into the given array + * starting at the given offset. + * + * @param dst the array into which values are to be written + * @param offset the offset within the array of the first value to be written; must be + * non-negative and no larger than {@code dst.length} + * @param length the maximum number of values to be written to the given array; must be + * non-negative and no larger than {@code dst.length - offset} + * @return this buffer + * @throws BufferUnderflowException if there are fewer than length values remaining in this buffer + * @throws IndexOutOfBoundsException if the preconditions on the offset and length parameters do + * not hold + */ + ShortDataBuffer read(short[] dst, int offset, int length); + + /** + * Bulk put method, using short arrays. + *

+ * This method transfers the values in the given source array into this buffer. If there are + * more values in the source array than in this buffer, that is, if + * {@code src.length > size()}, then no values are transferred and a + * BufferOverflowException is thrown. + *

+ * Otherwise, this method copies {@code n = src.length} values from the given array. + * + * @param src the source array from which values are to be read + * @return this buffer + * @throws BufferOverflowException if there is insufficient space in this buffer for the values in + * the source array + * @throws ReadOnlyBufferException if this buffer is read-only + */ + default ShortDataBuffer write(short[] src) { + return write(src, 0, src.length); + } + + /** + * Bulk put method, using short arrays. + *

+ * This method transfers the values in the given source array into this buffer. If there are + * more values in the source array than in this buffer, that is, if + * {@code length > size()}, then no values are transferred and a + * BufferOverflowException is thrown. + *

+ * Otherwise, this method copies {@code n = length} values from the given array into this buffer, + * starting at the given offset. + * + * @param src the source array from which values are to be read + * @param offset the offset within the array of the first value to be read; must be non-negative + * and no larger than {@code src.length} + * @param length the number of values to be read from the given array; must be non-negative and no + * larger than {@code src.length - offset} + * @return this buffer + * @throws BufferOverflowException if there is insufficient space in this buffer for the values in + * the source array + * @throws IndexOutOfBoundsException if the preconditions on the offset and length parameters do + * not hold + * @throws ReadOnlyBufferException if this buffer is read-only + */ + ShortDataBuffer write(short[] src, int offset, int length); + + @Override + default Short getObject(long index) { + return getShort(index); + } + + @Override + default ShortDataBuffer setObject(Short value, long index) { + return setShort(value, index); + } + + @Override + ShortDataBuffer copyTo(DataBuffer dst, long size); + + @Override + default ShortDataBuffer offset(long index) { + return slice(index, size() - index); + } + + @Override + default ShortDataBuffer narrow(long size) { + return slice(0, size); + } + + @Override + ShortDataBuffer slice(long index, long size); + + @Override + default DataBufferWindow window(long size) { + throw new UnsupportedOperationException(); + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/BooleanDataLayout.java b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/BooleanDataLayout.java new file mode 100644 index 00000000000..c7092c8720d --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/BooleanDataLayout.java @@ -0,0 +1,65 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ +package org.tensorflow.ndarray.buffer.layout; + +import org.tensorflow.ndarray.buffer.BooleanDataBuffer; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.impl.buffer.adapter.DataBufferAdapterFactory; + +/** + * A {@link DataLayout} that converts data stored in a buffer to booleans. + * + * @param type of buffer this layout can be applied to + * @see DataLayout + */ +public interface BooleanDataLayout> extends DataLayout { + + @Override + default BooleanDataBuffer applyTo(S buffer) { + return DataBufferAdapterFactory.create(buffer, this); + } + + /** + * Writes a boolean into the buffer at the given index after converting it to the buffer type. + * + * @param buffer the buffer to write to + * @param value the boolean to convert and write + * @param index index in the buffer where the converted value should be written + * @see #writeObject(DataBuffer, Boolean, long) + */ + void writeBoolean(S buffer, boolean value, long index); + + /** + * Reads {@code n = scale()} values from the buffer at the given index and return them as a boolean. + * + * @param buffer the buffer to read from + * @param index position of the buffer to read in the buffer + * @return the boolean value + * @see #readObject(DataBuffer, long) + */ + boolean readBoolean(S buffer, long index); + + @Override + default void writeObject(S buffer, Boolean value, long index) { + writeBoolean(buffer, value, index); + } + + @Override + default Boolean readObject(S buffer, long index) { + return readBoolean(buffer, index); + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/ByteDataLayout.java b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/ByteDataLayout.java new file mode 100644 index 00000000000..e4d4bf9c8cf --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/ByteDataLayout.java @@ -0,0 +1,65 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.buffer.layout; + +import org.tensorflow.ndarray.buffer.ByteDataBuffer; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.impl.buffer.adapter.DataBufferAdapterFactory; + +/** + * A {@link DataLayout} that converts data stored in a buffer to bytes. + * + * @param type of buffer this layout can be applied to + * @see DataLayout + */ +public interface ByteDataLayout> extends DataLayout { + + @Override + default ByteDataBuffer applyTo(S buffer) { + return DataBufferAdapterFactory.create(buffer, this); + } + + /** + * Writes a byte into the buffer at the given index after converting it to the buffer type. + * + * @param buffer the buffer to write to + * @param value the byte to convert and write + * @param index index in the buffer where the converted value should be written + * @see #writeObject(DataBuffer, Byte, long) + */ + void writeByte(S buffer, byte value, long index); + + /** + * Reads {@code n = scale()} values from the buffer at the given index and return them as a byte. + * + * @param buffer the buffer to read from + * @param index position of the buffer to read in the buffer + * @return the byte value + * @see #readObject(DataBuffer, long) + */ + byte readByte(S buffer, long index); + + @Override + default void writeObject(S buffer, Byte value, long index) { + writeByte(buffer, value, index); + } + + @Override + default Byte readObject(S buffer, long index) { + return readByte(buffer, index); + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/DataLayout.java b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/DataLayout.java new file mode 100644 index 00000000000..93cc542e07a --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/DataLayout.java @@ -0,0 +1,129 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ +package org.tensorflow.ndarray.buffer.layout; + +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.impl.buffer.adapter.DataBufferAdapterFactory; + +/** + * Converts data stored in a buffer to a given type. + * + *

{@code DataLayout} instances are used to define a custom format for storing and reading data + * of a {@link DataBuffer}. They provide a segregation layer between the type of data stored in the + * buffer (the buffer type) and the type of data manipulated by the end user (the + * user type). + * + *

Since the conversion methods are invoked for every value that is written or read, working + * with data layouts may have a negative impact on the performances so using primitive types directly + * should be preferred whenever possible. + * + *

It is also recommended to implement immutable data layouts so they can be reapplied to multiple + * buffers without reallocating a new instance for each of them. For example: + * + *

+ * class BigIntegerBufferAllocator {
+ *
+ *     public DataBuffer<BigInteger> allocate(long size) {
+ *         return LAYOUT.applyTo(DataBuffers.ofLongs(size * LAYOUT.scale()));  // scale is 1 by default
+ *     }
+ *
+ *     private static final DataLayout<LongDataBuffer, BigInteger> LAYOUT = new DataLayout<LongDataBuffer, BigInteger>() {
+ *
+ *         @Override
+ *         public void writeObject(LongDataBuffer buffer, BigInteger value, long index) {
+ *             buffer.setLong(value.longValue(), index);
+ *         }
+ *
+ *         @Override
+ *         public BigInteger readObject(LongDataBuffer buffer, long index) {
+ *             return BigInteger.valueOf(buffer.getLong(index));
+ *         }
+ *     };
+ * }
+ * 
+ * + * @param type of buffer this layout can be applied to + * @param user data type of this layout + */ +public interface DataLayout, T> { + + /** + * Apply this layout to the provided buffer. + * + *

The returned {@link DataBuffer} instance is simply a wrapper to the original buffer and does + * not have a backing storage of his own. + * + * @param buffer the target buffer to apply this layout to + * @return a buffer with this layout + */ + default DataBuffer applyTo(S buffer) { + return DataBufferAdapterFactory.create(buffer, this); + } + + /** + * Writes a user value into the buffer at the given index after converting it to the buffer type. + * + *

It is the responsibility of the implementors of this interface to write the converted value + * to the given buffer before this call returns, using the most appropriate method. For example, + * for a layout converting a {@code BigInteger} to a single {@code long}, + *

+   * @Override
+   * public void writeObject(LongDataBuffer buffer, BigInteger value, long index) {
+   *   buffer.setLong(value.longValue(), index);
+   * }
+   * 
+ * If a single user value scales over more than one buffer values, {@code index} indicates the + * starting position of the sequence to be written to the buffer. + * + * @param buffer the buffer to write to + * @param value the value in the user type to convert and write + * @param index index in the buffer where the converted value should be written + */ + void writeObject(S buffer, T value, long index); + + /** + * Reads {@code n = scale()} values from the buffer at the given index and return them as a single + * value in the user type. + * + *

It is the responsibility of the implementors of this interface to read the value to be + * converted from the given buffer, using the most appropriate method. For example, for a layout + * that converting a single {@code long} to a {@code BigInteger}, + *

+   * @Override
+   * public BigInteger readObject(LongDataBuffer buffer, long index) {
+   *   return BigInteger.valueOf(buffer.getLong(index));
+   * }
+   * 
+ * If a single user value scales over more than one buffer values, {@code index} indicates the + * starting position of the sequence to be read from the buffer. + * + * @param buffer the buffer to read from + * @param index position of the buffer to read in the buffer + * @return the converted value + */ + T readObject(S buffer, long index); + + /** + * Indicates the number of buffer values are required to represent a single user value, default is 1. + * + *

Scale must be positive and must be an integer, meaning that a single buffer value in a buffer cannot + * be used to represent more than one user value. + */ + default int scale() { + return 1; + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/DataLayouts.java b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/DataLayouts.java new file mode 100644 index 00000000000..8f69168930c --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/DataLayouts.java @@ -0,0 +1,96 @@ +/* + * Copyright 2020 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.buffer.layout; + +import java.nio.charset.Charset; +import org.tensorflow.ndarray.buffer.ByteDataBuffer; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.ShortDataBuffer; +import org.tensorflow.ndarray.impl.buffer.layout.Bfloat16Layout; +import org.tensorflow.ndarray.impl.buffer.layout.BoolLayout; +import org.tensorflow.ndarray.impl.buffer.layout.Float16Layout; +import org.tensorflow.ndarray.impl.buffer.layout.StringLayout; + +/** + * Exposes {@link DataLayout} instances of data formats frequently used in linear algebra computation. + * + *

Example of usage: + *

{@code
+ * // Storing boolean values in a ByteDataBuffer
+ * BooleanDataBuffer boolBuffer = DataLayouts.BOOL.applyTo(byteDataBuffer);
+ *
+ * // Allocating a new buffer of 256 half floats
+ * FloatDataBuffer halfBuffer = DataLayouts.FLOAT16.applyTo(DataBuffers.ofShorts(256 * DataLayouts.FLOAT16.scale());
+ * }
+ */ +public final class DataLayouts { + + /** + * Data layout for converting 16-bit bfloats to/from short values. + * + *

This format used to be specific to TensorFlow but has now been adopted more broadly in the + * machine learning field. It is optimized for fast conversion with single-precision 32-bit + * floating points by simply shifting their value and truncating the mantissa to only 7 bits. + * + *

Therefore, this is a lost of precision in the fraction part compared to the IEEE-754 + * half-precision floating point specification (see {@link #FLOAT16} but it has a larger range of + * possible values in the whole part as it preserves the 8-bit exponent and uses the same bias, + * (i.e. an absolute range above 0 of approximately [10-40, 3.39 × 1038] + * + *

Some CPUs support the bfloat16 format natively for better performances. + */ + public static final FloatDataLayout BFLOAT16 = new Bfloat16Layout(); + + /** + * Data layout for converting 16-bit half floats to/from short values. + * + *

Half floats are stored in memory accordingly to the IEEE-754 half-precision floating point + * specification, and are converted to/from 32-bit floats in the user space. + * + *

There is a potential loss of precision when converting a single float (32-bit) to a half + * float (16-bit). Absolute range of values above 0 for a half float is approximately + * [5.96 × 10-8, 6.55 × 104] and their decimal part is rounded up + * to a 10 bits mantissa. + * + *

In general, half float computation perform better on GPUs since, in general, CPUs do not + * support this format natively.

+ */ + public static final FloatDataLayout FLOAT16 = new Float16Layout(); + + /** + * Data layout for converting booleans to/from byte values. + * + *

Since there is no Java NIO boolean buffer, this layout is particularly useful for mapping + * booleans values to standard byte buffers. The conversion between a boolean and a byte requires + * explicit type casting. + */ + public static final BooleanDataLayout BOOL = new BoolLayout(); + + /** + * Creates a data layout for converting strings to/from byte sequences. + * + *

This layout requires a {@code charset} in parameter to specify how the strings must be + * encoded/decoded as byte sequences. So a new layout instance is always returned. + * + * @param charset charset to use + * @return a new string layout + */ + public static DataLayout, String> ofStrings(Charset charset) { + return StringLayout.of(charset); + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/DoubleDataLayout.java b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/DoubleDataLayout.java new file mode 100644 index 00000000000..efd1e461802 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/DoubleDataLayout.java @@ -0,0 +1,65 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ +package org.tensorflow.ndarray.buffer.layout; + +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DoubleDataBuffer; +import org.tensorflow.ndarray.impl.buffer.adapter.DataBufferAdapterFactory; + +/** + * A {@link DataLayout} that converts data stored in a buffer to doubles. + * + * @param type of buffer this layout can be applied to + * @see DataLayout + */ +public interface DoubleDataLayout> extends DataLayout { + + @Override + default DoubleDataBuffer applyTo(S buffer) { + return DataBufferAdapterFactory.create(buffer, this); + } + + /** + * Writes a double into the buffer at the given index after converting it to the buffer type. + * + * @param buffer the buffer to write to + * @param value the double to convert and write + * @param index index in the buffer where the converted value should be written + * @see #writeObject(DataBuffer, Double, long) + */ + void writeDouble(S buffer, double value, long index); + + /** + * Reads {@code n = scale()} buffer values at the given index and return them as a double. + * + * @param buffer the buffer to read from + * @param index position of the buffer to read in the buffer + * @return the double value + * @see #readObject(DataBuffer, long) + */ + double readDouble(S buffer, long index); + + @Override + default void writeObject(S buffer, Double value, long index) { + writeDouble(buffer, value, index); + } + + @Override + default Double readObject(S buffer, long index) { + return readDouble(buffer, index); + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/FloatDataLayout.java b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/FloatDataLayout.java new file mode 100644 index 00000000000..a57f525d69f --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/FloatDataLayout.java @@ -0,0 +1,65 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ +package org.tensorflow.ndarray.buffer.layout; + +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.FloatDataBuffer; +import org.tensorflow.ndarray.impl.buffer.adapter.DataBufferAdapterFactory; + +/** + * A {@link DataLayout} that converts data stored in a buffer to floats. + * + * @param type of buffer this layout can be applied to + * @see DataLayout + */ +public interface FloatDataLayout> extends DataLayout { + + @Override + default FloatDataBuffer applyTo(S buffer) { + return DataBufferAdapterFactory.create(buffer, this); + } + + /** + * Writes a float into the buffer at the given index after converting it to the buffer type. + * + * @param buffer the buffer to write to + * @param value the float to convert and write + * @param index index in the buffer where the converted value should be written + * @see #writeObject(DataBuffer, Float, long) + */ + void writeFloat(S buffer, float value, long index); + + /** + * Reads {@code n = scale()} values from the buffer at the given index and return them as a float. + * + * @param buffer the buffer to read from + * @param index position of the buffer to read in the buffer + * @return the float value + * @see #readObject(DataBuffer, long) + */ + float readFloat(S buffer, long index); + + @Override + default void writeObject(S buffer, Float value, long index) { + writeFloat(buffer, value, index); + } + + @Override + default Float readObject(S buffer, long index) { + return readFloat(buffer, index); + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/IntDataLayout.java b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/IntDataLayout.java new file mode 100644 index 00000000000..718deac9b9f --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/IntDataLayout.java @@ -0,0 +1,66 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.buffer.layout; + +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.IntDataBuffer; +import org.tensorflow.ndarray.impl.buffer.adapter.DataBufferAdapterFactory; + +/** + * A {@link DataLayout} that converts data stored in a buffer to ints. + * + * @param type of buffer this layout can be applied to + * @see DataLayout + */ +public interface IntDataLayout> extends DataLayout { + + @Override + default IntDataBuffer applyTo(S buffer) { + return DataBufferAdapterFactory.create(buffer, this); + } + + /** + * Writes a int into the buffer at the given index after converting it to the buffer type. + * + * @param buffer the buffer to write to + * @param value the int to convert and write + * @param index index in the buffer where the converted value should be written + * @see #writeObject(DataBuffer, Integer, long) + */ + void writeInt(S buffer, int value, long index); + + /** + * Reads {@code n = scale()} values from the buffer at the given index and return them as an int. + * + * @param buffer the buffer to read from + * @param index position of the buffer to read in the buffer + * @return the int value + * @see #readObject(DataBuffer, long) + */ + int readInt(S buffer, long index); + + @Override + default void writeObject(S buffer, Integer value, long index) { + writeInt(buffer, value, index); + } + + @Override + default Integer readObject(S buffer, long index) { + return readInt(buffer, index); + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/LongDataLayout.java b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/LongDataLayout.java new file mode 100644 index 00000000000..f5c86ddd378 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/LongDataLayout.java @@ -0,0 +1,65 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ +package org.tensorflow.ndarray.buffer.layout; + +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.LongDataBuffer; +import org.tensorflow.ndarray.impl.buffer.adapter.DataBufferAdapterFactory; + +/** + * A {@link DataLayout} that converts data stored in a buffer to longs. + * + * @param type of buffer this layout can be applied to + * @see DataLayout + */ +public interface LongDataLayout> extends DataLayout { + + @Override + default LongDataBuffer applyTo(S buffer) { + return DataBufferAdapterFactory.create(buffer, this); + } + + /** + * Writes a long into the buffer at the given index after converting it to the buffer type. + * + * @param buffer the buffer to write to + * @param value the long to convert and write + * @param index index in the buffer where the converted value should be written + * @see #writeObject(DataBuffer, Long, long) + */ + void writeLong(S buffer, long value, long index); + + /** + * Reads {@code n = scale()} values from the buffer at the given index and return them as a long. + * + * @param buffer the buffer to read from + * @param index position of the buffer to read in the buffer + * @return the long value + * @see #readObject(DataBuffer, long) + */ + long readLong(S buffer, long index); + + @Override + default void writeObject(S buffer, Long value, long index) { + writeLong(buffer, value, index); + } + + @Override + default Long readObject(S buffer, long index) { + return readLong(buffer, index); + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/ShortDataLayout.java b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/ShortDataLayout.java new file mode 100644 index 00000000000..89c1fd0dec4 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/buffer/layout/ShortDataLayout.java @@ -0,0 +1,65 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ +package org.tensorflow.ndarray.buffer.layout; + +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.ShortDataBuffer; +import org.tensorflow.ndarray.impl.buffer.adapter.DataBufferAdapterFactory; + +/** + * A {@link DataLayout} that converts data stored in a buffer to shorts. + * + * @param type of buffer this layout can be applied to + * @see DataLayout + */ +public interface ShortDataLayout> extends DataLayout { + + @Override + default ShortDataBuffer applyTo(S buffer) { + return DataBufferAdapterFactory.create(buffer, this); + } + + /** + * Writes a short into the buffer at the given index after converting it to the buffer type. + * + * @param buffer the buffer to write to + * @param value the short to convert and write + * @param index index in the buffer where the converted value should be written + * @see #writeObject(DataBuffer, Short, long) + */ + void writeShort(S buffer, short value, long index); + + /** + * Reads {@code n = scale()} buffer values at the given index and return them as a short. + * + * @param buffer the buffer to read from + * @param index position of the value to read in the buffer + * @return the short value + * @see #readObject(DataBuffer, long) + */ + short readShort(S buffer, long index); + + @Override + default void writeObject(S buffer, Short value, long index) { + writeShort(buffer, value, index); + } + + @Override + default Short readObject(S buffer, long index) { + return readShort(buffer, index); + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/AbstractNdArray.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/AbstractNdArray.java new file mode 100644 index 00000000000..690dedc2042 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/AbstractNdArray.java @@ -0,0 +1,92 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl; + +import java.util.Iterator; +import org.tensorflow.ndarray.NdArray; +import org.tensorflow.ndarray.NdArraySequence; +import org.tensorflow.ndarray.Shape; +import org.tensorflow.ndarray.impl.dimension.DimensionalSpace; + +@SuppressWarnings("unchecked") +public abstract class AbstractNdArray> implements NdArray { + + public abstract U slice(long position, DimensionalSpace dimensions); + + public DimensionalSpace dimensions() { + return dimensions; + } + + @Override + public Shape shape() { + return dimensions.shape(); + } + + @Override + public NdArraySequence scalars() { + // negative if this array is a scalar, should be handled in `elements(dimIdx)` + return (NdArraySequence)elements(shape().numDimensions() - 1); + } + + @Override + public int hashCode() { + return slowHashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof NdArray)) { + return false; + } + return slowEquals((NdArray)obj); + } + + protected AbstractNdArray(DimensionalSpace dimensions) { + this.dimensions = dimensions; + } + + protected void slowCopyTo(NdArray array) { + scalars().forEachIndexed((coords, e) -> array.setObject(e.getObject(), coords)); + } + + protected int slowHashCode() { + final int prime = 31; + int result = 1; + for (NdArray scalar : scalars()) { + result = prime * result + scalar.getObject().hashCode(); + } + result = prime * result + shape().hashCode(); + return result; + } + + protected boolean slowEquals(NdArray array) { + if (!shape().equals(array.shape())) { // this guarantees also that we have the same number of scalar values + return false; + } + for (Iterator> thisIter = scalars().iterator(), otherIter = array.scalars().iterator(); thisIter.hasNext();) { + if (!thisIter.next().getObject().equals(otherIter.next().getObject())) { + return false; + } + } + return true; + } + + protected final DimensionalSpace dimensions; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/Validator.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/Validator.java new file mode 100644 index 00000000000..285d09966de --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/Validator.java @@ -0,0 +1,55 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl; + +import java.nio.BufferOverflowException; +import java.nio.BufferUnderflowException; +import org.tensorflow.ndarray.NdArray; +import org.tensorflow.ndarray.buffer.DataBuffer; + +public class Validator { + + public static void copyToNdArrayArgs(NdArray ndArray, NdArray otherNdArray) { + if (!ndArray.shape().equals(otherNdArray.shape())) { + throw new IllegalArgumentException("Can only copy to arrays of the same shape (" + + ndArray.shape() + " != " + otherNdArray.shape() + ")"); + } + } + + public static void readToBufferArgs(NdArray ndArray, DataBuffer dst) { + if (dst.size() < ndArray.size()) { + throw new BufferOverflowException(); + } + } + + public static void writeFromBufferArgs(NdArray ndArray, DataBuffer src) { + if (src.size() < ndArray.size()) { + throw new BufferUnderflowException(); + } + } + + private static void copyArrayArgs(int arrayLength, int arrayOffset) { + if (arrayOffset < 0) { + throw new IndexOutOfBoundsException("Offset must be non-negative"); + } + if (arrayOffset > arrayLength) { + throw new IndexOutOfBoundsException("Offset must be no larger than array length"); + } + } + + protected Validator() {} +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/AbstractDataBuffer.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/AbstractDataBuffer.java new file mode 100644 index 00000000000..e5103a2c17a --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/AbstractDataBuffer.java @@ -0,0 +1,182 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.buffer; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import org.tensorflow.ndarray.buffer.DataBuffer; + +public abstract class AbstractDataBuffer implements DataBuffer { + + @Override + public DataBuffer read(T[] dst, int offset, int length) { + Validator.readArgs(this, dst.length, offset, length); + for (int i = 0; i < length; ++i) { + dst[i + offset] = getObject(i); + } + return this; + } + + @Override + public DataBuffer write(T[] src, int offset, int length) { + Validator.writeArgs(this, src.length, offset, length); + for (int i = 0; i < length; ++i) { + setObject(src[i + offset], i); + } + return this; + } + + @Override + public DataBuffer copyTo(DataBuffer dst, long size) { + return slowCopyTo(dst, size); + } + + @Override + public int hashCode() { + // This hash code computation is generic to all types of data buffers and accurate but not optimized + // for performances, it needs to be improved if there is a present use case for such hash codes. + return slowHashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof DataBuffer)) { + return false; + } + return slowEquals((DataBuffer)obj); + } + + @SuppressWarnings("unchecked") + protected > U slowCopyTo(DataBuffer dst, long size) { + Validator.copyToArgs(this, dst, size); + for (long idx = 0L; idx < size; ++idx) { + dst.setObject(getObject(idx), idx); + } + return (U)this; + } + + protected int slowHashCode() { + final int prime = 31; + int result = 1; + + // First check from the first non-null element if we are dealing with a buffer of arrays + long idx = 0L; + for (; idx < size(); ++idx) { + T o = getObject(idx); + if (o != null) { + if (o.getClass().isArray()) { + result = prime * result + arrayHashCode(idx, o.getClass()); // compute hash codes based on array elements + return result; + } + result = prime * result + o.hashCode(); + break; // continue hash code computation without array type check + } + result = prime * result; + } + while (++idx < size()) { + result = prime * result + Objects.hashCode(getObject(idx)); + } + return result; + } + + protected boolean slowEquals(DataBuffer other) { + if (other.size() != size()) { + return false; + } + long idx = 0L; + for (; idx < size(); ++idx) { + Object thisObject = getObject(idx); + if (thisObject != null) { + if (thisObject.getClass().isArray()) { + return arrayEquals(idx, thisObject.getClass(), other); + } + if (!Objects.equals(other.getObject(idx), thisObject)) { + return false; + } + break; // continue equality comparison without array type check + } + if (other.getObject(idx) != null) { + return false; + } + } + while (++idx < size()) { + if (!Objects.equals(other.getObject(idx), getObject(idx))) { + return false; + } + } + return true; + } + + private int arrayHashCode(long startIdx, Class arrayClass) { + ArrayHashCoder hashCoder = ARRAY_HASH_CODERS.getOrDefault(arrayClass, DEFAULT_ARRAY_HASH_CODER); + final int prime = 31; + int result = 1; + for (long idx = startIdx; idx < size(); ++idx) { + result = prime * result + hashCoder.hashCode(this, idx); + } + return result; + } + + private boolean arrayEquals(long startIdx, Class arrayClass, DataBuffer other) { + ArrayComparator comparator = ARRAY_COMPARATORS.getOrDefault(arrayClass, DEFAULT_ARRAY_COMPARATOR); + for (long idx = startIdx; idx < size(); ++idx) { + if (!comparator.equals(this, other, idx)) { + return false; + } + } + return true; + } + + @FunctionalInterface + private static interface ArrayHashCoder { + int hashCode(DataBuffer buffer, long index); + } + private static final Map, ArrayHashCoder> ARRAY_HASH_CODERS = new HashMap<>(); + private static final ArrayHashCoder DEFAULT_ARRAY_HASH_CODER; + + @FunctionalInterface + private static interface ArrayComparator { + boolean equals(DataBuffer buffer, DataBuffer otherBuffer, long index); + } + private static final Map, ArrayComparator> ARRAY_COMPARATORS = new HashMap<>(); + private static final ArrayComparator DEFAULT_ARRAY_COMPARATOR; + + static { + ARRAY_HASH_CODERS.put(byte[].class, (b, idx) -> Arrays.hashCode((byte[])b.getObject(idx))); + ARRAY_HASH_CODERS.put(int[].class, (b, idx) -> Arrays.hashCode((int[])b.getObject(idx))); + ARRAY_HASH_CODERS.put(short[].class, (b, idx) -> Arrays.hashCode((short[])b.getObject(idx))); + ARRAY_HASH_CODERS.put(long[].class, (b, idx) -> Arrays.hashCode((long[])b.getObject(idx))); + ARRAY_HASH_CODERS.put(float[].class, (b, idx) -> Arrays.hashCode((float[])b.getObject(idx))); + ARRAY_HASH_CODERS.put(double[].class, (b, idx) -> Arrays.hashCode((double[])b.getObject(idx))); + ARRAY_HASH_CODERS.put(boolean[].class, (b, idx) -> Arrays.hashCode((boolean[])b.getObject(idx))); + DEFAULT_ARRAY_HASH_CODER = (b, idx) -> Arrays.deepHashCode((Object[])b.getObject(idx)); + + ARRAY_COMPARATORS.put(byte[].class, (b1, b2, idx) -> Arrays.equals((byte[])b1.getObject(idx), (byte[])b2.getObject(idx))); + ARRAY_COMPARATORS.put(int[].class, (b1, b2, idx) -> Arrays.equals((int[])b1.getObject(idx), (int[])b2.getObject(idx))); + ARRAY_COMPARATORS.put(short[].class, (b1, b2, idx) -> Arrays.equals((short[])b1.getObject(idx), (short[])b2.getObject(idx))); + ARRAY_COMPARATORS.put(long[].class, (b1, b2, idx) -> Arrays.equals((long[])b1.getObject(idx), (long[])b2.getObject(idx))); + ARRAY_COMPARATORS.put(float[].class, (b1, b2, idx) -> Arrays.equals((float[])b1.getObject(idx), (float[])b2.getObject(idx))); + ARRAY_COMPARATORS.put(double[].class, (b1, b2, idx) -> Arrays.equals((double[])b1.getObject(idx), (double[])b2.getObject(idx))); + ARRAY_COMPARATORS.put(boolean[].class, (b1, b2, idx) -> Arrays.equals((boolean[])b1.getObject(idx), (boolean[])b2.getObject(idx))); + DEFAULT_ARRAY_COMPARATOR = (b1, b2, idx) -> Arrays.deepEquals((Object[])b1.getObject(idx), (Object[])b2.getObject(idx)); + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/AbstractDataBufferWindow.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/AbstractDataBufferWindow.java new file mode 100644 index 00000000000..55d4fd56021 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/AbstractDataBufferWindow.java @@ -0,0 +1,48 @@ +package org.tensorflow.ndarray.impl.buffer; + +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DataBufferWindow; + +public abstract class AbstractDataBufferWindow> implements DataBufferWindow { + + @Override + public final long offset() { + return offset; + } + + @Override + public final long size() { + return windowBuffer.size(); + } + + @Override + public final DataBufferWindow slideTo(long index) { + if (index < 0 || index > maxOffset) { + throw new IndexOutOfBoundsException(); + } + offset(index); + offset = index; + return this; + } + + @Override + public final DataBufferWindow slide(long step) { + return slideTo(offset + step); + } + + @Override + public final B buffer() { + return windowBuffer; + } + + protected abstract void offset(long offset); + + protected AbstractDataBufferWindow(B windowBuffer, long bufferLimit) { + this.windowBuffer = windowBuffer; + maxOffset = bufferLimit - windowBuffer.size(); + } + + private final B windowBuffer; + private final long maxOffset; + private long offset = 0; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/Validator.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/Validator.java new file mode 100644 index 00000000000..8f18e620b90 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/Validator.java @@ -0,0 +1,132 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.buffer; + +import java.nio.BufferOverflowException; +import java.nio.BufferUnderflowException; +import java.nio.ReadOnlyBufferException; +import org.tensorflow.ndarray.buffer.DataBuffer; + +public class Validator { + + public static void createArgs(long size, long maxSize) { + if (size < 0) { + throw new IllegalArgumentException("Size must be non-negative"); + } + if (size > maxSize) { + throw new IllegalArgumentException("Buffer size must be no greater than maximum size allowed (" + maxSize + ")"); + } + } + + public static void getArgs(DataBuffer buffer, long index) { + if (index < 0) { + throw new IndexOutOfBoundsException("Index must be non-negative"); + } + if (index >= buffer.size()) { + throw new IndexOutOfBoundsException("Index must be smaller than the buffer size"); + } + } + + public static void setArgs(DataBuffer buffer, long index) { + if (index < 0) { + throw new IndexOutOfBoundsException("Index must be non-negative"); + } + if (index >= buffer.size()) { + throw new IndexOutOfBoundsException("Index must be smaller than the buffer size"); + } + if (buffer.isReadOnly()) { + throw new ReadOnlyBufferException(); + } + } + + public static void copyToArgs(DataBuffer src, DataBuffer dst, long size) { + if (dst == src) { + throw new IllegalArgumentException("Source cannot be the same buffer as destination"); + } + if (size > dst.size()) { + throw new BufferOverflowException(); + } + if (size > src.size()) { + throw new BufferUnderflowException(); + } + if (dst.isReadOnly()) { + throw new ReadOnlyBufferException(); + } + } + + public static void readArgs(DataBuffer buffer, int arrayLength, int offset, int length) { + if (length > buffer.size()) { + throw new BufferUnderflowException(); + } + arrayArgs(arrayLength, offset, length); + } + + public static void writeArgs(DataBuffer buffer, int arrayLength, int offset, int length) { + if (length > buffer.size()) { + throw new BufferOverflowException(); + } + if (buffer.isReadOnly()) { + throw new ReadOnlyBufferException(); + } + arrayArgs(arrayLength, offset, length); + } + + public static void offsetArgs(DataBuffer buffer, long index) { + if (index < 0) { + throw new IllegalArgumentException("Index must be non-negative"); + } + if (index > buffer.size()) { + throw new IllegalArgumentException("Index must not exceed buffer size"); + } + } + + public static void narrowArgs(DataBuffer buffer, long size) { + if (size < 0) { + throw new IllegalArgumentException("Size must be non-negative"); + } + if (size > buffer.size()) { + throw new IllegalArgumentException("Cannot narrow a buffer of size " + buffer.size() + " to " + size); + } + } + + public static void sliceArgs(DataBuffer buffer, long index, long size) { + if (index < 0) { + throw new IllegalArgumentException("Index must be non-negative"); + } + if (size < 0) { + throw new IllegalArgumentException("Size must be non-negative"); + } + if (index + size > buffer.size()) { + throw new IllegalArgumentException("Buffer view must not exceed original buffer limits"); + } + } + + private static void arrayArgs(int arrayLength, int offset, int length) { + if (offset < 0) { + throw new IndexOutOfBoundsException("Offset must be non-negative"); + } + if (offset > arrayLength) { + throw new IndexOutOfBoundsException("Offset must be no larger than array length"); + } + if (length < 0) { + throw new IndexOutOfBoundsException("Length must be non-negative"); + } + if (length > arrayLength - offset) { + throw new IndexOutOfBoundsException("Length must be no larger than array length minus the offset"); + } + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/AbstractDataBufferAdapter.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/AbstractDataBufferAdapter.java new file mode 100644 index 00000000000..3c9b6df1e93 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/AbstractDataBufferAdapter.java @@ -0,0 +1,68 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.adapter; + +import org.tensorflow.ndarray.impl.buffer.Validator; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.impl.buffer.AbstractDataBuffer; +import org.tensorflow.ndarray.buffer.layout.DataLayout; + +@SuppressWarnings("unchecked") +abstract class AbstractDataBufferAdapter, T, U extends DataBuffer> extends AbstractDataBuffer { + + @Override + public long size() { + return size; + } + + @Override + public boolean isReadOnly() { + return buffer.isReadOnly(); + } + + @Override + public T getObject(long index) { + Validator.getArgs(this, index); + return layout.readObject(buffer, index * layout.scale()); + } + + @Override + public U setObject(T value, long index) { + Validator.setArgs(this, index); + layout.writeObject(buffer, value, index * layout.scale()); + return (U)this; + } + + AbstractDataBufferAdapter(S buffer, DataLayout layout) { + this.buffer = buffer; + this.layout = layout; + size = buffer.size() / layout.scale(); + } + + DataLayout layout() { + return layout; + } + + S buffer() { + return buffer; + } + + private final S buffer; + private final DataLayout layout; + private final long size; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/BooleanDataBufferAdapter.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/BooleanDataBufferAdapter.java new file mode 100644 index 00000000000..40217b57d6a --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/BooleanDataBufferAdapter.java @@ -0,0 +1,116 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.adapter; + +import org.tensorflow.ndarray.impl.buffer.Validator; +import org.tensorflow.ndarray.buffer.BooleanDataBuffer; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.layout.BooleanDataLayout; + +class BooleanDataBufferAdapter> extends AbstractDataBufferAdapter + implements BooleanDataBuffer { + + @Override + public boolean getBoolean(long index) { + Validator.getArgs(this, index); + return layout.readBoolean(buffer(), index * layout.scale()); + } + + @Override + public BooleanDataBuffer setBoolean(boolean value, long index) { + Validator.setArgs(this, index); + layout.writeBoolean(buffer(), value, index * layout.scale()); + return this; + } + + @Override + public BooleanDataBuffer read(boolean[] dst, int offset, int length) { + Validator.readArgs(this, dst.length, offset, length); + for (int i = 0, j = offset; i < length; ++i, ++j) { + dst[j] = layout.readBoolean(buffer(), i * layout.scale()); + } + return this; + } + + @Override + public BooleanDataBuffer write(boolean[] src, int offset, int length) { + Validator.writeArgs(this, src.length, offset, length); + for (int i = 0, j = offset; i < length; ++i, ++j) { + layout.writeBoolean(buffer(), src[j], i * layout.scale()); + } + return this; + } + + @Override + public BooleanDataBuffer copyTo(DataBuffer dst, long size) { + Validator.copyToArgs(this, dst, size); + if (dst instanceof BooleanDataBuffer) { + BooleanDataBuffer booleanDst = (BooleanDataBuffer)dst; + for (long idx = 0L; idx < size; ++idx) { + booleanDst.setBoolean(getBoolean(idx), idx); + } + return this; + } + return slowCopyTo(dst, size); + } + + @Override + @SuppressWarnings("unchecked") + public BooleanDataBuffer offset(long index) { + return new BooleanDataBufferAdapter<>((S)buffer().offset(index * layout.scale()), layout); + } + + @Override + @SuppressWarnings("unchecked") + public BooleanDataBuffer narrow(long size) { + return new BooleanDataBufferAdapter<>((S)buffer().narrow(size * layout.scale()), layout); + } + + @Override + @SuppressWarnings("unchecked") + public BooleanDataBuffer slice(long index, long size) { + return new BooleanDataBufferAdapter<>((S)buffer().slice(index * layout.scale(), size * layout.scale()), layout); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof BooleanDataBuffer)) { + return super.equals(obj); + } + BooleanDataBuffer other = (BooleanDataBuffer)obj; + if (other.size() != size()) { + return false; + } + for (long idx = 0L; idx < size(); ++idx) { + if (other.getBoolean(idx) != getBoolean(idx)) { + return false; + } + } + return true; + } + + BooleanDataBufferAdapter(S buffer, BooleanDataLayout layout) { + super(buffer, layout); + this.layout = layout; + } + + private BooleanDataLayout layout; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/ByteDataBufferAdapter.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/ByteDataBufferAdapter.java new file mode 100644 index 00000000000..c120a3ba810 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/ByteDataBufferAdapter.java @@ -0,0 +1,135 @@ +package org.tensorflow.ndarray.impl.buffer.adapter; + +import org.tensorflow.ndarray.impl.buffer.Validator; +import org.tensorflow.ndarray.buffer.BooleanDataBuffer; +import org.tensorflow.ndarray.buffer.ByteDataBuffer; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DoubleDataBuffer; +import org.tensorflow.ndarray.buffer.FloatDataBuffer; +import org.tensorflow.ndarray.buffer.IntDataBuffer; +import org.tensorflow.ndarray.buffer.LongDataBuffer; +import org.tensorflow.ndarray.buffer.ShortDataBuffer; +import org.tensorflow.ndarray.buffer.layout.ByteDataLayout; + +class ByteDataBufferAdapter> extends AbstractDataBufferAdapter + implements ByteDataBuffer { + + @Override + public byte getByte(long index) { + Validator.getArgs(this, index); + return layout.readByte(buffer(), index * layout.scale()); + } + + @Override + public ByteDataBuffer setByte(byte value, long index) { + Validator.setArgs(this, index); + layout.writeByte(buffer(), value, index * layout.scale()); + return this; + } + + @Override + public ByteDataBuffer read(byte[] dst, int offset, int length) { + Validator.readArgs(this, dst.length, offset, length); + for (int i = 0, j = offset; i < length; ++i, ++j) { + dst[j] = layout.readByte(buffer(), i * layout.scale()); + } + return this; + } + + @Override + public ByteDataBuffer write(byte[] src, int offset, int length) { + Validator.writeArgs(this, src.length, offset, length); + for (int i = 0, j = offset; i < length; ++i, ++j) { + layout.writeByte(buffer(), src[j], i * layout.scale()); + } + return this; + } + + @Override + public ByteDataBuffer copyTo(DataBuffer dst, long size) { + Validator.copyToArgs(this, dst, size); + if (dst instanceof ByteDataBuffer) { + ByteDataBuffer byteDst = (ByteDataBuffer)dst; + for (long idx = 0L; idx < size; ++idx) { + byteDst.setByte(getByte(idx), idx); + } + return this; + } + return slowCopyTo(dst, size); + } + + @Override + public IntDataBuffer asInts() { + throw new IllegalStateException("Byte buffers with layout cannot be converted"); + } + + @Override + public ShortDataBuffer asShorts() { + throw new IllegalStateException("Byte buffers with layout cannot be converted"); + } + + @Override + public LongDataBuffer asLongs() { + throw new IllegalStateException("Byte buffers with layout cannot be converted"); + } + + @Override + public FloatDataBuffer asFloats() { + throw new IllegalStateException("Byte buffers with layout cannot be converted"); + } + + @Override + public DoubleDataBuffer asDoubles() { + throw new IllegalStateException("Byte buffers with layout cannot be converted"); + } + + @Override + public BooleanDataBuffer asBooleans() { + throw new IllegalStateException("Byte buffers with layout cannot be converted"); + } + + @Override + @SuppressWarnings("unchecked") + public ByteDataBuffer offset(long index) { + return new ByteDataBufferAdapter<>((S)buffer().offset(index * layout.scale()), layout); + } + + @Override + @SuppressWarnings("unchecked") + public ByteDataBuffer narrow(long size) { + return new ByteDataBufferAdapter<>((S)buffer().narrow(size * layout.scale()), layout); + } + + @Override + @SuppressWarnings("unchecked") + public ByteDataBuffer slice(long index, long size) { + return new ByteDataBufferAdapter<>((S)buffer().slice(index * layout.scale(), size * layout.scale()), layout); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof ByteDataBuffer)) { + return super.equals(obj); + } + ByteDataBuffer other = (ByteDataBuffer)obj; + if (other.size() != size()) { + return false; + } + for (long idx = 0L; idx < size(); ++idx) { + if (other.getByte(idx) != getByte(idx)) { + return false; + } + } + return true; + } + + ByteDataBufferAdapter(S buffer, ByteDataLayout layout) { + super(buffer, layout); + this.layout = layout; + } + + private ByteDataLayout layout; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/DataBufferAdapter.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/DataBufferAdapter.java new file mode 100644 index 00000000000..de20ab2cfd7 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/DataBufferAdapter.java @@ -0,0 +1,47 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.adapter; + +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.layout.DataLayout; + +@SuppressWarnings("unchecked") +class DataBufferAdapter, T> extends AbstractDataBufferAdapter> { + + @Override + @SuppressWarnings("unchecked") + public DataBuffer offset(long index) { + return new DataBufferAdapter<>((S)buffer().offset(index * layout().scale()), layout()); + } + + @Override + @SuppressWarnings("unchecked") + public DataBuffer narrow(long size) { + return new DataBufferAdapter<>((S)buffer().narrow(size * layout().scale()), layout()); + } + + @Override + @SuppressWarnings("unchecked") + public DataBuffer slice(long index, long size) { + return new DataBufferAdapter<>((S)buffer().slice(index * layout().scale(), size * layout().scale()), layout()); + } + + DataBufferAdapter(S buffer, DataLayout layout) { + super(buffer, layout); + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/DataBufferAdapterFactory.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/DataBufferAdapterFactory.java new file mode 100644 index 00000000000..468051e1b46 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/DataBufferAdapterFactory.java @@ -0,0 +1,142 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.adapter; + +import org.tensorflow.ndarray.buffer.BooleanDataBuffer; +import org.tensorflow.ndarray.buffer.ByteDataBuffer; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DoubleDataBuffer; +import org.tensorflow.ndarray.buffer.FloatDataBuffer; +import org.tensorflow.ndarray.buffer.IntDataBuffer; +import org.tensorflow.ndarray.buffer.LongDataBuffer; +import org.tensorflow.ndarray.buffer.ShortDataBuffer; +import org.tensorflow.ndarray.buffer.layout.BooleanDataLayout; +import org.tensorflow.ndarray.buffer.layout.ByteDataLayout; +import org.tensorflow.ndarray.buffer.layout.DataLayout; +import org.tensorflow.ndarray.buffer.layout.DoubleDataLayout; +import org.tensorflow.ndarray.buffer.layout.FloatDataLayout; +import org.tensorflow.ndarray.buffer.layout.IntDataLayout; +import org.tensorflow.ndarray.buffer.layout.LongDataLayout; +import org.tensorflow.ndarray.buffer.layout.ShortDataLayout; + +/** + * Factory of data buffer adapters. + * + *

Data buffer adapters are used to apply a {@link DataLayout} to a buffer. Conceptually, they act + * as a proxy that intercept each I/O call and perform the required type conversions after/before + * delegating the task to the underlying buffer. + */ +public class DataBufferAdapterFactory { + + /** + * Creates an adapter that applies a byte data layout to the given buffer. + * + * @param buffer the delegate buffer + * @param layout layout to apply + * @param the type of the buffer + * @return buffer adapter + */ + public static > ByteDataBuffer create(S buffer, ByteDataLayout layout) { + return new ByteDataBufferAdapter<>(buffer, layout); + } + + /** + * Creates an adapter that applies a boolean data layout to the given buffer. + * + * @param buffer the delegate buffer + * @param layout layout to apply + * @param the type of the buffer + * @return buffer adapter + */ + public static > BooleanDataBuffer create(S buffer, BooleanDataLayout layout) { + return new BooleanDataBufferAdapter<>(buffer, layout); + } + + /** + * Creates an adapter that applies a double data layout to the given buffer. + * + * @param buffer the delegate buffer + * @param layout layout to apply + * @param the type of the buffer + * @return buffer adapter + */ + public static > DoubleDataBuffer create(S buffer, DoubleDataLayout layout) { + return new DoubleDataBufferAdapter<>(buffer, layout); + } + + /** + * Creates an adapter that applies a float data layout to the given buffer. + * + * @param buffer the delegate buffer + * @param layout layout to apply + * @param the type of the buffer + * @return buffer adapter + */ + public static > FloatDataBuffer create(S buffer, FloatDataLayout layout) { + return new FloatDataBufferAdapter<>(buffer, layout); + } + + /** + * Creates an adapter that applies a integer data layout to the given buffer. + * + * @param buffer the delegate buffer + * @param layout layout to apply + * @param the type of the buffer + * @return buffer adapter + */ + public static > IntDataBuffer create(S buffer, IntDataLayout layout) { + return new IntDataBufferAdapter<>(buffer, layout); + } + + /** + * Creates an adapter that applies a long data layout to the given buffer. + * + * @param buffer the delegate buffer + * @param layout layout to apply + * @param the type of the buffer + * @return buffer adapter + */ + public static > LongDataBuffer create(S buffer, LongDataLayout layout) { + return new LongDataBufferAdapter<>(buffer, layout); + } + + /** + * Creates an adapter that applies a short data layout to the given buffer. + * + * @param buffer the delegate buffer + * @param layout layout to apply + * @param the type of the buffer + * @return buffer adapter + */ + public static > ShortDataBuffer create(S buffer, ShortDataLayout layout) { + return new ShortDataBufferAdapter<>(buffer, layout); + } + + /** + * Creates an adapter that applies a data layout to the given buffer. + * + * @param buffer the delegate buffer + * @param layout layout to apply + * @param the type of the buffer + * @param the type of data returned by the layout + * @return buffer adapter + */ + public static , T> DataBuffer create(S buffer, DataLayout layout) { + return new DataBufferAdapter<>(buffer, layout); + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/DoubleDataBufferAdapter.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/DoubleDataBufferAdapter.java new file mode 100644 index 00000000000..253acbac269 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/DoubleDataBufferAdapter.java @@ -0,0 +1,116 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.adapter; + +import org.tensorflow.ndarray.impl.buffer.Validator; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DoubleDataBuffer; +import org.tensorflow.ndarray.buffer.layout.DoubleDataLayout; + +class DoubleDataBufferAdapter> extends AbstractDataBufferAdapter + implements DoubleDataBuffer { + + @Override + public double getDouble(long index) { + Validator.getArgs(this, index); + return layout.readDouble(buffer(), index * layout.scale()); + } + + @Override + public DoubleDataBuffer setDouble(double value, long index) { + Validator.setArgs(this, index); + layout.writeDouble(buffer(), value, index * layout.scale()); + return this; + } + + @Override + public DoubleDataBuffer read(double[] dst, int offset, int length) { + Validator.readArgs(this, dst.length, offset, length); + for (int i = 0, j = offset; i < length; ++i, ++j) { + dst[j] = layout.readDouble(buffer(), i * layout.scale()); + } + return this; + } + + @Override + public DoubleDataBuffer write(double[] src, int offset, int length) { + Validator.writeArgs(this, src.length, offset, length); + for (int i = 0, j = offset; i < length; ++i, ++j) { + layout.writeDouble(buffer(), src[j], i * layout.scale()); + } + return this; + } + + @Override + public DoubleDataBuffer copyTo(DataBuffer dst, long size) { + Validator.copyToArgs(this, dst, size); + if (dst instanceof DoubleDataBuffer) { + DoubleDataBuffer doubleDst = (DoubleDataBuffer)dst; + for (long idx = 0L; idx < size; ++idx) { + doubleDst.setDouble(getDouble(idx), idx); + } + return this; + } + return slowCopyTo(dst, size); + } + + @Override + @SuppressWarnings("unchecked") + public DoubleDataBuffer offset(long index) { + return new DoubleDataBufferAdapter<>((S)buffer().offset(index * layout.scale()), layout); + } + + @Override + @SuppressWarnings("unchecked") + public DoubleDataBuffer narrow(long size) { + return new DoubleDataBufferAdapter<>((S)buffer().narrow(size * layout.scale()), layout); + } + + @Override + @SuppressWarnings("unchecked") + public DoubleDataBuffer slice(long index, long size) { + return new DoubleDataBufferAdapter<>((S)buffer().slice(index * layout.scale(), size * layout.scale()), layout); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof DoubleDataBuffer)) { + return super.equals(obj); + } + DoubleDataBuffer other = (DoubleDataBuffer)obj; + if (other.size() != size()) { + return false; + } + for (long idx = 0L; idx < size(); ++idx) { + if (other.getDouble(idx) != getDouble(idx)) { + return false; + } + } + return true; + } + + DoubleDataBufferAdapter(S buffer, DoubleDataLayout layout) { + super(buffer, layout); + this.layout = layout; + } + + private DoubleDataLayout layout; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/FloatDataBufferAdapter.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/FloatDataBufferAdapter.java new file mode 100644 index 00000000000..69928bf0ccb --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/FloatDataBufferAdapter.java @@ -0,0 +1,116 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.adapter; + +import org.tensorflow.ndarray.impl.buffer.Validator; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.FloatDataBuffer; +import org.tensorflow.ndarray.buffer.layout.FloatDataLayout; + +class FloatDataBufferAdapter> extends AbstractDataBufferAdapter + implements FloatDataBuffer { + + @Override + public float getFloat(long index) { + Validator.getArgs(this, index); + return layout.readFloat(buffer(), index * layout.scale()); + } + + @Override + public FloatDataBuffer setFloat(float value, long index) { + Validator.setArgs(this, index); + layout.writeFloat(buffer(), value, index * layout.scale()); + return this; + } + + @Override + public FloatDataBuffer read(float[] dst, int offset, int length) { + Validator.readArgs(this, dst.length, offset, length); + for (int i = 0, j = offset; i < length; ++i, ++j) { + dst[j] = layout.readFloat(buffer(), i * layout.scale()); + } + return this; + } + + @Override + public FloatDataBuffer write(float[] src, int offset, int length) { + Validator.writeArgs(this, src.length, offset, length); + for (int i = 0, j = offset; i < length; ++i, ++j) { + layout.writeFloat(buffer(), src[j], i * layout.scale()); + } + return this; + } + + @Override + public FloatDataBuffer copyTo(DataBuffer dst, long size) { + Validator.copyToArgs(this, dst, size); + if (dst instanceof FloatDataBuffer) { + FloatDataBuffer floatDst = (FloatDataBuffer)dst; + for (long idx = 0L; idx < size; ++idx) { + floatDst.setFloat(getFloat(idx), idx); + } + return this; + } + return slowCopyTo(dst, size); + } + + @Override + @SuppressWarnings("unchecked") + public FloatDataBuffer offset(long index) { + return new FloatDataBufferAdapter<>((S)buffer().offset(index * layout.scale()), layout); + } + + @Override + @SuppressWarnings("unchecked") + public FloatDataBuffer narrow(long size) { + return new FloatDataBufferAdapter<>((S)buffer().narrow(size * layout.scale()), layout); + } + + @Override + @SuppressWarnings("unchecked") + public FloatDataBuffer slice(long index, long size) { + return new FloatDataBufferAdapter<>((S)buffer().slice(index * layout.scale(), size * layout.scale()), layout); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof FloatDataBuffer)) { + return super.equals(obj); + } + FloatDataBuffer other = (FloatDataBuffer)obj; + if (other.size() != size()) { + return false; + } + for (long idx = 0L; idx < size(); ++idx) { + if (other.getFloat(idx) != getFloat(idx)) { + return false; + } + } + return true; + } + + FloatDataBufferAdapter(S buffer, FloatDataLayout layout) { + super(buffer, layout); + this.layout = layout; + } + + private FloatDataLayout layout; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/IntDataBufferAdapter.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/IntDataBufferAdapter.java new file mode 100644 index 00000000000..052b63fe0f3 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/IntDataBufferAdapter.java @@ -0,0 +1,116 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.adapter; + +import org.tensorflow.ndarray.impl.buffer.Validator; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.IntDataBuffer; +import org.tensorflow.ndarray.buffer.layout.IntDataLayout; + +class IntDataBufferAdapter> extends AbstractDataBufferAdapter + implements IntDataBuffer { + + @Override + public int getInt(long index) { + Validator.getArgs(this, index); + return layout.readInt(buffer(), index * layout.scale()); + } + + @Override + public IntDataBuffer setInt(int value, long index) { + Validator.setArgs(this, index); + layout.writeInt(buffer(), value, index * layout.scale()); + return this; + } + + @Override + public IntDataBuffer read(int[] dst, int offset, int length) { + Validator.readArgs(this, dst.length, offset, length); + for (int i = 0, j = offset; i < length; ++i, ++j) { + dst[j] = layout.readInt(buffer(), i * layout.scale()); + } + return this; + } + + @Override + public IntDataBuffer write(int[] src, int offset, int length) { + Validator.writeArgs(this, src.length, offset, length); + for (int i = 0, j = offset; i < length; ++i, ++j) { + layout.writeInt(buffer(), src[j], i * layout.scale()); + } + return this; + } + + @Override + public IntDataBuffer copyTo(DataBuffer dst, long size) { + Validator.copyToArgs(this, dst, size); + if (dst instanceof IntDataBuffer) { + IntDataBuffer intDst = (IntDataBuffer)dst; + for (long idx = 0L; idx < size; ++idx) { + intDst.setInt(getInt(idx), idx); + } + return this; + } + return slowCopyTo(dst, size); + } + + @Override + @SuppressWarnings("unchecked") + public IntDataBuffer offset(long index) { + return new IntDataBufferAdapter<>((S)buffer().offset(index * layout.scale()), layout); + } + + @Override + @SuppressWarnings("unchecked") + public IntDataBuffer narrow(long size) { + return new IntDataBufferAdapter<>((S)buffer().narrow(size * layout.scale()), layout); + } + + @Override + @SuppressWarnings("unchecked") + public IntDataBuffer slice(long index, long size) { + return new IntDataBufferAdapter<>((S)buffer().slice(index * layout.scale(), size * layout.scale()), layout); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof IntDataBuffer)) { + return super.equals(obj); + } + IntDataBuffer other = (IntDataBuffer)obj; + if (other.size() != size()) { + return false; + } + for (long idx = 0L; idx < size(); ++idx) { + if (other.getInt(idx) != getInt(idx)) { + return false; + } + } + return true; + } + + IntDataBufferAdapter(S buffer, IntDataLayout layout) { + super(buffer, layout); + this.layout = layout; + } + + private IntDataLayout layout; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/LongDataBufferAdapter.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/LongDataBufferAdapter.java new file mode 100644 index 00000000000..aea154d4b9f --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/LongDataBufferAdapter.java @@ -0,0 +1,116 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.adapter; + +import org.tensorflow.ndarray.impl.buffer.Validator; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.LongDataBuffer; +import org.tensorflow.ndarray.buffer.layout.LongDataLayout; + +class LongDataBufferAdapter> extends AbstractDataBufferAdapter + implements LongDataBuffer { + + @Override + public long getLong(long index) { + Validator.getArgs(this, index); + return layout.readLong(buffer(), index * layout.scale()); + } + + @Override + public LongDataBuffer setLong(long value, long index) { + Validator.setArgs(this, index); + layout.writeLong(buffer(), value, index * layout.scale()); + return this; + } + + @Override + public LongDataBuffer read(long[] dst, int offset, int length) { + Validator.readArgs(this, dst.length, offset, length); + for (int i = 0, j = offset; i < length; ++i, ++j) { + dst[j] = layout.readLong(buffer(), i * layout.scale()); + } + return this; + } + + @Override + public LongDataBuffer write(long[] src, int offset, int length) { + Validator.writeArgs(this, src.length, offset, length); + for (int i = 0, j = offset; i < length; ++i, ++j) { + layout.writeLong(buffer(), src[j], i * layout.scale()); + } + return this; + } + + @Override + public LongDataBuffer copyTo(DataBuffer dst, long size) { + Validator.copyToArgs(this, dst, size); + if (dst instanceof LongDataBuffer) { + LongDataBuffer longDst = (LongDataBuffer)dst; + for (long idx = 0L; idx < size; ++idx) { + longDst.setLong(getLong(idx), idx); + } + return this; + } + return slowCopyTo(dst, size); + } + + @Override + @SuppressWarnings("unchecked") + public LongDataBuffer offset(long index) { + return new LongDataBufferAdapter<>((S)buffer().offset(index * layout.scale()), layout); + } + + @Override + @SuppressWarnings("unchecked") + public LongDataBuffer narrow(long size) { + return new LongDataBufferAdapter<>((S)buffer().narrow(size * layout.scale()), layout); + } + + @Override + @SuppressWarnings("unchecked") + public LongDataBuffer slice(long index, long size) { + return new LongDataBufferAdapter<>((S)buffer().slice(index * layout.scale(), size * layout.scale()), layout); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof LongDataBuffer)) { + return super.equals(obj); + } + LongDataBuffer other = (LongDataBuffer)obj; + if (other.size() != size()) { + return false; + } + for (long idx = 0L; idx < size(); ++idx) { + if (other.getLong(idx) != getLong(idx)) { + return false; + } + } + return true; + } + + LongDataBufferAdapter(S buffer, LongDataLayout layout) { + super(buffer, layout); + this.layout = layout; + } + + private LongDataLayout layout; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/ShortDataBufferAdapter.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/ShortDataBufferAdapter.java new file mode 100644 index 00000000000..6b6b1bb24b7 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/adapter/ShortDataBufferAdapter.java @@ -0,0 +1,116 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.adapter; + +import org.tensorflow.ndarray.impl.buffer.Validator; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.ShortDataBuffer; +import org.tensorflow.ndarray.buffer.layout.ShortDataLayout; + +class ShortDataBufferAdapter> extends AbstractDataBufferAdapter + implements ShortDataBuffer { + + @Override + public short getShort(long index) { + Validator.getArgs(this, index); + return layout.readShort(buffer(), index * layout.scale()); + } + + @Override + public ShortDataBuffer setShort(short value, long index) { + Validator.setArgs(this, index); + layout.writeShort(buffer(), value, index * layout.scale()); + return this; + } + + @Override + public ShortDataBuffer read(short[] dst, int offset, int length) { + Validator.readArgs(this, dst.length, offset, length); + for (int i = 0, j = offset; i < length; ++i, ++j) { + dst[j] = layout.readShort(buffer(), i * layout.scale()); + } + return this; + } + + @Override + public ShortDataBuffer write(short[] src, int offset, int length) { + Validator.writeArgs(this, src.length, offset, length); + for (int i = 0, j = offset; i < length; ++i, ++j) { + layout.writeShort(buffer(), src[j], i * layout.scale()); + } + return this; + } + + @Override + public ShortDataBuffer copyTo(DataBuffer dst, long size) { + Validator.copyToArgs(this, dst, size); + if (dst instanceof ShortDataBuffer) { + ShortDataBuffer shortDst = (ShortDataBuffer)dst; + for (long idx = 0L; idx < size; ++idx) { + shortDst.setShort(getShort(idx), idx); + } + return this; + } + return slowCopyTo(dst, size); + } + + @Override + @SuppressWarnings("unchecked") + public ShortDataBuffer offset(long index) { + return new ShortDataBufferAdapter<>((S)buffer().offset(index * layout.scale()), layout); + } + + @Override + @SuppressWarnings("unchecked") + public ShortDataBuffer narrow(long size) { + return new ShortDataBufferAdapter<>((S)buffer().narrow(size * layout.scale()), layout); + } + + @Override + @SuppressWarnings("unchecked") + public ShortDataBuffer slice(long index, long size) { + return new ShortDataBufferAdapter<>((S)buffer().slice(index * layout.scale(), size * layout.scale()), layout); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof ShortDataBuffer)) { + return super.equals(obj); + } + ShortDataBuffer other = (ShortDataBuffer)obj; + if (other.size() != size()) { + return false; + } + for (long idx = 0L; idx < size(); ++idx) { + if (other.getShort(idx) != getShort(idx)) { + return false; + } + } + return true; + } + + ShortDataBufferAdapter(S buffer, ShortDataLayout layout) { + super(buffer, layout); + this.layout = layout; + } + + private ShortDataLayout layout; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/layout/Bfloat16Layout.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/layout/Bfloat16Layout.java new file mode 100644 index 00000000000..3f8171088cb --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/layout/Bfloat16Layout.java @@ -0,0 +1,54 @@ +/* + * Copyright 2020 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.layout; + +import org.tensorflow.ndarray.buffer.ShortDataBuffer; +import org.tensorflow.ndarray.buffer.layout.FloatDataLayout; + +/** + * Data layout that converts 32-bit floats from/to 16-bit, truncating their mantissa to 7 bits but + * preserving the 8-bit exponent with the same bias. + */ +public final class Bfloat16Layout implements FloatDataLayout { + + @Override + public void writeFloat(ShortDataBuffer buffer, float value, long index) { + buffer.setShort(float32to16(value), index); + } + + @Override + public float readFloat(ShortDataBuffer buffer, long index) { + return float16to32(buffer.getShort(index)); + } + + // + // FLOAT 32-bit to/from BFLOAT 16-bit conversions + // + // We simply shift the value from 32-bit to 16-bit and vice-versa. NaN special case is ignored. + // + + // VisibleForTesting + static short float32to16(float f32) { + return (short)(Float.floatToIntBits(f32) >>> 16); + } + + // Visible for testing + static float float16to32(short i16) { + return Float.intBitsToFloat((int)i16 << 16); + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/layout/BoolLayout.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/layout/BoolLayout.java new file mode 100644 index 00000000000..0358d60d662 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/layout/BoolLayout.java @@ -0,0 +1,47 @@ +/* + * Copyright 2020 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.layout; + +import org.tensorflow.ndarray.buffer.ByteDataBuffer; +import org.tensorflow.ndarray.buffer.layout.BooleanDataLayout; + +/** + * Data layout that converts booleans from/to bytes. + */ +public final class BoolLayout implements BooleanDataLayout { + + @Override + public void writeBoolean(ByteDataBuffer buffer, boolean value, long index) { + buffer.setByte(booleanToByte(value), index); + } + + @Override + public boolean readBoolean(ByteDataBuffer buffer, long index) { + return byteToBoolean(buffer.getByte(index)); + } + + // Visible for testing + static byte booleanToByte(boolean b) { + return (byte)(b ? 0x1 : 0x0); + } + + // Visible for testing + static boolean byteToBoolean(byte b) { + return b != 0x0; + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/layout/Float16Layout.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/layout/Float16Layout.java new file mode 100644 index 00000000000..b19744bbd13 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/layout/Float16Layout.java @@ -0,0 +1,119 @@ +/* + * Copyright 2020 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.layout; + +import org.tensorflow.ndarray.buffer.ShortDataBuffer; +import org.tensorflow.ndarray.buffer.layout.FloatDataLayout; + +/** + * Data layout that converts 32-bit floats from/to 16-bit, accordingly to the IEEE-754 half-precision + * floating point specification. + */ +public final class Float16Layout implements FloatDataLayout { + + @Override + public void writeFloat(ShortDataBuffer buffer, float value, long index) { + buffer.setShort(float32to16(value), index); + } + + @Override + public float readFloat(ShortDataBuffer buffer, long index) { + return float16to32(buffer.getShort(index)); + } + + // + // FLOAT 32-bit to/from 16-bit conversions + // + // The following conversion algorithms are issued from the C++ implementation found in the + // Eigen library used by TensorFlow native library. + // See https://eigen.tuxfamily.org/dox-devel/Half_8h_source.html for more details. + // + + // VisibleForTesting + static short float32to16(float f32) { + int i16; + int i32 = Float.floatToIntBits(f32); + short sign16 = (short) ((i32 >>> 16) & 0x8000); + i32 &= 0x7FFFFFFF; // remove sign + + if (i32 >= (E32BIAS + E16MAX + 1) << E32SHIFT) { + // float32 value is higher than float16 max value (max16 -> 2^15 * 2 -> 2^16) + // - if float32 value is higher than infinite (i.e. s32 > 0), then it is NaN and should also + // be NaN in float16 (0x7e00) + // - else, float16 value is forced to infinite (0x7c00) + i16 = i32 > E32MASK ? 0x7E00 : 0x7C00; + + } else if (i32 < (E32BIAS + E16MIN) << E32SHIFT){ + // float32 abs value is smaller than float16 min abs value (min16 = 2^-14), could also be 0 + // - apply magic number to align significand 10 bits at the bottom on the float and subtract bias + i16 = Float.floatToIntBits(Float.intBitsToFloat(i32) + MAGIC_32_16_FLOAT) - MAGIC_32_16; + + } else { + // float32 value can be rounded up to a normalized float16 value (i.e. exp32 = [113(-14), 142(15)]) + // - rebase exponent to float16 + // - round up significand to the 13nd bit if s16 is even, on the 12nd bit if it is odd + int round = 0xFFF + ((i32 >>> 13) & 0x1); + i16 = (i32 + ((E16BIAS - E32BIAS) << E32SHIFT) + round) >>> 13; + } + return (short)(i16 | sign16); + } + + // Visible for testing + static float float16to32(short i16) { + int i32 = (i16 & 0x7FFF) << (S32BITS - S16BITS); // remove sign and align in float32 + i32 += (E32BIAS - E16BIAS) << E32SHIFT; // rebase exponent to float32 + + // Handle float16 exponent special cases + switch (i16 & E16MASK) { + case E16MASK: + // float16 value is infinite or NaN + // - adjust float32 exponent one more time + i32 += (E32BIAS - E16BIAS) << E32SHIFT; + break; + case 0x0: + // float16 value is zero or subnormal + // - adjust float32 exponent + // - renormalize using magic number + i32 = Float.floatToIntBits(Float.intBitsToFloat(i32 + (1 << E32SHIFT)) - MAGIC_16_32_FLOAT); + break; + default: + break; + } + return Float.intBitsToFloat(i32 | ((i16 & 0x8000) << 16)); // reapply sign + } + + // float32 format + private static final int E32SHIFT = 23; // position of the exponent in float32 + private static final int E32MASK = 0xFF << E32SHIFT; // mask for float32 exponent (== Infinity) + private static final int E32BIAS = 127; // exponent bias for float32 + private static final int S32BITS = 23; // number of bits in float32 significand + + // float16 format + private static final int E16SHIFT = 10; // position of the exponent in float16 + private static final int E16MASK = 0x1F << E16SHIFT; // mask for float16 exponent (== Infinity) + private static final int E16BIAS = 15; // exponent bias for float16 + private static final int E16MAX = 15; // max value for float16 exponent + private static final int E16MIN = -14; // min value for float16 exponent + private static final int S16BITS = 10; // number of bits in float16 significand + + // magic numbers used when converting denormalized values + private static final int MAGIC_32_16 = ((E32BIAS - E16BIAS) + (S32BITS - S16BITS) + 1) << E32SHIFT; + private static final float MAGIC_32_16_FLOAT = Float.intBitsToFloat(MAGIC_32_16); + private static final int MAGIC_16_32 = (E32BIAS - E16BIAS + 1) << E32SHIFT; + private static final float MAGIC_16_32_FLOAT = Float.intBitsToFloat(MAGIC_16_32); +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/layout/StringLayout.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/layout/StringLayout.java new file mode 100644 index 00000000000..51576c0100b --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/layout/StringLayout.java @@ -0,0 +1,48 @@ +/* + * Copyright 2020 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.layout; + +import java.nio.charset.Charset; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.layout.DataLayout; + +/** + * Data layout that converts a String to/from a sequence of bytes applying a given charset. + */ +public final class StringLayout implements DataLayout, String> { + + public static StringLayout of(Charset charset) { + return new StringLayout(charset); + } + + @Override + public void writeObject(DataBuffer buffer, String value, long index) { + buffer.setObject(value.getBytes(charset), index); + } + + @Override + public String readObject(DataBuffer buffer, long index) { + return new String(buffer.getObject(index), charset); + } + + private StringLayout(Charset charset) { + this.charset = charset; + } + + private final Charset charset; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/misc/ArrayDataBuffer.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/misc/ArrayDataBuffer.java new file mode 100644 index 00000000000..676e291357a --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/misc/ArrayDataBuffer.java @@ -0,0 +1,126 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.buffer.misc; + +import java.util.Arrays; +import org.tensorflow.ndarray.impl.buffer.AbstractDataBuffer; +import org.tensorflow.ndarray.impl.buffer.Validator; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DataStorageVisitor; + +class ArrayDataBuffer extends AbstractDataBuffer { + + @Override + public long size() { + return length; + } + + @Override + public boolean isReadOnly() { + return readOnly; + } + + @Override + public T getObject(long index) { + Validator.getArgs(this, index); + return values[(int)index + offset]; + } + + @Override + public DataBuffer setObject(T value, long index) { + Validator.setArgs(this, index); + values[(int)index + offset] = value; + return this; + } + + @Override + public DataBuffer copyTo(DataBuffer dst, long size) { + Validator.copyToArgs(this, dst, size); + return dst.accept(new DataStorageVisitor>() { + + @Override + public DataBuffer visit(Object[] array, int arrayOffset, int arrayLength) { + System.arraycopy(values, offset, array, arrayOffset, (int)size); + return ArrayDataBuffer.this; + } + + @Override + public DataBuffer fallback() { + for (int idx = 0; idx < size; ++idx) { + dst.setObject(values[idx + offset], idx); + } + return ArrayDataBuffer.this; + } + }); + } + + @Override + public DataBuffer slice(long index, long size) { + Validator.sliceArgs(this, index, size); + return new ArrayDataBuffer<>(values, readOnly, offset + (int)index, (int)size); + } + + @Override + public R accept(DataStorageVisitor visitor) { + return visitor.visit(values, offset, length); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof DataBuffer)) { + return false; + } + DataBuffer other = (DataBuffer)obj; + if (size() != other.size()) { + return false; + } + return other.accept(new DataStorageVisitor() { + + @Override + public Boolean visit(Object[] array, int arrayOffset, int arrayLength) { + if (offset == 0 && values.length == length && arrayOffset == 0 && array.length == arrayLength) { + return Arrays.deepEquals(array, values); + } + return slowEquals(other); + } + + @Override + public Boolean fallback() { + return slowEquals(other); + } + }); + } + + ArrayDataBuffer(T[] values, boolean readOnly) { + this(values, readOnly, 0, values.length); + } + + private ArrayDataBuffer(T[] values, boolean readOnly, int offset, int length) { + this.values = values; + this.readOnly = readOnly; + this.offset = offset; + this.length = length; + } + + private final T[] values; + private final boolean readOnly; + private final int offset; + private final int length; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/misc/BitSetDataBuffer.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/misc/BitSetDataBuffer.java new file mode 100644 index 00000000000..5b5ec15294b --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/misc/BitSetDataBuffer.java @@ -0,0 +1,183 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.misc; + +import java.util.BitSet; +import org.tensorflow.ndarray.impl.buffer.AbstractDataBuffer; +import org.tensorflow.ndarray.impl.buffer.Validator; +import org.tensorflow.ndarray.buffer.BooleanDataBuffer; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DataStorageVisitor; + +class BitSetDataBuffer extends AbstractDataBuffer implements BooleanDataBuffer { + + @Override + public long size() { + return numBits; + } + + @Override + public boolean isReadOnly() { + return readOnly; + } + + @Override + public boolean getBoolean(long index) { + Validator.getArgs(this, index); + return bitSet.get((int)index + offset); + } + + @Override + public BooleanDataBuffer setBoolean(boolean value, long index) { + Validator.setArgs(this, index); + bitSet.set((int)index + offset, value); + return this; + } + + @Override + public BooleanDataBuffer read(boolean[] dst, int offset, int length) { + Validator.readArgs(this, dst.length, offset, length); + for (int i = this.offset, j = offset; i < this.offset + length; ++i, ++j) { + dst[j] = bitSet.get(i); + } + return this; + } + + @Override + public BooleanDataBuffer write(boolean[] src, int offset, int length) { + Validator.readArgs(this, src.length, offset, length); + for (int i = this.offset, j = offset; i < this.offset + length; ++i, ++j) { + bitSet.set(i, src[j]); + } + return this; + } + + @Override + public BooleanDataBuffer copyTo(DataBuffer dst, long size) { + Validator.copyToArgs(this, dst, size); + return dst.accept(new DataStorageVisitor() { + + @Override + public BooleanDataBuffer visit(boolean[] array, int arrayOffset, int arrayLength) { + for (int idx = 0; idx < size; ++idx) { + array[idx + arrayOffset] = bitSet.get(idx + offset); + } + return BitSetDataBuffer.this; + } + + @Override + public BooleanDataBuffer visit(BitSet dstBitSet, int dstOffset, long numBits) { + for (int idx = 0; idx < size; ++idx) { + dstBitSet.set(idx + dstOffset, bitSet.get(idx + offset)); + } + return BitSetDataBuffer.this; + } + + @Override + public BooleanDataBuffer fallback() { + if (dst instanceof BooleanDataBuffer) { + BooleanDataBuffer booleanDst = (BooleanDataBuffer)dst; + for (int idx = 0; idx < size; ++idx) { + booleanDst.setBoolean(bitSet.get(idx + offset), idx); + } + } else { + for (int idx = 0; idx < size; ++idx) { + dst.setObject(bitSet.get(idx + offset), idx); + } + } + return BitSetDataBuffer.this; + } + }); + } + + @Override + public BooleanDataBuffer slice(long index, long size) { + Validator.sliceArgs(this, index, size); + return new BitSetDataBuffer(bitSet, size, readOnly, offset + (int)index); + } + + @Override + public R accept(DataStorageVisitor visitor) { + return visitor.visit(bitSet, offset, numBits); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof BooleanDataBuffer)) { + return super.equals(obj); + } + BooleanDataBuffer other = (BooleanDataBuffer)obj; + if (size() != other.size()) { + return false; + } + return other.accept(new DataStorageVisitor() { + + @Override + public Boolean visit(boolean[] array, int arrayOffset, int length) { + for (int idx = 0; idx < size(); ++idx) { + if (array[idx + arrayOffset] != bitSet.get(idx + offset)) { + return false; + } + } + return true; + } + + @Override + public Boolean visit(BitSet otherBitSet, int otherOffset, long otherNumBits) { + if (offset == 0 && otherOffset == 0 && numBits == otherNumBits) { + return bitSet.equals(otherBitSet); + } + for (int idx = 0; idx < size(); ++idx) { + if (otherBitSet.get(idx + otherOffset) != bitSet.get(idx + offset)) { + return false; + } + } + return true; + } + + @Override + public Boolean fallback() { + for (int idx = 0; idx < size(); ++idx) { + if (other.getBoolean(idx) != bitSet.get(idx + offset)) { + return false; + } + } + return true; + } + }); + } + + BitSetDataBuffer(BitSet bitSet, long numBits, boolean readOnly) { + this(bitSet, numBits, readOnly, 0); + } + + private BitSetDataBuffer(BitSet bitSet, long numBits, boolean readOnly, int offset) { + this.bitSet = bitSet; + this.numBits = numBits; + this.readOnly = readOnly; + this.offset = offset; + } + + private final BitSet bitSet; + private final long numBits; + private final boolean readOnly; + private final int offset; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/misc/BooleanArrayDataBuffer.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/misc/BooleanArrayDataBuffer.java new file mode 100644 index 00000000000..f8d033519ec --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/misc/BooleanArrayDataBuffer.java @@ -0,0 +1,176 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.buffer.misc; + +import java.util.Arrays; +import java.util.BitSet; +import org.tensorflow.ndarray.impl.buffer.AbstractDataBuffer; +import org.tensorflow.ndarray.impl.buffer.Validator; +import org.tensorflow.ndarray.buffer.BooleanDataBuffer; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DataStorageVisitor; + +class BooleanArrayDataBuffer extends AbstractDataBuffer implements + BooleanDataBuffer { + + @Override + public long size() { + return length; + } + + @Override + public boolean isReadOnly() { + return readOnly; + } + + @Override + public boolean getBoolean(long index) { + Validator.getArgs(this, index); + return values[(int)index + offset]; + } + + @Override + public BooleanDataBuffer setBoolean(boolean value, long index) { + Validator.setArgs(this, index); + values[(int)index + offset] = value; + return this; + } + + @Override + public BooleanDataBuffer read(boolean[] dst, int offset, int length) { + System.arraycopy(values, this.offset, dst, offset, length); + return this; + } + + @Override + public BooleanDataBuffer write(boolean[] src, int offset, int length) { + System.arraycopy(src, offset, values, this.offset, length); + return null; + } + + @Override + public BooleanDataBuffer copyTo(DataBuffer dst, long size) { + Validator.copyToArgs(this, dst, size); + return dst.accept(new DataStorageVisitor() { + + @Override + public BooleanDataBuffer visit(boolean[] array, int arrayOffset, int arrayLength) { + System.arraycopy(values, offset, array, arrayOffset, (int)size); + return BooleanArrayDataBuffer.this; + } + + @Override + public BooleanDataBuffer visit(BitSet bitSet, int bitSetOffset, long numBits) { + for (int idx = 0; idx < size; ++idx) { + bitSet.set(idx + bitSetOffset, values[idx + offset]); + } + return BooleanArrayDataBuffer.this; + } + + @Override + public BooleanDataBuffer fallback() { + if (dst instanceof BooleanDataBuffer) { + BooleanDataBuffer booleanDst = (BooleanDataBuffer)dst; + for (int idx = 0; idx < size; ++idx) { + booleanDst.setBoolean(values[idx + offset], idx); + } + } else { + for (int idx = 0; idx < size; ++idx) { + dst.setObject(values[idx + offset], idx); + } + } + return BooleanArrayDataBuffer.this; + } + }); + } + + @Override + public BooleanDataBuffer slice(long index, long size) { + Validator.sliceArgs(this, index, size); + return new BooleanArrayDataBuffer(values, readOnly, offset + (int)index, (int)size); + } + + @Override + public R accept(DataStorageVisitor visitor) { + return visitor.visit(values, offset, length); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof BooleanDataBuffer)) { + return super.equals(obj); + } + BooleanDataBuffer other = (BooleanDataBuffer)obj; + if (size() != other.size()) { + return false; + } + return other.accept(new DataStorageVisitor() { + + @Override + public Boolean visit(boolean[] array, int arrayOffset, int arrayLength) { + if (offset == 0 && values.length == length && arrayOffset == 0 && array.length == arrayLength) { + return Arrays.equals(array, values); + } + for (int idx = 0; idx < size(); ++idx) { + if (array[idx + arrayOffset] != values[idx + offset]) { + return false; + } + } + return true; + } + + @Override + public Boolean visit(BitSet bitSet, int bitSetOffset, long numBits) { + for (int idx = 0; idx < size(); ++idx) { + if (bitSet.get(idx + bitSetOffset) != values[idx + offset]) { + return false; + } + } + return true; + } + + @Override + public Boolean fallback() { + for (int idx = 0; idx < size(); ++idx) { + if (other.getBoolean(idx) != values[idx + offset]) { + return false; + } + } + return true; + } + }); + } + + BooleanArrayDataBuffer(boolean[] values, boolean readOnly) { + this(values, readOnly, 0, values.length); + } + + private BooleanArrayDataBuffer(boolean[] values, boolean readOnly, int offset, int length) { + this.values = values; + this.readOnly = readOnly; + this.offset = offset; + this.length = length; + } + + private final boolean[] values; + private final boolean readOnly; + private final int offset; + private final int length; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/misc/MiscDataBufferFactory.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/misc/MiscDataBufferFactory.java new file mode 100644 index 00000000000..84cfce6bc66 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/misc/MiscDataBufferFactory.java @@ -0,0 +1,40 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.misc; + +import java.util.BitSet; +import org.tensorflow.ndarray.buffer.BooleanDataBuffer; +import org.tensorflow.ndarray.buffer.DataBuffer; + +/** + * Factory of miscellaneous data buffers + */ +public class MiscDataBufferFactory { + + public static BooleanDataBuffer create(BitSet bitSet, long numBits, boolean readOnly) { + return new BitSetDataBuffer(bitSet, numBits, readOnly); + } + + public static BooleanDataBuffer create(boolean[] array, boolean readOnly) { + return new BooleanArrayDataBuffer(array, readOnly); + } + + public static DataBuffer create(T[] array, boolean readOnly) { + return new ArrayDataBuffer<>(array, readOnly); + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/nio/AbstractNioDataBuffer.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/nio/AbstractNioDataBuffer.java new file mode 100644 index 00000000000..82bc981ad46 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/nio/AbstractNioDataBuffer.java @@ -0,0 +1,41 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.nio; + +import java.nio.Buffer; +import org.tensorflow.ndarray.impl.buffer.AbstractDataBuffer; + +/** + * Base class for all JDK-based data buffers. + * + * @param type of elements (or values) stored in this buffer + */ +abstract class AbstractNioDataBuffer extends AbstractDataBuffer { + + @Override + public long size() { + return buf().capacity(); + } + + @Override + public boolean isReadOnly() { + return buf().isReadOnly(); + } + + abstract Buffer buf(); +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/nio/ByteNioDataBuffer.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/nio/ByteNioDataBuffer.java new file mode 100644 index 00000000000..5ede97cef78 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/nio/ByteNioDataBuffer.java @@ -0,0 +1,185 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.nio; + +import java.nio.ByteBuffer; +import org.tensorflow.ndarray.impl.buffer.Validator; +import org.tensorflow.ndarray.impl.buffer.adapter.DataBufferAdapterFactory; +import org.tensorflow.ndarray.buffer.BooleanDataBuffer; +import org.tensorflow.ndarray.buffer.ByteDataBuffer; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DataStorageVisitor; +import org.tensorflow.ndarray.buffer.DoubleDataBuffer; +import org.tensorflow.ndarray.buffer.FloatDataBuffer; +import org.tensorflow.ndarray.buffer.IntDataBuffer; +import org.tensorflow.ndarray.buffer.LongDataBuffer; +import org.tensorflow.ndarray.buffer.ShortDataBuffer; +import org.tensorflow.ndarray.buffer.layout.DataLayouts; + +/** + * A buffer of bytes using a JDK {@link ByteBuffer} for storage. + */ +final class ByteNioDataBuffer extends AbstractNioDataBuffer + implements ByteDataBuffer { + + @Override + public byte getByte(long index) { + return buf.get((int)index); + } + + @Override + public ByteDataBuffer setByte(byte value, long index) { + buf.put((int)index, value); + return this; + } + + @Override + public ByteDataBuffer read(byte[] dst, int offset, int length) { + buf.duplicate().get(dst, offset, length); + return this; + } + + @Override + public ByteDataBuffer write(byte[] src, int offset, int length) { + buf.duplicate().put(src, offset, length); + return this; + } + + @Override + public ByteDataBuffer copyTo(DataBuffer dst, long size) { + Validator.copyToArgs(this, dst, size); + return dst.accept(new DataStorageVisitor() { + + @Override + public ByteDataBuffer visit(ByteBuffer buffer) { + buffer.duplicate().put((ByteBuffer)buf.duplicate().limit((int)size)); + return ByteNioDataBuffer.this; + } + + @Override + public ByteDataBuffer fallback() { + if (dst instanceof ByteDataBuffer) { + ByteDataBuffer byteDst = (ByteDataBuffer)dst; + for (long idx = 0L; idx < size; ++idx) { + byteDst.setByte(getByte(idx), idx); + } + return ByteNioDataBuffer.this; + } + return slowCopyTo(dst, size); + } + }); + } + + @Override + public IntDataBuffer asInts() { + return new IntNioDataBuffer(buf.asIntBuffer()); + } + + @Override + public ShortDataBuffer asShorts() { + return new ShortNioDataBuffer(buf.asShortBuffer()); + } + + @Override + public LongDataBuffer asLongs() { + return new LongNioDataBuffer(buf.asLongBuffer()); + } + + @Override + public FloatDataBuffer asFloats() { + return new FloatNioDataBuffer(buf.asFloatBuffer()); + } + + @Override + public DoubleDataBuffer asDoubles() { + return new DoubleNioDataBuffer(buf.asDoubleBuffer()); + } + + @Override + public BooleanDataBuffer asBooleans() { + return DataBufferAdapterFactory.create(this, DataLayouts.BOOL); + } + + @Override + public ByteDataBuffer offset(long index) { + Validator.offsetArgs(this, index); + return new ByteNioDataBuffer(((ByteBuffer)buf.duplicate().position((int)index)).slice()); + } + + @Override + public ByteDataBuffer narrow(long size) { + Validator.narrowArgs(this, size); + return new ByteNioDataBuffer(((ByteBuffer)buf.duplicate().limit((int)size)).slice()); + } + + @Override + public ByteDataBuffer slice(long index, long size) { + Validator.sliceArgs(this, index, size); + ByteBuffer sliceBuf = buf.duplicate(); + sliceBuf.position((int)index); + sliceBuf.limit((int)index + (int)size); + return new ByteNioDataBuffer(sliceBuf.slice()); + } + + @Override + public R accept(DataStorageVisitor visitor) { + return visitor.visit(buf); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof ByteDataBuffer)) { + return super.equals(obj); + } + ByteDataBuffer other = (ByteDataBuffer)obj; + if (size() != other.size()) { + return false; + } + return other.accept(new DataStorageVisitor() { + + @Override + public Boolean visit(ByteBuffer buffer) { + return buf.equals(buffer); + } + + @Override + public Boolean fallback() { + for (int idx = 0; idx < size(); ++idx) { + if (other.getByte(idx) != getByte(idx)) { + return false; + } + } + return true; + } + }); + } + + @Override + ByteBuffer buf() { + return buf; + } + + ByteNioDataBuffer(ByteBuffer buf) { + this.buf = buf; + } + + private ByteBuffer buf; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/nio/DoubleNioDataBuffer.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/nio/DoubleNioDataBuffer.java new file mode 100644 index 00000000000..bddc5db1e3f --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/nio/DoubleNioDataBuffer.java @@ -0,0 +1,147 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.nio; + +import java.nio.DoubleBuffer; +import org.tensorflow.ndarray.impl.buffer.Validator; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DataStorageVisitor; +import org.tensorflow.ndarray.buffer.DoubleDataBuffer; + +/** + * A buffer of bytes using a JDK {@link DoubleBuffer} for storage. + */ +final class DoubleNioDataBuffer extends AbstractNioDataBuffer + implements DoubleDataBuffer { + + @Override + public double getDouble(long index) { + return buf.get((int)index); + } + + @Override + public DoubleDataBuffer setDouble(double value, long index) { + buf.put((int)index, value); + return this; + } + + @Override + public DoubleDataBuffer read(double[] dst, int offset, int length) { + buf.duplicate().get(dst, offset, length); + return this; + } + + @Override + public DoubleDataBuffer write(double[] src, int offset, int length) { + buf.duplicate().put(src, offset, length); + return this; + } + + @Override + public DoubleDataBuffer copyTo(DataBuffer dst, long size) { + Validator.copyToArgs(this, dst, size); + return dst.accept(new DataStorageVisitor() { + + @Override + public DoubleDataBuffer visit(DoubleBuffer buffer) { + buffer.duplicate().put((DoubleBuffer)buf.duplicate().limit((int)size)); + return DoubleNioDataBuffer.this; + } + + @Override + public DoubleDataBuffer fallback() { + if (dst instanceof DoubleDataBuffer) { + DoubleDataBuffer doubleDst = (DoubleDataBuffer)dst; + for (long idx = 0L; idx < size; ++idx) { + doubleDst.setDouble(getDouble(idx), idx); + } + return DoubleNioDataBuffer.this; + } + return slowCopyTo(dst, size); + } + }); + } + + @Override + public DoubleDataBuffer offset(long index) { + Validator.offsetArgs(this, index); + return new DoubleNioDataBuffer(((DoubleBuffer)buf.duplicate().position((int)index)).slice()); + } + + @Override + public DoubleDataBuffer narrow(long size) { + Validator.narrowArgs(this, size); + return new DoubleNioDataBuffer(((DoubleBuffer)buf.duplicate().limit((int)size)).slice()); + } + + @Override + public DoubleDataBuffer slice(long index, long size) { + Validator.sliceArgs(this, index, size); + DoubleBuffer sliceBuf = buf.duplicate(); + sliceBuf.position((int)index); + sliceBuf.limit((int)index + (int)size); + return new DoubleNioDataBuffer(sliceBuf.slice()); + } + + @Override + public R accept(DataStorageVisitor visitor) { + return visitor.visit(buf); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof DoubleDataBuffer)) { + return super.equals(obj); + } + DoubleDataBuffer other = (DoubleDataBuffer)obj; + if (size() != other.size()) { + return false; + } + return other.accept(new DataStorageVisitor() { + + @Override + public Boolean visit(DoubleBuffer buffer) { + return buf.equals(buffer); + } + + @Override + public Boolean fallback() { + for (int idx = 0; idx < size(); ++idx) { + if (other.getDouble(idx) != getDouble(idx)) { + return false; + } + } + return true; + } + }); + } + + @Override + DoubleBuffer buf() { + return buf; + } + + DoubleNioDataBuffer(DoubleBuffer buf) { + this.buf = buf; + } + + private DoubleBuffer buf; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/nio/FloatNioDataBuffer.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/nio/FloatNioDataBuffer.java new file mode 100644 index 00000000000..06a9a31b56a --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/nio/FloatNioDataBuffer.java @@ -0,0 +1,147 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.nio; + +import java.nio.FloatBuffer; +import org.tensorflow.ndarray.impl.buffer.Validator; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DataStorageVisitor; +import org.tensorflow.ndarray.buffer.FloatDataBuffer; + +/** + * A buffer of bytes using a JDK {@link FloatBuffer} for storage. + */ +final class FloatNioDataBuffer extends AbstractNioDataBuffer + implements FloatDataBuffer { + + @Override + public float getFloat(long index) { + return buf.get((int)index); + } + + @Override + public FloatDataBuffer setFloat(float value, long index) { + buf.put((int)index, value); + return this; + } + + @Override + public FloatDataBuffer read(float[] dst, int offset, int length) { + buf.duplicate().get(dst, offset, length); + return this; + } + + @Override + public FloatDataBuffer write(float[] src, int offset, int length) { + buf.duplicate().put(src, offset, length); + return this; + } + + @Override + public FloatDataBuffer copyTo(DataBuffer dst, long size) { + Validator.copyToArgs(this, dst, size); + return dst.accept(new DataStorageVisitor() { + + @Override + public FloatDataBuffer visit(FloatBuffer buffer) { + buffer.duplicate().put((FloatBuffer)buf.duplicate().limit((int)size)); + return FloatNioDataBuffer.this; + } + + @Override + public FloatDataBuffer fallback() { + if (dst instanceof FloatDataBuffer) { + FloatDataBuffer floatDst = (FloatDataBuffer)dst; + for (long idx = 0L; idx < size; ++idx) { + floatDst.setFloat(getFloat(idx), idx); + } + return FloatNioDataBuffer.this; + } + return slowCopyTo(dst, size); + } + }); + } + + @Override + public FloatDataBuffer offset(long index) { + Validator.offsetArgs(this, index); + return new FloatNioDataBuffer(((FloatBuffer)buf.duplicate().position((int)index)).slice()); + } + + @Override + public FloatDataBuffer narrow(long size) { + Validator.narrowArgs(this, size); + return new FloatNioDataBuffer(((FloatBuffer)buf.duplicate().limit((int)size)).slice()); + } + + @Override + public FloatDataBuffer slice(long index, long size) { + Validator.sliceArgs(this, index, size); + FloatBuffer sliceBuf = buf.duplicate(); + sliceBuf.position((int)index); + sliceBuf.limit((int)index + (int)size); + return new FloatNioDataBuffer(sliceBuf.slice()); + } + + @Override + public R accept(DataStorageVisitor visitor) { + return visitor.visit(buf); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof FloatDataBuffer)) { + return super.equals(obj); + } + FloatDataBuffer other = (FloatDataBuffer)obj; + if (size() != other.size()) { + return false; + } + return other.accept(new DataStorageVisitor() { + + @Override + public Boolean visit(FloatBuffer buffer) { + return buf.equals(buffer); + } + + @Override + public Boolean fallback() { + for (int idx = 0; idx < size(); ++idx) { + if (other.getFloat(idx) != getFloat(idx)) { + return false; + } + } + return true; + } + }); + } + + @Override + FloatBuffer buf() { + return buf; + } + + FloatNioDataBuffer(FloatBuffer buf) { + this.buf = buf; + } + + private FloatBuffer buf; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/nio/IntNioDataBuffer.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/nio/IntNioDataBuffer.java new file mode 100644 index 00000000000..cea729e86a7 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/nio/IntNioDataBuffer.java @@ -0,0 +1,147 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.nio; + +import java.nio.IntBuffer; +import org.tensorflow.ndarray.impl.buffer.Validator; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DataStorageVisitor; +import org.tensorflow.ndarray.buffer.IntDataBuffer; + +/** + * A buffer of bytes using a JDK {@link IntBuffer} for storage. + */ +final class IntNioDataBuffer extends AbstractNioDataBuffer + implements IntDataBuffer { + + @Override + public int getInt(long index) { + return buf.get((int)index); + } + + @Override + public IntDataBuffer setInt(int value, long index) { + buf.put((int)index, value); + return this; + } + + @Override + public IntDataBuffer read(int[] dst, int offset, int length) { + buf.duplicate().get(dst, offset, length); + return this; + } + + @Override + public IntDataBuffer write(int[] src, int offset, int length) { + buf.duplicate().put(src, offset, length); + return this; + } + + @Override + public IntDataBuffer copyTo(DataBuffer dst, long size) { + Validator.copyToArgs(this, dst, size); + return dst.accept(new DataStorageVisitor() { + + @Override + public IntDataBuffer visit(IntBuffer buffer) { + buffer.duplicate().put((IntBuffer)buf.duplicate().limit((int)size)); + return IntNioDataBuffer.this; + } + + @Override + public IntDataBuffer fallback() { + if (dst instanceof IntDataBuffer) { + IntDataBuffer intDst = (IntDataBuffer)dst; + for (long idx = 0L; idx < size; ++idx) { + intDst.setInt(getInt(idx), idx); + } + return IntNioDataBuffer.this; + } + return slowCopyTo(dst, size); + } + }); + } + + @Override + public IntDataBuffer offset(long index) { + Validator.offsetArgs(this, index); + return new IntNioDataBuffer(((IntBuffer)buf.duplicate().position((int)index)).slice()); + } + + @Override + public IntDataBuffer narrow(long size) { + Validator.narrowArgs(this, size); + return new IntNioDataBuffer(((IntBuffer)buf.duplicate().limit((int)size)).slice()); + } + + @Override + public IntDataBuffer slice(long index, long size) { + Validator.sliceArgs(this, index, size); + IntBuffer sliceBuf = buf.duplicate(); + sliceBuf.position((int)index); + sliceBuf.limit((int)index + (int)size); + return new IntNioDataBuffer(sliceBuf.slice()); + } + + @Override + public R accept(DataStorageVisitor visitor) { + return visitor.visit(buf); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof IntDataBuffer)) { + return super.equals(obj); + } + IntDataBuffer other = (IntDataBuffer)obj; + if (size() != other.size()) { + return false; + } + return other.accept(new DataStorageVisitor() { + + @Override + public Boolean visit(IntBuffer buffer) { + return buf.equals(buffer); + } + + @Override + public Boolean fallback() { + for (int idx = 0; idx < size(); ++idx) { + if (other.getInt(idx) != getInt(idx)) { + return false; + } + } + return true; + } + }); + } + + @Override + IntBuffer buf() { + return buf; + } + + IntNioDataBuffer(IntBuffer buf) { + this.buf = buf; + } + + private IntBuffer buf; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/nio/LongNioDataBuffer.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/nio/LongNioDataBuffer.java new file mode 100644 index 00000000000..7231ee7d408 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/nio/LongNioDataBuffer.java @@ -0,0 +1,147 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.nio; + +import java.nio.LongBuffer; +import org.tensorflow.ndarray.impl.buffer.Validator; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DataStorageVisitor; +import org.tensorflow.ndarray.buffer.LongDataBuffer; + +/** + * A buffer of bytes using a JDK {@link LongBuffer} for storage. + */ +final class LongNioDataBuffer extends AbstractNioDataBuffer + implements LongDataBuffer { + + @Override + public long getLong(long index) { + return buf.get((int)index); + } + + @Override + public LongDataBuffer setLong(long value, long index) { + buf.put((int)index, value); + return this; + } + + @Override + public LongDataBuffer read(long[] dst, int offset, int length) { + buf.duplicate().get(dst, offset, length); + return this; + } + + @Override + public LongDataBuffer write(long[] src, int offset, int length) { + buf.duplicate().put(src, offset, length); + return this; + } + + @Override + public LongDataBuffer copyTo(DataBuffer dst, long size) { + Validator.copyToArgs(this, dst, size); + return dst.accept(new DataStorageVisitor() { + + @Override + public LongDataBuffer visit(LongBuffer buffer) { + buffer.duplicate().put((LongBuffer)buf.duplicate().limit((int)size)); + return LongNioDataBuffer.this; + } + + @Override + public LongDataBuffer fallback() { + if (dst instanceof LongDataBuffer) { + LongDataBuffer longDst = (LongDataBuffer)dst; + for (long idx = 0L; idx < size; ++idx) { + longDst.setLong(getLong(idx), idx); + } + return LongNioDataBuffer.this; + } + return slowCopyTo(dst, size); + } + }); + } + + @Override + public LongDataBuffer offset(long index) { + Validator.offsetArgs(this, index); + return new LongNioDataBuffer(((LongBuffer)buf.duplicate().position((int)index)).slice()); + } + + @Override + public LongDataBuffer narrow(long size) { + Validator.narrowArgs(this, size); + return new LongNioDataBuffer(((LongBuffer)buf.duplicate().limit((int)size)).slice()); + } + + @Override + public LongDataBuffer slice(long index, long size) { + Validator.sliceArgs(this, index, size); + LongBuffer sliceBuf = buf.duplicate(); + sliceBuf.position((int)index); + sliceBuf.limit((int)index + (int)size); + return new LongNioDataBuffer(sliceBuf.slice()); + } + + @Override + public R accept(DataStorageVisitor visitor) { + return visitor.visit(buf); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof LongDataBuffer)) { + return super.equals(obj); + } + LongDataBuffer other = (LongDataBuffer)obj; + if (size() != other.size()) { + return false; + } + return other.accept(new DataStorageVisitor() { + + @Override + public Boolean visit(LongBuffer buffer) { + return buf.equals(buffer); + } + + @Override + public Boolean fallback() { + for (int idx = 0; idx < size(); ++idx) { + if (other.getLong(idx) != getLong(idx)) { + return false; + } + } + return true; + } + }); + } + + @Override + LongBuffer buf() { + return buf; + } + + LongNioDataBuffer(LongBuffer buf) { + this.buf = buf; + } + + private LongBuffer buf; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/nio/NioDataBufferFactory.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/nio/NioDataBufferFactory.java new file mode 100644 index 00000000000..4e84fc9bc17 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/nio/NioDataBufferFactory.java @@ -0,0 +1,61 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.nio; + +import java.nio.ByteBuffer; +import java.nio.DoubleBuffer; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.nio.LongBuffer; +import java.nio.ShortBuffer; +import org.tensorflow.ndarray.buffer.ByteDataBuffer; +import org.tensorflow.ndarray.buffer.DoubleDataBuffer; +import org.tensorflow.ndarray.buffer.FloatDataBuffer; +import org.tensorflow.ndarray.buffer.IntDataBuffer; +import org.tensorflow.ndarray.buffer.LongDataBuffer; +import org.tensorflow.ndarray.buffer.ShortDataBuffer; + +/** + * Factory of JDK NIO-based data buffers + */ +public class NioDataBufferFactory { + + public static ByteDataBuffer create(ByteBuffer buffer) { + return new ByteNioDataBuffer(buffer); + } + + public static DoubleDataBuffer create(DoubleBuffer buffer) { + return new DoubleNioDataBuffer(buffer); + } + + public static FloatDataBuffer create(FloatBuffer buffer) { + return new FloatNioDataBuffer(buffer); + } + + public static IntDataBuffer create(IntBuffer buffer) { + return new IntNioDataBuffer(buffer); + } + + public static LongDataBuffer create(LongBuffer buffer) { + return new LongNioDataBuffer(buffer); + } + + public static ShortDataBuffer create(ShortBuffer buffer) { + return new ShortNioDataBuffer(buffer); + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/nio/ShortNioDataBuffer.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/nio/ShortNioDataBuffer.java new file mode 100644 index 00000000000..776faa103c2 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/nio/ShortNioDataBuffer.java @@ -0,0 +1,147 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.nio; + +import java.nio.ShortBuffer; +import org.tensorflow.ndarray.impl.buffer.Validator; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DataStorageVisitor; +import org.tensorflow.ndarray.buffer.ShortDataBuffer; + +/** + * A buffer of bytes using a JDK {@link ShortBuffer} for storage. + */ +final class ShortNioDataBuffer extends AbstractNioDataBuffer + implements ShortDataBuffer { + + @Override + public short getShort(long index) { + return buf.get((int)index); + } + + @Override + public ShortDataBuffer setShort(short value, long index) { + buf.put((int)index, value); + return this; + } + + @Override + public ShortDataBuffer read(short[] dst, int offset, int length) { + buf.duplicate().get(dst, offset, length); + return this; + } + + @Override + public ShortDataBuffer write(short[] src, int offset, int length) { + buf.duplicate().put(src, offset, length); + return this; + } + + @Override + public ShortDataBuffer copyTo(DataBuffer dst, long size) { + Validator.copyToArgs(this, dst, size); + return dst.accept(new DataStorageVisitor() { + + @Override + public ShortDataBuffer visit(ShortBuffer buffer) { + buffer.duplicate().put((ShortBuffer)buf.duplicate().limit((int)size)); + return ShortNioDataBuffer.this; + } + + @Override + public ShortDataBuffer fallback() { + if (dst instanceof ShortDataBuffer) { + ShortDataBuffer shortDst = (ShortDataBuffer)dst; + for (long idx = 0L; idx < size; ++idx) { + shortDst.setShort(getShort(idx), idx); + } + return ShortNioDataBuffer.this; + } + return slowCopyTo(dst, size); + } + }); + } + + @Override + public ShortDataBuffer offset(long index) { + Validator.offsetArgs(this, index); + return new ShortNioDataBuffer(((ShortBuffer)buf.duplicate().position((int)index)).slice()); + } + + @Override + public ShortDataBuffer narrow(long size) { + Validator.narrowArgs(this, size); + return new ShortNioDataBuffer(((ShortBuffer)buf.duplicate().limit((int)size)).slice()); + } + + @Override + public ShortDataBuffer slice(long index, long size) { + Validator.sliceArgs(this, index, size); + ShortBuffer sliceBuf = buf.duplicate(); + sliceBuf.position((int)index); + sliceBuf.limit((int)index + (int)size); + return new ShortNioDataBuffer(sliceBuf.slice()); + } + + @Override + public R accept(DataStorageVisitor visitor) { + return visitor.visit(buf); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof ShortDataBuffer)) { + return super.equals(obj); + } + ShortDataBuffer other = (ShortDataBuffer)obj; + if (size() != other.size()) { + return false; + } + return other.accept(new DataStorageVisitor() { + + @Override + public Boolean visit(ShortBuffer buffer) { + return buf.equals(buffer); + } + + @Override + public Boolean fallback() { + for (int idx = 0; idx < size(); ++idx) { + if (other.getShort(idx) != getShort(idx)) { + return false; + } + } + return true; + } + }); + } + + @Override + ShortBuffer buf() { + return buf; + } + + ShortNioDataBuffer(ShortBuffer buf) { + this.buf = buf; + } + + private ShortBuffer buf; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/AbstractRawDataBuffer.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/AbstractRawDataBuffer.java new file mode 100644 index 00000000000..c6050385b77 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/AbstractRawDataBuffer.java @@ -0,0 +1,94 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.raw; + +import org.tensorflow.ndarray.impl.buffer.AbstractDataBuffer; +import org.tensorflow.ndarray.impl.buffer.Validator; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DataBufferWindow; + +@SuppressWarnings("unchecked") +abstract class AbstractRawDataBuffer> extends AbstractDataBuffer { + + public long size() { + return memory.size(); + } + + @Override + public boolean isReadOnly() { + return readOnly; + } + + public B read(Object dst, int dstLength) { + Validator.readArgs(this, dstLength, 0, dstLength); + memory.copyTo(UnsafeMemoryHandle.fromArray(dst, dstLength), dstLength); + return (B)this; + } + + public B read(Object dst, int dstLength, int offset, int length) { + Validator.readArgs(this, dstLength, offset, length); + memory.copyTo(UnsafeMemoryHandle.fromArray(dst, dstLength).offset(offset), length); + return (B)this; + } + + public B write(Object src, int srcLength) { + Validator.writeArgs(this, srcLength, 0, srcLength); + UnsafeMemoryHandle.fromArray(src, srcLength).copyTo(memory, srcLength); + return (B)this; + } + + public B write(Object src, int srcLength, int offset, int length) { + Validator.writeArgs(this, srcLength, offset, length); + UnsafeMemoryHandle.fromArray(src, srcLength).offset(offset).copyTo(memory, length); + return (B)this; + } + + @Override + public B copyTo(DataBuffer dst, long size) { + Validator.copyToArgs(this, dst, size); + if (dst instanceof AbstractRawDataBuffer) { + AbstractRawDataBuffer unsafeDst = (AbstractRawDataBuffer)dst; + memory.copyTo(unsafeDst.memory, size); + } else { + super.copyTo(dst, size); + } + return (B)this; + } + + @Override + public B slice(long index, long size) { + Validator.sliceArgs(this, index, size); + return instantiate(memory.slice(index, size)); + } + + @Override + public DataBufferWindow window(long size) { + B windowBuffer = instantiate(memory.slice(0, size)); + return new RawDataBufferWindow<>((AbstractRawDataBuffer)windowBuffer, size()); + } + + protected final UnsafeMemoryHandle memory; + protected final boolean readOnly; + + protected abstract B instantiate(UnsafeMemoryHandle region); + + AbstractRawDataBuffer(UnsafeMemoryHandle memory, boolean readOnly) { + this.memory = memory; + this.readOnly = readOnly; + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/BooleanRawDataBuffer.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/BooleanRawDataBuffer.java new file mode 100644 index 00000000000..e7e825ea505 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/BooleanRawDataBuffer.java @@ -0,0 +1,146 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.raw; + +import java.util.Arrays; +import org.tensorflow.ndarray.impl.buffer.Validator; +import org.tensorflow.ndarray.buffer.BooleanDataBuffer; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DataStorageVisitor; + +final class BooleanRawDataBuffer extends AbstractRawDataBuffer + implements BooleanDataBuffer { + + @Override + public boolean getBoolean(long index) { + Validator.getArgs(this, index); + return memory.getBoolean(index); + } + + @Override + public BooleanDataBuffer setBoolean(boolean value, long index) { + Validator.setArgs(this, index); + memory.setBoolean(value, index); + return this; + } + + @Override + public BooleanDataBuffer read(boolean[] dst) { + return read(dst, dst.length); + } + + @Override + public BooleanDataBuffer read(boolean[] dst, int offset, int length) { + return read(dst, dst.length, offset, length); + } + + @Override + public BooleanDataBuffer write(boolean[] src) { + return write(src, src.length); + } + + @Override + public BooleanDataBuffer write(boolean[] src, int offset, int length) { + return write(src, src.length, offset, length); + } + + @Override + public BooleanDataBuffer copyTo(DataBuffer dst, long size) { + Validator.copyToArgs(this, dst, size); + return dst.accept(new DataStorageVisitor() { + + @Override + public BooleanDataBuffer visit(boolean[] array, int offset, int length) { + memory.copyTo(UnsafeMemoryHandle.fromArray(array, offset, length), size); + return BooleanRawDataBuffer.this; + } + + @Override + public BooleanDataBuffer visit(long address, long length, long scale) { + memory.copyTo(UnsafeMemoryHandle.fromAddress(address, length, scale), size); + return BooleanRawDataBuffer.this; + } + + @Override + public BooleanDataBuffer fallback() { + if (dst instanceof BooleanDataBuffer) { + BooleanDataBuffer booleanDst = (BooleanDataBuffer)dst; + for (long idx = 0L; idx < size; ++idx) { + booleanDst.setBoolean(getBoolean(idx), idx); + } + return BooleanRawDataBuffer.this; + } + return slowCopyTo(dst, size); + } + }); + } + + @Override + public R accept(DataStorageVisitor visitor) { + if (memory.isArray()) { + return visitor.visit((boolean[])memory.object, memory.arrayOffset(boolean[].class), (int)memory.size()); + } + return visitor.visit(memory.byteOffset, memory.byteSize, memory.scale); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof BooleanDataBuffer)) { + return super.equals(obj); + } + BooleanDataBuffer other = (BooleanDataBuffer)obj; + if (size() != other.size()) { + return false; + } + return other.accept(new DataStorageVisitor() { + + @Override + public Boolean visit(boolean[] array, int offset, int length) { + if (memory.isArray() && memory.arrayOffset(boolean[].class) == 0 && offset == 0) { + boolean[] thisArray = memory.array(); + if (thisArray.length == array.length) { + return Arrays.equals(thisArray, array); + } + } + return fallback(); + } + + @Override + public Boolean fallback() { + for (long idx = 0L; idx < size(); ++idx) { + if (other.getBoolean(idx) != getBoolean(idx)) { + return false; + } + } + return true; + } + }); + } + + @Override + protected BooleanDataBuffer instantiate(UnsafeMemoryHandle memory) { + return new BooleanRawDataBuffer(memory, readOnly); + } + + BooleanRawDataBuffer(UnsafeMemoryHandle memory, boolean readOnly) { + super(memory, readOnly); + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/ByteRawDataBuffer.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/ByteRawDataBuffer.java new file mode 100644 index 00000000000..b4b490e98ed --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/ByteRawDataBuffer.java @@ -0,0 +1,185 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.raw; + +import java.nio.ByteBuffer; +import org.tensorflow.ndarray.impl.buffer.Validator; +import org.tensorflow.ndarray.buffer.BooleanDataBuffer; +import org.tensorflow.ndarray.buffer.ByteDataBuffer; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DataStorageVisitor; +import org.tensorflow.ndarray.buffer.DoubleDataBuffer; +import org.tensorflow.ndarray.buffer.FloatDataBuffer; +import org.tensorflow.ndarray.buffer.IntDataBuffer; +import org.tensorflow.ndarray.buffer.LongDataBuffer; +import org.tensorflow.ndarray.buffer.ShortDataBuffer; + +final class ByteRawDataBuffer extends AbstractRawDataBuffer + implements ByteDataBuffer { + + @Override + public byte getByte(long index) { + Validator.getArgs(this, index); + return memory.getByte(index); + } + + @Override + public ByteDataBuffer setByte(byte value, long index) { + Validator.setArgs(this, index); + memory.setByte(value, index); + return this; + } + + @Override + public ByteDataBuffer read(byte[] dst) { + return read(dst, dst.length); + } + + @Override + public ByteDataBuffer read(byte[] dst, int offset, int length) { + return read(dst, dst.length, offset, length); + } + + @Override + public ByteDataBuffer write(byte[] src) { + return write(src, src.length); + } + + @Override + public ByteDataBuffer write(byte[] src, int offset, int length) { + return write(src, src.length, offset, length); + } + + @Override + public ByteDataBuffer copyTo(DataBuffer dst, long size) { + Validator.copyToArgs(this, dst, size); + return dst.accept(new DataStorageVisitor() { + + @Override + public ByteDataBuffer visit(ByteBuffer buffer) { + if (buffer.hasArray()) { + memory.copyTo(UnsafeMemoryHandle.fromArray(buffer.array(), buffer.position(), buffer.limit()), size); + } else if (memory.isArray()) { + buffer.put(memory.toArrayByteBuffer()); + } else { + slowCopyTo(dst, size); + } + return ByteRawDataBuffer.this; + } + + @Override + public ByteDataBuffer visit(long address, long length, long scale) { + memory.copyTo(UnsafeMemoryHandle.fromAddress(address, length, scale), size); + return ByteRawDataBuffer.this; + } + + @Override + public ByteDataBuffer fallback() { + if (dst instanceof ByteDataBuffer) { + ByteDataBuffer byteDst = (ByteDataBuffer)dst; + for (long idx = 0L; idx < size; ++idx) { + byteDst.setByte(getByte(idx), idx); + } + return ByteRawDataBuffer.this; + } + return slowCopyTo(dst, size); + } + }); + } + + @Override + public IntDataBuffer asInts() { + return new IntRawDataBuffer(memory.rescale(Integer.BYTES), readOnly); + } + + @Override + public ShortDataBuffer asShorts() { + return new ShortRawDataBuffer(memory.rescale(Short.BYTES), readOnly); + } + + @Override + public LongDataBuffer asLongs() { + return new LongRawDataBuffer(memory.rescale(Long.BYTES), readOnly); + } + + @Override + public FloatDataBuffer asFloats() { + return new FloatRawDataBuffer(memory.rescale(Float.BYTES), readOnly); + } + + @Override + public DoubleDataBuffer asDoubles() { + return new DoubleRawDataBuffer(memory.rescale(Double.BYTES), readOnly); + } + + @Override + public BooleanDataBuffer asBooleans() { + return new BooleanRawDataBuffer(memory.rescale(Byte.BYTES), readOnly); + } + + @Override + public R accept(DataStorageVisitor visitor) { + if (memory.isArray()) { + return visitor.visit(memory.toArrayByteBuffer()); + } + return visitor.visit(memory.byteOffset, memory.byteSize, memory.scale); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof ByteDataBuffer)) { + return super.equals(obj); + } + ByteDataBuffer other = (ByteDataBuffer)obj; + if (size() != other.size()) { + return false; + } + return other.accept(new DataStorageVisitor() { + + @Override + public Boolean visit(ByteBuffer buffer) { + if (memory.isArray()) { + return buffer.equals(memory.toArrayByteBuffer()); + } + return fallback(); + } + + @Override + public Boolean fallback() { + for (long idx = 0L; idx < size(); ++idx) { + if (other.getByte(idx) != getByte(idx)) { + return false; + } + } + return true; + } + }); + } + + @Override + protected ByteDataBuffer instantiate(UnsafeMemoryHandle memory) { + return new ByteRawDataBuffer(memory, readOnly); + } + + ByteRawDataBuffer(UnsafeMemoryHandle memory, boolean readOnly) { + super(memory, readOnly); + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/DoubleRawDataBuffer.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/DoubleRawDataBuffer.java new file mode 100644 index 00000000000..680d9565184 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/DoubleRawDataBuffer.java @@ -0,0 +1,149 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.raw; + +import java.nio.DoubleBuffer; +import org.tensorflow.ndarray.impl.buffer.Validator; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DataStorageVisitor; +import org.tensorflow.ndarray.buffer.DoubleDataBuffer; + +final class DoubleRawDataBuffer extends AbstractRawDataBuffer + implements DoubleDataBuffer { + + @Override + public double getDouble(long index) { + Validator.getArgs(this, index); + return memory.getDouble(index); + } + + @Override + public DoubleDataBuffer setDouble(double value, long index) { + Validator.setArgs(this, index); + memory.setDouble(value, index); + return this; + } + + @Override + public DoubleDataBuffer read(double[] dst) { + return read(dst, dst.length); + } + + @Override + public DoubleDataBuffer read(double[] dst, int offset, int length) { + return read(dst, dst.length, offset, length); + } + + @Override + public DoubleDataBuffer write(double[] src) { + return write(src, src.length); + } + + @Override + public DoubleDataBuffer write(double[] src, int offset, int length) { + return write(src, src.length, offset, length); + } + + @Override + public DoubleDataBuffer copyTo(DataBuffer dst, long size) { + Validator.copyToArgs(this, dst, size); + return dst.accept(new DataStorageVisitor() { + + @Override + public DoubleDataBuffer visit(DoubleBuffer buffer) { + if (buffer.hasArray()) { + memory.copyTo(UnsafeMemoryHandle.fromArray(buffer.array(), buffer.position(), buffer.limit()), size); + } else if (memory.isArray()) { + buffer.put(memory.toArrayDoubleBuffer()); + } else { + slowCopyTo(dst, size); + } + return DoubleRawDataBuffer.this; + } + + @Override + public DoubleDataBuffer visit(long address, long length, long scale) { + memory.copyTo(UnsafeMemoryHandle.fromAddress(address, length, scale), size); + return DoubleRawDataBuffer.this; + } + + @Override + public DoubleDataBuffer fallback() { + if (dst instanceof DoubleDataBuffer) { + DoubleDataBuffer doubleDst = (DoubleDataBuffer)dst; + for (long idx = 0L; idx < size; ++idx) { + doubleDst.setDouble(getDouble(idx), idx); + } + return DoubleRawDataBuffer.this; + } + return slowCopyTo(dst, size); + } + }); + } + + @Override + public R accept(DataStorageVisitor visitor) { + if (memory.isArray()) { + return visitor.visit(memory.toArrayDoubleBuffer()); + } + return visitor.visit(memory.byteOffset, memory.byteSize, memory.scale); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof DoubleDataBuffer)) { + return super.equals(obj); + } + DoubleDataBuffer other = (DoubleDataBuffer)obj; + if (size() != other.size()) { + return false; + } + return other.accept(new DataStorageVisitor() { + + @Override + public Boolean visit(DoubleBuffer buffer) { + if (memory.isArray()) { + return buffer.equals(memory.toArrayDoubleBuffer()); + } + return fallback(); + } + + @Override + public Boolean fallback() { + for (long idx = 0L; idx < size(); ++idx) { + if (other.getDouble(idx) != getDouble(idx)) { + return false; + } + } + return true; + } + }); + } + + @Override + protected DoubleDataBuffer instantiate(UnsafeMemoryHandle memory) { + return new DoubleRawDataBuffer(memory, readOnly); + } + + DoubleRawDataBuffer(UnsafeMemoryHandle memory, boolean readOnly) { + super(memory, readOnly); + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/FloatRawDataBuffer.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/FloatRawDataBuffer.java new file mode 100644 index 00000000000..43bd370a88b --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/FloatRawDataBuffer.java @@ -0,0 +1,150 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.raw; + +import java.nio.FloatBuffer; + +import org.tensorflow.ndarray.impl.buffer.Validator; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DataStorageVisitor; +import org.tensorflow.ndarray.buffer.FloatDataBuffer; + +final class FloatRawDataBuffer extends AbstractRawDataBuffer + implements FloatDataBuffer { + + @Override + public float getFloat(long index) { + Validator.getArgs(this, index); + return memory.getFloat(index); + } + + @Override + public FloatDataBuffer setFloat(float value, long index) { + Validator.setArgs(this, index); + memory.setFloat(value, index); + return this; + } + + @Override + public FloatDataBuffer read(float[] dst) { + return read(dst, dst.length); + } + + @Override + public FloatDataBuffer read(float[] dst, int offset, int length) { + return read(dst, dst.length, offset, length); + } + + @Override + public FloatDataBuffer write(float[] src) { + return write(src, src.length); + } + + @Override + public FloatDataBuffer write(float[] src, int offset, int length) { + return write(src, src.length, offset, length); + } + + @Override + public FloatDataBuffer copyTo(DataBuffer dst, long size) { + Validator.copyToArgs(this, dst, size); + return dst.accept(new DataStorageVisitor() { + + @Override + public FloatDataBuffer visit(FloatBuffer buffer) { + if (buffer.hasArray()) { + memory.copyTo(UnsafeMemoryHandle.fromArray(buffer.array(), buffer.position(), buffer.limit()), size); + } else if (memory.isArray()) { + buffer.put(memory.toArrayFloatBuffer()); + } else { + slowCopyTo(dst, size); + } + return FloatRawDataBuffer.this; + } + + @Override + public FloatDataBuffer visit(long address, long length, long scale) { + memory.copyTo(UnsafeMemoryHandle.fromAddress(address, length, scale), size); + return FloatRawDataBuffer.this; + } + + @Override + public FloatDataBuffer fallback() { + if (dst instanceof FloatDataBuffer) { + FloatDataBuffer floatDst = (FloatDataBuffer)dst; + for (long idx = 0L; idx < size; ++idx) { + floatDst.setFloat(getFloat(idx), idx); + } + return FloatRawDataBuffer.this; + } + return slowCopyTo(dst, size); + } + }); + } + + @Override + public R accept(DataStorageVisitor visitor) { + if (memory.isArray()) { + return visitor.visit(memory.toArrayFloatBuffer()); + } + return visitor.visit(memory.byteOffset, memory.byteSize, memory.scale); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof FloatDataBuffer)) { + return super.equals(obj); + } + FloatDataBuffer other = (FloatDataBuffer)obj; + if (size() != other.size()) { + return false; + } + return other.accept(new DataStorageVisitor() { + + @Override + public Boolean visit(FloatBuffer buffer) { + if (memory.isArray()) { + return buffer.equals(memory.toArrayFloatBuffer()); + } + return fallback(); + } + + @Override + public Boolean fallback() { + for (long idx = 0L; idx < size(); ++idx) { + if (other.getFloat(idx) != getFloat(idx)) { + return false; + } + } + return true; + } + }); + } + + @Override + protected FloatDataBuffer instantiate(UnsafeMemoryHandle memory) { + return new FloatRawDataBuffer(memory, readOnly); + } + + FloatRawDataBuffer(UnsafeMemoryHandle memory, boolean readOnly) { + super(memory, readOnly); + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/IntRawDataBuffer.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/IntRawDataBuffer.java new file mode 100644 index 00000000000..1c905e2756d --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/IntRawDataBuffer.java @@ -0,0 +1,149 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.raw; + +import java.nio.IntBuffer; +import org.tensorflow.ndarray.impl.buffer.Validator; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DataStorageVisitor; +import org.tensorflow.ndarray.buffer.IntDataBuffer; + +final class IntRawDataBuffer extends AbstractRawDataBuffer + implements IntDataBuffer { + + @Override + public int getInt(long index) { + Validator.getArgs(this, index); + return memory.getInt(index); + } + + @Override + public IntDataBuffer setInt(int value, long index) { + Validator.setArgs(this, index); + memory.setInt(value, index); + return this; + } + + @Override + public IntDataBuffer read(int[] dst) { + return read(dst, dst.length); + } + + @Override + public IntDataBuffer read(int[] dst, int offset, int length) { + return read(dst, dst.length, offset, length); + } + + @Override + public IntDataBuffer write(int[] src) { + return write(src, src.length); + } + + @Override + public IntDataBuffer write(int[] src, int offset, int length) { + return write(src, src.length, offset, length); + } + + @Override + public IntDataBuffer copyTo(DataBuffer dst, long size) { + Validator.copyToArgs(this, dst, size); + return dst.accept(new DataStorageVisitor() { + + @Override + public IntDataBuffer visit(IntBuffer buffer) { + if (buffer.hasArray()) { + memory.copyTo(UnsafeMemoryHandle.fromArray(buffer.array(), buffer.position(), buffer.limit()), size); + } else if (memory.isArray()) { + buffer.put(memory.toArrayIntBuffer()); + } else { + slowCopyTo(dst, size); + } + return IntRawDataBuffer.this; + } + + @Override + public IntDataBuffer visit(long address, long length, long scale) { + memory.copyTo(UnsafeMemoryHandle.fromAddress(address, length, scale), size); + return IntRawDataBuffer.this; + } + + @Override + public IntDataBuffer fallback() { + if (dst instanceof IntDataBuffer) { + IntDataBuffer intDst = (IntDataBuffer)dst; + for (long idx = 0L; idx < size; ++idx) { + intDst.setInt(getInt(idx), idx); + } + return IntRawDataBuffer.this; + } + return slowCopyTo(dst, size); + } + }); + } + + @Override + public R accept(DataStorageVisitor visitor) { + if (memory.isArray()) { + return visitor.visit(memory.toArrayIntBuffer()); + } + return visitor.visit(memory.byteOffset, memory.byteSize, memory.scale); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof IntDataBuffer)) { + return super.equals(obj); + } + IntDataBuffer other = (IntDataBuffer)obj; + if (size() != other.size()) { + return false; + } + return other.accept(new DataStorageVisitor() { + + @Override + public Boolean visit(IntBuffer buffer) { + if (memory.isArray()) { + return buffer.equals(memory.toArrayIntBuffer()); + } + return fallback(); + } + + @Override + public Boolean fallback() { + for (long idx = 0L; idx < size(); ++idx) { + if (other.getInt(idx) != getInt(idx)) { + return false; + } + } + return true; + } + }); + } + + @Override + protected IntDataBuffer instantiate(UnsafeMemoryHandle memory) { + return new IntRawDataBuffer(memory, readOnly); + } + + IntRawDataBuffer(UnsafeMemoryHandle memory, boolean readOnly) { + super(memory, readOnly); + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/LongRawDataBuffer.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/LongRawDataBuffer.java new file mode 100644 index 00000000000..724868fe81f --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/LongRawDataBuffer.java @@ -0,0 +1,149 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.raw; + +import java.nio.LongBuffer; +import org.tensorflow.ndarray.impl.buffer.Validator; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DataStorageVisitor; +import org.tensorflow.ndarray.buffer.LongDataBuffer; + +final class LongRawDataBuffer extends AbstractRawDataBuffer + implements LongDataBuffer { + + @Override + public long getLong(long index) { + Validator.getArgs(this, index); + return memory.getLong(index); + } + + @Override + public LongDataBuffer setLong(long value, long index) { + Validator.setArgs(this, index); + memory.setLong(value, index); + return this; + } + + @Override + public LongDataBuffer read(long[] dst) { + return read(dst, dst.length); + } + + @Override + public LongDataBuffer read(long[] dst, int offset, int length) { + return read(dst, dst.length, offset, length); + } + + @Override + public LongDataBuffer write(long[] src) { + return write(src, src.length); + } + + @Override + public LongDataBuffer write(long[] src, int offset, int length) { + return write(src, src.length, offset, length); + } + + @Override + public LongDataBuffer copyTo(DataBuffer dst, long size) { + Validator.copyToArgs(this, dst, size); + return dst.accept(new DataStorageVisitor() { + + @Override + public LongDataBuffer visit(LongBuffer buffer) { + if (buffer.hasArray()) { + memory.copyTo(UnsafeMemoryHandle.fromArray(buffer.array(), buffer.position(), buffer.limit()), size); + } else if (memory.isArray()) { + buffer.put(memory.toArrayLongBuffer()); + } else { + slowCopyTo(dst, size); + } + return LongRawDataBuffer.this; + } + + @Override + public LongDataBuffer visit(long address, long length, long scale) { + memory.copyTo(UnsafeMemoryHandle.fromAddress(address, length, scale), size); + return LongRawDataBuffer.this; + } + + @Override + public LongDataBuffer fallback() { + if (dst instanceof LongDataBuffer) { + LongDataBuffer longDst = (LongDataBuffer)dst; + for (long idx = 0L; idx < size; ++idx) { + longDst.setLong(getLong(idx), idx); + } + return LongRawDataBuffer.this; + } + return slowCopyTo(dst, size); + } + }); + } + + @Override + public R accept(DataStorageVisitor visitor) { + if (memory.isArray()) { + return visitor.visit(memory.toArrayLongBuffer()); + } + return visitor.visit(memory.byteOffset, memory.byteSize, memory.scale); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof LongDataBuffer)) { + return super.equals(obj); + } + LongDataBuffer other = (LongDataBuffer)obj; + if (size() != other.size()) { + return false; + } + return other.accept(new DataStorageVisitor() { + + @Override + public Boolean visit(LongBuffer buffer) { + if (memory.isArray()) { + return buffer.equals(memory.toArrayLongBuffer()); + } + return fallback(); + } + + @Override + public Boolean fallback() { + for (long idx = 0L; idx < size(); ++idx) { + if (other.getLong(idx) != getLong(idx)) { + return false; + } + } + return true; + } + }); + } + + @Override + protected LongDataBuffer instantiate(UnsafeMemoryHandle memory) { + return new LongRawDataBuffer(memory, readOnly); + } + + LongRawDataBuffer(UnsafeMemoryHandle memory, boolean readOnly) { + super(memory, readOnly); + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/RawDataBufferFactory.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/RawDataBufferFactory.java new file mode 100644 index 00000000000..7253b239af2 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/RawDataBufferFactory.java @@ -0,0 +1,148 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.raw; + +import org.tensorflow.ndarray.impl.buffer.Validator; +import org.tensorflow.ndarray.buffer.BooleanDataBuffer; +import org.tensorflow.ndarray.buffer.ByteDataBuffer; +import org.tensorflow.ndarray.buffer.DoubleDataBuffer; +import org.tensorflow.ndarray.buffer.FloatDataBuffer; +import org.tensorflow.ndarray.buffer.IntDataBuffer; +import org.tensorflow.ndarray.buffer.LongDataBuffer; +import org.tensorflow.ndarray.buffer.ShortDataBuffer; + +/** + * Factory of raw data buffers + */ +public class RawDataBufferFactory { + + public static boolean canBeUsed() { + return UnsafeReference.isAvailable(); + } + + public static BooleanDataBuffer create(boolean[] array, boolean readOnly) { + return new BooleanRawDataBuffer(UnsafeMemoryHandle.fromArray(array, array.length), readOnly); + } + + public static ByteDataBuffer create(byte[] array, boolean readOnly) { + if (!canBeUsed()) { + throw new IllegalStateException("Raw data buffers are not available"); + } + return new ByteRawDataBuffer(UnsafeMemoryHandle.fromArray(array, array.length), readOnly); + } + + public static DoubleDataBuffer create(double[] array, boolean readOnly) { + if (!canBeUsed()) { + throw new IllegalStateException("Raw data buffers are not available"); + } + return new DoubleRawDataBuffer(UnsafeMemoryHandle.fromArray(array, array.length), readOnly); + } + + public static FloatDataBuffer create(float[] array, boolean readOnly) { + if (!canBeUsed()) { + throw new IllegalStateException("Raw data buffers are not available"); + } + return new FloatRawDataBuffer(UnsafeMemoryHandle.fromArray(array, array.length), readOnly); + } + + public static IntDataBuffer create(int[] array, boolean readOnly) { + if (!canBeUsed()) { + throw new IllegalStateException("Raw data buffers are not available"); + } + return new IntRawDataBuffer(UnsafeMemoryHandle.fromArray(array, array.length), readOnly); + } + + public static LongDataBuffer create(long[] array, boolean readOnly) { + if (!canBeUsed()) { + throw new IllegalStateException("Raw data buffers are not available"); + } + return new LongRawDataBuffer(UnsafeMemoryHandle.fromArray(array, array.length), readOnly); + } + + public static ShortDataBuffer create(short[] array, boolean readOnly) { + if (!canBeUsed()) { + throw new IllegalStateException("Raw data buffers are not available"); + } + return new ShortRawDataBuffer(UnsafeMemoryHandle.fromArray(array, array.length), readOnly); + } + + protected static BooleanDataBuffer mapNativeBooleans(long address, long size, boolean readOnly) { + if (!canBeUsed()) { + throw new IllegalStateException("Raw data buffers are not available"); + } + Validator.createArgs(size, MAX_64BITS); + return new BooleanRawDataBuffer(UnsafeMemoryHandle.fromAddress(address, size, Byte.BYTES), readOnly); + } + + protected static ByteDataBuffer mapNativeBytes(long address, long size, boolean readOnly) { + if (!canBeUsed()) { + throw new IllegalStateException("Raw data buffers are not available"); + } + Validator.createArgs(size, MAX_64BITS); + return new ByteRawDataBuffer(UnsafeMemoryHandle.fromAddress(address, size, Byte.BYTES), readOnly); + } + + protected static DoubleDataBuffer mapNativeDoubles(long address, long size, boolean readOnly) { + if (!canBeUsed()) { + throw new IllegalStateException("Raw data buffers are not available"); + } + Validator.createArgs(size, MAX_64BITS); + return new DoubleRawDataBuffer(UnsafeMemoryHandle.fromAddress(address, size, Double.BYTES), readOnly); + } + + protected static FloatDataBuffer mapNativeFloats(long address, long size, boolean readOnly) { + if (!canBeUsed()) { + throw new IllegalStateException("Raw data buffers are not available"); + } + Validator.createArgs(size, MAX_64BITS); + return new FloatRawDataBuffer(UnsafeMemoryHandle.fromAddress(address, size, Float.BYTES), readOnly); + } + + protected static IntDataBuffer mapNativeInts(long address, long size, boolean readOnly) { + if (!canBeUsed()) { + throw new IllegalStateException("Raw data buffers are not available"); + } + Validator.createArgs(size, MAX_64BITS); + return new IntRawDataBuffer(UnsafeMemoryHandle.fromAddress(address, size, Integer.BYTES), readOnly); + } + + protected static LongDataBuffer mapNativeLongs(long address, long size, boolean readOnly) { + if (!canBeUsed()) { + throw new IllegalStateException("Raw data buffers are not available"); + } + Validator.createArgs(size, MAX_64BITS); + return new LongRawDataBuffer(UnsafeMemoryHandle.fromAddress(address, size, Long.BYTES), readOnly); + } + + protected static ShortDataBuffer mapNativeShorts(long address, long size, boolean readOnly) { + if (!canBeUsed()) { + throw new IllegalStateException("Raw data buffers are not available"); + } + Validator.createArgs(size, MAX_64BITS); + return new ShortRawDataBuffer(UnsafeMemoryHandle.fromAddress(address, size, Short.BYTES), readOnly); + } + + /* + * The maximum size for a buffer of this type, i.e. the maximum number of bytes it can store. + *

+ * As the maximum size may vary depending on the JVM implementation and on the platform, this + * property returns a value that is safe for most of them. + */ + static long MAX_32BITS = Integer.MAX_VALUE - 10; + static long MAX_64BITS = Long.MAX_VALUE - 10; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/RawDataBufferWindow.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/RawDataBufferWindow.java new file mode 100644 index 00000000000..dc18a6caa6e --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/RawDataBufferWindow.java @@ -0,0 +1,19 @@ +package org.tensorflow.ndarray.impl.buffer.raw; + +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.impl.buffer.AbstractDataBufferWindow; + +final class RawDataBufferWindow> extends AbstractDataBufferWindow { + + @Override + public void offset(long offset) { + windowMemory.rebase(offset); + } + + > RawDataBufferWindow(R windowBuffer, long bufferLimit) { + super((B)windowBuffer, bufferLimit); + this.windowMemory = windowBuffer.memory; + } + + private final UnsafeMemoryHandle windowMemory; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/ShortRawDataBuffer.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/ShortRawDataBuffer.java new file mode 100644 index 00000000000..80f9c289852 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/ShortRawDataBuffer.java @@ -0,0 +1,149 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.raw; + +import java.nio.ShortBuffer; +import org.tensorflow.ndarray.impl.buffer.Validator; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DataStorageVisitor; +import org.tensorflow.ndarray.buffer.ShortDataBuffer; + +final class ShortRawDataBuffer extends AbstractRawDataBuffer + implements ShortDataBuffer { + + @Override + public short getShort(long index) { + Validator.getArgs(this, index); + return memory.getShort(index); + } + + @Override + public ShortDataBuffer setShort(short value, long index) { + Validator.setArgs(this, index); + memory.setShort(value, index); + return this; + } + + @Override + public ShortDataBuffer read(short[] dst) { + return read(dst, dst.length); + } + + @Override + public ShortDataBuffer read(short[] dst, int offset, int length) { + return read(dst, dst.length, offset, length); + } + + @Override + public ShortDataBuffer write(short[] src) { + return write(src, src.length); + } + + @Override + public ShortDataBuffer write(short[] src, int offset, int length) { + return write(src, src.length, offset, length); + } + + @Override + public ShortDataBuffer copyTo(DataBuffer dst, long size) { + Validator.copyToArgs(this, dst, size); + return dst.accept(new DataStorageVisitor() { + + @Override + public ShortDataBuffer visit(ShortBuffer buffer) { + if (buffer.hasArray()) { + memory.copyTo(UnsafeMemoryHandle.fromArray(buffer.array(), buffer.position(), buffer.limit()), size); + } else if (memory.isArray()) { + buffer.put(memory.toArrayShortBuffer()); + } else { + slowCopyTo(dst, size); + } + return ShortRawDataBuffer.this; + } + + @Override + public ShortDataBuffer visit(long address, long length, long scale) { + memory.copyTo(UnsafeMemoryHandle.fromAddress(address, length, scale), size); + return ShortRawDataBuffer.this; + } + + @Override + public ShortDataBuffer fallback() { + if (dst instanceof ShortDataBuffer) { + ShortDataBuffer shortDst = (ShortDataBuffer)dst; + for (long idx = 0L; idx < size; ++idx) { + shortDst.setShort(getShort(idx), idx); + } + return ShortRawDataBuffer.this; + } + return slowCopyTo(dst, size); + } + }); + } + + @Override + public R accept(DataStorageVisitor visitor) { + if (memory.isArray()) { + return visitor.visit(memory.toArrayShortBuffer()); + } + return visitor.visit(memory.byteOffset, memory.byteSize, memory.scale); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof ShortDataBuffer)) { + return super.equals(obj); + } + ShortDataBuffer other = (ShortDataBuffer)obj; + if (size() != other.size()) { + return false; + } + return other.accept(new DataStorageVisitor() { + + @Override + public Boolean visit(ShortBuffer buffer) { + if (memory.isArray()) { + return buffer.equals(memory.toArrayShortBuffer()); + } + return fallback(); + } + + @Override + public Boolean fallback() { + for (long idx = 0L; idx < size(); ++idx) { + if (other.getShort(idx) != getShort(idx)) { + return false; + } + } + return true; + } + }); + } + + @Override + protected ShortDataBuffer instantiate(UnsafeMemoryHandle memory) { + return new ShortRawDataBuffer(memory, readOnly); + } + + ShortRawDataBuffer(UnsafeMemoryHandle memory, boolean readOnly) { + super(memory, readOnly); + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/UnsafeMemoryHandle.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/UnsafeMemoryHandle.java new file mode 100644 index 00000000000..bd61e53a128 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/UnsafeMemoryHandle.java @@ -0,0 +1,195 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.raw; + +import java.nio.ByteBuffer; +import java.nio.DoubleBuffer; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.nio.LongBuffer; +import java.nio.ShortBuffer; + +final class UnsafeMemoryHandle { + + static UnsafeMemoryHandle fromArray(Object array, int length) { + return fromArray(array, 0, length); + } + + static UnsafeMemoryHandle fromArray(Object array, int arrayOffset, int length) { + long scale = UnsafeReference.UNSAFE.arrayIndexScale(array.getClass()); + int baseOffset = UnsafeReference.UNSAFE.arrayBaseOffset(array.getClass()); + return new UnsafeMemoryHandle(array, baseOffset + (arrayOffset * scale), length * scale, scale); + } + + static UnsafeMemoryHandle fromAddress(long address, long byteSize, long scale) { + return new UnsafeMemoryHandle(address, byteSize, scale); + } + + long size() { + return size; + } + + byte getByte(long index) { + return UnsafeReference.UNSAFE.getByte(object, align(index)); + } + + void setByte(byte value, long index) { + UnsafeReference.UNSAFE.putByte(object, align(index), value); + } + + boolean getBoolean(long index) { + return UnsafeReference.UNSAFE.getBoolean(object, align(index)); + } + + void setBoolean(boolean value, long index) { + UnsafeReference.UNSAFE.putBoolean(object, align(index), value); + } + + short getShort(long index) { + return UnsafeReference.UNSAFE.getShort(object, align(index)); + } + + void setShort(short value, long index) { + UnsafeReference.UNSAFE.putShort(object, align(index), value); + } + + int getInt(long index) { + return UnsafeReference.UNSAFE.getInt(object, align(index)); + } + + void setInt(int value, long index) { + UnsafeReference.UNSAFE.putInt(object, align(index), value); + } + + float getFloat(long index) { + return UnsafeReference.UNSAFE.getFloat(object, align(index)); + } + + void setFloat(float value, long index) { + UnsafeReference.UNSAFE.putFloat(object, align(index), value); + } + + double getDouble(long index) { + return UnsafeReference.UNSAFE.getDouble(object, align(index)); + } + + void setDouble(double value, long index) { + UnsafeReference.UNSAFE.putDouble(object, align(index), value); + } + + long getLong(long index) { + return UnsafeReference.UNSAFE.getLong(object, align(index)); + } + + void setLong(long value, long index) { + UnsafeReference.UNSAFE.putLong(object, align(index), value); + } + + void copyTo(UnsafeMemoryHandle memory, long length) { + UnsafeReference.UNSAFE.copyMemory(object, byteOffset, memory.object, memory.byteOffset, length * scale); + } + + UnsafeMemoryHandle offset(long index) { + long offset = scale(index); + return new UnsafeMemoryHandle(object, this.byteOffset + offset, byteSize - offset, scale); + } + + UnsafeMemoryHandle narrow(long size) { + return new UnsafeMemoryHandle(object, byteOffset, scale(size), scale); + } + + UnsafeMemoryHandle slice(long index, long size) { + return new UnsafeMemoryHandle(object, this.byteOffset + scale(index), scale(size), scale); + } + + UnsafeMemoryHandle rescale(long scale) { + if (object != null) { + throw new IllegalStateException("Raw heap memory cannot be rescaled"); + } + return new UnsafeMemoryHandle(null, byteOffset, byteSize, scale); + } + + void rebase(long index) { + byteOffset = baseOffset + scale(index); + } + + boolean isArray() { + return object != null; + } + + @SuppressWarnings("unchecked") + A array() { + return (A)object; + } + + int arrayOffset(Class arrayClass) { + return (int)((byteOffset - UnsafeReference.UNSAFE.arrayBaseOffset(arrayClass)) / scale); + } + + ByteBuffer toArrayByteBuffer() { + return ByteBuffer.wrap((byte[])object, (int) byteOffset - UnsafeReference.UNSAFE.arrayBaseOffset(byte[].class), (int)size); + } + + ShortBuffer toArrayShortBuffer() { + return ShortBuffer.wrap((short[])object, (int)((byteOffset - UnsafeReference.UNSAFE.arrayBaseOffset(short[].class)) / scale), (int)size); + } + + IntBuffer toArrayIntBuffer() { + return IntBuffer.wrap((int[])object, (int)((byteOffset - UnsafeReference.UNSAFE.arrayBaseOffset(int[].class)) / scale), (int)size); + } + + LongBuffer toArrayLongBuffer() { + return LongBuffer.wrap((long[])object, (int)((byteOffset - UnsafeReference.UNSAFE.arrayBaseOffset(long[].class)) / scale), (int)size); + } + + FloatBuffer toArrayFloatBuffer() { + return FloatBuffer.wrap((float[])object, (int)((byteOffset - UnsafeReference.UNSAFE.arrayBaseOffset(float[].class)) / scale), (int)size); + } + + DoubleBuffer toArrayDoubleBuffer() { + return DoubleBuffer.wrap((double[])object, (int)((byteOffset - UnsafeReference.UNSAFE.arrayBaseOffset(double[].class)) / scale), (int)size); + } + + final Object object; + final long baseOffset; + long byteOffset; + final long byteSize; + final long scale; + final long size; + + private UnsafeMemoryHandle(Object object, long baseOffset, long byteSize, long scale) { + this.object = object; + this.baseOffset = baseOffset; + byteOffset = baseOffset; + this.byteSize = byteSize; + this.scale = scale; + size = byteSize / scale; + } + + private UnsafeMemoryHandle(long address, long byteSize, long scale) { + this(null, address, byteSize, scale); + } + + private long align(long index) { + return byteOffset + index * scale; + } + + private long scale(long value) { + return value * scale; + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/UnsafeReference.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/UnsafeReference.java new file mode 100644 index 00000000000..7b95eac7349 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/buffer/raw/UnsafeReference.java @@ -0,0 +1,64 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.raw; + +import java.lang.reflect.Field; +import sun.misc.Unsafe; + +final class UnsafeReference { + + static boolean isAvailable() { + return UNSAFE != null; + } + + static final Unsafe UNSAFE; + + static { + Unsafe unsafe = null; + try { + Class clazz = Class.forName("sun.misc.Unsafe"); + Field theUnsafe = clazz.getDeclaredField("theUnsafe"); + theUnsafe.setAccessible(true); + Object instance = theUnsafe.get(null); + if (instance.getClass() == clazz) { + // Validate that this Unsafe instance exposes all methods we need + clazz.getDeclaredMethod("getByte", Object.class, long.class); + clazz.getDeclaredMethod("putByte", Object.class, long.class, byte.class); + clazz.getDeclaredMethod("getShort", Object.class, long.class); + clazz.getDeclaredMethod("putShort", Object.class, long.class, short.class); + clazz.getDeclaredMethod("getInt", Object.class, long.class); + clazz.getDeclaredMethod("putInt", Object.class, long.class, int.class); + clazz.getDeclaredMethod("getLong", Object.class, long.class); + clazz.getDeclaredMethod("putLong", Object.class, long.class, long.class); + clazz.getDeclaredMethod("getFloat", Object.class, long.class); + clazz.getDeclaredMethod("putFloat", Object.class, long.class, float.class); + clazz.getDeclaredMethod("getDouble", Object.class, long.class); + clazz.getDeclaredMethod("putDouble", Object.class, long.class, double.class); + clazz.getDeclaredMethod("getBoolean", Object.class, long.class); + clazz.getDeclaredMethod("putBoolean", Object.class, long.class, boolean.class); + clazz.getDeclaredMethod("copyMemory", Object.class, long.class, Object.class, long.class, long.class); + clazz.getDeclaredMethod("arrayBaseOffset", Class.class); + clazz.getDeclaredMethod("arrayIndexScale", Class.class); + unsafe = (Unsafe) instance; + } + } catch (ClassNotFoundException | NoSuchMethodException | NoSuchFieldException | SecurityException | IllegalAccessException | ClassCastException ex) { + // Do nothing, keep unsafe as null + } + UNSAFE = unsafe; + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/AbstractDenseNdArray.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/AbstractDenseNdArray.java new file mode 100644 index 00000000000..0497095116e --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/AbstractDenseNdArray.java @@ -0,0 +1,163 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.dense; + +import org.tensorflow.ndarray.NdArray; +import org.tensorflow.ndarray.NdArraySequence; +import org.tensorflow.ndarray.impl.AbstractNdArray; +import org.tensorflow.ndarray.impl.dimension.RelativeDimensionalSpace; +import org.tensorflow.ndarray.impl.sequence.FastElementSequence; +import org.tensorflow.ndarray.index.Index; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DataBufferWindow; +import org.tensorflow.ndarray.impl.dimension.DimensionalSpace; +import org.tensorflow.ndarray.impl.sequence.SlicingElementSequence; +import org.tensorflow.ndarray.impl.sequence.SingleElementSequence; + +@SuppressWarnings("unchecked") +public abstract class AbstractDenseNdArray> extends AbstractNdArray { + + @Override + public NdArraySequence elements(int dimensionIdx) { + if (dimensionIdx >= shape().numDimensions()) { + throw new IllegalArgumentException("Cannot iterate elements in dimension '" + dimensionIdx + + "' of array with shape " + shape()); + } + if (rank() == 0 && dimensionIdx < 0) { + return new SingleElementSequence<>(this); + } + DimensionalSpace elemDims = dimensions().from(dimensionIdx + 1); + try { + DataBufferWindow> elemWindow = buffer().window(elemDims.physicalSize()); + U element = instantiate(elemWindow.buffer(), elemDims); + return new FastElementSequence(this, dimensionIdx, element, elemWindow); + } catch (UnsupportedOperationException e) { + // If buffer windows are not supported, fallback to slicing (and slower) sequence + return new SlicingElementSequence<>(this, dimensionIdx, elemDims); + } + } + + @Override + public U slice(long position, DimensionalSpace sliceDimensions) { + DataBuffer sliceBuffer = buffer().slice(position, sliceDimensions.physicalSize()); + return instantiate(sliceBuffer, sliceDimensions); + } + + @Override + public U slice(Index... indices) { + if (indices == null) { + throw new IllegalArgumentException("Slicing requires at least one index"); + } + RelativeDimensionalSpace sliceDimensions = dimensions().mapTo(indices); + return slice(sliceDimensions.position(), sliceDimensions); + } + + @Override + public U get(long... coords) { + return slice(positionOf(coords, false), dimensions().from(coords.length)); + } + + @Override + public T getObject(long... coords) { + return buffer().getObject(positionOf(coords, true)); + } + + @Override + public U set(NdArray src, long... coordinates) { + src.copyTo((coordinates == null || coordinates.length == 0) ? this : get(coordinates)); + return (U)this; + } + + @Override + public U setObject(T value, long... coords) { + buffer().setObject(value, positionOf(coords, true)); + return (U)this; + } + + @Override + public U read(DataBuffer dst) { + Validator.readToBufferArgs(this, dst); + DataTransfer.execute(buffer(), dimensions(), dst, DataTransfer::ofValue); + return (U)this; + } + + @Override + public U write(DataBuffer src) { + Validator.writeFromBufferArgs(this, src); + DataTransfer.execute(src, buffer(), dimensions(), DataTransfer::ofValue); + return (U)this; + } + + @Override + public int hashCode() { + if (dimensions().isSegmented()) { + return slowHashCode(); + } + final int prime = 31; + int result = 1; + result = prime * result + buffer().hashCode(); + result = prime * result + shape().hashCode(); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof AbstractDenseNdArray)) { + return super.equals(obj); + } + AbstractDenseNdArray other = (AbstractDenseNdArray)obj; + if (dimensions().isSegmented() || other.dimensions().isSegmented()) { + return slowEquals(other); + } + if (!shape().equals(other.shape())) { + return false; + } + return buffer().equals(other.buffer()); + } + + protected AbstractDenseNdArray(DimensionalSpace dimensions) { + super(dimensions); + } + + abstract protected DataBuffer buffer(); + + abstract U instantiate(DataBuffer buffer, DimensionalSpace dimensions); + + long positionOf(long[] coords, boolean isValue) { + if (coords == null || coords.length == 0) { + return 0; + } + Validator.coordinates(dimensions, coords, isValue); + return dimensions.positionOf(coords); + } + + @Override + protected void slowCopyTo(NdArray array) { + if (array instanceof AbstractDenseNdArray) { + AbstractDenseNdArray dst = (AbstractDenseNdArray)array; + long offset = 0L; + for (NdArray s : scalars()) { + dst.buffer().setObject(s.getObject(), offset++); + } + } else { + super.slowCopyTo(array); + } + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/BooleanDenseNdArray.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/BooleanDenseNdArray.java new file mode 100644 index 00000000000..0764146f962 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/BooleanDenseNdArray.java @@ -0,0 +1,91 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.dense; + +import org.tensorflow.ndarray.BooleanNdArray; +import org.tensorflow.ndarray.NdArray; +import org.tensorflow.ndarray.Shape; +import org.tensorflow.ndarray.buffer.BooleanDataBuffer; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.impl.dimension.DimensionalSpace; + +public class BooleanDenseNdArray extends AbstractDenseNdArray + implements BooleanNdArray { + + public static BooleanNdArray create(BooleanDataBuffer buffer, Shape shape) { + Validator.denseShape(buffer, shape); + return new BooleanDenseNdArray(buffer, shape); + } + + @Override + public boolean getBoolean(long... indices) { + return buffer.getBoolean(positionOf(indices, true)); + } + + @Override + public BooleanNdArray setBoolean(boolean value, long... indices) { + buffer.setBoolean(value, positionOf(indices, true)); + return this; + } + + @Override + public BooleanNdArray copyTo(NdArray dst) { + Validator.copyToNdArrayArgs(this, dst); + if (dst instanceof BooleanDenseNdArray) { + BooleanDenseNdArray booleanDst = (BooleanDenseNdArray)dst; + DataTransfer.execute(buffer, dimensions(), booleanDst.buffer, booleanDst.dimensions(), DataTransfer::ofBoolean); + } else { + slowCopyTo(dst); + } + return this; + } + + @Override + public BooleanNdArray read(BooleanDataBuffer dst) { + Validator.readToBufferArgs(this, dst); + DataTransfer.execute(buffer, dimensions(), dst, DataTransfer::ofBoolean); + return this; + } + + @Override + public BooleanNdArray write(BooleanDataBuffer src) { + Validator.writeFromBufferArgs(this, src); + DataTransfer.execute(src, buffer, dimensions(), DataTransfer::ofBoolean); + return this; + } + + protected BooleanDenseNdArray(BooleanDataBuffer buffer, Shape shape) { + this(buffer, DimensionalSpace.create(shape)); + } + + @Override + BooleanDenseNdArray instantiate(DataBuffer buffer, DimensionalSpace dimensions) { + return new BooleanDenseNdArray((BooleanDataBuffer)buffer, dimensions); + } + + @Override + protected BooleanDataBuffer buffer() { + return buffer; + } + + private final BooleanDataBuffer buffer; + + private BooleanDenseNdArray(BooleanDataBuffer buffer, DimensionalSpace dimensions) { + super(dimensions); + this.buffer = buffer; + } +} \ No newline at end of file diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/ByteDenseNdArray.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/ByteDenseNdArray.java new file mode 100644 index 00000000000..172432b5939 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/ByteDenseNdArray.java @@ -0,0 +1,91 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.dense; + +import org.tensorflow.ndarray.ByteNdArray; +import org.tensorflow.ndarray.NdArray; +import org.tensorflow.ndarray.Shape; +import org.tensorflow.ndarray.buffer.ByteDataBuffer; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.impl.dimension.DimensionalSpace; + +public class ByteDenseNdArray extends AbstractDenseNdArray + implements ByteNdArray { + + public static ByteNdArray create(ByteDataBuffer buffer, Shape shape) { + Validator.denseShape(buffer, shape); + return new ByteDenseNdArray(buffer, shape); + } + + @Override + public byte getByte(long... indices) { + return buffer.getByte(positionOf(indices, true)); + } + + @Override + public ByteNdArray setByte(byte value, long... indices) { + buffer.setByte(value, positionOf(indices, true)); + return this; + } + + @Override + public ByteNdArray copyTo(NdArray dst) { + Validator.copyToNdArrayArgs(this, dst); + if (dst instanceof ByteDenseNdArray) { + ByteDenseNdArray byteDst = (ByteDenseNdArray)dst; + DataTransfer.execute(buffer, dimensions(), byteDst.buffer, byteDst.dimensions(), DataTransfer::ofByte); + } else { + slowCopyTo(dst); + } + return this; + } + + @Override + public ByteNdArray read(ByteDataBuffer dst) { + Validator.readToBufferArgs(this, dst); + DataTransfer.execute(buffer, dimensions(), dst, DataTransfer::ofByte); + return this; + } + + @Override + public ByteNdArray write(ByteDataBuffer src) { + Validator.writeFromBufferArgs(this, src); + DataTransfer.execute(src, buffer, dimensions(), DataTransfer::ofByte); + return this; + } + + protected ByteDenseNdArray(ByteDataBuffer buffer, Shape shape) { + this(buffer, DimensionalSpace.create(shape)); + } + + @Override + ByteDenseNdArray instantiate(DataBuffer buffer, DimensionalSpace dimensions) { + return new ByteDenseNdArray((ByteDataBuffer)buffer, dimensions); + } + + @Override + protected ByteDataBuffer buffer() { + return buffer; + } + + private final ByteDataBuffer buffer; + + private ByteDenseNdArray(ByteDataBuffer buffer, DimensionalSpace dimensions) { + super(dimensions); + this.buffer = buffer; + } +} \ No newline at end of file diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/DataTransfer.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/DataTransfer.java new file mode 100644 index 00000000000..d3afa223231 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/DataTransfer.java @@ -0,0 +1,136 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.dense; + +import org.tensorflow.ndarray.buffer.BooleanDataBuffer; +import org.tensorflow.ndarray.buffer.ByteDataBuffer; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DoubleDataBuffer; +import org.tensorflow.ndarray.buffer.FloatDataBuffer; +import org.tensorflow.ndarray.buffer.IntDataBuffer; +import org.tensorflow.ndarray.buffer.LongDataBuffer; +import org.tensorflow.ndarray.buffer.ShortDataBuffer; +import org.tensorflow.ndarray.impl.dimension.DimensionalSpace; +import org.tensorflow.ndarray.impl.sequence.PositionIterator; + +final class DataTransfer { + + @FunctionalInterface + interface OfValue> { + void copy(B srcBuffer, long srcIndex, B dstBuffer, long dstIndex); + } + + static > void ofValue(B srcBuf, long srcIdx, B dstBuf, long dstIdx) { + dstBuf.setObject(srcBuf.getObject(srcIdx), dstIdx); + } + + static void ofByte(ByteDataBuffer srcBuf, long srcIdx, ByteDataBuffer dstBuf, long dstIdx) { + dstBuf.setByte(srcBuf.getByte(srcIdx), dstIdx); + } + + static void ofInt(IntDataBuffer srcBuf, long srcIdx, IntDataBuffer dstBuf, long dstIdx) { + dstBuf.setInt(srcBuf.getInt(srcIdx), dstIdx); + } + + static void ofLong(LongDataBuffer srcBuf, long srcIdx, LongDataBuffer dstBuf, long dstIdx) { + dstBuf.setLong(srcBuf.getLong(srcIdx), dstIdx); + } + + static void ofDouble(DoubleDataBuffer srcBuf, long srcIdx, DoubleDataBuffer dstBuf, long dstIdx) { + dstBuf.setDouble(srcBuf.getDouble(srcIdx), dstIdx); + } + + static void ofFloat(FloatDataBuffer srcBuf, long srcIdx, FloatDataBuffer dstBuf, long dstIdx) { + dstBuf.setFloat(srcBuf.getFloat(srcIdx), dstIdx); + } + + static void ofShort(ShortDataBuffer srcBuf, long srcIdx, ShortDataBuffer dstBuf, long dstIdx) { + dstBuf.setShort(srcBuf.getShort(srcIdx), dstIdx); + } + + static void ofBoolean(BooleanDataBuffer srcBuf, long srcIdx, BooleanDataBuffer dstBuf, long dstIdx) { + dstBuf.setBoolean(srcBuf.getBoolean(srcIdx), dstIdx); + } + + static > void execute(B srcBuffer, DimensionalSpace srcDimensions, B dstBuffer, DimensionalSpace dstDimensions, OfValue valueTransfer) { + if (srcDimensions.isSegmented() || dstDimensions.isSegmented()) { + int segmentationIdx = Math.max(srcDimensions.segmentationIdx(), dstDimensions.segmentationIdx()); + copyByElement( + srcBuffer, + PositionIterator.create(srcDimensions, segmentationIdx), + dstBuffer, + PositionIterator.create(dstDimensions, segmentationIdx), + srcDimensions.get(segmentationIdx).elementSize(), + valueTransfer + ); + } else { + srcBuffer.copyTo(dstBuffer, srcDimensions.physicalSize()); + } + } + + static > void execute(B srcBuffer, B dstBuffer, DimensionalSpace dstDimensions, OfValue valueTransfer) { + if (dstDimensions.isSegmented()) { + long elementSize = dstDimensions.get(dstDimensions.segmentationIdx()).elementSize(); + copyByElement( + srcBuffer, + PositionIterator.sequence(elementSize, srcBuffer.size()), + dstBuffer, + PositionIterator.create(dstDimensions, dstDimensions.segmentationIdx()), + elementSize, + valueTransfer + ); + } else { + srcBuffer.copyTo(dstBuffer, dstDimensions.physicalSize()); + } + } + + static > void execute(B srcBuffer, DimensionalSpace srcDimensions, B dstBuffer, OfValue valueTransfer) { + if (srcDimensions.isSegmented()) { + long elementSize = srcDimensions.get(srcDimensions.segmentationIdx()).elementSize(); + copyByElement( + srcBuffer, + PositionIterator.create(srcDimensions, srcDimensions.segmentationIdx()), + dstBuffer, + PositionIterator.sequence(elementSize, dstBuffer.size()), + elementSize, + valueTransfer + ); + } else { + srcBuffer.copyTo(dstBuffer, srcDimensions.physicalSize()); + } + } + + private static > void copyByElement( + B srcBuffer, + PositionIterator srcIterator, + B dstBuffer, + PositionIterator dstIterator, + long elementSize, + OfValue valueTransfer + ) { + if (elementSize == 1) { + while (srcIterator.hasNext()) { + valueTransfer.copy(srcBuffer, srcIterator.nextLong(), dstBuffer, dstIterator.nextLong()); + } + } else { + while (srcIterator.hasNext()) { + srcBuffer.offset(srcIterator.nextLong()).copyTo(dstBuffer.offset(dstIterator.nextLong()), elementSize); + } + } + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/DenseNdArray.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/DenseNdArray.java new file mode 100644 index 00000000000..819d95de2fc --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/DenseNdArray.java @@ -0,0 +1,63 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.dense; + +import org.tensorflow.ndarray.Shape; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.NdArray; +import org.tensorflow.ndarray.impl.dimension.DimensionalSpace; + +public class DenseNdArray extends AbstractDenseNdArray> { + + public static NdArray wrap(DataBuffer buffer, Shape shape) { + Validator.denseShape(buffer, shape); + return new DenseNdArray<>(buffer, shape); + } + + @Override + public NdArray copyTo(NdArray dst) { + Validator.copyToNdArrayArgs(this, dst); + if (dst instanceof DenseNdArray) { + DenseNdArray denseDst = (DenseNdArray)dst; + DataTransfer.execute(buffer, dimensions(), denseDst.buffer, denseDst.dimensions(), DataTransfer::ofValue); + } else { + slowCopyTo(dst); + } + return this; + } + + protected DenseNdArray(DataBuffer buffer, Shape shape) { + this(buffer, DimensionalSpace.create(shape)); + } + + @Override + DenseNdArray instantiate(DataBuffer buffer, DimensionalSpace dimensions) { + return new DenseNdArray<>(buffer, dimensions); + } + + @Override + protected DataBuffer buffer() { + return buffer; + } + + private final DataBuffer buffer; + + private DenseNdArray(DataBuffer buffer, DimensionalSpace dimensions) { + super(dimensions); + this.buffer = buffer; + } +} \ No newline at end of file diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/DoubleDenseNdArray.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/DoubleDenseNdArray.java new file mode 100644 index 00000000000..f54b8d0347a --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/DoubleDenseNdArray.java @@ -0,0 +1,91 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.dense; + +import org.tensorflow.ndarray.DoubleNdArray; +import org.tensorflow.ndarray.NdArray; +import org.tensorflow.ndarray.Shape; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DoubleDataBuffer; +import org.tensorflow.ndarray.impl.dimension.DimensionalSpace; + +public class DoubleDenseNdArray extends AbstractDenseNdArray + implements DoubleNdArray { + + public static DoubleNdArray create(DoubleDataBuffer buffer, Shape shape) { + Validator.denseShape(buffer, shape); + return new DoubleDenseNdArray(buffer, shape); + } + + @Override + public double getDouble(long... indices) { + return buffer.getDouble(positionOf(indices, true)); + } + + @Override + public DoubleNdArray setDouble(double value, long... indices) { + buffer.setDouble(value, positionOf(indices, true)); + return this; + } + + @Override + public DoubleNdArray copyTo(NdArray dst) { + Validator.copyToNdArrayArgs(this, dst); + if (dst instanceof DoubleDenseNdArray) { + DoubleDenseNdArray doubleDst = (DoubleDenseNdArray)dst; + DataTransfer.execute(buffer, dimensions(), doubleDst.buffer, doubleDst.dimensions(), DataTransfer::ofDouble); + } else { + slowCopyTo(dst); + } + return this; + } + + @Override + public DoubleNdArray read(DoubleDataBuffer dst) { + Validator.readToBufferArgs(this, dst); + DataTransfer.execute(buffer, dimensions(), dst, DataTransfer::ofDouble); + return this; + } + + @Override + public DoubleNdArray write(DoubleDataBuffer src) { + Validator.writeFromBufferArgs(this, src); + DataTransfer.execute(src, buffer, dimensions(), DataTransfer::ofDouble); + return this; + } + + protected DoubleDenseNdArray(DoubleDataBuffer buffer, Shape shape) { + this(buffer, DimensionalSpace.create(shape)); + } + + @Override + DoubleDenseNdArray instantiate(DataBuffer buffer, DimensionalSpace dimensions) { + return new DoubleDenseNdArray((DoubleDataBuffer)buffer, dimensions); + } + + @Override + protected DoubleDataBuffer buffer() { + return buffer; + } + + private final DoubleDataBuffer buffer; + + private DoubleDenseNdArray(DoubleDataBuffer buffer, DimensionalSpace dimensions) { + super(dimensions); + this.buffer = buffer; + } +} \ No newline at end of file diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/FloatDenseNdArray.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/FloatDenseNdArray.java new file mode 100644 index 00000000000..196b5ef8b11 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/FloatDenseNdArray.java @@ -0,0 +1,91 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.dense; + +import org.tensorflow.ndarray.FloatNdArray; +import org.tensorflow.ndarray.NdArray; +import org.tensorflow.ndarray.Shape; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.FloatDataBuffer; +import org.tensorflow.ndarray.impl.dimension.DimensionalSpace; + +public class FloatDenseNdArray extends AbstractDenseNdArray + implements FloatNdArray { + + public static FloatNdArray create(FloatDataBuffer buffer, Shape shape) { + Validator.denseShape(buffer, shape); + return new FloatDenseNdArray(buffer, shape); + } + + @Override + public float getFloat(long... indices) { + return buffer.getFloat(positionOf(indices, true)); + } + + @Override + public FloatNdArray setFloat(float value, long... indices) { + buffer.setFloat(value, positionOf(indices, true)); + return this; + } + + @Override + public FloatNdArray copyTo(NdArray dst) { + Validator.copyToNdArrayArgs(this, dst); + if (dst instanceof FloatDenseNdArray) { + FloatDenseNdArray floatDst = (FloatDenseNdArray)dst; + DataTransfer.execute(buffer, dimensions(), floatDst.buffer, floatDst.dimensions(), DataTransfer::ofFloat); + } else { + slowCopyTo(dst); + } + return this; + } + + @Override + public FloatNdArray read(FloatDataBuffer dst) { + Validator.readToBufferArgs(this, dst); + DataTransfer.execute(buffer, dimensions(), dst, DataTransfer::ofFloat); + return this; + } + + @Override + public FloatNdArray write(FloatDataBuffer src) { + Validator.writeFromBufferArgs(this, src); + DataTransfer.execute(src, buffer, dimensions(), DataTransfer::ofFloat); + return this; + } + + protected FloatDenseNdArray(FloatDataBuffer buffer, Shape shape) { + this(buffer, DimensionalSpace.create(shape)); + } + + @Override + FloatDenseNdArray instantiate(DataBuffer buffer, DimensionalSpace dimensions) { + return new FloatDenseNdArray((FloatDataBuffer) buffer, dimensions); + } + + @Override + public FloatDataBuffer buffer() { + return buffer; + } + + private final FloatDataBuffer buffer; + + private FloatDenseNdArray(FloatDataBuffer buffer, DimensionalSpace dimensions) { + super(dimensions); + this.buffer = buffer; + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/IntDenseNdArray.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/IntDenseNdArray.java new file mode 100644 index 00000000000..a7af498dd6f --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/IntDenseNdArray.java @@ -0,0 +1,91 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.dense; + +import org.tensorflow.ndarray.Shape; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.IntDataBuffer; +import org.tensorflow.ndarray.IntNdArray; +import org.tensorflow.ndarray.NdArray; +import org.tensorflow.ndarray.impl.dimension.DimensionalSpace; + +public class IntDenseNdArray extends AbstractDenseNdArray + implements IntNdArray { + + public static IntNdArray create(IntDataBuffer buffer, Shape shape) { + Validator.denseShape(buffer, shape); + return new IntDenseNdArray(buffer, shape); + } + + @Override + public int getInt(long... indices) { + return buffer.getInt(positionOf(indices, true)); + } + + @Override + public IntNdArray setInt(int value, long... indices) { + buffer.setInt(value, positionOf(indices, true)); + return this; + } + + @Override + public IntNdArray copyTo(NdArray dst) { + Validator.copyToNdArrayArgs(this, dst); + if (dst instanceof IntDenseNdArray) { + IntDenseNdArray intDst = (IntDenseNdArray)dst; + DataTransfer.execute(buffer, dimensions(), intDst.buffer, intDst.dimensions(), DataTransfer::ofInt); + } else { + slowCopyTo(dst); + } + return this; + } + + @Override + public IntNdArray read(IntDataBuffer dst) { + Validator.readToBufferArgs(this, dst); + DataTransfer.execute(buffer, dimensions(), dst, DataTransfer::ofInt); + return this; + } + + @Override + public IntNdArray write(IntDataBuffer src) { + Validator.writeFromBufferArgs(this, src); + DataTransfer.execute(src, buffer, dimensions(), DataTransfer::ofInt); + return this; + } + + protected IntDenseNdArray(IntDataBuffer buffer, Shape shape) { + this(buffer, DimensionalSpace.create(shape)); + } + + @Override + IntDenseNdArray instantiate(DataBuffer buffer, DimensionalSpace dimensions) { + return new IntDenseNdArray((IntDataBuffer)buffer, dimensions); + } + + @Override + protected IntDataBuffer buffer() { + return buffer; + } + + private final IntDataBuffer buffer; + + private IntDenseNdArray(IntDataBuffer buffer, DimensionalSpace dimensions) { + super(dimensions); + this.buffer = buffer; + } +} \ No newline at end of file diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/LongDenseNdArray.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/LongDenseNdArray.java new file mode 100644 index 00000000000..cd56dadfb2b --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/LongDenseNdArray.java @@ -0,0 +1,91 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.dense; + +import org.tensorflow.ndarray.LongNdArray; +import org.tensorflow.ndarray.NdArray; +import org.tensorflow.ndarray.Shape; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.LongDataBuffer; +import org.tensorflow.ndarray.impl.dimension.DimensionalSpace; + +public class LongDenseNdArray extends AbstractDenseNdArray + implements LongNdArray { + + public static LongNdArray create(LongDataBuffer buffer, Shape shape) { + Validator.denseShape(buffer, shape); + return new LongDenseNdArray(buffer, shape); + } + + @Override + public long getLong(long... indices) { + return buffer.getLong(positionOf(indices, true)); + } + + @Override + public LongNdArray setLong(long value, long... indices) { + buffer.setLong(value, positionOf(indices, true)); + return this; + } + + @Override + public LongNdArray copyTo(NdArray dst) { + Validator.copyToNdArrayArgs(this, dst); + if (dst instanceof LongDenseNdArray) { + LongDenseNdArray longDst = (LongDenseNdArray)dst; + DataTransfer.execute(buffer, dimensions(), longDst.buffer, longDst.dimensions(), DataTransfer::ofLong); + } else { + slowCopyTo(dst); + } + return this; + } + + @Override + public LongNdArray read(LongDataBuffer dst) { + Validator.readToBufferArgs(this, dst); + DataTransfer.execute(buffer, dimensions(), dst, DataTransfer::ofLong); + return this; + } + + @Override + public LongNdArray write(LongDataBuffer src) { + Validator.writeFromBufferArgs(this, src); + DataTransfer.execute(src, buffer, dimensions(), DataTransfer::ofLong); + return this; + } + + protected LongDenseNdArray(LongDataBuffer buffer, Shape shape) { + this(buffer, DimensionalSpace.create(shape)); + } + + @Override + LongDenseNdArray instantiate(DataBuffer buffer, DimensionalSpace dimensions) { + return new LongDenseNdArray((LongDataBuffer)buffer, dimensions); + } + + @Override + protected LongDataBuffer buffer() { + return buffer; + } + + private final LongDataBuffer buffer; + + private LongDenseNdArray(LongDataBuffer buffer, DimensionalSpace dimensions) { + super(dimensions); + this.buffer = buffer; + } +} \ No newline at end of file diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/ShortDenseNdArray.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/ShortDenseNdArray.java new file mode 100644 index 00000000000..291c01ac8e1 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/ShortDenseNdArray.java @@ -0,0 +1,91 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.dense; + +import org.tensorflow.ndarray.NdArray; +import org.tensorflow.ndarray.ShortNdArray; +import org.tensorflow.ndarray.Shape; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.ShortDataBuffer; +import org.tensorflow.ndarray.impl.dimension.DimensionalSpace; + +public class ShortDenseNdArray extends AbstractDenseNdArray + implements ShortNdArray { + + public static ShortNdArray create(ShortDataBuffer buffer, Shape shape) { + Validator.denseShape(buffer, shape); + return new ShortDenseNdArray(buffer, shape); + } + + @Override + public short getShort(long... indices) { + return buffer.getShort(positionOf(indices, true)); + } + + @Override + public ShortNdArray setShort(short value, long... indices) { + buffer.setShort(value, positionOf(indices, true)); + return this; + } + + @Override + public ShortNdArray copyTo(NdArray dst) { + Validator.copyToNdArrayArgs(this, dst); + if (dst instanceof ShortDenseNdArray) { + ShortDenseNdArray shortDst = (ShortDenseNdArray)dst; + DataTransfer.execute(buffer, dimensions(), shortDst.buffer, shortDst.dimensions(), DataTransfer::ofShort); + } else { + slowCopyTo(dst); + } + return this; + } + + @Override + public ShortNdArray read(ShortDataBuffer dst) { + Validator.readToBufferArgs(this, dst); + DataTransfer.execute(buffer, dimensions(), dst, DataTransfer::ofShort); + return this; + } + + @Override + public ShortNdArray write(ShortDataBuffer src) { + Validator.writeFromBufferArgs(this, src); + DataTransfer.execute(src, buffer, dimensions(), DataTransfer::ofShort); + return this; + } + + protected ShortDenseNdArray(ShortDataBuffer buffer, Shape shape) { + this(buffer, DimensionalSpace.create(shape)); + } + + @Override + ShortDenseNdArray instantiate(DataBuffer buffer, DimensionalSpace dimensions) { + return new ShortDenseNdArray((ShortDataBuffer)buffer, dimensions); + } + + @Override + protected ShortDataBuffer buffer() { + return buffer; + } + + private final ShortDataBuffer buffer; + + private ShortDenseNdArray(ShortDataBuffer buffer, DimensionalSpace dimensions) { + super(dimensions); + this.buffer = buffer; + } +} \ No newline at end of file diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/Validator.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/Validator.java new file mode 100644 index 00000000000..b0bcae252fb --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dense/Validator.java @@ -0,0 +1,49 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.dense; + +import org.tensorflow.ndarray.IllegalRankException; +import org.tensorflow.ndarray.Shape; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.impl.dimension.DimensionalSpace; + +final class Validator extends org.tensorflow.ndarray.impl.Validator { + + static void coordinates(DimensionalSpace dimensions, long[] coords, + boolean isValue) { + if (coords.length > dimensions.numDimensions()) { + throw new IndexOutOfBoundsException(); + } + if (isValue && coords.length != dimensions.numDimensions()) { + throw new IllegalRankException("Not a scalar value"); + } + } + + static void denseShape(DataBuffer buffer, Shape shape) { + if (shape == null) { + throw new IllegalArgumentException("Shape cannot be null"); + } + if (shape.hasUnknownDimension()) { + throw new IllegalArgumentException("Dense arrays cannot have unknown dimension(s)"); + } + if (buffer.size() < shape.size()) { + throw new IllegalArgumentException("Buffer size is smaller than the shape size"); + }; + } + + private Validator() {} +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/dimension/AbstractDimension.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dimension/AbstractDimension.java new file mode 100644 index 00000000000..f2a0fb05b6e --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dimension/AbstractDimension.java @@ -0,0 +1,45 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.dimension; + +abstract class AbstractDimension implements Dimension { + + /** + * Dimensions are known to be equal if they have the same number of elements + */ + @Override + public int hashCode() { + final int prime = 17; + long numElements = numElements(); + return 31 * prime + (int)(numElements ^ (numElements >>> 32)); + } + + /** + * Dimensions are known to be equal if they have the same number of elements + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof Dimension) { + Dimension otherDimension = (Dimension) obj; + return numElements() == otherDimension.numElements(); + } + return false; + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/dimension/Axis.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dimension/Axis.java new file mode 100644 index 00000000000..91973c752a1 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dimension/Axis.java @@ -0,0 +1,61 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.dimension; + +final class Axis extends AbstractDimension { + + @Override + public long numElements() { + return numElements; + } + + @Override + public long positionOf(long coord) { + if (coord >= numElements) { + throw new IndexOutOfBoundsException(); + } + return elementSize * coord; + } + + @Override + public boolean isSegmented() { + return false; // all axis are continuous + } + + @Override + public long elementSize() { + return elementSize; + } + + @Override + public long physicalSize() { + return elementSize * numElements; + } + + @Override + public String toString() { + return String.valueOf(numElements); + } + + Axis(long numElements, long elementSize) { + this.numElements = numElements; + this.elementSize = elementSize; + } + + private final long numElements; + private final long elementSize; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/dimension/Dimension.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dimension/Dimension.java new file mode 100644 index 00000000000..cbae2d897a8 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dimension/Dimension.java @@ -0,0 +1,36 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.dimension; + +import org.tensorflow.ndarray.index.Index; + +public interface Dimension { + + default Dimension withIndex(Index index) { + return new IndexedDimension(index, this); + } + + long numElements(); + + long elementSize(); + + long physicalSize(); + + long positionOf(long coord); + + boolean isSegmented(); +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/dimension/DimensionalSpace.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dimension/DimensionalSpace.java new file mode 100644 index 00000000000..7d0f0222bbe --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dimension/DimensionalSpace.java @@ -0,0 +1,224 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ + +package org.tensorflow.ndarray.impl.dimension; + +import java.util.Arrays; +import org.tensorflow.ndarray.Shape; +import org.tensorflow.ndarray.index.Index; + +public class DimensionalSpace { + + public static DimensionalSpace create(Shape shape) { + Dimension[] dimensions = new Dimension[shape.numDimensions()]; + + // Start from the last dimension, where all elements are continuous + for (int i = dimensions.length - 1, elementSize = 1; i >= 0; --i) { + dimensions[i] = new Axis(shape.size(i), elementSize); + elementSize *= dimensions[i].numElements(); + } + return new DimensionalSpace(dimensions, shape); + } + + public RelativeDimensionalSpace mapTo(Index[] indices) { + if (dimensions == null) { + throw new ArrayIndexOutOfBoundsException(); + } + int dimIdx = 0; + int indexIdx = 0; + int newDimIdx = 0; + int segmentationIdx = -1; + long initialOffset = 0; + + int newAxes = 0; + boolean seenEllipsis = false; + for (Index idx : indices) { + if (idx.isNewAxis()) { + newAxes += 1; + } + if (idx.isEllipsis()) { + if (seenEllipsis) { + throw new IllegalArgumentException("Only one ellipsis allowed"); + } else { + seenEllipsis = true; + } + } + } + int newLength = dimensions.length + newAxes; + + Dimension[] newDimensions = new Dimension[newLength]; + while (indexIdx < indices.length) { + + if (indices[indexIdx].isPoint()) { + // When an index targets a single point in a given dimension, calculate the offset of this + // point and cumulate the offset of any subsequent point as well + long offset = 0; + do { + offset += indices[indexIdx].mapCoordinate(0, dimensions[dimIdx]); + dimIdx++; + } while (++indexIdx < indices.length && indices[indexIdx].isPoint()); + + // If this is the first index, then the offset is the position of the whole dimension + // space within the original one. If not, then we apply the offset to the last vectorial + // dimension + if (newDimIdx == 0) { + initialOffset = offset; + } else { + long reducedSize = dimensions[dimIdx - 1].elementSize(); + newDimensions[newDimIdx - 1] = new ReducedDimension(newDimensions[newDimIdx - 1], offset, reducedSize); + segmentationIdx = newDimIdx - 1; + } + + } else if (indices[indexIdx].isNewAxis()) { + long newSize; + if (dimIdx == 0) { + // includes everything. Should really include future reduction (at()) but that doesn't seem to cause issues + // elsewhere + newSize = dimensions[0].numElements() * dimensions[0].elementSize(); + } else { + newSize = dimensions[dimIdx - 1].elementSize(); + } + + newDimensions[newDimIdx] = new Axis(1, newSize); + segmentationIdx = newDimIdx; // is this correct? + ++newDimIdx; + ++indexIdx; + } else if (indices[indexIdx].isEllipsis()) { + int remainingDimensions = dimensions.length - dimIdx; + int requiredDimensions = 0; + for (int i = indexIdx + 1; i < indices.length; i++) { + if (!indices[i].isNewAxis()) { + requiredDimensions++; + } + } + // while the number of dimensions left < the number of indices that consume axes + while (remainingDimensions > requiredDimensions) { + Dimension dim = dimensions[dimIdx++]; + if (dim.isSegmented()) { + segmentationIdx = newDimIdx; + } + newDimensions[newDimIdx++] = dim; + remainingDimensions--; + } + indexIdx++; + } else { + // Map any other index to the appropriate dimension of this space + Dimension newDimension = indices[indexIdx].apply(dimensions[dimIdx++]); + newDimensions[newDimIdx] = newDimension; + if (newDimension.isSegmented()) { + segmentationIdx = newDimIdx; + } + ++newDimIdx; + ++indexIdx; + } + } + + // When the number of indices provided is smaller than the number of dimensions in this space, + // we copy the remaining dimensions directly to the new space as well. + for (; dimIdx < dimensions.length; ++dimIdx, ++newDimIdx) { + Dimension dim = dimensions[dimIdx]; + newDimensions[newDimIdx] = dim; + if (dim.isSegmented()) { + segmentationIdx = newDimIdx; + } + } + return new RelativeDimensionalSpace(Arrays.copyOf(newDimensions, newDimIdx), segmentationIdx, initialOffset); + } + + public DimensionalSpace from(int dimensionStart) { + if (dimensionStart > dimensions.length) { + throw new IndexOutOfBoundsException(); + } + Dimension[] newDimensions = Arrays.copyOfRange(dimensions, dimensionStart, dimensions.length); + if (segmentationIdx > dimensionStart) { + return new DimensionalSpace(newDimensions, segmentationIdx - dimensionStart); + } + return new DimensionalSpace(newDimensions); + } + + public Shape shape() { + if (shape == null) { + shape = toShape(dimensions); + } + return shape; + } + + public int numDimensions() { + return dimensions.length; + } + + public long numElements(int i) { + return dimensions[i].numElements(); + } + + public long physicalSize() { + return dimensions.length > 0 ? dimensions[0].physicalSize() : 1; // dimensions.length == 0 for scalars + } + + public Dimension get(int i) { + return dimensions[i]; + } + + public boolean isSegmented() { + return segmentationIdx >= 0; + } + + public int segmentationIdx() { + return segmentationIdx; + } + + public long positionOf(long[] coords) { + long position = 0L; + for (int i = 0; i < coords.length; ++i) { + position += dimensions[i].positionOf(coords[i]); + } + return position; + } + + /** Succinct description of the shape meant for debugging. */ + @Override + public String toString() { + return Arrays.toString(dimensions); + } + + DimensionalSpace(Dimension[] dimensions, int segmentationIdx) { + this.dimensions = dimensions; + this.segmentationIdx = segmentationIdx; + } + + private DimensionalSpace(Dimension[] dimensions) { + this(dimensions, -1); + } + + private DimensionalSpace(Dimension[] dimensions, Shape shape) { + this(dimensions); + this.shape = shape; + } + + private final Dimension[] dimensions; + private final int segmentationIdx; + private Shape shape; + + private static Shape toShape(Dimension[] dimensions) { + long[] shapeDimSizes = new long[dimensions.length]; + int i = 0; + for (Dimension dimension : dimensions) { + shapeDimSizes[i++] = dimension.numElements(); + } + return Shape.of(shapeDimSizes); + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/dimension/IndexedDimension.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dimension/IndexedDimension.java new file mode 100644 index 00000000000..2b609bc3535 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dimension/IndexedDimension.java @@ -0,0 +1,69 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.dimension; + +import org.tensorflow.ndarray.index.Index; + +final class IndexedDimension extends AbstractDimension { + + @Override + public long numElements() { + return numElements; + } + + @Override + public long positionOf(long coord) { + if (coord >= numElements()) { + throw new IndexOutOfBoundsException(); + } + return originalDimension.positionOf(index.mapCoordinate(coord, originalDimension)); + } + + @Override + public boolean isSegmented() { + // TODO (karllessard) for now we consider all indexed dimensions as segmented but might depend + // on the actual index + return true; + } + + @Override + public long elementSize() { + return originalDimension.elementSize(); // indices do not change the size of an inner element + } + + @Override + public long physicalSize() { + // TODO (karllessard) we consider this dimension takes the same amount of memory that the + // original one but might depend on the actual index + return originalDimension.physicalSize(); + } + + @Override + public String toString() { + return String.valueOf(numElements()); + } + + IndexedDimension(Index index, Dimension originalDimension) { + this.index = index; + this.originalDimension = originalDimension; + this.numElements = index.numElements(originalDimension); + } + + private final Index index; + private final Dimension originalDimension; + private final long numElements; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/dimension/ReducedDimension.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dimension/ReducedDimension.java new file mode 100644 index 00000000000..4b5cb1adcf8 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dimension/ReducedDimension.java @@ -0,0 +1,62 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.dimension; + +final class ReducedDimension extends AbstractDimension { + + @Override + public long numElements() { + return originalDimension.numElements(); + } + + @Override + public long positionOf(long coord) { + return originalDimension.positionOf(coord) + offset; + } + + @Override + public boolean isSegmented() { + return true; + } + + @Override + public long elementSize() { + return elementSize; + } + + @Override + public long physicalSize() { + // We simplify the computation by assuming that a reduced dimension takes the same amount of + // memory than the original one + return originalDimension.physicalSize(); + } + + @Override + public String toString() { + return String.valueOf(numElements()); + } + + ReducedDimension(Dimension originalDimension, long offset, long elementSize) { + this.originalDimension = originalDimension; + this.offset = offset; + this.elementSize = elementSize; + } + + private final Dimension originalDimension; + private final long offset; + private final long elementSize; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/dimension/RelativeDimensionalSpace.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dimension/RelativeDimensionalSpace.java new file mode 100644 index 00000000000..4259bbcf76e --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/dimension/RelativeDimensionalSpace.java @@ -0,0 +1,32 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ + +package org.tensorflow.ndarray.impl.dimension; + +public class RelativeDimensionalSpace extends DimensionalSpace { + + public long position() { + return position; + } + + RelativeDimensionalSpace(Dimension[] dimensions, int segmentationIdx, long position) { + super(dimensions, segmentationIdx); + this.position = position; + } + + private long position; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/CoordinatesIncrementor.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/CoordinatesIncrementor.java new file mode 100644 index 00000000000..8c9c9f86f4c --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/CoordinatesIncrementor.java @@ -0,0 +1,38 @@ +/* + * Copyright 2020 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.sequence; + +final class CoordinatesIncrementor { + + boolean increment() { + for (int i = coords.length - 1; i >= 0; --i) { + if ((coords[i] = (coords[i] + 1) % shape[i]) > 0) { + return true; + } + } + return false; + } + + CoordinatesIncrementor(long[] shape, int dimensionIdx) { + this.shape = shape; + this.coords = new long[dimensionIdx + 1]; + } + + final long[] shape; + final long[] coords; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/FastElementSequence.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/FastElementSequence.java new file mode 100644 index 00000000000..92cebeb2338 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/FastElementSequence.java @@ -0,0 +1,81 @@ +/* + * Copyright 2020 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.sequence; + +import java.util.Iterator; +import java.util.function.BiConsumer; + +import org.tensorflow.ndarray.NdArray; +import org.tensorflow.ndarray.NdArraySequence; +import org.tensorflow.ndarray.buffer.DataBufferWindow; +import org.tensorflow.ndarray.impl.AbstractNdArray; + +/** + * A sequence recycling the same {@code NdArray} instance when iterating its elements + * + * @param Type of the elements + * @param Type of the {@code NdArray} with this sequence + */ +public final class FastElementSequence> implements NdArraySequence { + + public FastElementSequence(AbstractNdArray ndArray, int dimensionIdx, U element, DataBufferWindow elementWindow) { + this.ndArray = ndArray; + this.dimensionIdx = dimensionIdx; + this.element = element; + this.elementWindow = elementWindow; + } + + @Override + public Iterator iterator() { + return new SequenceIterator(); + } + + @Override + public void forEachIndexed(BiConsumer consumer) { + PositionIterator.createIndexed(ndArray.dimensions(), dimensionIdx).forEachIndexed((long[] coords, long position) -> { + elementWindow.slideTo(position); + consumer.accept(coords, element); + }); + } + + @Override + public NdArraySequence asSlices() { + return new SlicingElementSequence(ndArray, dimensionIdx); + } + + private class SequenceIterator implements Iterator { + + @Override + public boolean hasNext() { + return positionIterator.hasNext(); + } + + @Override + public U next() { + elementWindow.slideTo(positionIterator.nextLong()); + return element; + } + + private final PositionIterator positionIterator = PositionIterator.create(ndArray.dimensions(), dimensionIdx); + } + + private final AbstractNdArray ndArray; + private final int dimensionIdx; + private final U element; + private final DataBufferWindow elementWindow; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/IndexedPositionIterator.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/IndexedPositionIterator.java new file mode 100644 index 00000000000..30ece1599b6 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/IndexedPositionIterator.java @@ -0,0 +1,28 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.sequence; + +public interface IndexedPositionIterator extends PositionIterator { + + @FunctionalInterface + interface CoordsLongConsumer { + void consume(long[] coords, long position); + } + + void forEachIndexed(CoordsLongConsumer consumer); +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/IndexedSequentialPositionIterator.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/IndexedSequentialPositionIterator.java new file mode 100644 index 00000000000..80b3de681bd --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/IndexedSequentialPositionIterator.java @@ -0,0 +1,51 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.sequence; + +import org.tensorflow.ndarray.impl.dimension.DimensionalSpace; + +class IndexedSequentialPositionIterator extends SequentialPositionIterator implements IndexedPositionIterator { + + @Override + public void forEachIndexed(CoordsLongConsumer consumer) { + while (hasNext()) { + consumer.consume(coords, nextLong()); + incrementCoords(); + } + } + + private void incrementCoords() { + for (int i = coords.length - 1; i >= 0; --i) { + if (coords[i] < shape[i] - 1) { + coords[i] += 1L; + return; + } + coords[i] = 0L; + } + } + + IndexedSequentialPositionIterator(DimensionalSpace dimensions, int dimensionIdx) { + super(dimensions, dimensionIdx); + this.shape = dimensions.shape().asArray(); + this.coords = new long[dimensionIdx + 1]; + //this.coordsIncrementor = new CoordinatesIncrementor(dimensions.shape().asArray(), dimensionIdx); + } + + private final long[] shape; + private final long[] coords; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/NdPositionIterator.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/NdPositionIterator.java new file mode 100644 index 00000000000..789474c58ae --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/NdPositionIterator.java @@ -0,0 +1,70 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.sequence; + +import java.util.NoSuchElementException; +import org.tensorflow.ndarray.impl.dimension.DimensionalSpace; + +class NdPositionIterator implements IndexedPositionIterator { + + @Override + public boolean hasNext() { + return coords != null; + } + + @Override + public long nextLong() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + long position = dimensions.positionOf(coords); + increment(); + return position; + } + + @Override + public void forEachIndexed(CoordsLongConsumer consumer) { + while (hasNext()) { + consumer.consume(coords, dimensions.positionOf(coords)); + increment(); + } + } + + private void increment() { + if (!increment(coords, dimensions)) { + coords = null; + } + } + + static boolean increment(long[] coords, DimensionalSpace dimensions) { + for (int i = coords.length - 1; i >= 0; --i) { + if ((coords[i] = (coords[i] + 1) % dimensions.get(i).numElements()) > 0) { + return true; + } + } + return false; + } + + NdPositionIterator(DimensionalSpace dimensions, int dimensionIdx) { + this.dimensions = dimensions; + this.coords = new long[dimensionIdx + 1]; + } + + private final DimensionalSpace dimensions; + private long[] coords; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/PositionIterator.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/PositionIterator.java new file mode 100644 index 00000000000..83ed940563c --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/PositionIterator.java @@ -0,0 +1,42 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.sequence; + +import java.util.PrimitiveIterator; +import org.tensorflow.ndarray.impl.dimension.DimensionalSpace; + +public interface PositionIterator extends PrimitiveIterator.OfLong { + + static PositionIterator create(DimensionalSpace dimensions, int dimensionIdx) { + if (dimensions.isSegmented()) { + return new NdPositionIterator(dimensions, dimensionIdx); + } + return new SequentialPositionIterator(dimensions, dimensionIdx); + } + + static IndexedPositionIterator createIndexed(DimensionalSpace dimensions, int dimensionIdx) { + if (dimensions.isSegmented()) { + return new NdPositionIterator(dimensions, dimensionIdx); + } + return new IndexedSequentialPositionIterator(dimensions, dimensionIdx); + } + + static PositionIterator sequence(long stride, long end) { + return new SequentialPositionIterator(stride, end); + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/SequentialPositionIterator.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/SequentialPositionIterator.java new file mode 100644 index 00000000000..65c6fc966cc --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/SequentialPositionIterator.java @@ -0,0 +1,55 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.sequence; + +import java.util.NoSuchElementException; +import org.tensorflow.ndarray.impl.dimension.DimensionalSpace; + +class SequentialPositionIterator implements PositionIterator { + + @Override + public boolean hasNext() { + return index < end; + } + + @Override + public long nextLong() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + return stride * index++; + } + + SequentialPositionIterator(DimensionalSpace dimensions, int dimensionIdx) { + long size = 1; + for (int i = 0; i <= dimensionIdx; ++i) { + size *= dimensions.get(i).numElements(); + } + this.stride = dimensions.get(dimensionIdx).elementSize(); + this.end = size; + } + + SequentialPositionIterator(long stride, long end) { + this.stride = stride; + this.end = end; + } + + private final long stride; + private final long end; + private long index; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/SingleElementSequence.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/SingleElementSequence.java new file mode 100644 index 00000000000..59525bf486b --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/SingleElementSequence.java @@ -0,0 +1,71 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.sequence; + +import java.util.Iterator; +import java.util.function.BiConsumer; +import org.tensorflow.ndarray.IllegalRankException; +import org.tensorflow.ndarray.NdArray; +import org.tensorflow.ndarray.NdArraySequence; +import org.tensorflow.ndarray.impl.AbstractNdArray; + +/** + * A sequence of one single element + * + * @param Type of the element + * @param Type of the {@code NdArray} with this sequence + */ +public final class SingleElementSequence> implements NdArraySequence { + + public SingleElementSequence(AbstractNdArray ndArray) { + this.ndArray = ndArray; + } + + @Override + public Iterator iterator() { + return new Iterator() { + + @Override + public boolean hasNext() { + return element != null; + } + + @Override + public U next() { + U ret = element; + element = null; + return ret; + } + + @SuppressWarnings("unchecked") + private U element = (U)ndArray; + }; + } + + @Override + public NdArraySequence asSlices() { + return this; // no need to slice, as there are only one element + } + + @Override + public void forEachIndexed(BiConsumer consumer) { + throw new IllegalRankException("Single element has no coordinates to iterate on, use forEach()"); + } + + private final AbstractNdArray ndArray; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/SlicingElementSequence.java b/ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/SlicingElementSequence.java new file mode 100644 index 00000000000..6fe8398ea70 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/impl/sequence/SlicingElementSequence.java @@ -0,0 +1,77 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.sequence; + +import java.util.Iterator; +import java.util.function.BiConsumer; +import org.tensorflow.ndarray.NdArray; +import org.tensorflow.ndarray.NdArraySequence; +import org.tensorflow.ndarray.impl.AbstractNdArray; +import org.tensorflow.ndarray.impl.dimension.DimensionalSpace; + +/** + * A sequence creating a new {@code NdArray} instance (slice) for each element of an iteration + * + * @param Type of the element + * @param Type of the {@code NdArray} with this sequence + */ +public final class SlicingElementSequence> implements NdArraySequence { + + public SlicingElementSequence(AbstractNdArray ndArray, int dimensionIdx) { + this(ndArray, dimensionIdx, ndArray.dimensions().from(dimensionIdx + 1)); + } + + public SlicingElementSequence(AbstractNdArray ndArray, int dimensionIdx, DimensionalSpace elementDimensions) { + this.ndArray = ndArray; + this.dimensionIdx = dimensionIdx; + this.elementDimensions = elementDimensions; + } + + @Override + public Iterator iterator() { + PositionIterator positionIterator = PositionIterator.create(ndArray.dimensions(), dimensionIdx); + return new Iterator() { + + @Override + public boolean hasNext() { + return positionIterator.hasNext(); + } + + @Override + public U next() { + return ndArray.slice(positionIterator.next(), elementDimensions); + } + }; + } + + @Override + public void forEachIndexed(BiConsumer consumer) { + PositionIterator.createIndexed(ndArray.dimensions(), dimensionIdx).forEachIndexed((long[] coords, long position) -> + consumer.accept(coords, ndArray.slice(position, elementDimensions)) + ); + } + + @Override + public NdArraySequence asSlices() { + return this; + } + + private final AbstractNdArray ndArray; + private final int dimensionIdx; + private final DimensionalSpace elementDimensions; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/index/All.java b/ndarray/src/main/java/org/tensorflow/ndarray/index/All.java new file mode 100644 index 00000000000..9d3139f3248 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/index/All.java @@ -0,0 +1,57 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.index; + +import org.tensorflow.ndarray.impl.dimension.Dimension; + +final class All implements Index { + + static final All INSTANCE = new All(); + + @Override + public long numElements(Dimension dim) { + return dim.numElements(); + } + + @Override + public long mapCoordinate(long coordinate, Dimension dim) { + return coordinate; + } + + @Override + public Dimension apply(Dimension dim) { + return dim; + } + + private All() { + } + + @Override + public boolean beginMask() { + return true; + } + + @Override + public boolean endMask() { + return true; + } + + @Override + public String toString() { + return All.class.getSimpleName() + "()"; + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/index/At.java b/ndarray/src/main/java/org/tensorflow/ndarray/index/At.java new file mode 100644 index 00000000000..31ce021ddc8 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/index/At.java @@ -0,0 +1,74 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.index; + +import java.util.StringJoiner; +import org.tensorflow.ndarray.impl.dimension.Dimension; + +final class At implements Index { + + @Override + public long numElements(Dimension dim) { + return 1; + } + + @Override + public long mapCoordinate(long coordinate, Dimension dim) { + long coord = this.coord >= 0 ? this.coord : dim.numElements() + this.coord; + return dim.positionOf(coord); + } + + @Override + public Dimension apply(Dimension dim) { + if (!keepDim) { + throw new UnsupportedOperationException("Should be handled in DimensionalSpace."); + } + + return dim.withIndex(this); + } + + @Override + public boolean isPoint() { + return !keepDim; + } + + At(long coord, boolean keepDim) { + this.coord = coord; + this.keepDim = keepDim; + } + + private final long coord; + private final boolean keepDim; + + @Override + public long begin() { + return coord; + } + + @Override + public long end() { + return coord + 1; + } + + @Override + public String toString() { + return new StringJoiner(", ", At.class.getSimpleName() + "(", ")") + .add("coord=" + coord) + .add("keepDim=" + keepDim) + .toString(); + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/index/Ellipsis.java b/ndarray/src/main/java/org/tensorflow/ndarray/index/Ellipsis.java new file mode 100644 index 00000000000..d4085735df2 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/index/Ellipsis.java @@ -0,0 +1,48 @@ +/* + Copyright 2020 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ============================================================================== + */ +package org.tensorflow.ndarray.index; + +import org.tensorflow.ndarray.impl.dimension.Dimension; + +final class Ellipsis implements Index { + + static final Ellipsis INSTANCE = new Ellipsis(); + + private Ellipsis() { + + } + + @Override + public long numElements(Dimension dim) { + throw new UnsupportedOperationException("Should be handled in DimensionalSpace."); + } + + @Override + public long mapCoordinate(long coordinate, Dimension dim) { + throw new UnsupportedOperationException("Should be handled in DimensionalSpace."); + } + + @Override + public boolean isEllipsis() { + return true; + } + + @Override + public String toString() { + return Ellipsis.class.getSimpleName() + "()"; + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/index/Hyperslab.java b/ndarray/src/main/java/org/tensorflow/ndarray/index/Hyperslab.java new file mode 100644 index 00000000000..55c4e510748 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/index/Hyperslab.java @@ -0,0 +1,90 @@ +/* + * Copyright 2020 Matteo Di Giovinazzo. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.tensorflow.ndarray.index; + +import java.util.StringJoiner; +import org.tensorflow.ndarray.impl.dimension.Dimension; + +/** + * A hyperslab is a rectangular pattern defined by four arrays. + * + * The {@code start} defines the origin of the hyperslab in the original coordinates. + * The {@code stride} is the number of elements to increment between selected elements. + * A stride of '1' is every element, a stride of '2' is every second element, etc. + * The default stride is 1. + * The {@code count} is the number of elements in the hyperslab selection. + * When the stride is 1, the selection is a hyper rectangle with a corner at {@code start} + * and size {@code count[0]} by {@code count[1]} by ... + * When stride is greater than one, the hyperslab bounded by start and the corners + * defined by {@code stride[n] * count[n]}. + * The {@code block} is a count on the number of repetitions of the hyperslab. + * The default block size is '1', which is one hyperslab. A block of 2 would be + * two hyperslabs in that dimension, with the second starting at {@code start[n]+ (count[n] * stride[n]) + 1}. + * + * @see https://portal.hdfgroup.org/display/HDF5/Reading+From+or+Writing+To+a+Subset+of+a+Dataset + * @see https://portal.hdfgroup.org/display/HDF5/H5S_SELECT_HYPERSLAB + * @see https://support.hdfgroup.org/HDF5/doc1.6/UG/12_Dataspaces.html + * @author Matteo Di Giovinazzo + */ +final class Hyperslab implements Index { + + @Override + public long numElements(Dimension dimension) { + return count * block; + } + + @Override + public long mapCoordinate(long coordinate, Dimension dimension) { + return start + stride * (coordinate / block) + (coordinate % block); + } + + @Override + public Dimension apply(Dimension dim) { + return dim.withIndex(this); + } + + @Override + public boolean isPoint() { + return false; + } + + Hyperslab(long start, long stride, long count, long block) { + this.start = start; + this.stride = stride; + this.count = count; + this.block = block; + } + + private final long start; + private final long stride; + private final long count; + private final long block; + + @Override + public String toString() { + return new StringJoiner(", ", Hyperslab.class.getSimpleName() + "Hyperslab(", ")") + .add("start=" + start) + .add("stride=" + stride) + .add("count=" + count) + .add("block=" + block) + .toString(); + } + + @Override + public boolean isStridedSlicingCompliant() { + return false; + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/index/Index.java b/ndarray/src/main/java/org/tensorflow/ndarray/index/Index.java new file mode 100644 index 00000000000..617ca4d474b --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/index/Index.java @@ -0,0 +1,131 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.index; + +import org.tensorflow.ndarray.NdArray; +import org.tensorflow.ndarray.impl.dimension.Dimension; + +/** + * An index used for slicing a view out of an N-dimensional array. + * + *

A slice, i.e. a reduced view, of an N-dimensional array is obtain by calling + * {@link NdArray#slice(Index...)}, given a list of indices that select which elements on a given dimension should be + * included/excluded from that view. + */ +public interface Index { + + /** + * Returns the number of elements that can be retrieved using this index on the given dimension. + * + *

An index that maps one-by-one all elements of the dimensions will return a value + * equal to {@code dim.numElements()}, while an index that only maps a subset of these will return a smaller value. + * + * @param dim the indexed dimension + * @return number of elements accessible + */ + long numElements(Dimension dim); + + /** + * Transforms an element coordinate to a new coordinate by applying this index to the given dimension. + * + *

For example, if the coordinate is 0 and this index flips the {@code n} elements on this + * dimension, then the returned value will be {@code n-1}. + * + * @param coordinate coordinate to transform + * @param dim dimension the indexed dimension + * @return transformed coordinate + */ + long mapCoordinate(long coordinate, Dimension dim); + + /** + * Applies this index to the given dimension. + * + *

When accessing the elements from the returned dimension, this index will automatically + * apply and may transform the original position. + * + * @param dim dimension to apply this index to + * @return an indexed dimension + */ + default Dimension apply(Dimension dim) { + return dim.withIndex(this); + } + + /** + * Returns true if this index is a single point, reducing the number of dimensions by one + */ + default boolean isPoint() { + return false; + } + + /** + * Returns true if this index is a new axis, adding a dimension of size 1 + */ + default boolean isNewAxis() { + return false; + } + + /** + * Returns true if this index is an ellipsis, expanding to take as many dimensions as possible (and applying all() to + * them) + */ + default boolean isEllipsis() { + return false; + } + + /** + * Get whether the Index supports strided slice style indexing (using start, end, stride, and flags, i.e. TensorFlow's). + */ + default boolean isStridedSlicingCompliant() { + return true; + } + + /** + * Get the start of the index, for strided slice style indexing. + */ + default long begin() { + return 0; + } + + /** + * Get the end of the index, strided slice style indexing. + */ + default long end() { + return 0; + } + + /** + * Get the stride of the index, for strided slice style indexing. + */ + default long stride() { + return 1; + } + + /** + * Get whether the Index should start at the beginning of the dimension, for strided slice style indexing. + */ + default boolean beginMask() { + return false; + } + + /** + * Get whether the Index should end at the beginning of the dimension, for strided slice style indexing. + */ + default boolean endMask() { + return false; + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/index/Indices.java b/ndarray/src/main/java/org/tensorflow/ndarray/index/Indices.java new file mode 100644 index 00000000000..346ab705595 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/index/Indices.java @@ -0,0 +1,363 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.index; + +import org.tensorflow.ndarray.IllegalRankException; +import org.tensorflow.ndarray.NdArray; +import org.tensorflow.ndarray.NdArrays; +import org.tensorflow.ndarray.Shape; +import org.tensorflow.ndarray.buffer.DataBuffers; + +/** + * Helper class for instantiating {@link Index} objects. + */ +public final class Indices { + + /** + * A coordinate that selects a specific element on a given dimension. + * + *

When this index is applied to a given dimension, the dimension is resolved as a + * single element and therefore is excluded from the computation of the rank. + * + *

For example, given a 3D matrix on the axis [x, y, z], if + * {@code matrix.slice(all(), at(0), at(0)}, then the rank of the returned slice is 1 and its number of elements is + * {@code x.numElements()} + * + * @param coord coordinate of the element on the indexed axis + * @return index + */ + public static Index at(long coord) { + return new At(coord, false); + } + + /** + * A coordinate that selects a specific element on a given dimension. + * + *

This is equivalent to call {@link #at(long)} but where the value of the coordinate is + * provided by an N-dimensional array. + * + * @param coord scalar indicating the coordinate of the element on the indexed axis + * @return index + * @throws IllegalRankException if {@code coord} is not a scalar (rank 0) + */ + public static Index at(NdArray coord) { + if (coord.rank() > 0) { + throw new IllegalRankException("Only scalars are accepted as a value index"); + } + return new At(coord.getObject().longValue(), false); + } + + /** + * A coordinate that selects a specific element on a given dimension. + * + *

When this index is applied to a given dimension, the dimension is resolved as a + * single element and therefore, if {@code keepDim} is false, is excluded from the computation of the rank. If {@code} + * keepDim is true, the dimension is collapsed down to one element. + * + *

For example, given a 3D matrix on the axis [x, y, z], if + * {@code matrix.slice(all(), at(0), at(0)}, then the rank of the returned slice is 1 and its number of elements is + * {@code x.numElements()} + * + * @param coord coordinate of the element on the indexed axis + * @param keepDim whether to remove the dimension. + * @return index + */ + public static Index at(long coord, boolean keepDim) { + return new At(coord, keepDim); + } + + /** + * A coordinate that selects a specific element on a given dimension. + * + *

This is equivalent to call {@link #at(long, boolean)} but where the value of the coordinate is + * provided by an N-dimensional array. + *

+ * If {@code} keepDim is true, the dimension is collapsed down to one element instead of being removed. + * + * @param coord scalar indicating the coordinate of the element on the indexed axis + * @param keepDim whether to remove the dimension. + * @return index + * @throws IllegalRankException if {@code coord} is not a scalar (rank 0) + */ + public static Index at(NdArray coord, boolean keepDim) { + if (coord.rank() > 0) { + throw new IllegalRankException("Only scalars are accepted as a value index"); + } + return new At(coord.getObject().longValue(), keepDim); + } + + /** + * An index that returns all elements of a dimension in the original order. + * + *

Applying this index to a given dimension will return the original dimension + * directly. + * + *

For example, given a vector with {@code n} elements, {@code all()} returns + * x0, x1, ..., xn-1 + * + * @return index + */ + public static Index all() { + return All.INSTANCE; + } + + /** + * An index that returns only specific elements on a given dimension. + * + *

For example, given a vector with {@code n} elements on the {@code x} axis, and {@code n > 10}, + * {@code seq(8, 0, 3)} returns x8, x0, x3 + * + * @param coords coordinates of the elements in the sequence + * @return index + */ + public static Index seq(long... coords) { + if (coords == null) { + throw new IllegalArgumentException(); + } + return new Sequence(NdArrays.wrap(Shape.of(coords.length), DataBuffers.of(coords, true, false))); + } + + /** + * An index that returns only specific elements on a given dimension. + * + *

This is equivalent to {@link #seq(long...)} but where the coordinates of the elements in + * the sequence are provided by an N-dimensional array. + * + * @param coords vector of coordinates of the elements in the sequence + * @return index + * @throws IllegalRankException if {@code coords} is not a vector (rank 1) + */ + public static Index seq(NdArray coords) { + if (coords.rank() != 1) { + throw new IllegalRankException("Only vectors are accepted as an element index"); + } + return new Sequence(coords); + } + + /** + * An index that returns only elements found at an even position in the original dimension. + * + *

For example, given a vector with {@code n} elements on the {@code x} axis, and n is even, + * {@code even()} returns x0, x2, ..., xn-2 + * + * @return index + */ + public static Index even() { + return step(2); + } + + /** + * An index that returns only elements found at an odd position in the original dimension. + * + *

For example, given a vector with {@code n} elements on the {@code x} axis, and n is even, + * {@code odd()} returns x1, x3, ..., xn-1 + * + * @return index + */ + public static Index odd() { + return sliceFrom(1, 2); + } + + /** + * An index that skips a fixed amount of coordinates between each values returned. + * + *

For example, given a vector with {@code n} elements on the {@code x} axis, + * {@code step(k)} returns x0, xk, xk*2, ... + * + * @param stride the number of elements between each steps + * @return index + */ + public static Index step(long stride) { + return new Step(stride); + } + + /** + * An index that returns only elements on a given dimension starting at a specific coordinate. + * + *

For example, given a vector with {@code n} elements on the {@code x} axis, and {@code n > k}, + * {@code from(k)} returns xk, xk+1, ..., xn-1 + * + * @param start coordinate of the first element of the sequence + * @return index + */ + public static Index sliceFrom(long start) { + return sliceFrom(start, 1); + } + + /** + * An index that returns only elements on a given dimension starting at a specific coordinate, using the given + * stride. + * + *

For example, given a vector with {@code n} elements on the {@code x} axis, and {@code n > k}, + * {@code from(k)} returns xk, xk+1, ..., xn-1 + * + * @param start coordinate of the first element of the sequence + * @param stride the stride to use + * @return index + * @see #slice(long, long, long) + */ + public static Index sliceFrom(long start, long stride) { + return new SliceFrom(start, stride); + } + + /** + * An index that returns only elements on a given dimension up to a specific coordinate. + * + *

For example, given a vector with {@code n} elements on the {@code x} axis, and {@code n > k}, + * {@code to(k)} returns x0, x1, ..., xk + * + * @param end coordinate of the last element of the sequence (exclusive) + * @return index + */ + public static Index sliceTo(long end) { + return sliceTo(end, 1); + } + + /** + * An index that returns only elements on a given dimension up to a specific coordinate, using the given stride. + * + *

For example, given a vector with {@code n} elements on the {@code x} axis, and {@code n > k}, + * {@code to(k)} returns x0, x1, ..., xk + * + * @param end coordinate of the last element of the sequence (exclusive) + * @param stride the stride to use + * @return index + * @see #slice(long, long, long) + */ + public static Index sliceTo(long end, long stride) { + return new SliceTo(end, stride); + } + + /** + * An index that returns only elements on a given dimension between two coordinates. + * + *

For example, given a vector with {@code n} elements on the {@code x} axis, and {@code n > k > j}, + * {@code range(j, k)} returns xj, xj+1, ..., xk + * + * @param start coordinate of the first element of the sequence + * @param end coordinate of the last element of the sequence (exclusive) + * @return index + */ + public static Index range(long start, long end) { + return slice(start, end); + } + + /** + * An index that returns only elements on a given dimension between two coordinates. + * + *

For example, given a vector with {@code n} elements on the {@code x} axis, and {@code n > k > j}, + * {@code range(j, k)} returns xj, xj+1, ..., xk + * + * @return index + */ + public static Index flip() { + return slice(null, null, -1); + } + + /** + * An index that returns elements according to an hyperslab defined by {@code start}, {@code stride}, {@code count}, + * {@code block}. See {@link Hyperslab}. + * + * @param start Starting location for the hyperslab. + * @param stride The number of elements to separate each element or block to be selected. + * @param count The number of elements or blocks to select along the dimension. + * @param block The size of the block selected from the dimension. + * @return index + */ + public static Index hyperslab(long start, long stride, long count, long block) { + return new Hyperslab(start, stride, count, block); + } + + /** + * An index that inserts a new dimension of size 1 into the resulting array. + * + * @return index + */ + public static Index newAxis() { + return NewAxis.INSTANCE; + } + + /** + * An index that expands to fill all available source dimensions. Works the same as Python's {@code ...}. + * + * @return index + */ + public static Index ellipsis() { + return Ellipsis.INSTANCE; + } + + /** + * An index that returns elements between {@code start} and {@code end}. If {@code start} or {@code end} is {@code + * null}, starts or ends at the beginning or the end, respectively. + *

+ * Analogous to Python's {@code :} slice syntax. + * + * @return index + */ + public static Index slice(long start, long end) { + return slice(start, end, 1); + } + + /** + * An index that returns every {@code stride}-th element between {@code start} and {@code end}. If {@code start} or + * {@code end} is {@code null}, starts or ends at the beginning or the end, respectively. + *

+ * Analogous to Python's {@code :} slice syntax. + * + * @return index + */ + public static Index slice(long start, long end, long stride) { + return new Slice(start, end, stride); + } + + /** + * An index that returns elements between {@code start} and {@code end}. If {@code start} or {@code end} is {@code + * null}, starts or ends at the beginning or the end, respectively. + *

+ * Analogous to Python's {@code :} slice syntax. + * + * @return index + */ + public static Index slice(Long start, Long end) { + return slice(start, end, 1); + } + + /** + * An index that returns every {@code stride}-th element between {@code start} and {@code end}. If {@code start} or + * {@code end} is {@code null}, starts or ends at the beginning or the end, respectively. + *

+ * Analogous to Python's {@code :} slice syntax. + * + * @return index + */ + public static Index slice(Long start, Long end, long stride) { + if (start == null && end == null) { + if (stride == 1) { + return Indices.all(); + } else { + return Indices.step(stride); + } + } else if (start == null) { + return Indices.sliceTo(end, stride); + } else if (end == null) { + return Indices.sliceFrom(start, stride); + } + + return slice(start.longValue(), end.longValue(), stride); + } + +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/index/NewAxis.java b/ndarray/src/main/java/org/tensorflow/ndarray/index/NewAxis.java new file mode 100644 index 00000000000..a68b1ed9ad1 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/index/NewAxis.java @@ -0,0 +1,53 @@ +/* + Copyright 2020 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ============================================================================== + */ +package org.tensorflow.ndarray.index; + +import org.tensorflow.ndarray.impl.dimension.Dimension; + +final class NewAxis implements Index { + + static final NewAxis INSTANCE = new NewAxis(); + + private NewAxis() { + + } + + @Override + public long numElements(Dimension dim) { + return 1; + } + + @Override + public long mapCoordinate(long coordinate, Dimension dim) { + return coordinate; + } + + @Override + public Dimension apply(Dimension dim) { + throw new IllegalStateException(); + } + + @Override + public boolean isNewAxis() { + return true; + } + + @Override + public String toString() { + return NewAxis.class.getSimpleName() + "()"; + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/index/Sequence.java b/ndarray/src/main/java/org/tensorflow/ndarray/index/Sequence.java new file mode 100644 index 00000000000..5b93e434e54 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/index/Sequence.java @@ -0,0 +1,52 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.index; + +import java.util.StringJoiner; +import org.tensorflow.ndarray.NdArray; +import org.tensorflow.ndarray.impl.dimension.Dimension; + +final class Sequence implements Index { + + @Override + public long numElements(Dimension dim) { + return coords.size(); + } + + @Override + public long mapCoordinate(long coordinate, Dimension dim) { + return coords.getObject(coordinate).longValue(); + } + + Sequence(NdArray coords) { + this.coords = coords; + } + + private final NdArray coords; + + @Override + public String toString() { + return new StringJoiner(", ", Sequence.class.getSimpleName() + "(", ")") + .add("coords=" + coords) + .toString(); + } + + @Override + public boolean isStridedSlicingCompliant() { + return false; + } +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/index/Slice.java b/ndarray/src/main/java/org/tensorflow/ndarray/index/Slice.java new file mode 100644 index 00000000000..1be4368261c --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/index/Slice.java @@ -0,0 +1,89 @@ +/* + Copyright 2020 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ============================================================================== + */ +package org.tensorflow.ndarray.index; + +import java.util.StringJoiner; +import org.tensorflow.ndarray.impl.dimension.Dimension; + +final class Slice implements Index { + + Slice(long start, long end, long stride) { + this.start = start; + this.end = end; + this.stride = stride; + + if (stride == 0) { + throw new IllegalArgumentException("Can not have a stride of 0"); + } + } + + @Override + public long numElements(Dimension dim) { + long length = end(dim) - start(dim); + + return (length / stride) + (length % stride != 0 ? 1 : 0); + } + + @Override + public long mapCoordinate(long coordinate, Dimension dim) { + return start(dim) + stride * coordinate; + } + + @Override + public long begin() { + return start; + } + + @Override + public long end() { + return end; + } + + @Override + public long stride() { + return stride; + } + + @Override + public String toString() { + return new StringJoiner(", ", Slice.class.getSimpleName() + "(", ")") + .add("start=" + start) + .add("end=" + end) + .add("stride=" + stride) + .toString(); + } + + private long start(Dimension dim) { + if (start < 0) { + return dim.numElements() + start; + } + + return start; + } + + private long end(Dimension dim) { + if (end < 0) { + return dim.numElements() + end; + } else { + return end; + } + } + + private final long start; + private final long end; + private final long stride; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/index/SliceFrom.java b/ndarray/src/main/java/org/tensorflow/ndarray/index/SliceFrom.java new file mode 100644 index 00000000000..c968a325cf7 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/index/SliceFrom.java @@ -0,0 +1,86 @@ +/* + Copyright 2020 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ============================================================================== + */ +package org.tensorflow.ndarray.index; + +import java.util.StringJoiner; +import org.tensorflow.ndarray.impl.dimension.Dimension; + +final class SliceFrom implements Index { + + SliceFrom(long start, long stride) { + this.start = start; + this.stride = stride; + + if (stride == 0) { + throw new IllegalArgumentException("Can not have a stride of 0"); + } + } + + @Override + public long numElements(Dimension dim) { + long length = end(dim) - start(dim); + + return (length / stride) + (length % stride != 0 ? 1 : 0); + } + + @Override + public long mapCoordinate(long coordinate, Dimension dim) { + return start(dim) + stride * coordinate; + } + + @Override + public long begin() { + return start; + } + + @Override + public boolean endMask() { + return true; + } + + @Override + public long stride() { + return stride; + } + + @Override + public String toString() { + return new StringJoiner(", ", SliceFrom.class.getSimpleName() + "(", ")") + .add("start=" + start) + .add("stride=" + stride) + .toString(); + } + + private long start(Dimension dim) { + if (start < 0) { + return dim.numElements() + start; + } + + return start; + } + + private long end(Dimension dim) { + if (stride > 0) { + return dim.numElements(); + } else { + return -1; // it's exclusive + } + } + + private final long start; + private final long stride; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/index/SliceTo.java b/ndarray/src/main/java/org/tensorflow/ndarray/index/SliceTo.java new file mode 100644 index 00000000000..761d1d52a3a --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/index/SliceTo.java @@ -0,0 +1,86 @@ +/* + Copyright 2020 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ============================================================================== + */ +package org.tensorflow.ndarray.index; + +import java.util.StringJoiner; +import org.tensorflow.ndarray.impl.dimension.Dimension; + +final class SliceTo implements Index { + + SliceTo(long end, long stride) { + this.end = end; + this.stride = stride; + + if (stride == 0) { + throw new IllegalArgumentException("Can not have a stride of 0"); + } + } + + @Override + public long numElements(Dimension dim) { + long length = end(dim) - start(dim); + + return (length / stride) + (length % stride != 0 ? 1 : 0); + } + + @Override + public long mapCoordinate(long coordinate, Dimension dim) { + return start(dim) + stride * coordinate; + } + + @Override + public long end() { + return end; + } + + @Override + public boolean beginMask() { + return true; + } + + @Override + public long stride() { + return stride; + } + + @Override + public String toString() { + return new StringJoiner(", ", SliceTo.class.getSimpleName() + "(", ")") + .add("end=" + end) + .add("stride=" + stride) + .toString(); + } + + private long start(Dimension dim) { + if (stride > 0) { + return 0; + } + + return dim.numElements() - 1; // it's inclusive + } + + private long end(Dimension dim) { + if (end < 0) { + return dim.numElements() + end; + } else { + return end; + } + } + + private final long end; + private final long stride; +} diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/index/Step.java b/ndarray/src/main/java/org/tensorflow/ndarray/index/Step.java new file mode 100644 index 00000000000..c9a21c507b6 --- /dev/null +++ b/ndarray/src/main/java/org/tensorflow/ndarray/index/Step.java @@ -0,0 +1,83 @@ +/* + Copyright 2020 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ============================================================================== + */ +package org.tensorflow.ndarray.index; + +import java.util.StringJoiner; +import org.tensorflow.ndarray.impl.dimension.Dimension; + +final class Step implements Index { + + Step(long stride) { + this.stride = stride; + + if (stride == 0) { + throw new IllegalArgumentException("Can not have a stride of 0"); + } + } + + @Override + public long numElements(Dimension dim) { + long length = end(dim) - start(dim); + + return (length / stride) + (length % stride != 0 ? 1 : 0); + } + + @Override + public long mapCoordinate(long coordinate, Dimension dim) { + return start(dim) + stride * coordinate; + } + + @Override + public boolean beginMask() { + return true; + } + + @Override + public boolean endMask() { + return true; + } + + @Override + public long stride() { + return stride; + } + + @Override + public String toString() { + return new StringJoiner(", ", Step.class.getSimpleName() + "(", ")") + .add("stride=" + stride) + .toString(); + } + + private long start(Dimension dim) { + if (stride > 0) { + return 0; + } + + return dim.numElements() - 1; // it's inclusive + } + + private long end(Dimension dim) { + if (stride > 0) { + return dim.numElements(); + } else { + return -1; // it's exclusive + } + } + + private final long stride; +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/BooleanNdArrayTestBase.java b/ndarray/src/test/java/org/tensorflow/ndarray/BooleanNdArrayTestBase.java new file mode 100644 index 00000000000..6426ff5a1c2 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/BooleanNdArrayTestBase.java @@ -0,0 +1,57 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.tensorflow.ndarray.NdArrays.vectorOf; + +import org.junit.jupiter.api.Test; + +public abstract class BooleanNdArrayTestBase extends NdArrayTestBase { + + @Override + protected abstract BooleanNdArray allocate(Shape shape); + + @Override + protected Boolean valueOf(Long val) { + return val > 0; + } + + @Test + public void iteratePrimitiveElements() { + BooleanNdArray matrix3d = allocate(Shape.of(5, 4, 5)); + + matrix3d.scalars().forEachIndexed((coords, scalar) -> + scalar.setBoolean(coords[2] > 0) + ); + + assertFalse(matrix3d.getBoolean(0, 0, 0)); + assertTrue(matrix3d.getBoolean(0, 0, 1)); + assertTrue(matrix3d.getBoolean(0, 0, 4)); + assertTrue(matrix3d.getBoolean(0, 1, 2)); + + matrix3d.elements(1).forEach(vector -> + vector.set(vectorOf(true, false, true, false, true)) + ); + + assertTrue(matrix3d.getBoolean(0, 0, 0)); + assertFalse(matrix3d.getBoolean(0, 0, 1)); + assertTrue(matrix3d.getBoolean(0, 0, 4)); + assertTrue(matrix3d.getBoolean(0, 1, 2)); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/ByteNdArrayTestBase.java b/ndarray/src/test/java/org/tensorflow/ndarray/ByteNdArrayTestBase.java new file mode 100644 index 00000000000..407efffda94 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/ByteNdArrayTestBase.java @@ -0,0 +1,55 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public abstract class ByteNdArrayTestBase extends NdArrayTestBase { + + @Override + protected abstract ByteNdArray allocate(Shape shape); + + @Override + protected Byte valueOf(Long val) { + return val.byteValue(); + } + + @Test + public void iteratePrimitiveElements() { + ByteNdArray matrix3d = allocate(Shape.of(5, 4, 5)); + + matrix3d.scalars().forEachIndexed((coords, scalar) -> + scalar.setByte((byte)coords[2]) + ); + + assertEquals(0, matrix3d.getByte(0, 0, 0)); + assertEquals(1, matrix3d.getByte(0, 0, 1)); + assertEquals(4, matrix3d.getByte(0, 0, 4)); + assertEquals(2, matrix3d.getByte(0, 1, 2)); + + matrix3d.elements(1).forEach(vector -> + vector.set(NdArrays.vectorOf((byte)5, (byte)6, (byte)7, (byte)8, (byte)9)) + ); + + assertEquals(5, matrix3d.getByte(0, 0, 0)); + assertEquals(6, matrix3d.getByte(0, 0, 1)); + assertEquals(9, matrix3d.getByte(0, 0, 4)); + assertEquals(7, matrix3d.getByte(0, 1, 2)); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/DoubleNdArrayTestBase.java b/ndarray/src/test/java/org/tensorflow/ndarray/DoubleNdArrayTestBase.java new file mode 100644 index 00000000000..d4f98e2caa0 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/DoubleNdArrayTestBase.java @@ -0,0 +1,55 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public abstract class DoubleNdArrayTestBase extends NdArrayTestBase { + + @Override + protected abstract DoubleNdArray allocate(Shape shape); + + @Override + protected Double valueOf(Long val) { + return val.doubleValue(); + } + + @Test + public void iteratePrimitiveElements() { + DoubleNdArray matrix3d = allocate(Shape.of(5, 4, 5)); + + matrix3d.scalars().forEachIndexed((coords, scalar) -> + scalar.setDouble((double)coords[2]) + ); + + assertEquals(0.0, matrix3d.getDouble(0, 0, 0), 0.0); + assertEquals(1.0, matrix3d.getDouble(0, 0, 1), 0.0); + assertEquals(4.0, matrix3d.getDouble(0, 0, 4), 0.0); + assertEquals(2.0, matrix3d.getDouble(0, 1, 2), 0.0); + + matrix3d.elements(1).forEach(vector -> + vector.set(NdArrays.vectorOf(5.0, 6.0, 7.0, 8.0, 9.0)) + ); + + assertEquals(5, matrix3d.getDouble(0, 0, 0), 0.0); + assertEquals(6, matrix3d.getDouble(0, 0, 1), 0.0); + assertEquals(9, matrix3d.getDouble(0, 0, 4), 0.0); + assertEquals(7, matrix3d.getDouble(0, 1, 2), 0.0); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/FloatNdArrayTestBase.java b/ndarray/src/test/java/org/tensorflow/ndarray/FloatNdArrayTestBase.java new file mode 100644 index 00000000000..55f05ae3de1 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/FloatNdArrayTestBase.java @@ -0,0 +1,55 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public abstract class FloatNdArrayTestBase extends NdArrayTestBase { + + @Override + protected abstract FloatNdArray allocate(Shape shape); + + @Override + protected Float valueOf(Long val) { + return val.floatValue(); + } + + @Test + public void iteratePrimitiveElements() { + FloatNdArray matrix3d = allocate(Shape.of(5, 4, 5)); + + matrix3d.scalars().forEachIndexed((coords, scalar) -> + scalar.setFloat((float)coords[2]) + ); + + assertEquals(0.0f, matrix3d.getFloat(0, 0, 0), 0.0f); + assertEquals(1.0f, matrix3d.getFloat(0, 0, 1), 0.0f); + assertEquals(4.0f, matrix3d.getFloat(0, 0, 4), 0.0f); + assertEquals(2.0f, matrix3d.getFloat(0, 1, 2), 0.0f); + + matrix3d.elements(1).forEach(vector -> + vector.set(NdArrays.vectorOf(5.0f, 6.0f, 7.0f, 8.0f, 9.0f)) + ); + + assertEquals(5, matrix3d.getFloat(0, 0, 0), 0.0f); + assertEquals(6, matrix3d.getFloat(0, 0, 1), 0.0f); + assertEquals(9, matrix3d.getFloat(0, 0, 4), 0.0f); + assertEquals(7, matrix3d.getFloat(0, 1, 2), 0.0f); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/IndexTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/IndexTest.java new file mode 100644 index 00000000000..6f92dab9b99 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/IndexTest.java @@ -0,0 +1,205 @@ +/* + Copyright 2020 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ============================================================================== + */ +package org.tensorflow.ndarray; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; +import org.tensorflow.ndarray.index.Indices; + +public class IndexTest { + @Test + public void testNullConversions(){ + assertTrue(Indices.slice(null, 0L).beginMask(), + "Passed null for slice start but didn't set begin mask"); + + assertTrue(Indices.slice(null, 0L).beginMask(), + "Passed null for slice start but didn't set begin mask"); + + assertTrue(Indices.slice(null, null).beginMask(), + "Passed null for slice start but didn't set begin mask"); + + assertTrue(Indices.slice(0L, null).endMask(), + "Passed null for slice end but didn't set end mask"); + + assertTrue(Indices.slice(0L, null).endMask(), + "Passed null for slice end but didn't set end mask"); + + assertTrue(Indices.slice(null, null).endMask(), + "Passed null for slice end but didn't set end mask"); + } + + @Test + public void testNewaxis(){ + IntNdArray matrix3d = NdArrays.ofInts(Shape.of(5, 4, 5)); + + matrix3d.scalars().forEachIndexed((coords, scalar) -> + scalar.setInt((int)coords[2]) + ); + + IntNdArray slice1 = matrix3d.slice(Indices.all(), Indices.all(), Indices.all(), Indices.newAxis()); + + assertEquals(Shape.of(5, 4, 5, 1), slice1.shape()); + assertEquals(0, slice1.getInt(0, 0, 0, 0)); + assertEquals(1, slice1.getInt(0, 0, 1, 0)); + assertEquals(4, slice1.getInt(0, 0, 4, 0)); + assertEquals(2, slice1.getInt(0, 1, 2, 0)); + + IntNdArray slice2 = matrix3d.slice(Indices.all(), Indices.all(), Indices.newAxis(), Indices.all()); + + assertEquals(Shape.of(5, 4, 1, 5), slice2.shape()); + assertEquals(0, slice2.getInt(0, 0, 0, 0)); + assertEquals(1, slice2.getInt(0, 0, 0, 1)); + assertEquals(4, slice2.getInt(0, 0, 0, 4)); + assertEquals(2, slice2.getInt(0, 1, 0, 2)); + + IntNdArray slice3 = matrix3d.slice(Indices.all(), Indices.newAxis(), Indices.all(), Indices.all()); + + assertEquals(Shape.of(5, 1, 4, 5), slice3.shape()); + assertEquals(0, slice3.getInt(0, 0, 0, 0)); + assertEquals(1, slice3.getInt(0, 0, 0, 1)); + assertEquals(4, slice3.getInt(0, 0, 0, 4)); + assertEquals(2, slice3.getInt(0, 0, 1, 2)); + + IntNdArray slice4 = matrix3d.slice(Indices.newAxis(), Indices.all(), Indices.all(), Indices.all()); + + assertEquals(Shape.of(1, 5, 4, 5), slice4.shape()); + assertEquals(0, slice4.getInt(0, 0, 0, 0)); + assertEquals(1, slice4.getInt(0, 0, 0, 1)); + assertEquals(4, slice4.getInt(0, 0, 0, 4)); + assertEquals(2, slice4.getInt(0, 0, 1, 2)); + + } + + @Test + public void testEllipsis(){ + IntNdArray matrix3d = NdArrays.ofInts(Shape.of(5, 4, 5)); + + matrix3d.scalars().forEachIndexed((coords, scalar) -> + scalar.setInt((int)coords[2]) + ); + + assertEquals( + matrix3d.slice(Indices.all(), Indices.all(), Indices.at(0)), + matrix3d.slice(Indices.ellipsis(), Indices.at(0)) + ); + + assertEquals( + matrix3d.slice(Indices.at(0), Indices.all(), Indices.all()), + matrix3d.slice(Indices.at(0), Indices.ellipsis()) + ); + + assertEquals( + matrix3d.slice(Indices.at(0), Indices.all(), Indices.at(0)), + matrix3d.slice(Indices.at(0), Indices.ellipsis(), Indices.at(0)) + ); + + // newaxis interacts specially with ellipsis (since it doesn't consume a dimension), test this + + assertEquals( + matrix3d.slice(Indices.all(), Indices.all(), Indices.newAxis(), Indices.at(0)), + matrix3d.slice(Indices.ellipsis(), Indices.newAxis(), Indices.at(0)) + ); + + assertEquals( + matrix3d.slice(Indices.newAxis(), Indices.all(), Indices.all(), Indices.at(0)), + matrix3d.slice(Indices.newAxis(), Indices.ellipsis(), Indices.at(0)) + ); + + assertEquals( + matrix3d.slice(Indices.all(), Indices.all(), Indices.at(0), Indices.newAxis()), + matrix3d.slice(Indices.ellipsis(), Indices.at(0), Indices.newAxis()) + ); + } + + @Test + public void testSlice(){ + IntNdArray matrix3d = NdArrays.ofInts(Shape.of(5, 4, 5)); + + matrix3d.scalars().forEachIndexed((coords, scalar) -> + scalar.setInt((int)coords[2]) + ); + + IntNdArray slice1 = matrix3d.slice(Indices.all(), Indices.sliceTo(3), Indices.all()); + + assertEquals(Shape.of(5, 3, 5), slice1.shape()); + assertEquals(0, slice1.getInt(0, 0, 0)); + assertEquals(1, slice1.getInt(0, 0, 1)); + assertEquals(2, slice1.getInt(0, 1, 2)); + + IntNdArray slice2 = matrix3d.slice(Indices.all(), Indices.all(), Indices.slice(1, 4)); + + assertEquals(Shape.of(5, 4, 3), slice2.shape()); + assertEquals(1, slice2.getInt(0, 0, 0)); + assertEquals(3, slice2.getInt(0, 0, 2)); + assertEquals(2, slice2.getInt(0, 1, 1)); + + assertEquals(slice2, matrix3d.slice(Indices.all(), Indices.all(), Indices.slice(1, -1))); + + assertEquals(slice2, matrix3d.slice(Indices.all(), Indices.all(), Indices.slice(-4, -1))); + + assertEquals(Shape.of(5, 4, 0), matrix3d.slice(Indices.all(), Indices.all(), Indices.slice(1, 4, -2)).shape()); + + IntNdArray slice3 = matrix3d.slice(Indices.all(), Indices.all(), Indices.slice(4, 1, -2)); + + assertEquals(Shape.of(5, 4, 2), slice3.shape()); + assertEquals(4, slice3.getInt(0, 0, 0)); + assertEquals(2, slice3.getInt(0, 1, 1)); + + assertEquals(slice3, matrix3d.slice(Indices.all(), Indices.all(), Indices.slice(-1, 1, -2))); + + assertEquals(slice3, matrix3d.slice(Indices.all(), Indices.all(), Indices.slice(-1, -4, -2))); + + IntNdArray slice4 = matrix3d.slice(Indices.all(), Indices.all(), Indices.slice(null, null, -1)); + + assertEquals(Shape.of(5, 4, 5), slice4.shape()); + assertEquals(4, slice4.getInt(0, 0, 0)); + assertEquals(3, slice4.getInt(0, 0, 1)); + assertEquals(2, slice4.getInt(0, 1, 2)); + } + + @Test + public void testAt(){ + IntNdArray matrix3d = NdArrays.ofInts(Shape.of(5, 4, 5)); + + matrix3d.scalars().forEachIndexed((coords, scalar) -> + scalar.setInt((int)coords[2]) + ); + + IntNdArray slice1 = matrix3d.slice(Indices.all(), Indices.all(), Indices.at(0)); + + assertEquals(Shape.of(5, 4), slice1.shape()); + assertEquals(0, slice1.getInt(0, 0)); + + IntNdArray slice2 = matrix3d.slice(Indices.all(), Indices.all(), Indices.at(3)); + + assertEquals(Shape.of(5, 4), slice2.shape()); + assertEquals(3, slice2.getInt(0, 0)); + + IntNdArray slice3 = matrix3d.slice(Indices.all(), Indices.all(), Indices.at(-3)); + + assertEquals(Shape.of(5, 4), slice3.shape()); + assertEquals(2, slice3.getInt(0, 0)); + + IntNdArray slice4 = matrix3d.slice(Indices.all(), Indices.all(), Indices.at(-3, true)); + + assertEquals(Shape.of(5, 4, 1), slice4.shape()); + assertEquals(2, slice4.getInt(0, 0, 0)); + } + +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/IntNdArrayTestBase.java b/ndarray/src/test/java/org/tensorflow/ndarray/IntNdArrayTestBase.java new file mode 100644 index 00000000000..1a3c7cb1a12 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/IntNdArrayTestBase.java @@ -0,0 +1,55 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public abstract class IntNdArrayTestBase extends NdArrayTestBase { + + @Override + protected abstract IntNdArray allocate(Shape shape); + + @Override + protected Integer valueOf(Long val) { + return val.intValue(); + } + + @Test + public void iteratePrimitiveElements() { + IntNdArray matrix3d = allocate(Shape.of(5, 4, 5)); + + matrix3d.scalars().forEachIndexed((coords, scalar) -> + scalar.setInt((int)coords[2]) + ); + + assertEquals(0, matrix3d.getInt(0, 0, 0)); + assertEquals(1, matrix3d.getInt(0, 0, 1)); + assertEquals(4, matrix3d.getInt(0, 0, 4)); + assertEquals(2, matrix3d.getInt(0, 1, 2)); + + matrix3d.elements(1).forEach(vector -> + vector.set(NdArrays.vectorOf(5, 6, 7, 8, 9)) + ); + + assertEquals(5, matrix3d.getInt(0, 0, 0)); + assertEquals(6, matrix3d.getInt(0, 0, 1)); + assertEquals(9, matrix3d.getInt(0, 0, 4)); + assertEquals(7, matrix3d.getInt(0, 1, 2)); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/LongNdArrayTestBase.java b/ndarray/src/test/java/org/tensorflow/ndarray/LongNdArrayTestBase.java new file mode 100644 index 00000000000..b91c19d6557 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/LongNdArrayTestBase.java @@ -0,0 +1,55 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public abstract class LongNdArrayTestBase extends NdArrayTestBase { + + @Override + protected abstract LongNdArray allocate(Shape shape); + + @Override + protected Long valueOf(Long val) { + return val; + } + + @Test + public void iteratePrimitiveElements() { + LongNdArray matrix3d = allocate(Shape.of(5, 4, 5)); + + matrix3d.scalars().forEachIndexed((coords, scalar) -> + scalar.setLong(coords[2]) + ); + + assertEquals(0, matrix3d.getLong(0, 0, 0)); + assertEquals(1, matrix3d.getLong(0, 0, 1)); + assertEquals(4, matrix3d.getLong(0, 0, 4)); + assertEquals(2, matrix3d.getLong(0, 1, 2)); + + matrix3d.elements(1).forEach(vector -> + vector.set(NdArrays.vectorOf(5L, 6L, 7L, 8L, 9L)) + ); + + assertEquals(5, matrix3d.getLong(0, 0, 0)); + assertEquals(6, matrix3d.getLong(0, 0, 1)); + assertEquals(9, matrix3d.getLong(0, 0, 4)); + assertEquals(7, matrix3d.getLong(0, 1, 2)); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/NdArrayTestBase.java b/ndarray/src/test/java/org/tensorflow/ndarray/NdArrayTestBase.java new file mode 100644 index 00000000000..26ac533daa8 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/NdArrayTestBase.java @@ -0,0 +1,338 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.fail; +import static org.tensorflow.ndarray.NdArrays.vectorOfObjects; +import static org.tensorflow.ndarray.index.Indices.all; +import static org.tensorflow.ndarray.index.Indices.at; +import static org.tensorflow.ndarray.index.Indices.even; +import static org.tensorflow.ndarray.index.Indices.flip; +import static org.tensorflow.ndarray.index.Indices.sliceFrom; +import static org.tensorflow.ndarray.index.Indices.odd; +import static org.tensorflow.ndarray.index.Indices.range; +import static org.tensorflow.ndarray.index.Indices.seq; +import static org.tensorflow.ndarray.index.Indices.sliceTo; + +import java.nio.BufferOverflowException; +import java.nio.BufferUnderflowException; +import org.junit.jupiter.api.Test; +import org.tensorflow.ndarray.buffer.DataBuffer; + +public abstract class NdArrayTestBase { + + protected abstract NdArray allocate(Shape shape); + + protected abstract DataBuffer allocateBuffer(long size); + + protected abstract T valueOf(Long val); + + protected T zeroOrNull() { + return valueOf(0L); + } + + @Test + public void shapeAndSizes() { + Shape scalarShape = Shape.scalar(); + NdArray scalar = allocate(scalarShape); + assertEquals(scalarShape, scalar.shape()); + assertEquals(0, scalar.rank()); + assertEquals(scalarShape, Shape.of()); + + Shape vectorShape = Shape.of(10); + NdArray vector = allocate(vectorShape); + assertEquals(vectorShape, vector.shape()); + assertEquals(1, vector.rank()); + } + + @Test + public void setAndGetValues() { + NdArray matrix = allocate(Shape.of(5, 4)); + assertEquals(zeroOrNull(), matrix.getObject(3, 3)); + + matrix.setObject(valueOf(10L), 3, 3); + assertEquals(valueOf(10L), matrix.getObject(3, 3)); + try { + matrix.setObject(valueOf(10L), 3, 4); + fail(); + } catch (IndexOutOfBoundsException e) { + // as expected + } + try { + matrix.setObject(valueOf(10L), -1, 3); + fail(); + } catch (IndexOutOfBoundsException e) { + // as expected + } + try { + matrix.getObject(3); + fail(); + } catch (IllegalRankException e) { + // as expected + } + try { + matrix.setObject(valueOf(10L), 3); + fail(); + } catch (IllegalRankException e) { + // as expected + } + + NdArray matrix2 = allocate(Shape.of(3, 2)) + .set(vectorOfObjects(valueOf(1L), valueOf(2L)), 0) + .set(vectorOfObjects(valueOf(3L), valueOf(4L)), 1) + .setObject(valueOf(5L), 2, 0) + .setObject(valueOf(6L), 2, 1); + + assertEquals(valueOf(1L), matrix2.getObject(0, 0)); + assertEquals(valueOf(2L), matrix2.getObject(0, 1)); + assertEquals(valueOf(3L), matrix2.getObject(1, 0)); + assertEquals(valueOf(4L), matrix2.getObject(1, 1)); + assertEquals(valueOf(5L), matrix2.getObject(2, 0)); + assertEquals(valueOf(6L), matrix2.getObject(2, 1)); + } + + @Test + public void iterateElements() { + NdArray matrix3d = allocate(Shape.of(5, 4, 5)); + + matrix3d.scalars().forEachIndexed((coords, scalar) -> { + scalar.setObject(valueOf(coords[2])); + }); + + assertEquals(valueOf(0L), matrix3d.getObject(0, 0, 0)); + assertEquals(valueOf(1L), matrix3d.getObject(0, 0, 1)); + assertEquals(valueOf(4L), matrix3d.getObject(0, 0, 4)); + assertEquals(valueOf(2L), matrix3d.getObject(0, 1, 2)); + + matrix3d.elements(1).forEach(vector -> { + vector.set(vectorOfObjects(valueOf(5L), valueOf(6L), valueOf(7L), valueOf(8L), valueOf(9L))); + }); + + assertEquals(valueOf(5L), matrix3d.getObject(0, 0, 0)); + assertEquals(valueOf(6L), matrix3d.getObject(0, 0, 1)); + assertEquals(valueOf(9L), matrix3d.getObject(0, 0, 4)); + assertEquals(valueOf(7L), matrix3d.getObject(0, 1, 2)); + + long value = 0L; + for (NdArray matrix : matrix3d.elements(0)) { + assertEquals(2L, matrix.shape().numDimensions()); + assertEquals(4L, matrix.shape().size(0)); + assertEquals(5L, matrix.shape().size(1)); + + for (NdArray vector : matrix.elements(0)) { + assertEquals(1L, vector.shape().numDimensions()) ; + assertEquals(5L, vector.shape().size(0)); + + for (NdArray scalar : vector.scalars()) { + assertEquals(0L, scalar.shape().numDimensions()) ; + scalar.setObject(valueOf(value++)); + try { + scalar.elements(0); + fail(); + } catch (IllegalArgumentException e) { + // as expected + } + } + } + } + assertEquals(valueOf(0L), matrix3d.getObject(0, 0, 0)); + assertEquals(valueOf(5L), matrix3d.getObject(0, 1, 0)); + assertEquals(valueOf(9L), matrix3d.getObject(0, 1, 4)); + assertEquals(valueOf(20L), matrix3d.getObject(1, 0, 0)); + assertEquals(valueOf(25L), matrix3d.getObject(1, 1, 0)); + assertEquals(valueOf(99L), matrix3d.getObject(4, 3, 4)); + } + + @Test + public void slices() { + NdArray matrix3d = allocate(Shape.of(5, 4, 5)); + + T val100 = valueOf(100L); + matrix3d.setObject(val100, 1, 0, 0); + T val101 = valueOf(101L); + matrix3d.setObject(val101, 1, 0, 1); + + // Vector (1,0,*) + NdArray vector10X = matrix3d.get(1, 0); + assertEquals(Shape.of(5), vector10X.shape()); + assertEquals(val100, vector10X.getObject(0)); + assertEquals(val101, vector10X.getObject(1)); + + T val102 = valueOf(102L); + vector10X.setObject(val102, 2); + assertEquals(val102, vector10X.getObject(2)); + assertEquals(val102, matrix3d.getObject(1, 0, 2)); + + // Vector (*,0,0) + NdArray vectorX00 = matrix3d.slice(all(), at(0), at(0)); + assertEquals(Shape.of(5), vectorX00.shape()); + assertEquals(val100, vectorX00.getObject(1)); + T val200 = valueOf(200L); + vectorX00.setObject(val200, 2); + assertEquals(val200, vectorX00.getObject(2)); + assertEquals(val200, matrix3d.getObject(2, 0, 0)); + + // Vector (1,0,[2,0]) + NdArray vector10_20 = matrix3d.slice(at(1), at(0), seq(2, 0)); + assertEquals(vector10_20.shape(), Shape.of(2)); + assertEquals(val102, vector10_20.getObject(0)); + assertEquals(val100, vector10_20.getObject(1)); + + // Vector (1,0,[even]) + NdArray vector10_even = matrix3d.slice(at(1), at(0), even()); + assertEquals(vector10_even.shape(), Shape.of(3)); + assertEquals(val100, vector10_even.getObject(0)); + assertEquals(val102, vector10_even.getObject(1)); + + // Vector ([odd]) from vector (1,0,[even]) + NdArray vector10_even_odd = vector10_even.slice(odd()); + assertEquals(vector10_even_odd.shape(), Shape.of(1)); + assertEquals(val102, vector10_even_odd.getObject(0)); + + // Vector (1,0,[flip]) + NdArray vector10_flip = matrix3d.slice(at(1), at(0), flip()); + assertEquals(vector10_flip.shape(), Shape.of(5)); + assertEquals(val100, vector10_flip.getObject(4)); + assertEquals(val101, vector10_flip.getObject(3)); + + // Vector (1,0,[from 1]) from vector (1,0,*) + NdArray vector10_1toX = vector10X.slice(sliceFrom(1)); + assertEquals(vector10_1toX.shape(), Shape.of(4)); + assertEquals(val101, vector10_1toX.getObject(0)); + assertEquals(val102, vector10_1toX.getObject(1)); + + // Vector (1,0,[to 1]) from vector (1,0,*) + NdArray vector10_Xto1 = vector10X.slice(sliceTo(2)); + assertEquals(vector10_Xto1.shape(), Shape.of(2)); + assertEquals(val100, vector10_Xto1.getObject(0)); + assertEquals(val101, vector10_Xto1.getObject(1)); + + // Vector (1,0,[1 to 3]) + NdArray vector10_1to3 = matrix3d.slice(at(1), at(0), range(1, 3)); + assertEquals(vector10_1to3.shape(), Shape.of(2)); + assertEquals(val101, vector10_1to3.getObject(0)); + assertEquals(val102, vector10_1to3.getObject(1)); + + // Scalar (1,0,0) from vector (1,0,*) + NdArray scalar100 = vector10X.get(0); + assertEquals(Shape.of(), scalar100.shape()); + assertEquals(val100, scalar100.getObject()); + + // Slice scalar (1,0,z) + LongNdArray z = NdArrays.scalarOf(2L); + NdArray scalar102 = matrix3d.slice(at(1), at(0), at(z)); + assertEquals(scalar102.shape(), Shape.of()); + assertEquals(val102, scalar102.getObject()); + + // Slicing the 3D matrix so we only keep the first element of the second dimension + NdArray matrix_X0Z = matrix3d.slice(all(), at(0)); + assertEquals(2, matrix_X0Z.rank()); + assertEquals(Shape.of(5, 5), matrix_X0Z.shape()); + assertEquals(val100, matrix_X0Z.getObject(1, 0)); + assertEquals(val101, matrix_X0Z.getObject(1, 1)); + assertEquals(val200, matrix_X0Z.getObject(2, 0)); + } + + @Test + public void writeAndReadWithBuffers() { + DataBuffer buffer = allocateBuffer(15L); + for (long val = 0L; val < buffer.size(); ++val) { + buffer.setObject(valueOf(val), val); + } + NdArray matrix = allocate(Shape.of(3, 5)); + matrix.write(buffer); + assertEquals(valueOf(0L), matrix.getObject(0, 0)); + assertEquals(valueOf(4L), matrix.getObject(0, 4)); + assertEquals(valueOf(5L), matrix.getObject(1, 0)); + assertEquals(valueOf(10L), matrix.getObject(2, 0)); + assertEquals(valueOf(14L), matrix.getObject(2, 4)); + + matrix.setObject(valueOf(100L), 1, 0); + matrix.read(buffer); + assertEquals(valueOf(0L), buffer.getObject(0)); + assertEquals(valueOf(4L), buffer.getObject(4)); + assertEquals(valueOf(100L), buffer.getObject(5)); + assertEquals(valueOf(10L), buffer.getObject(10)); + assertEquals(valueOf(14L), buffer.getObject(14)); + + try { + matrix.write(buffer.narrow(10)); + fail(); + } catch (BufferUnderflowException e) { + // as expected + } + try { + matrix.read(buffer.narrow(10)); + fail(); + } catch (BufferOverflowException e) { + // as expected + } + } + + @Test + public void ndArrayCopies() { + NdArray matrixA = allocate(Shape.of(3, 5)); + + long value = 0L; + for (NdArray s : matrixA.scalars()) { + s.setObject(valueOf(value++)); + } + NdArray matrixB = allocate(Shape.of(3, 5)).setObject(valueOf(100L), 1, 0); + matrixA.copyTo(matrixB); + assertEquals(valueOf(0L), matrixB.getObject(0, 0)); + assertEquals(valueOf(4L), matrixB.getObject(0, 4)); + assertEquals(valueOf(5L), matrixB.getObject(1, 0)); + assertEquals(valueOf(10L), matrixB.getObject(2, 0)); + assertEquals(valueOf(14L), matrixB.getObject(2, 4)); + + NdArray matrixC = allocate(Shape.of(3, 4)); + try { + matrixA.copyTo(matrixC); + fail(); + } catch (IllegalArgumentException e) { + // as expected + } + } + + @Test + public void equalsAndHashCode() { + NdArray array1 = allocate(Shape.of(2, 2)); + NdArray array2 = allocate(Shape.of(2, 2)); + NdArray array3 = allocate(Shape.of(2, 2)); + NdArray array4 = allocate(Shape.of(1, 2, 2)); + + @SuppressWarnings("unchecked") + T[][][] values = (T[][][])(new Object[][][] { + { { valueOf(0L), valueOf(1L) }, { valueOf(2L), valueOf(0L) } } + }); + + StdArrays.copyTo(values[0], array1); + StdArrays.copyTo(values[0], array2); + StdArrays.copyTo(values[0], array3); + array3.setObject(valueOf(0L), 0, 1); + StdArrays.copyTo(values, array4); + + assertEquals(array1, array2); + assertEquals(array1.hashCode(), array2.hashCode()); + assertNotEquals(array1, array3); + assertNotEquals(array1.hashCode(), array3.hashCode()); + assertNotEquals(array1, array4); + assertNotEquals(array1.hashCode(), array4.hashCode()); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/ShapeTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/ShapeTest.java new file mode 100644 index 00000000000..d2e3e432a2c --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/ShapeTest.java @@ -0,0 +1,170 @@ +/* +Copyright 2019 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +======================================================================= +*/ +package org.tensorflow.ndarray; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class ShapeTest { + + @Test + public void allKnownDimensions() { + Shape shape = Shape.of(5, 4, 5); + assertEquals(3, shape.numDimensions()); + assertEquals(5, shape.size(0)); + assertEquals(4, shape.size(1)); + assertEquals(5, shape.size(2)); + assertEquals(100, shape.size()); + assertArrayEquals(new long[] {5, 4, 5}, shape.asArray()); + try { + shape.size(3); + fail(); + } catch (IndexOutOfBoundsException e) { + // as expected + } + assertEquals(5, shape.size(-1)); + assertEquals(4, shape.size(-2)); + assertEquals(5, shape.size(-3)); + try { + shape.size(-4); + fail(); + } catch (IndexOutOfBoundsException e) { + // as expected + } + assertFalse(shape.isUnknown()); + assertFalse(shape.hasUnknownDimension()); + assertFalse(shape.isScalar()); + } + + @Test + public void hashCodeEquals() { + Shape shape1 = Shape.of(5, 4, 5); + Shape shape2 = Shape.of(5, 4, 5); + Shape shape3 = Shape.of(5, 4, 5, 6); + Shape shape4 = Shape.of(5, 4, 1); + + assertEquals(shape1, shape2); + assertEquals(shape1.hashCode(), shape2.hashCode()); + assertNotEquals(shape1, shape3); + assertNotEquals(shape1.hashCode(), shape3.hashCode()); + assertNotEquals(shape1, shape4); + assertNotEquals(shape1.hashCode(), shape4.hashCode()); + + Shape scalar1 = Shape.of(); + Shape scalar2 = Shape.of(); + assertEquals(scalar1, scalar2); + assertNotEquals(scalar1, shape1); + + Shape unknown1 = Shape.of(-1, 4, 5); + Shape unknown2 = Shape.of(-1, 4, 5); + assertNotEquals(unknown1, unknown2); + assertNotEquals(unknown1, shape1); + assertEquals(unknown1, unknown1); + + Shape sizeUnknown1 = Shape.unknown(); + Shape sizeUnknown2 = Shape.unknown(); + assertNotEquals(sizeUnknown1, sizeUnknown2); + assertEquals(sizeUnknown1, sizeUnknown1); + } + + @Test + public void testShapeModification() { + Shape one = Shape.of(2, 4, 6, 8); + assertEquals(one.head(), Shape.of(2)); + assertEquals(one.tail(), Shape.of(4, 6, 8)); + + Shape two = Shape.of(5); + assertEquals(two.head(), two); + assertEquals(two.tail(), Shape.of()); + + try { + Shape.of().head(); + fail(); + } catch (IndexOutOfBoundsException e) { + // as expected + } + + assertEquals(Shape.of().tail(), Shape.of()); + + Shape three = Shape.of(2, 4, 6); + assertEquals(three.prepend(5), Shape.of(5, 2, 4, 6)); + + assertEquals(Shape.of(5, 2, 4, 6), two.append(three)); + assertEquals(Shape.of(2, 4, 6, 5), two.prepend(three)); + assertEquals(Shape.of(1, 2, 3, 4), Shape.of(1, 2).append(Shape.of(3, 4))); + assertEquals(Shape.of(1, 2, 3, 4), Shape.of(1, 2, 3).append(4)); + assertEquals(Shape.of(1, 2, 3, 4), Shape.of(1, 2, 3, 4).append(Shape.scalar())); + assertEquals(Shape.of(3, 4, 1, 2), Shape.of(1, 2).prepend(Shape.of(3, 4))); + assertEquals(Shape.of(4, 6), three.takeLast(2)); + assertEquals(Shape.scalar(), three.takeLast(0)); + assertEquals(Shape.of(2, 4), three.take(2)); + assertEquals(Shape.scalar(), three.take(0)); + + try { + Shape.unknown().append(Shape.of(1, 2)); + fail(); + } catch (NullPointerException e) { + // as expected + } + + try { + Shape.unknown().prepend(Shape.of(1, 2)); + fail(); + } catch (NullPointerException e) { + // as expected + } + + // changing the values of the array returned by asArray should not mutate the shape + long[] internalShape = one.asArray(); + assertNotNull(internalShape); + internalShape[0] = 42L; + assertEquals(2L, one.size(0)); + } + + @Test + public void testShapeCompatible() { + Shape a = Shape.unknown(); + Shape b = Shape.of(2, 2); + assertTrue(a.isCompatibleWith(b)); + assertTrue(b.isCompatibleWith(a)); + + a = Shape.of(2, 2); + assertTrue(a.isCompatibleWith(b)); + assertTrue(b.isCompatibleWith(a)); + + a = Shape.of(2, -1); + assertTrue(a.isCompatibleWith(b)); + assertTrue(b.isCompatibleWith(a)); + + a = Shape.of(-1, 2); + assertTrue(a.isCompatibleWith(b)); + assertTrue(b.isCompatibleWith(a)); + + a = Shape.of(-1, -1); + assertTrue(a.isCompatibleWith(b)); + assertTrue(b.isCompatibleWith(a)); + + a = Shape.of(1, 2); + assertFalse(a.isCompatibleWith(b)); + assertFalse(b.isCompatibleWith(a)); + + a = Shape.of(1, 2, 3); + assertFalse(a.isCompatibleWith(b)); + assertFalse(b.isCompatibleWith(a)); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/ShortNdArrayTestBase.java b/ndarray/src/test/java/org/tensorflow/ndarray/ShortNdArrayTestBase.java new file mode 100644 index 00000000000..f9043fec4f5 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/ShortNdArrayTestBase.java @@ -0,0 +1,55 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public abstract class ShortNdArrayTestBase extends NdArrayTestBase { + + @Override + protected abstract ShortNdArray allocate(Shape shape); + + @Override + protected Short valueOf(Long val) { + return val.shortValue(); + } + + @Test + public void iteratePrimitiveElements() { + ShortNdArray matrix3d = allocate(Shape.of(5, 4, 5)); + + matrix3d.scalars().forEachIndexed((coords, scalar) -> + scalar.setShort((short)coords[2]) + ); + + assertEquals(0, matrix3d.getShort(0, 0, 0)); + assertEquals(1, matrix3d.getShort(0, 0, 1)); + assertEquals(4, matrix3d.getShort(0, 0, 4)); + assertEquals(2, matrix3d.getShort(0, 1, 2)); + + matrix3d.elements(1).forEach(vector -> + vector.set(NdArrays.vectorOf((short)5, (short)6, (short)7, (short)8, (short)9)) + ); + + assertEquals(5, matrix3d.getShort(0, 0, 0)); + assertEquals(6, matrix3d.getShort(0, 0, 1)); + assertEquals(9, matrix3d.getShort(0, 0, 4)); + assertEquals(7, matrix3d.getShort(0, 1, 2)); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/StdArraysTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/StdArraysTest.java new file mode 100644 index 00000000000..b7b41564c33 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/StdArraysTest.java @@ -0,0 +1,211 @@ +package org.tensorflow.ndarray; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.fail; + +import org.junit.jupiter.api.Test; + +public class StdArraysTest { + + @Test + public void vectors() { + IntNdArray vector = NdArrays.ofInts(Shape.of(2)); + + StdArrays.copyTo(new int[] {1, 2}, vector); + assertEquals(1, vector.getInt(0)); + assertEquals(2, vector.getInt(1)); + + try { + StdArrays.copyTo(new int[] {1, 2, 3}, vector); + fail(); + } catch (IllegalArgumentException e) { + // as expected + } + try { + StdArrays.copyTo(new int[] {1, 2}, NdArrays.ofInts(Shape.of(4))); + fail(); + } catch (IllegalArgumentException e) { + // as expected + } + try { + StdArrays.copyTo(new int[] {1, 2}, NdArrays.ofInts(Shape.of(2, 2))); + fail(); + } catch (IllegalArgumentException e) { + // as expected + } + + int[] array = StdArrays.array1dCopyOf(vector); + assertEquals(1, array[0]); + assertEquals(2, array[1]); + + array = new int[3]; + StdArrays.copyFrom(vector, array); + assertEquals(1, array[0]); + assertEquals(2, array[1]); + assertEquals(0, array[2]); + + try { + StdArrays.copyFrom(vector, new int[1]); + fail(); + } catch (ArrayIndexOutOfBoundsException e) { + // as expected + } + try { + StdArrays.copyFrom(vector, new int[1][2]); + fail(); + } catch (IllegalArgumentException e) { + // as expected + } + try { + StdArrays.copyFrom(vector, new int[2][2][2]); + fail(); + } catch (IllegalArgumentException e) { + // as expected + } + } + + @Test + public void matrices() { + IntNdArray matrix = NdArrays.ofInts(Shape.of(2, 2)); + + StdArrays.copyTo(new int[][] { + {1, 2}, + {3, 4} + }, matrix); + assertEquals(1, matrix.getInt(0, 0)); + assertEquals(2, matrix.getInt(0, 1)); + assertEquals(3, matrix.getInt(1, 0)); + assertEquals(4, matrix.getInt(1, 1)); + try { + StdArrays.copyTo(new int[][] {{1, 2, 3}, {4, 5, 6}}, matrix); + fail(); + } catch (IllegalArgumentException e) { + // as expected + } + try { + StdArrays.copyTo(new int[][] {{1, 2}, {3, 4}}, NdArrays.ofInts(Shape.of(3, 3))); + fail(); + } catch (IllegalArgumentException e) { + // as expected + } + try { + StdArrays.copyTo(new int[][] {{1, 2}, {3, 4}}, NdArrays.ofInts(Shape.of(2, 2, 1))); + fail(); + } catch (IllegalArgumentException e) { + // as expected + } + + int[][] array = StdArrays.array2dCopyOf(matrix); + assertEquals(1, array[0][0]); + assertEquals(2, array[0][1]); + assertEquals(3, array[1][0]); + assertEquals(4, array[1][1]); + + array = new int[3][3]; + StdArrays.copyFrom(matrix, array); + assertArrayEquals(new int[] { 1, 2, 0 }, array[0]); + assertArrayEquals(new int[] { 3, 4, 0 }, array[1]); + assertArrayEquals(new int[] { 0, 0, 0 }, array[2]); + + try { + StdArrays.copyFrom(matrix, new int[1][2]); + fail(); + } catch (ArrayIndexOutOfBoundsException e) { + // as expected + } + try { + StdArrays.copyFrom(matrix, new int[2][1]); + fail(); + } catch (ArrayIndexOutOfBoundsException e) { + // as expected + } + try { + StdArrays.copyFrom(matrix, new int[2]); + fail(); + } catch (IllegalArgumentException e) { + // as expected + } + try { + StdArrays.copyFrom(matrix, new int[1][2][2]); + fail(); + } catch (IllegalArgumentException e) { + // as expected + } + try { + StdArrays.copyFrom(matrix, new int[2][2][2]); + fail(); + } catch (IllegalArgumentException e) { + // as expected + } + } + + @Test + public void objectMatrix() { + NdArray matrix = StdArrays.ndCopyOf(new String[][] {{"ab", "bc"}, {"cd", "de"}}); + assertEquals(NdArrays.vectorOfObjects("ab", "bc"), matrix.get(0)); + assertEquals(NdArrays.vectorOfObjects("cd", "de"), matrix.get(1)); + + String[][] array = StdArrays.array2dCopyOf(matrix, String.class); + assertEquals("ab", array[0][0]); + assertEquals("bc", array[0][1]); + assertEquals("cd", array[1][0]); + assertEquals("de", array[1][1]); + + array = new String[2][3]; + StdArrays.copyFrom(matrix, array); + assertEquals("ab", array[0][0]); + assertEquals("bc", array[0][1]); + assertNull(array[0][2]); + assertEquals("cd", array[1][0]); + assertEquals("de", array[1][1]); + assertNull(array[1][2]); + } + + @Test + public void cannotInitDenseMatrixWithRaggedArray() { + IntNdArray matrix = NdArrays.ofInts(Shape.of(2, 2)); + try { + StdArrays.copyTo(new int[][]{ + {1, 2}, + {3} + }, matrix); + fail(); + } catch (IllegalArgumentException e) { + // as expected + } + } + + @Test + public void computeShapeDense3DMatrix() { + Shape shape = StdArrays.shapeOf(new int[][][] { + { + {1, 2, 3}, {4, 5, 6} + }, + { + {1, 2, 3}, {4, 5, 6} + } + }); + assertArrayEquals(new long[] {2, 2, 3}, shape.asArray()); + } + + @Test + public void shapeOfRagged3DMatrix() { + Shape shape = StdArrays.shapeOf(new int[][][] { + { + {1, 2, 3}, {4, 5, 6}, {7, 8, 9} + }, + { + {1, 2, 3}, {4, 5, 6} + } + }); + assertArrayEquals(new long[] {2, Shape.UNKNOWN_SIZE, 3}, shape.asArray()); + } + + @Test + public void shapeOfEmptyArray() { + Shape shape = StdArrays.shapeOf(new int[2][2][3]); + assertArrayEquals(new long[] {2, 2, 3}, shape.asArray()); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/benchmark/NdArrayBenchmark.java b/ndarray/src/test/java/org/tensorflow/ndarray/benchmark/NdArrayBenchmark.java new file mode 100644 index 00000000000..fb7022bc830 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/benchmark/NdArrayBenchmark.java @@ -0,0 +1,163 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.benchmark; + +import static org.tensorflow.ndarray.index.Indices.all; +import static org.tensorflow.ndarray.index.Indices.at; + +import java.awt.image.BufferedImage; +import java.awt.image.Raster; +import java.io.IOException; +import javax.imageio.ImageIO; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.runner.RunnerException; +import org.tensorflow.ndarray.Shape; +import org.tensorflow.ndarray.FloatNdArray; +import org.tensorflow.ndarray.NdArrays; +import org.tensorflow.ndarray.StdArrays; + +@Fork(value = 1, jvmArgs = {"-Xms4G", "-Xmx4G"}) +@BenchmarkMode(Mode.AverageTime) +@Warmup(iterations = 3) +@Measurement(iterations = 5) +@State(Scope.Benchmark) +public class NdArrayBenchmark { + + public static void main(String[] args) throws IOException, RunnerException { + org.openjdk.jmh.Main.main(args); + } + + @Setup + public void setUp() throws IOException { + BufferedImage image = ImageIO.read(getClass().getClassLoader().getResourceAsStream(TEST_IMAGE)); + + int numPixels = image.getWidth() * image.getHeight(); + pixels = NdArrays.ofFloats(Shape.of(numPixels, 3)); + channels = NdArrays.ofFloats(Shape.of(3, numPixels)); + + Raster imageData = image.getData(); + float[] pixel = new float[3]; + for (int y = 0, pixelIdx = 0; y < image.getHeight(); ++y) { + for (int x = 0; x < image.getWidth(); ++x, ++pixelIdx) { + imageData.getPixel(x, y, pixel); + StdArrays.copyTo(pixel, pixels.get(pixelIdx)); + StdArrays.copyTo(pixel, channels.slice(all(), at(pixelIdx))); + } + } + batches = NdArrays.ofFloats(Shape.of(BATCH_SIZE, 3, numPixels)); + firstBatch = batches.get(0); + } + + @Benchmark + @Measurement(batchSize = 2049 * 1537) + public void getElementAtIndex() { + pixels.get(0); + } + + @Benchmark + @Measurement(batchSize = 2049 * 1537) + public void slicing() { + batches.slice(at(0), all(), at(0)); + } + + @Benchmark + public void readingAllPixelsChannelsBySequence() { + pixels.scalars().forEach(pixel -> pixel.getFloat()); + } + + @Benchmark + public void readingAllPixelsChannelsBySequenceSlices() { + pixels.scalars().asSlices().forEach(pixel -> pixel.getFloat()); + } + + @Benchmark + @Measurement(batchSize = 100) + public void readingAllPixelsChannelsByIndex() { + long[] shape = pixels.shape().asArray(); + for (int i = 0; i < shape[0]; ++i) { + for (int j = 0; j < shape[1]; ++j) { + pixels.getFloat(i, j); + } + } + } + + @Benchmark + @Measurement(batchSize = BATCH_SIZE) + public void writeFirstBatchChannels() { + firstBatch.set(channels); + } + + @Benchmark + public void writeAllBatchChannels() { + batches.elements(0).forEach(batch -> + batch.set(channels) + ); + } + + @Benchmark + @Measurement(batchSize = 2049 * 1537) + public void writeOnePixelBySlicing() { + batches.slice(at(0), all(), at(0)).set(pixels.get(0)); + } + + @Benchmark + public void writeAllPixelsBySlicing() { + batches.elements(0).forEach(batch -> + pixels.elements(0).forEachIndexed((coords, pixel) -> + batch.slice(all(), at(coords[0])).set(pixel) + ) + ); + } + + @Benchmark + @Measurement(batchSize = 2049 * 1537) + public void writeOnePixelsByIndex() { + batches + .setFloat(pixels.getFloat(0, 0), 0, 0, 0) + .setFloat(pixels.getFloat(0, 1), 0, 1, 0) + .setFloat(pixels.getFloat(0, 2), 0, 2, 0); + } + + @Benchmark + public void writeAllPixelsByIndex() { + batches.elements(0).forEach(batch -> + pixels.elements(0).forEachIndexed((coords, pixel) -> { + long pixelIndex = coords[0]; + batch + .setFloat(pixel.getFloat(0), 0, pixelIndex) + .setFloat(pixel.getFloat(1), 1, pixelIndex) + .setFloat(pixel.getFloat(2), 2, pixelIndex); + }) + ); + } + + private static final String TEST_IMAGE = "castle.jpg"; + private static final int BATCH_SIZE = 60; + + private FloatNdArray pixels; + private FloatNdArray channels; + private FloatNdArray batches; + private FloatNdArray firstBatch; +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/buffer/BooleanDataBufferTestBase.java b/ndarray/src/test/java/org/tensorflow/ndarray/buffer/BooleanDataBufferTestBase.java new file mode 100644 index 00000000000..3f6df8aa1ce --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/buffer/BooleanDataBufferTestBase.java @@ -0,0 +1,142 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.buffer; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +import java.util.Arrays; +import java.util.BitSet; +import org.junit.jupiter.api.Test; +import org.tensorflow.ndarray.impl.buffer.misc.MiscDataBufferFactory; + +public abstract class BooleanDataBufferTestBase extends DataBufferTestBase { + + @Override + protected abstract BooleanDataBuffer allocate(long size); + + @Override + protected Boolean valueOf(Long val) { + return val != 0; + } + + @Test + public void writeAndReadFromArray() { + BooleanDataBuffer buffer = allocate(10L); + boolean[] values = new boolean[]{true, false, false, true, false}; + + buffer.write(values); + assertTrue(buffer.getObject(0)); + assertFalse(buffer.getObject(1)); + + buffer.offset(5).write(values); + assertTrue(buffer.getObject(5)); + + boolean[] read = new boolean[5]; + buffer.read(read); + assertArrayEquals(values, read); + + buffer.write(values, 2, 3); + assertFalse(buffer.getObject(0)); + assertTrue(buffer.getObject(1)); + assertFalse(buffer.getObject(2)); + + Arrays.fill(read, false); + buffer.read(read, 1, 2); + assertFalse(read[0]); + assertFalse(read[1]); + assertTrue(read[2]); + assertFalse(read[3]); + } + + @Test + public void equalWithBitSetBuffer() { + BitSet bitSet1 = BitSet.valueOf(new byte[] { 0x01, 0x01 }); + BooleanDataBuffer bitSet1Buffer = MiscDataBufferFactory.create(bitSet1, 12, true); + + BitSet bitSet2 = BitSet.valueOf(new byte[] { 0x11, 0x01 }); + BooleanDataBuffer bitSet2Buffer = MiscDataBufferFactory.create(bitSet2, 12, true); + + BooleanDataBuffer buffer = allocate(12) + .setBoolean(true, 0) + .setBoolean(true, 8); + + assertTrue(bitSet1Buffer.equals(buffer)); + assertTrue(buffer.equals(bitSet1Buffer)); + assertEquals(bitSet1Buffer.hashCode(), buffer.hashCode()); + + assertFalse(bitSet2Buffer.equals(buffer)); + assertFalse(buffer.equals(bitSet2Buffer)); + assertNotEquals(bitSet2Buffer.hashCode(), buffer.hashCode()); + } + + @Test + public void equalWithBooleanArrayBuffer() { + boolean[] array1 = new boolean[] { false, false, false, true, true, false }; + BooleanDataBuffer array1Buffer = MiscDataBufferFactory.create(array1, true); + + boolean[] array2 = new boolean[] { false, false, false, true, true, true }; + BooleanDataBuffer array2Buffer = MiscDataBufferFactory.create(array2, true); + + BooleanDataBuffer buffer = allocate(6) + .setBoolean(true, 3) + .setBoolean(true, 4); + + assertTrue(array1Buffer.equals(buffer)); + assertTrue(buffer.equals(array1Buffer)); + assertEquals(array1Buffer.hashCode(), buffer.hashCode()); + + assertFalse(array2Buffer.equals(buffer)); + assertFalse(buffer.equals(array2Buffer)); + assertNotEquals(array2Buffer.hashCode(), buffer.hashCode()); + } + + @Test + public void equalWithBooleanObjectBuffer() { + Boolean[] array1 = new Boolean[] { false, false, false, true, true, false }; + DataBuffer array1Buffer = MiscDataBufferFactory.create(array1, true); + + boolean[] array2 = new boolean[] { false, false, false, true, true, true }; + DataBuffer array2Buffer = MiscDataBufferFactory.create(array2, true); + + BooleanDataBuffer buffer = allocate(6) + .setBoolean(true, 3) + .setBoolean(true, 4); + + assertTrue(array1Buffer.equals(buffer)); + assertTrue(buffer.equals(array1Buffer)); + assertEquals(array1Buffer.hashCode(), buffer.hashCode()); + + assertFalse(array2Buffer.equals(buffer)); + assertFalse(buffer.equals(array2Buffer)); + assertNotEquals(array2Buffer.hashCode(), buffer.hashCode()); + } + + @Test + public void notEqualWithOtherTypes() { + BooleanDataBuffer buffer = allocate(2) + .setBoolean(false, 0) + .setBoolean(true, 1); + ByteDataBuffer byteBuffer = DataBuffers.of((byte)0, (byte)1); + + assertFalse(buffer.equals(byteBuffer)); + assertFalse(byteBuffer.equals(buffer)); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/buffer/ByteDataBufferTestBase.java b/ndarray/src/test/java/org/tensorflow/ndarray/buffer/ByteDataBufferTestBase.java new file mode 100644 index 00000000000..777368466f5 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/buffer/ByteDataBufferTestBase.java @@ -0,0 +1,145 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.buffer; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.junit.jupiter.api.Test; +import org.tensorflow.ndarray.impl.buffer.misc.MiscDataBufferFactory; +import org.tensorflow.ndarray.impl.buffer.nio.NioDataBufferFactory; +import org.tensorflow.ndarray.impl.buffer.raw.RawDataBufferFactory; + +public abstract class ByteDataBufferTestBase extends DataBufferTestBase { + + @Override + protected abstract ByteDataBuffer allocate(long size); + + @Override + protected Byte valueOf(Long val) { + return val.byteValue(); + } + + @Test + public void writeAndReadFromArray() { + ByteDataBuffer buffer = allocate(10L); + byte[] oneToFive = new byte[]{ 1, 2, 3, 4, 5 }; + + buffer.write(oneToFive); + assertEquals(2, buffer.getByte(1)); + + buffer.offset(5).write(oneToFive); + assertEquals(2, buffer.getByte(1)); + assertEquals(2, buffer.getByte(6)); + + byte[] read = new byte[5]; + buffer.read(read); + assertArrayEquals(oneToFive, read); + + buffer.write(oneToFive, 2, 2); + assertEquals(3, buffer.getByte(0)); + assertEquals(4, buffer.getByte(1)); + assertEquals(3, buffer.getByte(2)); + + Arrays.fill(read, valueOf(0L)); + buffer.read(read, 1, 2); + assertEquals(0, read[0]); + assertEquals(3, read[1]); + assertEquals(4, read[2]); + assertEquals(0, read[3]); + } + + @Test + public void equalWithByteNioBuffer() { + ByteDataBuffer nioBuffer1 = NioDataBufferFactory.create(ByteBuffer.wrap(new byte[] { 0x01, 0x10 })); + ByteDataBuffer nioBuffer2 = NioDataBufferFactory.create(ByteBuffer.wrap(new byte[] { 0x01, 0x11 })); + + ByteDataBuffer buffer = allocate(2) + .setByte((byte)0x01, 0) + .setByte((byte)0x10, 1); + + assertTrue(nioBuffer1.equals(buffer)); + assertTrue(buffer.equals(nioBuffer1)); + assertEquals(nioBuffer1.hashCode(), buffer.hashCode()); + + assertFalse(nioBuffer2.equals(buffer)); + assertFalse(buffer.equals(nioBuffer2)); + assertNotEquals(nioBuffer2.hashCode(), buffer.hashCode()); + } + + @Test + public void equalWithByteRawBuffer() { + ByteDataBuffer rawBuffer1 = RawDataBufferFactory.create(new byte[] { 0x01, 0x10 }, true); + ByteDataBuffer rawBuffer2 = RawDataBufferFactory.create(new byte[] { 0x01, 0x11 }, true); + + ByteDataBuffer buffer = allocate(2) + .setByte((byte)0x01, 0) + .setByte((byte)0x10, 1); + + assertTrue(rawBuffer1.equals(buffer)); + assertTrue(buffer.equals(rawBuffer1)); + assertEquals(rawBuffer1.hashCode(), buffer.hashCode()); + + assertFalse(rawBuffer2.equals(buffer)); + assertFalse(buffer.equals(rawBuffer2)); + assertNotEquals(rawBuffer2.hashCode(), buffer.hashCode()); + } + + @Test + public void equalWithByteObjectBuffer() { + DataBuffer objBuffer1 = MiscDataBufferFactory.create(new Byte[] { 0x01, 0x10 }, true); + DataBuffer objBuffer2 = MiscDataBufferFactory.create(new Byte[] { 0x01, 0x11 }, true); + + ByteDataBuffer buffer = allocate(2) + .setByte((byte)0x01, 0) + .setByte((byte)0x10, 1); + + assertTrue(objBuffer1.equals(buffer)); + assertTrue(buffer.equals(objBuffer1)); + assertEquals(objBuffer1.hashCode(), buffer.hashCode()); + + assertFalse(objBuffer2.equals(buffer)); + assertFalse(buffer.equals(objBuffer2)); + assertNotEquals(objBuffer2.hashCode(), buffer.hashCode()); + } + + @Test + public void notEqualWithOtherTypes() { + ByteDataBuffer buffer = allocate(2) + .setByte((byte)1, 0) + .setByte((byte)16, 1); + LongDataBuffer longBuffer = DataBuffers.of(1L, 16L); + + assertFalse(buffer.equals(longBuffer)); + assertFalse(longBuffer.equals(buffer)); + + try { + IntDataBuffer intBuffer = buffer.asInts(); + + assertFalse(buffer.equals(intBuffer)); + assertFalse(intBuffer.equals(buffer)); + + } catch (IllegalStateException e) { + // some byte buffers cannot be converted to ints, ignore the test in that case + } + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/buffer/DataBufferTestBase.java b/ndarray/src/test/java/org/tensorflow/ndarray/buffer/DataBufferTestBase.java new file mode 100644 index 00000000000..9a023915735 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/buffer/DataBufferTestBase.java @@ -0,0 +1,293 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.buffer; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +import java.nio.BufferOverflowException; +import java.nio.BufferUnderflowException; +import org.junit.jupiter.api.Test; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DataBufferWindow; +import org.tensorflow.ndarray.buffer.DataBuffers; + +public abstract class DataBufferTestBase { + + protected final boolean enableLargeBufferTests = System.getProperty("testLargeBuffers") != null; + + protected long maxSize() { + return DataBuffers.MAX_32BITS; + } + + protected abstract DataBuffer allocate(long size); + + protected abstract T valueOf(Long val); + + @Test + public void bufferSize() { + DataBuffer buffer = allocate(10L); + assertEquals(10L, buffer.size()); + + buffer = allocate(0L); + assertEquals(0L, buffer.size()); + + if (enableLargeBufferTests) { + buffer = allocate(maxSize()); + assertEquals(maxSize(), buffer.size()); + } + } + + @Test + public void offsetNarrowAndSlice() { + DataBuffer buffer = allocate(10L).setObject(valueOf(1L), 5); // 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 + assertEquals(10L, buffer.size()); + assertEquals(valueOf(1L), buffer.getObject(5)); + + DataBuffer subBuffer = buffer.slice(2, 6); // 0, 0, 0, 1, 0, 0 + assertEquals(6L, subBuffer.size()); + assertEquals(valueOf(1L), subBuffer.getObject(3)); + + subBuffer = subBuffer.offset(2L); // 0, 1, 0, 0 + assertEquals(4L, subBuffer.size()); + assertEquals(valueOf(1L), subBuffer.getObject(1)); + + subBuffer = subBuffer.narrow(2L); // 0, 1 + assertEquals(2L, subBuffer.size()); + assertEquals(valueOf(1L), subBuffer.getObject(1)); + try { + subBuffer.getObject(2); + fail(); + } catch (IndexOutOfBoundsException e) { + //as expected + } + try { + buffer.slice(2, 12); + fail(); + } catch (IllegalArgumentException e) { + // as expected + } + try { + buffer.slice(-1, 3); + fail(); + } catch (IllegalArgumentException e) { + // as expected + } + try { + buffer.slice(2, -1); + fail(); + } catch (IllegalArgumentException e) { + // as expected + } + try { + buffer.offset(-1L); + fail(); + } catch (IllegalArgumentException e) { + // as expected + } + try { + buffer.offset(11L); + fail(); + } catch (IllegalArgumentException e) { + // as expected + } + try { + buffer.narrow(-1L); + fail(); + } catch (IllegalArgumentException e) { + // as expected + } + try { + buffer.narrow(11L); + fail(); + } catch (IllegalArgumentException e) { + // as expected + } + } + + @Test + public void putAndGet() { + DataBuffer buffer = allocate(10L); + + buffer.setObject(valueOf(5L), 5L); + assertEquals(valueOf(5L), buffer.getObject(5L)); + try { + buffer.setObject(valueOf(10L), 10L); + fail(); + } catch (IndexOutOfBoundsException e) { + // as expected + } + try { + buffer.getObject(10L); + fail(); + } catch (IndexOutOfBoundsException e) { + // as expected + } + try { + buffer.setObject(valueOf(-1L), -1L); + fail(); + } catch (IndexOutOfBoundsException e) { + // as expected + } + try { + buffer.getObject(-1L); + fail(); + } catch (IndexOutOfBoundsException e) { + // as expected + } + } + + @Test + public void copyToBuffer() { + DataBuffer srcBuffer = allocate(25L); + srcBuffer.setObject(valueOf(5L), 5L); + srcBuffer.setObject(valueOf(10L), 10L); + srcBuffer.setObject(valueOf(15L), 15L); + srcBuffer.setObject(valueOf(20L), 20L); + try { + srcBuffer.copyTo(srcBuffer, srcBuffer.size()); + fail(); + } catch (IllegalArgumentException e) { + // as expected + } + DataBuffer dstBuffer = allocate(30L); + srcBuffer.copyTo(dstBuffer, srcBuffer.size()); + assertEquals(valueOf(5L), dstBuffer.getObject(5L)); + try { + srcBuffer.copyTo(dstBuffer, dstBuffer.size()); + fail(); + } catch (BufferUnderflowException e) { + // as expected + } + try { + dstBuffer.copyTo(srcBuffer, dstBuffer.size()); + fail(); + } catch (BufferOverflowException e) { + // as expected + } + } + + @Test + public void createFromVarargs() { + DataBuffer buffer = DataBuffers.ofObjects(valueOf(1L), valueOf(2L), valueOf(3L)); + assertEquals(3, buffer.size()); + assertEquals(valueOf(1L), buffer.getObject(0)); + assertEquals(valueOf(2L), buffer.getObject(1)); + assertEquals(valueOf(3L), buffer.getObject(2)); + } + + @Test + public void equalWithObjectBuffer() { + DataBuffer buffer1 = allocate(2) + .setObject(valueOf(0L), 0) + .setObject(valueOf(1L), 1); + DataBuffer buffer2 = allocate(2) + .setObject(valueOf(0L), 0) + .setObject(valueOf(1L), 1); + DataBuffer buffer3 = allocate(2) + .setObject(valueOf(1L), 0) + .setObject(valueOf(0L), 1); + DataBuffer buffer4 = allocate(1) + .setObject(valueOf(0L), 0); + DataBuffer buffer5 = allocate(3) + .setObject(valueOf(0L), 0) + .setObject(valueOf(1L), 1) + .setObject(valueOf(2L), 2); + + assertTrue(buffer1.equals(buffer2)); + assertTrue(buffer2.equals(buffer1)); + assertEquals(buffer1.hashCode(), buffer1.hashCode()); + assertEquals(buffer1.hashCode(), buffer2.hashCode()); + + assertFalse(buffer3.equals(buffer1)); + assertFalse(buffer1.equals(buffer3)); + assertNotEquals(buffer3.hashCode(), buffer1.hashCode()); + + assertFalse(buffer4.equals(buffer1)); + assertFalse(buffer1.equals(buffer4)); + assertNotEquals(buffer4.hashCode(), buffer1.hashCode()); + + assertFalse(buffer5.equals(buffer1)); + assertFalse(buffer1.equals(buffer5)); + assertNotEquals(buffer5.hashCode(), buffer1.hashCode()); + } + + @Test + public void bufferWindow() { + DataBuffer buffer = allocate(20); + DataBufferWindow> bufferWindow; + try { + bufferWindow = buffer.window(4); + } catch (UnsupportedOperationException e) { + return; // skip test if this buffer does not support windows + } + assertEquals(0, bufferWindow.offset()); + assertEquals(4, bufferWindow.size()); + assertEquals(4, bufferWindow.buffer().size()); + + for (long i = 0; i < buffer.size(); ++i) { + buffer.setObject(valueOf(i), i); + } + assertEquals(valueOf(2L), bufferWindow.buffer().getObject(2)); + DataBuffer windowBuffer = bufferWindow.buffer(); + + bufferWindow.slide(10); + assertEquals(10, bufferWindow.offset()); + assertEquals(4, bufferWindow.size()); + assertEquals(valueOf(12L), bufferWindow.buffer().getObject(2)); + assertSame(windowBuffer, bufferWindow.buffer()); + + bufferWindow.slide(-2); + assertEquals(8, bufferWindow.offset()); + assertEquals(4, bufferWindow.size()); + assertEquals(valueOf(10L), bufferWindow.buffer().getObject(2)); + + bufferWindow.slideTo(16); + assertEquals(16, bufferWindow.offset()); + assertEquals(4, bufferWindow.size()); + assertEquals(valueOf(18L), bufferWindow.buffer().getObject(2)); + + try { + bufferWindow.slide(1); + fail(); + } catch (IndexOutOfBoundsException e) { + // as expected + } + try { + bufferWindow.slide(-17); + fail(); + } catch (IndexOutOfBoundsException e) { + // as expected + } + try { + bufferWindow.slideTo(-1); + fail(); + } catch (IndexOutOfBoundsException e) { + // as expected + } + try { + bufferWindow.slideTo(17); + fail(); + } catch (IndexOutOfBoundsException e) { + // as expected + } + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/buffer/DoubleDataBufferTestBase.java b/ndarray/src/test/java/org/tensorflow/ndarray/buffer/DoubleDataBufferTestBase.java new file mode 100644 index 00000000000..4dee064968c --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/buffer/DoubleDataBufferTestBase.java @@ -0,0 +1,135 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.buffer; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.nio.DoubleBuffer; +import java.util.Arrays; +import org.junit.jupiter.api.Test; +import org.tensorflow.ndarray.impl.buffer.misc.MiscDataBufferFactory; +import org.tensorflow.ndarray.impl.buffer.nio.NioDataBufferFactory; +import org.tensorflow.ndarray.impl.buffer.raw.RawDataBufferFactory; + +public abstract class DoubleDataBufferTestBase extends DataBufferTestBase { + + @Override + protected abstract DoubleDataBuffer allocate(long size); + + @Override + protected Double valueOf(Long val) { + return val.doubleValue(); + } + + @Test + public void writeAndReadFromArray() { + DoubleDataBuffer buffer = allocate(10L); + double[] oneToFive = new double[]{ 1.0, 2.0, 3.0, 4.0, 5.0 }; + + buffer.write(oneToFive); + assertEquals(2.0, buffer.getDouble(1), 0.0); + + buffer.offset(5).write(oneToFive); + assertEquals(2.0, buffer.getDouble(1), 0.0); + assertEquals(2.0, buffer.getDouble(6), 0.0); + + double[] read = new double[5]; + buffer.read(read); + assertArrayEquals(oneToFive, read, 0.0); + + buffer.write(oneToFive, 2, 2); + assertEquals(3.0, buffer.getDouble(0), 0.0); + assertEquals(4.0, buffer.getDouble(1), 0.0); + assertEquals(3.0, buffer.getDouble(2), 0.0); + + Arrays.fill(read, valueOf(0L)); + buffer.read(read, 1, 2); + assertEquals(0.0, read[0], 0.0); + assertEquals(3.0, read[1], 0.0); + assertEquals(4.0, read[2], 0.0); + assertEquals(0.0, read[3], 0.0); + } + + @Test + public void equalWithDoubleNioBuffer() { + DoubleDataBuffer nioBuffer1 = NioDataBufferFactory.create(DoubleBuffer.wrap(new double[] { 1.0, 16.0 })); + DoubleDataBuffer nioBuffer2 = NioDataBufferFactory.create(DoubleBuffer.wrap(new double[] { 1.0, 25.0 })); + + DoubleDataBuffer buffer = allocate(2) + .setDouble(1.0, 0) + .setDouble(16.0, 1); + + assertTrue(nioBuffer1.equals(buffer)); + assertTrue(buffer.equals(nioBuffer1)); + assertEquals(nioBuffer1.hashCode(), buffer.hashCode()); + + assertFalse(nioBuffer2.equals(buffer)); + assertFalse(buffer.equals(nioBuffer2)); + assertNotEquals(nioBuffer2.hashCode(), buffer.hashCode()); + } + + @Test + public void equalWithDoubleRawBuffer() { + DoubleDataBuffer rawBuffer1 = RawDataBufferFactory.create(new double[] { 1.0, 16.0 }, true); + DoubleDataBuffer rawBuffer2 = RawDataBufferFactory.create(new double[] { 1.0, 25.0 }, true); + + DoubleDataBuffer buffer = allocate(2) + .setDouble(1.0, 0) + .setDouble(16.0, 1); + + assertTrue(rawBuffer1.equals(buffer)); + assertTrue(buffer.equals(rawBuffer1)); + assertEquals(rawBuffer1.hashCode(), buffer.hashCode()); + + assertFalse(rawBuffer2.equals(buffer)); + assertFalse(buffer.equals(rawBuffer2)); + assertNotEquals(rawBuffer2.hashCode(), buffer.hashCode()); + } + + @Test + public void equalWithDoubleObjectBuffer() { + DataBuffer objBuffer1 = MiscDataBufferFactory.create(new Double[] { 1.0, 16.0 }, true); + DataBuffer objBuffer2 = MiscDataBufferFactory.create(new Double[] { 1.0, 25.0 }, true); + + DoubleDataBuffer buffer = allocate(2) + .setDouble(1.0, 0) + .setDouble(16.0, 1); + + assertTrue(objBuffer1.equals(buffer)); + assertTrue(buffer.equals(objBuffer1)); + assertEquals(objBuffer1.hashCode(), buffer.hashCode()); + + assertFalse(objBuffer2.equals(buffer)); + assertFalse(buffer.equals(objBuffer2)); + assertNotEquals(objBuffer2.hashCode(), buffer.hashCode()); + } + + @Test + public void notEqualWithOtherTypes() { + DoubleDataBuffer buffer = allocate(2) + .setDouble(1.0, 0) + .setDouble(16.0, 1); + FloatDataBuffer floatBuffer = DataBuffers.of(1.0f, 16.0f); + + assertFalse(buffer.equals(floatBuffer)); + assertFalse(floatBuffer.equals(buffer)); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/buffer/FloatDataBufferTestBase.java b/ndarray/src/test/java/org/tensorflow/ndarray/buffer/FloatDataBufferTestBase.java new file mode 100644 index 00000000000..49c4f15b808 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/buffer/FloatDataBufferTestBase.java @@ -0,0 +1,135 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.buffer; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.nio.FloatBuffer; +import java.util.Arrays; +import org.junit.jupiter.api.Test; +import org.tensorflow.ndarray.impl.buffer.misc.MiscDataBufferFactory; +import org.tensorflow.ndarray.impl.buffer.nio.NioDataBufferFactory; +import org.tensorflow.ndarray.impl.buffer.raw.RawDataBufferFactory; + +public abstract class FloatDataBufferTestBase extends DataBufferTestBase { + + @Override + protected abstract FloatDataBuffer allocate(long size); + + @Override + protected Float valueOf(Long val) { + return val.floatValue(); + } + + @Test + public void writeAndReadFromArray() { + FloatDataBuffer buffer = allocate(10L); + float[] oneToFive = new float[]{ 1.0f, 2.0f, 3.0f, 4.0f, 5.0f }; + + buffer.write(oneToFive); + assertEquals(2.0f, buffer.getFloat(1), 0.0f); + + buffer.offset(5).write(oneToFive); + assertEquals(2.0f, buffer.getFloat(1), 0.0f); + assertEquals(2.0f, buffer.getFloat(6), 0.0f); + + float[] read = new float[5]; + buffer.read(read); + assertArrayEquals(oneToFive, read, 0.0f); + + buffer.write(oneToFive, 2, 2); + assertEquals(3.0f, buffer.getFloat(0), 0.0f); + assertEquals(4.0f, buffer.getFloat(1), 0.0f); + assertEquals(3.0f, buffer.getFloat(2), 0.0f); + + Arrays.fill(read, valueOf(0L)); + buffer.read(read, 1, 2); + assertEquals(0.0f, read[0], 0.0f); + assertEquals(3.0f, read[1], 0.0f); + assertEquals(4.0f, read[2], 0.0f); + assertEquals(0.0f, read[3], 0.0f); + } + + @Test + public void equalWithFloatNioBuffer() { + FloatDataBuffer nioBuffer1 = NioDataBufferFactory.create(FloatBuffer.wrap(new float[] { 1.0f, 16.0f })); + FloatDataBuffer nioBuffer2 = NioDataBufferFactory.create(FloatBuffer.wrap(new float[] { 1.0f, 25.0f })); + + FloatDataBuffer buffer = allocate(2) + .setFloat(1.0f, 0) + .setFloat(16.0f, 1); + + assertTrue(nioBuffer1.equals(buffer)); + assertTrue(buffer.equals(nioBuffer1)); + assertEquals(nioBuffer1.hashCode(), buffer.hashCode()); + + assertFalse(nioBuffer2.equals(buffer)); + assertFalse(buffer.equals(nioBuffer2)); + assertNotEquals(nioBuffer2.hashCode(), buffer.hashCode()); + } + + @Test + public void equalWithFloatRawBuffer() { + FloatDataBuffer rawBuffer1 = RawDataBufferFactory.create(new float[] { 1.0f, 16.0f }, true); + FloatDataBuffer rawBuffer2 = RawDataBufferFactory.create(new float[] { 1.0f, 25.0f }, true); + + FloatDataBuffer buffer = allocate(2) + .setFloat(1.0f, 0) + .setFloat(16.0f, 1); + + assertTrue(rawBuffer1.equals(buffer)); + assertTrue(buffer.equals(rawBuffer1)); + assertEquals(rawBuffer1.hashCode(), buffer.hashCode()); + + assertFalse(rawBuffer2.equals(buffer)); + assertFalse(buffer.equals(rawBuffer2)); + assertNotEquals(rawBuffer2.hashCode(), buffer.hashCode()); + } + + @Test + public void equalWithFloatObjectBuffer() { + DataBuffer objBuffer1 = MiscDataBufferFactory.create(new Float[] { 1.0f, 16.0f }, true); + DataBuffer objBuffer2 = MiscDataBufferFactory.create(new Float[] { 1.0f, 25.0f }, true); + + FloatDataBuffer buffer = allocate(2) + .setFloat(1.0f, 0) + .setFloat(16.0f, 1); + + assertTrue(objBuffer1.equals(buffer)); + assertTrue(buffer.equals(objBuffer1)); + assertEquals(objBuffer1.hashCode(), buffer.hashCode()); + + assertFalse(objBuffer2.equals(buffer)); + assertFalse(buffer.equals(objBuffer2)); + assertNotEquals(objBuffer2.hashCode(), buffer.hashCode()); + } + + @Test + public void notEqualWithOtherTypes() { + FloatDataBuffer buffer = allocate(2) + .setFloat(1.0f, 0) + .setFloat(16.0f, 1); + DoubleDataBuffer doubleBuffer = DataBuffers.of(1.0, 16.0); + + assertFalse(buffer.equals(doubleBuffer)); + assertFalse(doubleBuffer.equals(buffer)); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/buffer/IntDataBufferTestBase.java b/ndarray/src/test/java/org/tensorflow/ndarray/buffer/IntDataBufferTestBase.java new file mode 100644 index 00000000000..f3642e88ef8 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/buffer/IntDataBufferTestBase.java @@ -0,0 +1,135 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.buffer; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.nio.IntBuffer; +import java.util.Arrays; +import org.junit.jupiter.api.Test; +import org.tensorflow.ndarray.impl.buffer.misc.MiscDataBufferFactory; +import org.tensorflow.ndarray.impl.buffer.nio.NioDataBufferFactory; +import org.tensorflow.ndarray.impl.buffer.raw.RawDataBufferFactory; + +public abstract class IntDataBufferTestBase extends DataBufferTestBase { + + @Override + protected abstract IntDataBuffer allocate(long size); + + @Override + protected Integer valueOf(Long val) { + return val.intValue(); + } + + @Test + public void writeAndReadFromArray() { + IntDataBuffer buffer = allocate(10L); + int[] oneToFive = new int[]{ 1, 2, 3, 4, 5 }; + + buffer.write(oneToFive); + assertEquals(2, buffer.getInt(1)); + + buffer.offset(5).write(oneToFive); + assertEquals(2, buffer.getInt(1)); + assertEquals(2, buffer.getInt(6)); + + int[] read = new int[5]; + buffer.read(read); + assertArrayEquals(oneToFive, read); + + buffer.write(oneToFive, 2, 2); + assertEquals(3, buffer.getInt(0)); + assertEquals(4, buffer.getInt(1)); + assertEquals(3, buffer.getInt(2)); + + Arrays.fill(read, valueOf(0L)); + buffer.read(read, 1, 2); + assertEquals(0, read[0]); + assertEquals(3, read[1]); + assertEquals(4, read[2]); + assertEquals(0, read[3]); + } + + @Test + public void equalWithIntNioBuffer() { + IntDataBuffer nioBuffer1 = NioDataBufferFactory.create(IntBuffer.wrap(new int[] { 1, 16 })); + IntDataBuffer nioBuffer2 = NioDataBufferFactory.create(IntBuffer.wrap(new int[] { 1, 25 })); + + IntDataBuffer buffer = allocate(2) + .setInt(1, 0) + .setInt(16, 1); + + assertTrue(nioBuffer1.equals(buffer)); + assertTrue(buffer.equals(nioBuffer1)); + assertEquals(nioBuffer1.hashCode(), buffer.hashCode()); + + assertFalse(nioBuffer2.equals(buffer)); + assertFalse(buffer.equals(nioBuffer2)); + assertNotEquals(nioBuffer2.hashCode(), buffer.hashCode()); + } + + @Test + public void equalWithIntRawBuffer() { + IntDataBuffer rawBuffer1 = RawDataBufferFactory.create(new int[] { 1, 16 }, true); + IntDataBuffer rawBuffer2 = RawDataBufferFactory.create(new int[] { 1, 25 }, true); + + IntDataBuffer buffer = allocate(2) + .setInt(1, 0) + .setInt(16, 1); + + assertTrue(rawBuffer1.equals(buffer)); + assertTrue(buffer.equals(rawBuffer1)); + assertEquals(rawBuffer1.hashCode(), buffer.hashCode()); + + assertFalse(rawBuffer2.equals(buffer)); + assertFalse(buffer.equals(rawBuffer2)); + assertNotEquals(rawBuffer2.hashCode(), buffer.hashCode()); + } + + @Test + public void equalWithIntObjectBuffer() { + DataBuffer objBuffer1 = MiscDataBufferFactory.create(new Integer[] { 1, 16 }, true); + DataBuffer objBuffer2 = MiscDataBufferFactory.create(new Integer[] { 1, 25 }, true); + + IntDataBuffer buffer = allocate(2) + .setInt(1, 0) + .setInt(16, 1); + + assertTrue(objBuffer1.equals(buffer)); + assertTrue(buffer.equals(objBuffer1)); + assertEquals(objBuffer1.hashCode(), buffer.hashCode()); + + assertFalse(objBuffer2.equals(buffer)); + assertFalse(buffer.equals(objBuffer2)); + assertNotEquals(objBuffer2.hashCode(), buffer.hashCode()); + } + + @Test + public void notEqualWithOtherTypes() { + IntDataBuffer buffer = allocate(2) + .setInt(1, 0) + .setInt(16, 1); + LongDataBuffer longBuffer = DataBuffers.of(1L, 16L); + + assertFalse(buffer.equals(longBuffer)); + assertFalse(longBuffer.equals(buffer)); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/buffer/LongDataBufferTestBase.java b/ndarray/src/test/java/org/tensorflow/ndarray/buffer/LongDataBufferTestBase.java new file mode 100644 index 00000000000..e0d8b1b4539 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/buffer/LongDataBufferTestBase.java @@ -0,0 +1,135 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.buffer; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.nio.LongBuffer; +import java.util.Arrays; +import org.junit.jupiter.api.Test; +import org.tensorflow.ndarray.impl.buffer.misc.MiscDataBufferFactory; +import org.tensorflow.ndarray.impl.buffer.nio.NioDataBufferFactory; +import org.tensorflow.ndarray.impl.buffer.raw.RawDataBufferFactory; + +public abstract class LongDataBufferTestBase extends DataBufferTestBase { + + @Override + protected abstract LongDataBuffer allocate(long size); + + @Override + protected Long valueOf(Long val) { + return val; + } + + @Test + public void writeAndReadFromArray() { + LongDataBuffer buffer = allocate(10L); + long[] oneToFive = new long[]{ 1L, 2L, 3L, 4L, 5L }; + + buffer.write(oneToFive); + assertEquals(2, buffer.getLong(1)); + + buffer.offset(5).write(oneToFive); + assertEquals(2L, buffer.getLong(1)); + assertEquals(2L, buffer.getLong(6)); + + long[] read = new long[5]; + buffer.read(read); + assertArrayEquals(oneToFive, read); + + buffer.write(oneToFive, 2, 2); + assertEquals(3L, buffer.getLong(0)); + assertEquals(4L, buffer.getLong(1)); + assertEquals(3L, buffer.getLong(2)); + + Arrays.fill(read, valueOf(0L)); + buffer.read(read, 1, 2); + assertEquals(0L, read[0]); + assertEquals(3L, read[1]); + assertEquals(4L, read[2]); + assertEquals(0L, read[3]); + } + + @Test + public void equalWithLongNioBuffer() { + LongDataBuffer nioBuffer1 = NioDataBufferFactory.create(LongBuffer.wrap(new long[] { 1, 16 })); + LongDataBuffer nioBuffer2 = NioDataBufferFactory.create(LongBuffer.wrap(new long[] { 1, 25 })); + + LongDataBuffer buffer = allocate(2) + .setLong(1, 0) + .setLong(16, 1); + + assertTrue(nioBuffer1.equals(buffer)); + assertTrue(buffer.equals(nioBuffer1)); + assertEquals(nioBuffer1.hashCode(), buffer.hashCode()); + + assertFalse(nioBuffer2.equals(buffer)); + assertFalse(buffer.equals(nioBuffer2)); + assertNotEquals(nioBuffer2.hashCode(), buffer.hashCode()); + } + + @Test + public void equalWithLongRawBuffer() { + LongDataBuffer rawBuffer1 = RawDataBufferFactory.create(new long[] { 1, 16 }, true); + LongDataBuffer rawBuffer2 = RawDataBufferFactory.create(new long[] { 1, 25 }, true); + + LongDataBuffer buffer = allocate(2) + .setLong(1, 0) + .setLong(16, 1); + + assertTrue(rawBuffer1.equals(buffer)); + assertTrue(buffer.equals(rawBuffer1)); + assertEquals(rawBuffer1.hashCode(), buffer.hashCode()); + + assertFalse(rawBuffer2.equals(buffer)); + assertFalse(buffer.equals(rawBuffer2)); + assertNotEquals(rawBuffer2.hashCode(), buffer.hashCode()); + } + + @Test + public void equalWithLongObjectBuffer() { + DataBuffer objBuffer1 = MiscDataBufferFactory.create(new Long[] { 1L, 16L }, true); + DataBuffer objBuffer2 = MiscDataBufferFactory.create(new Long[] { 1L, 25L }, true); + + LongDataBuffer buffer = allocate(2) + .setLong(1, 0) + .setLong(16, 1); + + assertTrue(objBuffer1.equals(buffer)); + assertTrue(buffer.equals(objBuffer1)); + assertEquals(objBuffer1.hashCode(), buffer.hashCode()); + + assertFalse(objBuffer2.equals(buffer)); + assertFalse(buffer.equals(objBuffer2)); + assertNotEquals(objBuffer2.hashCode(), buffer.hashCode()); + } + + @Test + public void notEqualWithOtherTypes() { + LongDataBuffer buffer = allocate(2) + .setLong(1L, 0) + .setLong(16L, 1); + IntDataBuffer intBuffer = DataBuffers.of(1, 16); + + assertFalse(buffer.equals(intBuffer)); + assertFalse(intBuffer.equals(buffer)); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/buffer/ShortDataBufferTestBase.java b/ndarray/src/test/java/org/tensorflow/ndarray/buffer/ShortDataBufferTestBase.java new file mode 100644 index 00000000000..f3269e85a8f --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/buffer/ShortDataBufferTestBase.java @@ -0,0 +1,135 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.buffer; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.nio.ShortBuffer; +import java.util.Arrays; +import org.junit.jupiter.api.Test; +import org.tensorflow.ndarray.impl.buffer.misc.MiscDataBufferFactory; +import org.tensorflow.ndarray.impl.buffer.nio.NioDataBufferFactory; +import org.tensorflow.ndarray.impl.buffer.raw.RawDataBufferFactory; + +public abstract class ShortDataBufferTestBase extends DataBufferTestBase { + + @Override + protected abstract ShortDataBuffer allocate(long size); + + @Override + protected Short valueOf(Long val) { + return val.shortValue(); + } + + @Test + public void writeAndReadFromArray() { + ShortDataBuffer buffer = allocate(10L); + short[] oneToFive = new short[]{ 1, 2, 3, 4, 5 }; + + buffer.write(oneToFive); + assertEquals(2, buffer.getShort(1)); + + buffer.offset(5).write(oneToFive); + assertEquals(2, buffer.getShort(1), 0); + assertEquals(2, buffer.getShort(6), 0); + + short[] read = new short[5]; + buffer.read(read); + assertArrayEquals(oneToFive, read); + + buffer.write(oneToFive, 2, 2); + assertEquals(3, buffer.getShort(0)); + assertEquals(4, buffer.getShort(1)); + assertEquals(3, buffer.getShort(2)); + + Arrays.fill(read, valueOf(0L)); + buffer.read(read, 1, 2); + assertEquals(0, read[0]); + assertEquals(3, read[1]); + assertEquals(4, read[2]); + assertEquals(0, read[3]); + } + + @Test + public void equalWithShortNioBuffer() { + ShortDataBuffer nioBuffer1 = NioDataBufferFactory.create(ShortBuffer.wrap(new short[] { 1, 16 })); + ShortDataBuffer nioBuffer2 = NioDataBufferFactory.create(ShortBuffer.wrap(new short[] { 1, 25 })); + + ShortDataBuffer buffer = allocate(2) + .setShort((short)1, 0) + .setShort((short)16, 1); + + assertTrue(nioBuffer1.equals(buffer)); + assertTrue(buffer.equals(nioBuffer1)); + assertEquals(nioBuffer1.hashCode(), buffer.hashCode()); + + assertFalse(nioBuffer2.equals(buffer)); + assertFalse(buffer.equals(nioBuffer2)); + assertNotEquals(nioBuffer2.hashCode(), buffer.hashCode()); + } + + @Test + public void equalWithShortRawBuffer() { + ShortDataBuffer rawBuffer1 = RawDataBufferFactory.create(new short[] { 1, 16 }, true); + ShortDataBuffer rawBuffer2 = RawDataBufferFactory.create(new short[] { 1, 25 }, true); + + ShortDataBuffer buffer = allocate(2) + .setShort((short)1, 0) + .setShort((short)16, 1); + + assertTrue(rawBuffer1.equals(buffer)); + assertTrue(buffer.equals(rawBuffer1)); + assertEquals(rawBuffer1.hashCode(), buffer.hashCode()); + + assertFalse(rawBuffer2.equals(buffer)); + assertFalse(buffer.equals(rawBuffer2)); + assertNotEquals(rawBuffer2.hashCode(), buffer.hashCode()); + } + + @Test + public void equalWithShortObjectBuffer() { + DataBuffer objBuffer1 = MiscDataBufferFactory.create(new Short[] { 1, 16 }, true); + DataBuffer objBuffer2 = MiscDataBufferFactory.create(new Short[] { 1, 25 }, true); + + ShortDataBuffer buffer = allocate(2) + .setShort((short)1, 0) + .setShort((short)16, 1); + + assertTrue(objBuffer1.equals(buffer)); + assertTrue(buffer.equals(objBuffer1)); + assertEquals(objBuffer1.hashCode(), buffer.hashCode()); + + assertFalse(objBuffer2.equals(buffer)); + assertFalse(buffer.equals(objBuffer2)); + assertNotEquals(objBuffer2.hashCode(), buffer.hashCode()); + } + + @Test + public void notEqualWithOtherTypes() { + ShortDataBuffer buffer = allocate(2) + .setShort((short)1, 0) + .setShort((short)16, 1); + LongDataBuffer longBuffer = DataBuffers.of(1L, 16L); + + assertFalse(buffer.equals(longBuffer)); + assertFalse(longBuffer.equals(buffer)); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/adapter/BigIntegerDataBufferAdapterTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/adapter/BigIntegerDataBufferAdapterTest.java new file mode 100644 index 00000000000..4bb86fe3f33 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/adapter/BigIntegerDataBufferAdapterTest.java @@ -0,0 +1,67 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.adapter; + +import java.math.BigInteger; +import org.tensorflow.ndarray.buffer.ByteDataBuffer; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DataBufferTestBase; +import org.tensorflow.ndarray.buffer.DataBuffers; +import org.tensorflow.ndarray.buffer.layout.DataLayout; + +public class BigIntegerDataBufferAdapterTest extends DataBufferTestBase { + + @Override + protected DataBuffer allocate(long size) { + return LAYOUT.applyTo(DataBuffers.ofBytes(size * LAYOUT.scale())); + } + + @Override + protected long maxSize() { + return super.maxSize() / 3; + } + + @Override + protected BigInteger valueOf(Long val) { + return BigInteger.valueOf(val); + } + + private static DataLayout LAYOUT = new DataLayout() { + + @Override + public void writeObject(ByteDataBuffer buffer, BigInteger value, long index) { + byte[] bytes = value.toByteArray(); + buffer.setByte(bytes.length > 2 ? bytes[2] : 0, index); + buffer.setByte(bytes.length > 1 ? bytes[1] : 0, index + 1); + buffer.setByte(bytes[0], index + 2); + } + + @Override + public BigInteger readObject(ByteDataBuffer buffer, long index) { + byte byte2 = buffer.getByte(index); + byte byte1 = buffer.getByte(index + 1); + byte byte0 = buffer.getByte(index + 2); + return new BigInteger(new byte[] { byte2, byte1, byte0 }); + } + + @Override + public int scale() { + return 3; + } + }; +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/adapter/BooleanDataBufferAdapterTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/adapter/BooleanDataBufferAdapterTest.java new file mode 100644 index 00000000000..a15e8f388a8 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/adapter/BooleanDataBufferAdapterTest.java @@ -0,0 +1,45 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.adapter; + +import org.tensorflow.ndarray.buffer.BooleanDataBuffer; +import org.tensorflow.ndarray.buffer.BooleanDataBufferTestBase; +import org.tensorflow.ndarray.buffer.ByteDataBuffer; +import org.tensorflow.ndarray.buffer.DataBuffers; +import org.tensorflow.ndarray.buffer.layout.BooleanDataLayout; + +public class BooleanDataBufferAdapterTest extends BooleanDataBufferTestBase { + + @Override + protected BooleanDataBuffer allocate(long size) { + return LAYOUT.applyTo(DataBuffers.ofBytes(size * LAYOUT.scale())); + } + + private static BooleanDataLayout LAYOUT = new BooleanDataLayout() { + + @Override + public void writeBoolean(ByteDataBuffer buffer, boolean value, long index) { + buffer.setByte((byte)(value ? 1 : 0), index); + } + + @Override + public boolean readBoolean(ByteDataBuffer buffer, long index) { + return buffer.getByte(index) > 0; + } + }; +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/adapter/ByteDataBufferAdapterTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/adapter/ByteDataBufferAdapterTest.java new file mode 100644 index 00000000000..8a6287601f5 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/adapter/ByteDataBufferAdapterTest.java @@ -0,0 +1,27 @@ +package org.tensorflow.ndarray.impl.buffer.adapter; + +import org.tensorflow.ndarray.buffer.ByteDataBuffer; +import org.tensorflow.ndarray.buffer.ByteDataBufferTestBase; +import org.tensorflow.ndarray.buffer.DataBuffers; +import org.tensorflow.ndarray.buffer.ShortDataBuffer; +import org.tensorflow.ndarray.buffer.layout.ByteDataLayout; + +public class ByteDataBufferAdapterTest extends ByteDataBufferTestBase { + + public ByteDataBuffer allocate(long size) { + return LAYOUT.applyTo(DataBuffers.ofShorts(size * LAYOUT.scale())); + } + + private static ByteDataLayout LAYOUT = new ByteDataLayout() { + + @Override + public void writeByte(ShortDataBuffer buffer, byte value, long index) { + buffer.setShort(value, index); + } + + @Override + public byte readByte(ShortDataBuffer buffer, long index) { + return (byte)buffer.getShort(index); + } + }; +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/adapter/DoubleDataBufferAdapterTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/adapter/DoubleDataBufferAdapterTest.java new file mode 100644 index 00000000000..8dfee1182b1 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/adapter/DoubleDataBufferAdapterTest.java @@ -0,0 +1,61 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.adapter; + +import org.tensorflow.ndarray.buffer.ByteDataBuffer; +import org.tensorflow.ndarray.buffer.DataBuffers; +import org.tensorflow.ndarray.buffer.DoubleDataBuffer; +import org.tensorflow.ndarray.buffer.DoubleDataBufferTestBase; +import org.tensorflow.ndarray.buffer.layout.DoubleDataLayout; + +public class DoubleDataBufferAdapterTest extends DoubleDataBufferTestBase { + + @Override + protected DoubleDataBuffer allocate(long size) { + return LAYOUT.applyTo(DataBuffers.ofBytes(size * LAYOUT.scale())); + } + + @Override + protected long maxSize() { + return super.maxSize() / 3; + } + + private static DoubleDataLayout LAYOUT = new DoubleDataLayout() { + + @Override + public void writeDouble(ByteDataBuffer buffer, double value, long index) { + long bits = Double.doubleToLongBits(value); + buffer.setByte((byte)((bits >> 56) & 0xFF), index); + buffer.setByte((byte)((bits >> 48) & 0xFF), index + 1); + buffer.setByte((byte)((bits >> 40) & 0xFF), index + 2); + } + + @Override + public double readDouble(ByteDataBuffer buffer, long index) { + long byte7 = buffer.getByte(index); + long byte6 = buffer.getByte(index + 1); + long byte5 = buffer.getByte(index + 2); + return Double.longBitsToDouble(((byte7 & 0xFF) << 56) | ((byte6 & 0xFF) << 48) | ((byte5 & 0xFF) << 40)); + } + + @Override + public int scale() { + return 3; + } + }; +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/adapter/FloatDataBufferAdapterTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/adapter/FloatDataBufferAdapterTest.java new file mode 100644 index 00000000000..82b8ee947dd --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/adapter/FloatDataBufferAdapterTest.java @@ -0,0 +1,52 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.adapter; + +import org.tensorflow.ndarray.buffer.DataBuffers; +import org.tensorflow.ndarray.buffer.FloatDataBuffer; +import org.tensorflow.ndarray.buffer.FloatDataBufferTestBase; +import org.tensorflow.ndarray.buffer.ShortDataBuffer; +import org.tensorflow.ndarray.buffer.layout.FloatDataLayout; + +public class FloatDataBufferAdapterTest extends FloatDataBufferTestBase { + + @Override + public FloatDataBuffer allocate(long size) { + return LAYOUT.applyTo(DataBuffers.ofShorts(size * LAYOUT.scale())); + } + + @Override + protected long maxSize() { + return super.maxSize() / 2; + } + + private static FloatDataLayout LAYOUT = new FloatDataLayout() { + + @Override + public void writeFloat(ShortDataBuffer buffer, float value, long index) { + int bits = Float.floatToIntBits(value); + buffer.setShort((short)(bits >> 16), index); + } + + @Override + public float readFloat(ShortDataBuffer buffer, long index) { + int i = buffer.getShort(index); + return Float.intBitsToFloat(i << 16); + } + }; +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/adapter/IntDataBufferAdapterTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/adapter/IntDataBufferAdapterTest.java new file mode 100644 index 00000000000..9c00f92b00d --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/adapter/IntDataBufferAdapterTest.java @@ -0,0 +1,51 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.adapter; + +import org.tensorflow.ndarray.buffer.DataBuffers; +import org.tensorflow.ndarray.buffer.IntDataBuffer; +import org.tensorflow.ndarray.buffer.IntDataBufferTestBase; +import org.tensorflow.ndarray.buffer.ShortDataBuffer; +import org.tensorflow.ndarray.buffer.layout.IntDataLayout; + +public class IntDataBufferAdapterTest extends IntDataBufferTestBase { + + @Override + protected IntDataBuffer allocate(long size) { + return LAYOUT.applyTo(DataBuffers.ofShorts(size * LAYOUT.scale())); + } + + @Override + protected long maxSize() { + return super.maxSize() / 2; + } + + private static IntDataLayout LAYOUT = new IntDataLayout() { + + @Override + public void writeInt(ShortDataBuffer buffer, int value, long index) { + buffer.setShort((short)(((value & 0x80000000) >> 16) | (value & 0x7FFF)), index); + } + + @Override + public int readInt(ShortDataBuffer buffer, long index) { + int i = buffer.getShort(index); + return ((i & 0x8000) << 16) | ((i & 0x7FFF)); + } + }; +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/adapter/LongDataBufferAdapterTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/adapter/LongDataBufferAdapterTest.java new file mode 100644 index 00000000000..40bc4c55b3e --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/adapter/LongDataBufferAdapterTest.java @@ -0,0 +1,60 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.adapter; + +import org.tensorflow.ndarray.buffer.ByteDataBuffer; +import org.tensorflow.ndarray.buffer.DataBuffers; +import org.tensorflow.ndarray.buffer.LongDataBuffer; +import org.tensorflow.ndarray.buffer.LongDataBufferTestBase; +import org.tensorflow.ndarray.buffer.layout.LongDataLayout; + +public class LongDataBufferAdapterTest extends LongDataBufferTestBase { + + @Override + protected LongDataBuffer allocate(long size) { + return LAYOUT.applyTo(DataBuffers.ofBytes(size * LAYOUT.scale())); + } + + @Override + protected long maxSize() { + return super.maxSize() / 3; + } + + private static LongDataLayout LAYOUT = new LongDataLayout() { + + @Override + public void writeLong(ByteDataBuffer buffer, long value, long index) { + buffer.setByte((byte)(((value >> 56) & 0x80) | ((value >> 16) & 0x7F)), index); + buffer.setByte((byte)((value >> 8) & 0xFF), index + 1); + buffer.setByte((byte)(value & 0xFF), index + 2); + } + + @Override + public long readLong(ByteDataBuffer buffer, long index) { + long msb = buffer.getByte(index); + long midb = buffer.getByte(index + 1); + long lsb = buffer.getByte(index + 2); + return ((msb & 0x80) << 56) | ((msb & 0x7F) << 16) | ((midb & 0xFF) << 8) | (lsb & 0xFF); + } + + @Override + public int scale() { + return 3; + } + }; +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/adapter/ShortDataBufferAdapterTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/adapter/ShortDataBufferAdapterTest.java new file mode 100644 index 00000000000..3c11d3a46ad --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/adapter/ShortDataBufferAdapterTest.java @@ -0,0 +1,45 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.adapter; + +import org.tensorflow.ndarray.buffer.ByteDataBuffer; +import org.tensorflow.ndarray.buffer.DataBuffers; +import org.tensorflow.ndarray.buffer.ShortDataBuffer; +import org.tensorflow.ndarray.buffer.ShortDataBufferTestBase; +import org.tensorflow.ndarray.buffer.layout.ShortDataLayout; + +public class ShortDataBufferAdapterTest extends ShortDataBufferTestBase { + + public ShortDataBuffer allocate(long size) { + return LAYOUT.applyTo(DataBuffers.ofBytes(size * LAYOUT.scale())); + } + + private static ShortDataLayout LAYOUT = new ShortDataLayout() { + + @Override + public void writeShort(ByteDataBuffer buffer, short value, long index) { + buffer.setByte((byte)(((value & 0x8000) >> 8) | (value & 0x7F)), index); + } + + @Override + public short readShort(ByteDataBuffer buffer, long index) { + int b = buffer.getByte(index); + return (short)(((b & 0x80) << 8) | (b & 0x7F)); + } + }; +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/layout/Bfloat16LayoutTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/layout/Bfloat16LayoutTest.java new file mode 100644 index 00000000000..48ddeb1c56e --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/layout/Bfloat16LayoutTest.java @@ -0,0 +1,84 @@ +/* + * Copyright 2020 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.layout; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class Bfloat16LayoutTest { + + @Test + public void testFloat32to16() { + + // Zero and subnormals + assertEquals((short)0x0000, Bfloat16Layout.float32to16(0.0f)); + assertEquals((short)0x8000, Bfloat16Layout.float32to16(-0.0f)); + assertEquals((short)0x0001, Bfloat16Layout.float32to16(1e-40f)); + assertEquals((short)0xC000, Bfloat16Layout.float32to16(-2.0f)); + assertEquals((short)0x0000, Bfloat16Layout.float32to16(4.59e-41f)); + + // Infinite and NaN + assertEquals((short)0x7F80, Bfloat16Layout.float32to16(Float.POSITIVE_INFINITY)); + assertEquals((short)0xFF80, Bfloat16Layout.float32to16(Float.NEGATIVE_INFINITY)); + assertEquals((short)0x7FC0, Bfloat16Layout.float32to16(Float.NaN)); + assertEquals((short)0x7FC0, Bfloat16Layout.float32to16(Float.intBitsToFloat(0xFFFFFFFF))); + + // Normalized + assertEquals((short)0x3F80, Bfloat16Layout.float32to16(1.0f)); + assertEquals((short)0xBF80, Bfloat16Layout.float32to16(-1.0f)); + assertEquals((short)0x42C8, Bfloat16Layout.float32to16(100.0f)); + assertEquals((short)0xC2CA, Bfloat16Layout.float32to16(-101.0f)); + assertEquals((short)0x3F8F, Bfloat16Layout.float32to16(1.1171875f)); + assertEquals((short)0x4800, Bfloat16Layout.float32to16(131072f)); + assertEquals((short)0x7F7F, Bfloat16Layout.float32to16(3.3895314e38f)); + assertEquals((short)0xFF7F, Bfloat16Layout.float32to16(-3.3895314e38f)); + + // Rounding up + assertEquals((short)0x3FCF, Bfloat16Layout.float32to16(1.6191406f)); // 1.6171875 + assertEquals((short)0x4780, Bfloat16Layout.float32to16(65600.0f)); // 65536.0 + } + + @Test + public void testFloat16to32() { + + // Zero and subnormals + assertEquals(0.0f, Bfloat16Layout.float16to32((short)0x0000), 0); + assertEquals(-0.0f, Bfloat16Layout.float16to32((short)0x8000), 0); + assertEquals(9.18355E-41f, Bfloat16Layout.float16to32((short)0x0001), 1e-8f); + assertEquals(-9.403955E-38, Bfloat16Layout.float16to32((short)0x8200), 1e-8f); + + // Infinite and NaN + assertEquals(Float.POSITIVE_INFINITY, Bfloat16Layout.float16to32((short)0x7F80), 0); + assertEquals(Float.NEGATIVE_INFINITY, Bfloat16Layout.float16to32((short)0xFF80), 0); + assertEquals(Float.NaN, Bfloat16Layout.float16to32((short)0x7FC0), 0); + assertEquals(Float.intBitsToFloat(0xFFFFFFFF), Bfloat16Layout.float16to32((short)0x7FC0), 0); + + // Normalized + assertEquals(1.0f, Bfloat16Layout.float16to32((short)0x3F80), 0); + assertEquals(-1.0f, Bfloat16Layout.float16to32((short)0xBF80), 0); + assertEquals(100.0f, Bfloat16Layout.float16to32((short)0x42C8), 0); + assertEquals(-101.0f, Bfloat16Layout.float16to32((short)0xC2CA), 0); + assertEquals(1.1171875f, Bfloat16Layout.float16to32((short)0x3F8F), 0); + assertEquals(131072f, Bfloat16Layout.float16to32((short)0x4800), 0); + assertEquals(3.3895314e38f, Bfloat16Layout.float16to32((short)0x7F7F), 0); + assertEquals(-3.3895314e38f, Bfloat16Layout.float16to32((short)0xFF7F), 0); + assertEquals(1.6171875f, Bfloat16Layout.float16to32((short)0x3FCF), 0); + assertEquals(65536.0, Bfloat16Layout.float16to32((short)0x4780), 0); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/layout/BoolLayoutTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/layout/BoolLayoutTest.java new file mode 100644 index 00000000000..6ba903cadec --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/layout/BoolLayoutTest.java @@ -0,0 +1,42 @@ +/* + * Copyright 2020 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.layout; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +public class BoolLayoutTest { + + @Test + public void booleanToByteTest() { + assertEquals((byte)1, BoolLayout.booleanToByte(true)); + assertEquals((byte)0, BoolLayout.booleanToByte(false)); + } + + @Test + public void byteToBooleanTest() { + assertTrue(BoolLayout.byteToBoolean((byte)1)); + assertTrue(BoolLayout.byteToBoolean((byte)127)); + assertTrue(BoolLayout.byteToBoolean((byte)-128)); + assertTrue(BoolLayout.byteToBoolean((byte)255)); + assertFalse(BoolLayout.byteToBoolean((byte)0)); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/layout/Float16LayoutTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/layout/Float16LayoutTest.java new file mode 100644 index 00000000000..7bc430ac4ba --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/layout/Float16LayoutTest.java @@ -0,0 +1,90 @@ +/* + * Copyright 2020 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.buffer.layout; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class Float16LayoutTest { + + @Test + public void testFloat32to16() { + + // Zero and subnormals + assertEquals((short)0x0000, Float16Layout.float32to16(0.0f)); + assertEquals((short)0x8000, Float16Layout.float32to16(-0.0f)); + assertEquals((short)0x0001, Float16Layout.float32to16(6e-8f)); + assertEquals((short)0x8200, Float16Layout.float32to16(-3.052e-5f)); + assertEquals((short)0x0000, Float16Layout.float32to16(6e-9f)); + + // Infinite and NaN + assertEquals((short)0x7C00, Float16Layout.float32to16(Float.POSITIVE_INFINITY)); + assertEquals((short)0xFC00, Float16Layout.float32to16(Float.NEGATIVE_INFINITY)); + assertEquals((short)0x7C00, Float16Layout.float32to16(65520.0f)); + assertEquals((short)0x7C00, Float16Layout.float32to16(165536.0f)); + assertEquals((short)0xFC00, Float16Layout.float32to16(-65520.0f)); + assertEquals((short)0x7E00, Float16Layout.float32to16(Float.NaN)); + assertEquals((short)0x7E00, Float16Layout.float32to16(Float.intBitsToFloat(0xFFFFFFFF))); + + // Normalized + assertEquals((short)0x7BFF, Float16Layout.float32to16(65519.0f)); + assertEquals((short)0x3C00, Float16Layout.float32to16(1.0f)); + assertEquals((short)0xBC00, Float16Layout.float32to16(-1.0f)); + assertEquals((short)0x5640, Float16Layout.float32to16(100.0f)); + assertEquals((short)0xD650, Float16Layout.float32to16(-101.0f)); + assertEquals((short)0x3C7E, Float16Layout.float32to16(1.123f)); + + // Rounding up + assertEquals((short)0x3C7E, Float16Layout.float32to16(1.1235f)); // 1.123 + assertEquals((short)0x3C7F, Float16Layout.float32to16(1.1236f)); // 1.124 + assertEquals((short)0x4000, Float16Layout.float32to16(2.0009f)); // 2.0 + assertEquals((short)0x4001, Float16Layout.float32to16(2.001f)); // 2.002 + assertEquals((short)0x5C00, Float16Layout.float32to16(256.125f)); // 256.0 + assertEquals((short)0x5C01, Float16Layout.float32to16(256.126f)); // 256.3 + assertEquals((short)0x5C01, Float16Layout.float32to16(256.30f)); // 256.3 + assertEquals((short)0x5C01, Float16Layout.float32to16(256.374f)); // 256.3 + assertEquals((short)0x5C02, Float16Layout.float32to16(256.375f)); // 256.5 + assertEquals((short)0x5C02, Float16Layout.float32to16(256.51f)); // 256.5 + } + + @Test + public void testFloat16to32() { + + // Zero and subnormals + assertEquals(0.0f, Float16Layout.float16to32((short)0x0000), 0); + assertEquals(-0.0f, Float16Layout.float16to32((short)0x8000), 0); + assertEquals(6e-8f, Float16Layout.float16to32((short)0x0001), 1e-8f); + assertEquals(-3.052e-5f, Float16Layout.float16to32((short)0x8200), 1e-8f); + + // Infinite and NaN + assertEquals(Float.POSITIVE_INFINITY, Float16Layout.float16to32((short)0x7C00), 0); + assertEquals(Float.NEGATIVE_INFINITY, Float16Layout.float16to32((short)0xFC00), 0); + assertEquals(Float.NaN, Float16Layout.float16to32((short)0x7E00), 0); + assertEquals(Float.intBitsToFloat(0xFFFFFFFF), Float16Layout.float16to32((short)0x7E00), 0); + + // Normalized + assertEquals(1.0f, Float16Layout.float16to32((short)0x3C00), 1e-1f); + assertEquals(-1.0f, Float16Layout.float16to32((short)0xBC00), 1e-1f); + assertEquals(100.0f, Float16Layout.float16to32((short)0x5640), 1e-1f); + assertEquals(-101.0f, Float16Layout.float16to32((short)0xD650), 1e-1f); + assertEquals(1.123f, Float16Layout.float16to32((short)0x3C7E), 1e-3f); + assertEquals(1.123f, Float16Layout.float16to32((short)0x3C7E), 1e-3f); + assertEquals(-62.34f, Float16Layout.float16to32((short)0xD3CB), 1e-2f); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/misc/ArrayDataBufferTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/misc/ArrayDataBufferTest.java new file mode 100644 index 00000000000..1c43a3e3638 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/misc/ArrayDataBufferTest.java @@ -0,0 +1,265 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.buffer.misc; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.math.BigDecimal; +import org.junit.jupiter.api.Test; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DataBufferTestBase; + +public class ArrayDataBufferTest extends DataBufferTestBase { + + @Override + protected DataBuffer allocate(long size) { + return new ArrayDataBuffer<>(new BigDecimal[(int)size], false); + } + + @Override + protected BigDecimal valueOf(Long val) { + return BigDecimal.valueOf(val); + } + + @Test + public void byteArrayBufferEquals() { + DataBuffer buffer1 = new ArrayDataBuffer<>(new byte[][] { { 0x01 }, { 0x03 } }, true); + DataBuffer buffer2 = new ArrayDataBuffer<>(new byte[][] { { 0x01 }, { 0x03 } }, true); + DataBuffer buffer3 = new ArrayDataBuffer<>(new byte[][] { { 0x02 }, { 0x03 } }, true); + DataBuffer buffer4 = new ArrayDataBuffer<>(new byte[][][] { { { 0x01 } }, { { 0x03 } } }, true); + DataBuffer buffer5 = new ArrayDataBuffer<>(new byte[][][] { { { 0x01 } }, { { 0x03 } } }, true); + + assertTrue(buffer1.equals(buffer2)); + assertTrue(buffer2.equals(buffer1)); + assertEquals(buffer1.hashCode(), buffer2.hashCode()); + + assertFalse(buffer1.equals(buffer3)); + assertFalse(buffer3.equals(buffer1)); + assertNotEquals(buffer1.hashCode(), buffer3.hashCode()); + + assertFalse(buffer1.equals(buffer4)); + assertFalse(buffer4.equals(buffer1)); + assertNotEquals(buffer1.hashCode(), buffer4.hashCode()); + + assertTrue(buffer4.equals(buffer5)); + assertTrue(buffer4.equals(buffer5)); + assertEquals(buffer4.hashCode(), buffer5.hashCode()); + } + + @Test + public void intArrayBufferEquals() { + DataBuffer buffer1 = new ArrayDataBuffer<>(new int[][] { { 10 }, { 30 } }, true); + DataBuffer buffer2 = new ArrayDataBuffer<>(new int[][] { { 10 }, { 30 } }, true); + DataBuffer buffer3 = new ArrayDataBuffer<>(new int[][] { { 20 }, { 30 } }, true); + DataBuffer buffer4 = new ArrayDataBuffer<>(new int[][][] { { { 10 } }, { { 30 } } }, true); + DataBuffer buffer5 = new ArrayDataBuffer<>(new int[][][] { { { 10 } }, { { 30 } } }, true); + + assertTrue(buffer1.equals(buffer2)); + assertTrue(buffer2.equals(buffer1)); + assertEquals(buffer1.hashCode(), buffer2.hashCode()); + + assertFalse(buffer1.equals(buffer3)); + assertFalse(buffer3.equals(buffer1)); + assertNotEquals(buffer1.hashCode(), buffer3.hashCode()); + + assertFalse(buffer1.equals(buffer4)); + assertFalse(buffer4.equals(buffer1)); + assertNotEquals(buffer1.hashCode(), buffer4.hashCode()); + + assertTrue(buffer4.equals(buffer5)); + assertTrue(buffer4.equals(buffer5)); + assertEquals(buffer4.hashCode(), buffer5.hashCode()); + } + + @Test + public void shortArrayBufferEquals() { + DataBuffer buffer1 = new ArrayDataBuffer<>(new short[][] { { 10 }, { 30 } }, true); + DataBuffer buffer2 = new ArrayDataBuffer<>(new short[][] { { 10 }, { 30 } }, true); + DataBuffer buffer3 = new ArrayDataBuffer<>(new short[][] { { 20 }, { 30 } }, true); + DataBuffer buffer4 = new ArrayDataBuffer<>(new short[][][] { { { 10 } }, { { 30 } } }, true); + DataBuffer buffer5 = new ArrayDataBuffer<>(new short[][][] { { { 10 } }, { { 30 } } }, true); + + assertTrue(buffer1.equals(buffer2)); + assertTrue(buffer2.equals(buffer1)); + assertEquals(buffer1.hashCode(), buffer2.hashCode()); + + assertFalse(buffer1.equals(buffer3)); + assertFalse(buffer3.equals(buffer1)); + assertNotEquals(buffer1.hashCode(), buffer3.hashCode()); + + assertFalse(buffer1.equals(buffer4)); + assertFalse(buffer4.equals(buffer1)); + assertNotEquals(buffer1.hashCode(), buffer4.hashCode()); + + assertTrue(buffer4.equals(buffer5)); + assertTrue(buffer4.equals(buffer5)); + assertEquals(buffer4.hashCode(), buffer5.hashCode()); + } + + @Test + public void longArrayBufferEquals() { + DataBuffer buffer1 = new ArrayDataBuffer<>(new long[][] { { 10 }, { 30 } }, true); + DataBuffer buffer2 = new ArrayDataBuffer<>(new long[][] { { 10 }, { 30 } }, true); + DataBuffer buffer3 = new ArrayDataBuffer<>(new long[][] { { 20 }, { 30 } }, true); + DataBuffer buffer4 = new ArrayDataBuffer<>(new long[][][] { { { 10 } }, { { 30 } } }, true); + DataBuffer buffer5 = new ArrayDataBuffer<>(new long[][][] { { { 10 } }, { { 30 } } }, true); + + assertTrue(buffer1.equals(buffer2)); + assertTrue(buffer2.equals(buffer1)); + assertEquals(buffer1.hashCode(), buffer2.hashCode()); + + assertFalse(buffer1.equals(buffer3)); + assertFalse(buffer3.equals(buffer1)); + assertNotEquals(buffer1.hashCode(), buffer3.hashCode()); + + assertFalse(buffer1.equals(buffer4)); + assertFalse(buffer4.equals(buffer1)); + assertNotEquals(buffer1.hashCode(), buffer4.hashCode()); + + assertTrue(buffer4.equals(buffer5)); + assertTrue(buffer4.equals(buffer5)); + assertEquals(buffer4.hashCode(), buffer5.hashCode()); + } + + @Test + public void floatArrayBufferEquals() { + DataBuffer buffer1 = new ArrayDataBuffer<>(new float[][] { { 10 }, { 30 } }, true); + DataBuffer buffer2 = new ArrayDataBuffer<>(new float[][] { { 10 }, { 30 } }, true); + DataBuffer buffer3 = new ArrayDataBuffer<>(new float[][] { { 20 }, { 30 } }, true); + DataBuffer buffer4 = new ArrayDataBuffer<>(new float[][][] { { { 10 } }, { { 30 } } }, true); + DataBuffer buffer5 = new ArrayDataBuffer<>(new float[][][] { { { 10 } }, { { 30 } } }, true); + + assertTrue(buffer1.equals(buffer2)); + assertTrue(buffer2.equals(buffer1)); + assertEquals(buffer1.hashCode(), buffer2.hashCode()); + + assertFalse(buffer1.equals(buffer3)); + assertFalse(buffer3.equals(buffer1)); + assertNotEquals(buffer1.hashCode(), buffer3.hashCode()); + + assertFalse(buffer1.equals(buffer4)); + assertFalse(buffer4.equals(buffer1)); + assertNotEquals(buffer1.hashCode(), buffer4.hashCode()); + + assertTrue(buffer4.equals(buffer5)); + assertTrue(buffer4.equals(buffer5)); + assertEquals(buffer4.hashCode(), buffer5.hashCode()); + } + + @Test + public void doubleArrayBufferEquals() { + DataBuffer buffer1 = new ArrayDataBuffer<>(new double[][] { { 10 }, { 30 } }, true); + DataBuffer buffer2 = new ArrayDataBuffer<>(new double[][] { { 10 }, { 30 } }, true); + DataBuffer buffer3 = new ArrayDataBuffer<>(new double[][] { { 20 }, { 30 } }, true); + DataBuffer buffer4 = new ArrayDataBuffer<>(new double[][][] { { { 10 } }, { { 30 } } }, true); + DataBuffer buffer5 = new ArrayDataBuffer<>(new double[][][] { { { 10 } }, { { 30 } } }, true); + + assertTrue(buffer1.equals(buffer2)); + assertTrue(buffer2.equals(buffer1)); + assertEquals(buffer1.hashCode(), buffer2.hashCode()); + + assertFalse(buffer1.equals(buffer3)); + assertFalse(buffer3.equals(buffer1)); + assertNotEquals(buffer1.hashCode(), buffer3.hashCode()); + + assertFalse(buffer1.equals(buffer4)); + assertFalse(buffer4.equals(buffer1)); + assertNotEquals(buffer1.hashCode(), buffer4.hashCode()); + + assertTrue(buffer4.equals(buffer5)); + assertTrue(buffer4.equals(buffer5)); + assertEquals(buffer4.hashCode(), buffer5.hashCode()); + } + + @Test + public void booleanArrayBufferEquals() { + DataBuffer buffer1 = new ArrayDataBuffer<>(new boolean[][] { { true }, { false } }, true); + DataBuffer buffer2 = new ArrayDataBuffer<>(new boolean[][] { { true }, { false} }, true); + DataBuffer buffer3 = new ArrayDataBuffer<>(new boolean[][] { { false }, { false } }, true); + DataBuffer buffer4 = new ArrayDataBuffer<>(new boolean[][][] { { { true } }, { { false } } }, true); + DataBuffer buffer5 = new ArrayDataBuffer<>(new boolean[][][] { { { true } }, { { false } } }, true); + + assertTrue(buffer1.equals(buffer2)); + assertTrue(buffer2.equals(buffer1)); + assertEquals(buffer1.hashCode(), buffer2.hashCode()); + + assertFalse(buffer1.equals(buffer3)); + assertFalse(buffer3.equals(buffer1)); + assertNotEquals(buffer1.hashCode(), buffer3.hashCode()); + + assertFalse(buffer1.equals(buffer4)); + assertFalse(buffer4.equals(buffer1)); + assertNotEquals(buffer1.hashCode(), buffer4.hashCode()); + + assertTrue(buffer4.equals(buffer5)); + assertTrue(buffer4.equals(buffer5)); + assertEquals(buffer4.hashCode(), buffer5.hashCode()); + } + + @Test + public void objectArrayBufferEquals() { + DataBuffer buffer1 = new ArrayDataBuffer<>(new String[][] { { "10" }, { "30" } }, true); + DataBuffer buffer2 = new ArrayDataBuffer<>(new String[][] { { "10" }, { "30" } }, true); + DataBuffer buffer3 = new ArrayDataBuffer<>(new String[][] { { "20" }, { "30" } }, true); + DataBuffer buffer4 = new ArrayDataBuffer<>(new String[][][] { { { "10" } }, { { "30" } } }, true); + DataBuffer buffer5 = new ArrayDataBuffer<>(new String[][][] { { { "10" } }, { { "30" } } }, true); + + assertTrue(buffer1.equals(buffer2)); + assertTrue(buffer2.equals(buffer1)); + assertEquals(buffer1.hashCode(), buffer2.hashCode()); + + assertFalse(buffer1.equals(buffer3)); + assertFalse(buffer3.equals(buffer1)); + assertNotEquals(buffer1.hashCode(), buffer3.hashCode()); + + assertFalse(buffer1.equals(buffer4)); + assertFalse(buffer4.equals(buffer1)); + assertNotEquals(buffer1.hashCode(), buffer4.hashCode()); + + assertTrue(buffer4.equals(buffer5)); + assertTrue(buffer4.equals(buffer5)); + assertEquals(buffer4.hashCode(), buffer5.hashCode()); + } + + @Test + public void nullableObjectArrayBufferEquals() { + DataBuffer buffer1 = new ArrayDataBuffer<>(new String[][] { null, { "30" } }, true); + DataBuffer buffer2 = new ArrayDataBuffer<>(new String[][] { null, { "30" } }, true); + DataBuffer buffer3 = new ArrayDataBuffer<>(new String[][] { { "20" }, { "30" } }, true); + DataBuffer buffer4 = new ArrayDataBuffer<>(new String[][][] { { { "10" } }, null }, true); + DataBuffer buffer5 = new ArrayDataBuffer<>(new String[][][] { { { "10" } }, null }, true); + + assertTrue(buffer1.equals(buffer2)); + assertTrue(buffer2.equals(buffer1)); + assertEquals(buffer1.hashCode(), buffer2.hashCode()); + + assertFalse(buffer1.equals(buffer3)); + assertFalse(buffer3.equals(buffer1)); + assertNotEquals(buffer1.hashCode(), buffer3.hashCode()); + + assertFalse(buffer1.equals(buffer4)); + assertFalse(buffer4.equals(buffer1)); + assertNotEquals(buffer1.hashCode(), buffer4.hashCode()); + + assertTrue(buffer4.equals(buffer5)); + assertTrue(buffer4.equals(buffer5)); + assertEquals(buffer4.hashCode(), buffer5.hashCode()); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/misc/BitSetDataBufferTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/misc/BitSetDataBufferTest.java new file mode 100644 index 00000000000..ec5c513869a --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/misc/BitSetDataBufferTest.java @@ -0,0 +1,34 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.buffer.misc; + +import java.util.BitSet; +import org.tensorflow.ndarray.buffer.BooleanDataBuffer; +import org.tensorflow.ndarray.buffer.BooleanDataBufferTestBase; + +public class BitSetDataBufferTest extends BooleanDataBufferTestBase { + + @Override + protected BooleanDataBuffer allocate(long size) { + return new BitSetDataBuffer(new BitSet((int)size), size, false); + } + + @Override + protected Boolean valueOf(Long val) { + return val != 0; + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/misc/StringArrayDataBufferTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/misc/StringArrayDataBufferTest.java new file mode 100644 index 00000000000..3e9c3c0cdbf --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/misc/StringArrayDataBufferTest.java @@ -0,0 +1,33 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.buffer.misc; + +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DataBufferTestBase; + +public class StringArrayDataBufferTest extends DataBufferTestBase { + + @Override + protected DataBuffer allocate(long size) { + return new ArrayDataBuffer<>(new String[(int)size], false); + } + + @Override + protected String valueOf(Long val) { + return val.toString(); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/nio/ByteNioDataBufferTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/nio/ByteNioDataBufferTest.java new file mode 100644 index 00000000000..28ff5a6c104 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/nio/ByteNioDataBufferTest.java @@ -0,0 +1,29 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.buffer.nio; + +import java.nio.ByteBuffer; +import org.tensorflow.ndarray.buffer.ByteDataBuffer; +import org.tensorflow.ndarray.buffer.ByteDataBufferTestBase; + +public class ByteNioDataBufferTest extends ByteDataBufferTestBase { + + @Override + protected ByteDataBuffer allocate(long size) { + return new ByteNioDataBuffer(ByteBuffer.allocate((int)size)); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/nio/DoubleNioDataBufferTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/nio/DoubleNioDataBufferTest.java new file mode 100644 index 00000000000..7a4d39dce94 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/nio/DoubleNioDataBufferTest.java @@ -0,0 +1,29 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.buffer.nio; + +import java.nio.DoubleBuffer; +import org.tensorflow.ndarray.buffer.DoubleDataBuffer; +import org.tensorflow.ndarray.buffer.DoubleDataBufferTestBase; + +public class DoubleNioDataBufferTest extends DoubleDataBufferTestBase { + + @Override + protected DoubleDataBuffer allocate(long size) { + return new DoubleNioDataBuffer(DoubleBuffer.allocate((int)size)); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/nio/FloatNioDataBufferTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/nio/FloatNioDataBufferTest.java new file mode 100644 index 00000000000..08089e76ad8 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/nio/FloatNioDataBufferTest.java @@ -0,0 +1,29 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.buffer.nio; + +import java.nio.FloatBuffer; +import org.tensorflow.ndarray.buffer.FloatDataBuffer; +import org.tensorflow.ndarray.buffer.FloatDataBufferTestBase; + +public class FloatNioDataBufferTest extends FloatDataBufferTestBase { + + @Override + protected FloatDataBuffer allocate(long size) { + return new FloatNioDataBuffer(FloatBuffer.allocate((int)size)); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/nio/IntNioDataBufferTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/nio/IntNioDataBufferTest.java new file mode 100644 index 00000000000..00a993e42ed --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/nio/IntNioDataBufferTest.java @@ -0,0 +1,29 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.buffer.nio; + +import java.nio.IntBuffer; +import org.tensorflow.ndarray.buffer.IntDataBuffer; +import org.tensorflow.ndarray.buffer.IntDataBufferTestBase; + +public class IntNioDataBufferTest extends IntDataBufferTestBase { + + @Override + protected IntDataBuffer allocate(long size) { + return new IntNioDataBuffer(IntBuffer.allocate((int)size)); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/nio/LongNioDataBufferTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/nio/LongNioDataBufferTest.java new file mode 100644 index 00000000000..5922d2b922c --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/nio/LongNioDataBufferTest.java @@ -0,0 +1,29 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.buffer.nio; + +import java.nio.LongBuffer; +import org.tensorflow.ndarray.buffer.LongDataBuffer; +import org.tensorflow.ndarray.buffer.LongDataBufferTestBase; + +public class LongNioDataBufferTest extends LongDataBufferTestBase { + + @Override + protected LongDataBuffer allocate(long size) { + return new LongNioDataBuffer(LongBuffer.allocate((int)size)); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/nio/ShortNioDataBufferTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/nio/ShortNioDataBufferTest.java new file mode 100644 index 00000000000..c76191fbcf1 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/nio/ShortNioDataBufferTest.java @@ -0,0 +1,29 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.buffer.nio; + +import java.nio.ShortBuffer; +import org.tensorflow.ndarray.buffer.ShortDataBuffer; +import org.tensorflow.ndarray.buffer.ShortDataBufferTestBase; + +public class ShortNioDataBufferTest extends ShortDataBufferTestBase { + + @Override + protected ShortDataBuffer allocate(long size) { + return new ShortNioDataBuffer(ShortBuffer.allocate((int)size)); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/raw/BooleanRawDataBufferTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/raw/BooleanRawDataBufferTest.java new file mode 100644 index 00000000000..1f09d76055d --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/raw/BooleanRawDataBufferTest.java @@ -0,0 +1,28 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.buffer.raw; + +import org.tensorflow.ndarray.buffer.BooleanDataBuffer; +import org.tensorflow.ndarray.buffer.BooleanDataBufferTestBase; + +public class BooleanRawDataBufferTest extends BooleanDataBufferTestBase { + + @Override + protected BooleanDataBuffer allocate(long size) { + return new BooleanRawDataBuffer(UnsafeMemoryHandle.fromArray(new boolean[(int)size], (int)size), false); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/raw/ByteRawDataBufferTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/raw/ByteRawDataBufferTest.java new file mode 100644 index 00000000000..4a415aff49f --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/raw/ByteRawDataBufferTest.java @@ -0,0 +1,28 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.buffer.raw; + +import org.tensorflow.ndarray.buffer.ByteDataBuffer; +import org.tensorflow.ndarray.buffer.ByteDataBufferTestBase; + +public class ByteRawDataBufferTest extends ByteDataBufferTestBase { + + @Override + protected ByteDataBuffer allocate(long size) { + return new ByteRawDataBuffer(UnsafeMemoryHandle.fromArray(new byte[(int)size], (int)size), false); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/raw/DoubleRawDataBufferTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/raw/DoubleRawDataBufferTest.java new file mode 100644 index 00000000000..df845092dd1 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/raw/DoubleRawDataBufferTest.java @@ -0,0 +1,28 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.buffer.raw; + +import org.tensorflow.ndarray.buffer.DoubleDataBuffer; +import org.tensorflow.ndarray.buffer.DoubleDataBufferTestBase; + +public class DoubleRawDataBufferTest extends DoubleDataBufferTestBase { + + @Override + protected DoubleDataBuffer allocate(long size) { + return new DoubleRawDataBuffer(UnsafeMemoryHandle.fromArray(new double[(int)size], (int)size), false); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/raw/FloatRawDataBufferTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/raw/FloatRawDataBufferTest.java new file mode 100644 index 00000000000..bc453d79f37 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/raw/FloatRawDataBufferTest.java @@ -0,0 +1,28 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.buffer.raw; + +import org.tensorflow.ndarray.buffer.FloatDataBuffer; +import org.tensorflow.ndarray.buffer.FloatDataBufferTestBase; + +public class FloatRawDataBufferTest extends FloatDataBufferTestBase { + + @Override + protected FloatDataBuffer allocate(long size) { + return new FloatRawDataBuffer(UnsafeMemoryHandle.fromArray(new float[(int)size], (int)size), false); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/raw/IntRawDataBufferTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/raw/IntRawDataBufferTest.java new file mode 100644 index 00000000000..1142f19131d --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/raw/IntRawDataBufferTest.java @@ -0,0 +1,28 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.buffer.raw; + +import org.tensorflow.ndarray.buffer.IntDataBuffer; +import org.tensorflow.ndarray.buffer.IntDataBufferTestBase; + +public class IntRawDataBufferTest extends IntDataBufferTestBase { + + @Override + protected IntDataBuffer allocate(long size) { + return new IntRawDataBuffer(UnsafeMemoryHandle.fromArray(new int[(int)size], (int)size), false); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/raw/LongRawDataBufferTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/raw/LongRawDataBufferTest.java new file mode 100644 index 00000000000..af86d64a414 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/raw/LongRawDataBufferTest.java @@ -0,0 +1,28 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.buffer.raw; + +import org.tensorflow.ndarray.buffer.LongDataBuffer; +import org.tensorflow.ndarray.buffer.LongDataBufferTestBase; + +public class LongRawDataBufferTest extends LongDataBufferTestBase { + + @Override + protected LongDataBuffer allocate(long size) { + return new LongRawDataBuffer(UnsafeMemoryHandle.fromArray(new long[(int)size], (int)size), false); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/raw/ShortRawDataBufferTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/raw/ShortRawDataBufferTest.java new file mode 100644 index 00000000000..1ce1f25391b --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/buffer/raw/ShortRawDataBufferTest.java @@ -0,0 +1,28 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.buffer.raw; + +import org.tensorflow.ndarray.buffer.ShortDataBuffer; +import org.tensorflow.ndarray.buffer.ShortDataBufferTestBase; + +public class ShortRawDataBufferTest extends ShortDataBufferTestBase { + + @Override + protected ShortDataBuffer allocate(long size) { + return new ShortRawDataBuffer(UnsafeMemoryHandle.fromArray(new short[(int)size], (int)size), false); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/BooleanDenseNdArrayTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/BooleanDenseNdArrayTest.java new file mode 100644 index 00000000000..36540104eb7 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/BooleanDenseNdArrayTest.java @@ -0,0 +1,35 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.dense; + +import org.tensorflow.ndarray.Shape; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DataBuffers; +import org.tensorflow.ndarray.BooleanNdArray; +import org.tensorflow.ndarray.BooleanNdArrayTestBase; +import org.tensorflow.ndarray.NdArrays; + +public class BooleanDenseNdArrayTest extends BooleanNdArrayTestBase { + + @Override protected BooleanNdArray allocate(Shape shape) { + return NdArrays.ofBooleans(shape); + } + + @Override protected DataBuffer allocateBuffer(long size) { + return DataBuffers.ofBooleans(size); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/ByteDenseNdArrayTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/ByteDenseNdArrayTest.java new file mode 100644 index 00000000000..2e5d1939bc3 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/ByteDenseNdArrayTest.java @@ -0,0 +1,35 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.dense; + +import org.tensorflow.ndarray.Shape; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DataBuffers; +import org.tensorflow.ndarray.ByteNdArray; +import org.tensorflow.ndarray.ByteNdArrayTestBase; +import org.tensorflow.ndarray.NdArrays; + +public class ByteDenseNdArrayTest extends ByteNdArrayTestBase { + + @Override protected ByteNdArray allocate(Shape shape) { + return NdArrays.ofBytes(shape); + } + + @Override protected DataBuffer allocateBuffer(long size) { + return DataBuffers.ofBytes(size); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/DenseNdArrayTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/DenseNdArrayTest.java new file mode 100644 index 00000000000..375f7643875 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/DenseNdArrayTest.java @@ -0,0 +1,51 @@ +package org.tensorflow.ndarray.impl.dense; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; +import org.tensorflow.ndarray.Shape; +import org.tensorflow.ndarray.IntNdArray; +import org.tensorflow.ndarray.NdArrays; +import org.tensorflow.ndarray.StdArrays; +import org.tensorflow.ndarray.index.Indices; + +public class DenseNdArrayTest { + + @Test + public void arrayEquals() { + IntNdArray array = NdArrays.ofInts(Shape.of(2, 2)) + .set(NdArrays.vectorOf(1, 2), 0) + .set(NdArrays.vectorOf(3, 4), 1); + + assertTrue(array.equals(StdArrays.ndCopyOf(new int[][] {{1, 2}, {3, 4}}))); + assertTrue(array.equals(StdArrays.ndCopyOf(new Integer[][] {{1, 2}, {3, 4}}))); + assertFalse(array.equals(NdArrays.vectorOf(1, 2, 3, 4))); + assertFalse(array.equals(StdArrays.ndCopyOf(new int[][] {{3, 4}, {1, 2}}))); + assertFalse(array.equals(StdArrays.ndCopyOf(new long[][] {{1L, 2L}, {3L, 4L}}))); + } + + @Test + public void equalsAndHashCodeOnSlices() { + IntNdArray vector1 = NdArrays.vectorOf(3, 4); + IntNdArray vector2 = NdArrays.vectorOf(1, 2, 3, 4); + IntNdArray matrix1 = StdArrays.ndCopyOf(new int[][] {{1, 2}, {3, 4}}); + IntNdArray matrix2 = StdArrays.ndCopyOf(new int[][] {{1, 0, 2, 0}, {3, 0, 4, 0}}); + IntNdArray matrix3d1 = StdArrays.ndCopyOf(new int[][][] { + {{1, 2}, {3, 4}}, + {{5, 6}, {7, 8}} + }); + IntNdArray matrix3d2 = StdArrays.ndCopyOf(new int[][][] { + {{1, 2}, {4, 5}}, + {{3, 4}, {6, 7}} + }); + + assertTrue(vector1.equals(vector2.slice(Indices.sliceFrom(2)))); + assertTrue(vector1.equals(matrix1.get(1))); + assertTrue(vector1.equals(matrix2.get(1).slice(Indices.even()))); + assertTrue(matrix1.equals(matrix2.slice(Indices.all(), Indices.even()))); + assertTrue(matrix3d1.get(0).equals(matrix1)); + assertFalse(matrix3d1.get(0).equals(vector2)); + assertTrue(matrix1.equals(matrix3d2.slice(Indices.all(), Indices.at(0)))); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/DoubleDenseNdArrayTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/DoubleDenseNdArrayTest.java new file mode 100644 index 00000000000..9810a744c50 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/DoubleDenseNdArrayTest.java @@ -0,0 +1,35 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.dense; + +import org.tensorflow.ndarray.Shape; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DataBuffers; +import org.tensorflow.ndarray.DoubleNdArray; +import org.tensorflow.ndarray.DoubleNdArrayTestBase; +import org.tensorflow.ndarray.NdArrays; + +public class DoubleDenseNdArrayTest extends DoubleNdArrayTestBase { + + @Override protected DoubleNdArray allocate(Shape shape) { + return NdArrays.ofDoubles(shape); + } + + @Override protected DataBuffer allocateBuffer(long size) { + return DataBuffers.ofDoubles(size); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/FloatDenseNdArrayTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/FloatDenseNdArrayTest.java new file mode 100644 index 00000000000..efee2bf2cb8 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/FloatDenseNdArrayTest.java @@ -0,0 +1,35 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.dense; + +import org.tensorflow.ndarray.Shape; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DataBuffers; +import org.tensorflow.ndarray.FloatNdArray; +import org.tensorflow.ndarray.FloatNdArrayTestBase; +import org.tensorflow.ndarray.NdArrays; + +public class FloatDenseNdArrayTest extends FloatNdArrayTestBase { + + @Override protected FloatNdArray allocate(Shape shape) { + return NdArrays.ofFloats(shape); + } + + @Override protected DataBuffer allocateBuffer(long size) { + return DataBuffers.ofFloats(size); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/IntDenseNdArrayTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/IntDenseNdArrayTest.java new file mode 100644 index 00000000000..712f6f44333 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/IntDenseNdArrayTest.java @@ -0,0 +1,35 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.dense; + +import org.tensorflow.ndarray.Shape; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DataBuffers; +import org.tensorflow.ndarray.IntNdArray; +import org.tensorflow.ndarray.IntNdArrayTestBase; +import org.tensorflow.ndarray.NdArrays; + +public class IntDenseNdArrayTest extends IntNdArrayTestBase { + + @Override protected IntNdArray allocate(Shape shape) { + return NdArrays.ofInts(shape); + } + + @Override protected DataBuffer allocateBuffer(long size) { + return DataBuffers.ofInts(size); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/LongDenseNdArrayTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/LongDenseNdArrayTest.java new file mode 100644 index 00000000000..346e3845080 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/LongDenseNdArrayTest.java @@ -0,0 +1,35 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.dense; + +import org.tensorflow.ndarray.Shape; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DataBuffers; +import org.tensorflow.ndarray.LongNdArray; +import org.tensorflow.ndarray.LongNdArrayTestBase; +import org.tensorflow.ndarray.NdArrays; + +public class LongDenseNdArrayTest extends LongNdArrayTestBase { + + @Override protected LongNdArray allocate(Shape shape) { + return NdArrays.ofLongs(shape); + } + + @Override protected DataBuffer allocateBuffer(long size) { + return DataBuffers.ofLongs(size); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/ShortDenseNdArrayTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/ShortDenseNdArrayTest.java new file mode 100644 index 00000000000..6f845c7c65d --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/ShortDenseNdArrayTest.java @@ -0,0 +1,35 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.dense; + +import org.tensorflow.ndarray.Shape; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DataBuffers; +import org.tensorflow.ndarray.NdArrays; +import org.tensorflow.ndarray.ShortNdArray; +import org.tensorflow.ndarray.ShortNdArrayTestBase; + +public class ShortDenseNdArrayTest extends ShortNdArrayTestBase { + + @Override protected ShortNdArray allocate(Shape shape) { + return NdArrays.ofShorts(shape); + } + + @Override protected DataBuffer allocateBuffer(long size) { + return DataBuffers.ofShorts(size); + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/StringDenseNdArrayTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/StringDenseNdArrayTest.java new file mode 100644 index 00000000000..5afc1420ab2 --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/dense/StringDenseNdArrayTest.java @@ -0,0 +1,43 @@ +/* + Copyright 2019 The TensorFlow Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ======================================================================= + */ +package org.tensorflow.ndarray.impl.dense; + +import org.tensorflow.ndarray.Shape; +import org.tensorflow.ndarray.buffer.DataBuffer; +import org.tensorflow.ndarray.buffer.DataBuffers; +import org.tensorflow.ndarray.NdArray; +import org.tensorflow.ndarray.NdArrayTestBase; +import org.tensorflow.ndarray.NdArrays; + +public class StringDenseNdArrayTest extends NdArrayTestBase { + + @Override protected NdArray allocate(Shape shape) { + return NdArrays.ofObjects(String.class, shape); + } + + @Override protected DataBuffer allocateBuffer(long size) { + return DataBuffers.ofObjects(String.class, size); + } + + @Override protected String valueOf(Long val) { + return val.toString(); + } + + protected String zeroOrNull() { + return null; + } +} diff --git a/ndarray/src/test/java/org/tensorflow/ndarray/impl/sequence/ElementSequenceTest.java b/ndarray/src/test/java/org/tensorflow/ndarray/impl/sequence/ElementSequenceTest.java new file mode 100644 index 00000000000..bad78404e9b --- /dev/null +++ b/ndarray/src/test/java/org/tensorflow/ndarray/impl/sequence/ElementSequenceTest.java @@ -0,0 +1,145 @@ +/* + * Copyright 2019 The TensorFlow Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================= + */ + +package org.tensorflow.ndarray.impl.sequence; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.tensorflow.ndarray.Shape; +import org.tensorflow.ndarray.buffer.DataBufferWindow; +import org.tensorflow.ndarray.buffer.DataBuffers; +import org.tensorflow.ndarray.buffer.IntDataBuffer; +import org.tensorflow.ndarray.IntNdArray; +import org.tensorflow.ndarray.NdArraySequence; +import org.tensorflow.ndarray.NdArrays; +import org.tensorflow.ndarray.impl.AbstractNdArray; + +public class ElementSequenceTest { + + @Test + public void iterateVectorsWithIndex() { + IntNdArray array = NdArrays.ofInts(Shape.of(2, 3, 2)); + + NdArraySequence sequence = new SlicingElementSequence( + (AbstractNdArray)array, 1); + List coords = new ArrayList<>((int)array.shape().size()); + sequence.forEachIndexed((c, e) -> coords.add(Arrays.copyOf(c, c.length))); + + assertEquals(6, coords.size()); + assertArrayEquals(new long[] {0, 0}, coords.get(0)); + assertArrayEquals(new long[] {0, 1}, coords.get(1)); + assertArrayEquals(new long[] {0, 2}, coords.get(2)); + assertArrayEquals(new long[] {1, 0}, coords.get(3)); + assertArrayEquals(new long[] {1, 1}, coords.get(4)); + assertArrayEquals(new long[] {1, 2}, coords.get(5)); + } + + @Test + public void iterateScalarsWithIndex() { + IntNdArray array = NdArrays.ofInts(Shape.of(2, 3, 2)); + + NdArraySequence cursor = new SlicingElementSequence( + (AbstractNdArray)array, 2); + List coords = new ArrayList<>((int)array.shape().size()); + cursor.forEachIndexed((c, e) -> coords.add(Arrays.copyOf(c, c.length))); + + assertEquals(12, coords.size()); + assertArrayEquals(new long[] {0, 0, 0}, coords.get(0)); + assertArrayEquals(new long[] {0, 0, 1}, coords.get(1)); + assertArrayEquals(new long[] {0, 1, 0}, coords.get(2)); + assertArrayEquals(new long[] {0, 1, 1}, coords.get(3)); + assertArrayEquals(new long[] {0, 2, 0}, coords.get(4)); + assertArrayEquals(new long[] {0, 2, 1}, coords.get(5)); + assertArrayEquals(new long[] {1, 0, 0}, coords.get(6)); + assertArrayEquals(new long[] {1, 0, 1}, coords.get(7)); + assertArrayEquals(new long[] {1, 1, 0}, coords.get(8)); + assertArrayEquals(new long[] {1, 1, 1}, coords.get(9)); + assertArrayEquals(new long[] {1, 2, 0}, coords.get(10)); + assertArrayEquals(new long[] {1, 2, 1}, coords.get(11)); + } + + @Test + public void slicingElementSequenceReturnsUniqueInstances() { + IntNdArray array = NdArrays.ofInts(Shape.of(2, 3, 2)); + NdArraySequence sequence = new SlicingElementSequence( + (AbstractNdArray) array, 1); + List elements = new ArrayList<>(); + sequence.forEach(e -> { + elements.forEach(tmp -> { + if (tmp == e) { + fail(); + } + }); + elements.add(e); + }); + } + + @Test + public void fastElementSequenceReturnsSameInstance() { + IntNdArray array = NdArrays.ofInts(Shape.of(2, 3, 2)); + IntNdArray element = array.get(0); + NdArraySequence sequence = new FastElementSequence( + (AbstractNdArray) array, 1, element, mockDataBufferWindow(2)); + sequence.forEach(e -> { + if (e != element) { + fail(); + } + }); + } + + private DataBufferWindow mockDataBufferWindow(long size) { + return new DataBufferWindow() { + + @Override + public long offset() { + return offset; + } + + @Override + public long size() { + return size; + } + + @Override + public DataBufferWindow slideTo(long index) { + offset = index; + return this; + } + + @Override + public DataBufferWindow slide(long step) { + offset += step; + return this; + } + + @Override + public IntDataBuffer buffer() { + return buffer; + } + + private long offset; + private final long size = 2; + private final IntDataBuffer buffer = DataBuffers.ofInts(2); + }; + } +} diff --git a/ndarray/src/test/resources/COPYRIGHT.txt b/ndarray/src/test/resources/COPYRIGHT.txt new file mode 100644 index 00000000000..5e7bd50bb48 --- /dev/null +++ b/ndarray/src/test/resources/COPYRIGHT.txt @@ -0,0 +1 @@ +All images in this folder and its subfolders are free of any copyright. \ No newline at end of file diff --git a/ndarray/src/test/resources/castle.jpg b/ndarray/src/test/resources/castle.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c5b07b4bc2a47a14c91184211a08fda45a2d79d9 GIT binary patch literal 436164 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%0D*hK^mNe+a-^+ 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

9xXu2LpQ4sa5`7w#gVi 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%0A=!>Nz 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

eQu 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�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ļ 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 literal 0 HcmV?d00001 From 3f9d689ccef4d7ffeebdba6ecd26f57b039f4451 Mon Sep 17 00:00:00 2001 From: klessard Date: Sun, 25 Apr 2021 22:27:28 -0400 Subject: [PATCH 02/63] Add missing dependencies --- ndarray/pom.xml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/ndarray/pom.xml b/ndarray/pom.xml index d852f9bcd32..af863042f57 100644 --- a/ndarray/pom.xml +++ b/ndarray/pom.xml @@ -36,6 +36,29 @@ org.tensorflow.ndarray + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-engine + test + + + org.openjdk.jmh + jmh-core + test + + + org.openjdk.jmh + jmh-generator-annprocess + test + + + From edfc4d6eb15d49eea7bb6a83de013ed6689cd2c6 Mon Sep 17 00:00:00 2001 From: klessard Date: Sun, 25 Apr 2021 22:43:32 -0400 Subject: [PATCH 03/63] Fix settings.xml path --- ndarray/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ndarray/pom.xml b/ndarray/pom.xml index af863042f57..3a8ba7189f4 100644 --- a/ndarray/pom.xml +++ b/ndarray/pom.xml @@ -27,7 +27,7 @@ ndarray jar - Java NdArray Library + NdArray Java Library Utility library for N-dimensional data I/O operations in Java. From 2fe76c0f4ddec7b00ca9c202030cb25fe915433d Mon Sep 17 00:00:00 2001 From: Ryan Nett Date: Tue, 18 May 2021 16:07:36 -0700 Subject: [PATCH 04/63] Kotlin friendly names (Shape.get) --- .../java/org/tensorflow/ndarray/Shape.java | 75 ++++++++++++++++--- .../org/tensorflow/ndarray/StdArrays.java | 4 +- .../impl/dimension/DimensionalSpace.java | 6 +- .../tensorflow/ndarray/NdArrayTestBase.java | 18 ++--- .../org/tensorflow/ndarray/ShapeTest.java | 30 +++++--- 5 files changed, 96 insertions(+), 37 deletions(-) diff --git a/ndarray/src/main/java/org/tensorflow/ndarray/Shape.java b/ndarray/src/main/java/org/tensorflow/ndarray/Shape.java index 85a905408c7..d8bb2bb5c38 100644 --- a/ndarray/src/main/java/org/tensorflow/ndarray/Shape.java +++ b/ndarray/src/main/java/org/tensorflow/ndarray/Shape.java @@ -17,7 +17,9 @@ package org.tensorflow.ndarray; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; /** * The shape of a Tensor or {@link NdArray}. @@ -74,8 +76,8 @@ public static Shape scalar() { * Shape scalar = Shape.of() * } * - * @param dimensionSizes number of elements in each dimension of this shape, if any, or - * {@link Shape#UNKNOWN_SIZE} if unknown. + * @param dimensionSizes number of elements in each dimension of this shape, if any, or {@link + * Shape#UNKNOWN_SIZE} if unknown. * @return a new shape */ public static Shape of(long... dimensionSizes) { @@ -108,13 +110,34 @@ public long size() { * an unknown size, {@link Shape#UNKNOWN_SIZE} is returned. * * @param i the index of the dimension to get the size for. If this Shape has a known number of - * dimensions, it must be < {@link Shape#numDimensions()}. The index may be negative, in which - * case the position is counted from the end of the shape. E.g.: {@code size(-1)} returns the - * size of the last dimension, {@code size(-2)} the size of the second to last dimension etc. + * dimensions, it must be < {@link Shape#numDimensions()}. The index may be negative, in + * which case the position is counted from the end of the shape. E.g.: {@code size(-1)} + * returns the size of the last dimension, {@code size(-2)} the size of the second to last + * dimension etc. * @return The size of the dimension with the given index if known, {@link Shape#UNKNOWN_SIZE} * otherwise. + * @deprecated Renamed to {@link #get(int)}. */ - public long size(int i) { + @Deprecated + public long size(int i){ + return get(i); + } + + /** + * The size of the dimension with the given index. + * + *

If {@link Shape#isUnknown()} is true or the size of the dimension with the given index has + * an unknown size, {@link Shape#UNKNOWN_SIZE} is returned. + * + * @param i the index of the dimension to get the size for. If this Shape has a known number of + * dimensions, it must be < {@link Shape#numDimensions()}. The index may be negative, in + * which case the position is counted from the end of the shape. E.g.: {@code size(-1)} + * returns the size of the last dimension, {@code size(-2)} the size of the second to last + * dimension etc. + * @return The size of the dimension with the given index if known, {@link Shape#UNKNOWN_SIZE} + * otherwise. + */ + public long get(int i) { if (dimensionSizes == null) { return UNKNOWN_SIZE; } else if (i >= 0) { @@ -177,6 +200,24 @@ public long[] asArray() { } } + /** + * Returns a defensive copy of the this Shape's axes. Changes to the returned list do not change + * this Shape's state. Returns null if {@link Shape#isUnknown()} is true. + */ + public List toListOrNull() { + long[] array = asArray(); + if (array == null) { + return null; + } + + List list = new ArrayList<>(array.length); + for (long l : array) { + list.add(l); + } + + return list; + } + @Override public int hashCode() { return dimensionSizes != null ? Arrays.hashCode(dimensionSizes) : super.hashCode(); @@ -186,6 +227,7 @@ public int hashCode() { * Equals implementation for Shapes. Two Shapes are considered equal iff: * *

+ * *

* - * @param data type for {@code output} output * @param inputs List of 1 or 2 Tensors. * @param equation String describing the Einstein Summation operation; in the format of np.einsum. * @param data type for {@code Einsum} output and operands @@ -531,7 +513,6 @@ public Einsum einsum(Iterable> inputs, String eq * {@code axis}. If {@code keep_dims} is true, the reduced dimensions are * retained with length 1. * - * @param data type for {@code output} output * @param input The tensor to reduce. * @param axis The dimensions to reduce. Must be in the range * {@code [-rank(input), rank(input))}. @@ -554,7 +535,6 @@ public EuclideanNorm euclideanNorm(Operand input, * may detect the condition and raise an exception or it may simply return a * garbage result. * - * @param data type for {@code output} output * @param input Shape is {@code [..., M, M]}. * @param options carries optional attribute values * @param data type for {@code MatrixInverse} output and operands @@ -632,7 +612,6 @@ public LoadAndRemapMatrix loadAndRemapMatrix(Operand ckptPath, * is the {@code LU} decomposition of the input and {@code P} is the corresponding * permutation matrix. * - * @param data type for {@code sign} output * @param input Shape is {@code [N, M, M]}. * @param data type for {@code LogMatrixDeterminant} output and operands * @return a new instance of LogMatrixDeterminant @@ -657,8 +636,6 @@ public LogMatrixDeterminant logMatrixDeterminant(Operand * and {@code M-1}, inclusive. If P_mat denotes the permutation matrix corresponding to * P, then the L, U and P satisfies P_mat * input = L * U. * - * @param data type for {@code lu} output - * @param data type for {@code p} output * @param input A tensor of shape {@code [..., M, M]} whose inner-most 2 dimensions form matrices of * size {@code [M, M]}. * @param data type for {@code Lu} output and operands @@ -684,8 +661,6 @@ public Lu lu(Operand input) { * and {@code M-1}, inclusive. If P_mat denotes the permutation matrix corresponding to * P, then the L, U and P satisfies P_mat * input = L * U. * - * @param data type for {@code lu} output - * @param data type for {@code p} output * @param input A tensor of shape {@code [..., M, M]} whose inner-most 2 dimensions form matrices of * size {@code [M, M]}. * @param outputIdxType The value of the outputIdxType attribute @@ -707,7 +682,6 @@ public Lu lu(Operand input, *

Note: The default kernel implementation for MatMul on GPUs uses * cublas. * - * @param data type for {@code product} output * @param a The a value * @param b The b value * @param options carries optional attribute values @@ -801,7 +775,6 @@ public MatMul matMul(Operand a, Operand b, MatMul.Opt * [9, 2]] * * - * @param data type for {@code output} output * @param diagonal Rank {@code r}, where {@code r >= 1} * @param k Diagonal offset(s). Positive value means superdiagonal, 0 refers to the main * diagonal, and negative value means subdiagonals. {@code k} can be a single integer @@ -886,7 +859,6 @@ public MatrixDiag matrixDiag(Operand diagonal, Operand * - * @param data type for {@code diagonal} output * @param input Rank {@code r} tensor where {@code r >= 2}. * @param k Diagonal offset(s). Positive value means superdiagonal, 0 refers to the main * diagonal, and negative value means subdiagonals. {@code k} can be a single integer @@ -995,7 +967,6 @@ public MatrixDiagPart matrixDiagPart(Operand input, Oper * * * - * @param data type for {@code diagonal} output * @param input Rank {@code r} tensor where {@code r >= 2}. * @param k Diagonal offset(s). Positive value means superdiagonal, 0 refers to the main * diagonal, and negative value means subdiagonals. {@code k} can be a single integer @@ -1123,7 +1094,6 @@ public MatrixDiagPartV3 matrixDiagPartV3(Operand input, * * * - * @param data type for {@code output} output * @param diagonal Rank {@code r}, where {@code r >= 1} * @param k Diagonal offset(s). Positive value means superdiagonal, 0 refers to the main * diagonal, and negative value means subdiagonals. {@code k} can be a single integer @@ -1150,7 +1120,6 @@ public MatrixDiagV3 matrixDiagV3(Operand diagonal, Opera /** * Deprecated, use python implementation tf.linalg.matrix_exponential. * - * @param data type for {@code output} output * @param input The input value * @param data type for {@code MatrixExponential} output and operands * @return a new instance of MatrixExponential @@ -1173,7 +1142,6 @@ public MatrixExponential matrixExponential(Operand input * form square matrices. The output is a tensor of the same shape as the input * containing the exponential for all input submatrices {@code [..., :, :]}. * - * @param data type for {@code output} output * @param input Shape is {@code [..., M, M]}. * @param data type for {@code MatrixLogarithm} output and operands * @return a new instance of MatrixLogarithm @@ -1281,7 +1249,6 @@ public MatrixLogarithm matrixLogarithm(Operand input) { * * * - * @param data type for {@code output} output * @param input Rank {@code r+1}, where {@code r >= 1}. * @param diagonal Rank {@code r} when {@code k} is an integer or {@code k[0] == k[1]}. Otherwise, it has rank {@code r+1}. * {@code k >= 1}. @@ -1331,7 +1298,6 @@ public MatrixSetDiag matrixSetDiag(Operand input, Operan * typically 6-7 times slower than the fast path. If {@code fast} is {@code False} then * {@code l2_regularizer} is ignored. * - * @param data type for {@code output} output * @param matrix Shape is {@code [..., M, N]}. * @param rhs Shape is {@code [..., M, K]}. * @param l2Regularizer Scalar tensor. @@ -1362,7 +1328,6 @@ public MatrixSolveLs matrixSolveLs(Operand matrix, Opera * q_full, r_full = qr(a, full_matrices=True) * * - * @param data type for {@code q} output * @param input A tensor of shape {@code [..., M, N]} whose inner-most 2 dimensions * form matrices of size {@code [M, N]}. Let {@code P} be the minimum of {@code M} and {@code N}. * @param options carries optional attribute values @@ -1380,7 +1345,6 @@ public Qr qr(Operand input, Qr.Options... options) { * outer dimension of {@code b} (after being transposed if {@code transposed_b} is * non-zero). * - * @param data type for {@code out} output * @param a Must be a two-dimensional tensor. * @param b Must be a two-dimensional tensor. * @param minA The float value that the lowest quantized {@code a} value represents. @@ -1411,7 +1375,6 @@ public QuantizedMatMul quantizedMatMul * non-zero). Then do broadcast add operation with bias values on the matrix * multiplication result. The bias size must match inner dimension of {@code b}. * - * @param data type for {@code out} output * @param a A matrix to be multiplied. Must be a two-dimensional tensor of type {@code quint8}. * @param b A matrix to be multiplied and must be a two-dimensional tensor of type {@code qint8}. * @param bias A 1D bias tensor with size matching inner dimension of {@code b} (after being @@ -1442,7 +1405,6 @@ public QuantizedMatMulWithBias quantizedMatMulWithBias( * multiplication result. The bias size must match inner dimension of {@code b}. Then do * relu activation to get non-negative result. * - * @param data type for {@code out} output * @param a A matrix to be multiplied. Must be a two-dimensional tensor of type {@code quint8}. * @param b A matrix to be multiplied and must be a two-dimensional tensor of type {@code qint8}. * @param bias A 1D bias tensor with size matching with inner dimension of {@code b} (after being @@ -1474,7 +1436,6 @@ public QuantizedMatMulWithBiasAndRelu quantizedMatMulWith * relu activation to get non-negative result. Then do requantize operation to get * final uint8 result. * - * @param data type for {@code out} output * @param a A matrix to be multiplied. Must be a two-dimensional tensor of type {@code quint8}. * @param b A matrix to be multiplied and must be a two-dimensional tensor of type {@code qint8}. * @param bias A 1D bias tensor with size matching with inner dimension of {@code b} (after being @@ -1512,7 +1473,6 @@ public QuantizedMatMulWithBiasAndReluAndRequantize quanti * e = self_adjoint_eig(a, compute_v=False) * * - * @param data type for {@code e} output * @param input {@code Tensor} input of shape {@code [N, N]}. * @param options carries optional attribute values * @param data type for {@code SelfAdjointEigV2} output and operands @@ -1532,7 +1492,6 @@ public SelfAdjointEig selfAdjointEig(Operand input, * If {@code adjoint} is {@code True} then each output matrix satisfies * {@code adjoint(matrix[..., :, :]) * output[..., :, :] = rhs[..., :, :]}. * - * @param data type for {@code output} output * @param matrix Shape is {@code [..., M, M]}. * @param rhs Shape is {@code [..., M, K]}. * @param options carries optional attribute values @@ -1559,7 +1518,6 @@ public Solve solve(Operand matrix, Operand rhs, * form square matrices. The output is a tensor of the same shape as the input * containing the matrix square root for all input submatrices {@code [..., :, :]}. * - * @param data type for {@code output} output * @param input Shape is {@code [..., M, M]}. * @param data type for {@code MatrixSquareRoot} output and operands * @return a new instance of Sqrtm @@ -1581,7 +1539,6 @@ public Sqrtm sqrtm(Operand input) { * s, _, _ = svd(a, compute_uv=False) * * - * @param data type for {@code s} output * @param input A tensor of shape {@code [..., M, N]} whose inner-most 2 dimensions * form matrices of size {@code [M, N]}. Let {@code P} be the minimum of {@code M} and {@code N}. * @param options carries optional attribute values @@ -1608,7 +1565,6 @@ public Svd svd(Operand input, Svd.Options... options) { * [0, 0, 0, 4]] * * - * @param data type for {@code output} output * @param diagonal Rank k tensor where k is at most 1. * @param data type for {@code Diag} output and operands * @return a new instance of TensorDiag @@ -1634,7 +1590,6 @@ public TensorDiag tensorDiag(Operand diagonal) { * tf.diag_part(input) ==> [1, 2, 3, 4] * * - * @param data type for {@code diagonal} output * @param input Rank k tensor where k is even and not zero. * @param data type for {@code DiagPart} output and operands * @return a new instance of TensorDiagPart @@ -1648,7 +1603,6 @@ public TensorDiagPart tensorDiagPart(Operand input) { * The output {@code y} has the same rank as {@code x}. The shapes of {@code x} and {@code y} satisfy: * {@code y.shape[i] == x.shape[perm[i]] for i in [0, 1, ..., rank(x) - 1]} * - * @param data type for {@code y} output * @param x The x value * @param perm The perm value * @param data type for {@code Transpose} output and operands @@ -1703,7 +1657,6 @@ public Transpose transpose(Operand x, Operand * - * @param data type for {@code output} output * @param matrix Shape is {@code [..., M, M]}. * @param rhs Shape is {@code [..., M, K]}. * @param options carries optional attribute values @@ -1719,7 +1672,6 @@ public TriangularSolve triangularSolve(Operand matrix, O * Calculate product with tridiagonal matrix. * Calculates product of two matrices, where left matrix is a tridiagonal matrix. * - * @param data type for {@code output} output * @param superdiag Tensor of shape {@code [..., 1, M]}, representing superdiagonals of * tri-diagonal matrices to the left of multiplication. Last element is ignored. * @param maindiag Tensor of shape {@code [..., 1, M]}, representing main diagonals of tri-diagonal @@ -1746,7 +1698,6 @@ public TridiagonalMatMul tridiagonalMatMul(Operand super * library is used: https://docs.nvidia.com/cuda/cusparse/index.html#gtsv * Partial pivoting is not yet supported by XLA backends. * - * @param data type for {@code output} output * @param diagonals Tensor of shape {@code [..., 3, M]} whose innermost 2 dimensions represent the * tridiagonal matrices with three rows being the superdiagonal, diagonals, and * subdiagonals, in order. The last element of the superdiagonal and the first diff --git a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/LinalgSparseOps.java b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/LinalgSparseOps.java index ed8c4fdbb90..7210249ba1f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/LinalgSparseOps.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/LinalgSparseOps.java @@ -59,7 +59,6 @@ public final class LinalgSparseOps { * This op is meant only for debugging / testing, and its interface is not expected * to be stable. * - * @param data type for {@code values} output * @param csrSparseMatrix A batched CSRSparseMatrix. * @param index The index in {@code csr_sparse_matrix}'s batch. * @param type The value of the type attribute @@ -74,7 +73,6 @@ public CSRSparseMatrixComponents cSRSparseMatrixComponents( /** * Convert a (possibly batched) CSRSparseMatrix to dense. * - * @param data type for {@code dense_output} output * @param sparseInput A batched CSRSparseMatrix. * @param type The value of the type attribute * @param data type for {@code CSRSparseMatrixToDense} output and operands @@ -88,7 +86,6 @@ public CSRSparseMatrixToDense cSRSparseMatrixToDense( /** * Converts a (possibly batched) CSRSparesMatrix to a SparseTensor. * - * @param data type for {@code values} output * @param sparseMatrix A (possibly batched) CSRSparseMatrix. * @param type The value of the type attribute * @param data type for {@code CSRSparseMatrixToSparseTensor} output and operands @@ -152,7 +149,6 @@ public SparseMatrixAdd sparseMatrixAdd(Operand * - * @param data type for {@code output} output * @param a A CSRSparseMatrix. * @param b A dense tensor. * @param options carries optional attribute values diff --git a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/MathOps.java b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/MathOps.java index ee2e3a46c27..d3dcfc686ad 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/MathOps.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/MathOps.java @@ -168,7 +168,6 @@ public final class MathOps { * value of each element in {@code x}. For example, if x is an input element and y is * an output element, this operation computes \(y = |x|\). * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Abs} output and operands * @return a new instance of Abs @@ -186,7 +185,6 @@ public Abs abs(Operand x) { *

Unlike the original {@code accumulate_n}, {@code accumulate_n_v2} is differentiable. *

Returns a {@code Tensor} of same shape and type as the elements of {@code inputs}. * - * @param data type for {@code sum} output * @param inputs A list of {@code Tensor} objects, each with same shape and type. * @param shape Shape of elements of {@code inputs}. * @param data type for {@code AccumulateNV2} output and operands @@ -201,7 +199,6 @@ public AccumulateN accumulateN(Iterable> inputs, * Provided an input tensor, the {@code tf.math.acos} operation returns the inverse cosine of each element of the tensor. If {@code y = tf.math.cos(x)} then, {@code x = tf.math.acos(y)}. *

Input range is {@code [-1, 1]} and the output has a range of {@code [0, pi]}. * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Acos} output and operands * @return a new instance of Acos @@ -219,7 +216,6 @@ public Acos acos(Operand x) { * tf.math.acosh(x) ==> [nan nan 0. 0.62236255 5.9914584 9.903487 inf] * * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Acosh} output and operands * @return a new instance of Acosh @@ -235,7 +231,6 @@ public Acosh acosh(Operand x) { *

Given two input tensors, the {@code tf.add} operation computes the sum for every element in the tensor. *

Both input and output have a range {@code (-inf, inf)}. * - * @param data type for {@code z} output * @param x The x value * @param y The y value * @param data type for {@code Add} output and operands @@ -253,7 +248,6 @@ public Add add(Operand x, Operand y) { * tf.math.add_n(x) ==> 26 * * - * @param data type for {@code sum} output * @param inputs The inputs value * @param data type for {@code AddN} output and operands * @return a new instance of AddN @@ -278,7 +272,6 @@ public AddN addN(Iterable> inputs) { * Equivalent to np.angle. *
{@literal @}end_compatibility * - * @param data type for {@code output} output * @param input The input value * @return a new instance of Angle, with default output types */ @@ -302,7 +295,6 @@ public Angle angle(Operand input) { * Equivalent to np.angle. *
{@literal @}end_compatibility * - * @param data type for {@code output} output * @param input The input value * @param Tout The value of the Tout attribute * @param data type for {@code Angle} output and operands @@ -339,7 +331,6 @@ public ApproximateEqual approximateEqual(Operand x, Operand * # here a[4] = 166.32 which is the largest element of a across axis 0 * * - * @param data type for {@code output} output * @param input The input value * @param dimension int16, int32 or int64, must be in the range {@code [-rank(input), rank(input))}. * Describes which dimension of the input Tensor to reduce across. For vectors, @@ -364,7 +355,6 @@ public ArgMax argMax(Operand input, * # here a[4] = 166.32 which is the largest element of a across axis 0 * * - * @param data type for {@code output} output * @param input The input value * @param dimension int16, int32 or int64, must be in the range {@code [-rank(input), rank(input))}. * Describes which dimension of the input Tensor to reduce across. For vectors, @@ -391,7 +381,6 @@ public ArgMax argMax(Operand input, * # here a[0] = 1 which is the smallest element of a across axis 0 * * - * @param data type for {@code output} output * @param input The input value * @param dimension int32 or int64, must be in the range {@code [-rank(input), rank(input))}. * Describes which dimension of the input Tensor to reduce across. For vectors, @@ -416,7 +405,6 @@ public ArgMin argMin(Operand input, * # here a[0] = 1 which is the smallest element of a across axis 0 * * - * @param data type for {@code output} output * @param input The input value * @param dimension int32 or int64, must be in the range {@code [-rank(input), rank(input))}. * Describes which dimension of the input Tensor to reduce across. For vectors, @@ -445,7 +433,6 @@ public ArgMin argMin(Operand input, * tf.math.asin(y) # [1.047, 0.785] = x * * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Asin} output and operands * @return a new instance of Asin @@ -464,7 +451,6 @@ public Asin asin(Operand x) { * tf.math.asinh(x) ==> [-inf -1.4436355 -0.4812118 0.8813736 1.0159732 5.991471 9.903487 inf] * * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Asinh} output and operands * @return a new instance of Asinh @@ -488,7 +474,6 @@ public Asinh asinh(Operand x) { * tf.math.atan(y) # [1.047, 0.785] = x * * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Atan} output and operands * @return a new instance of Atan @@ -516,7 +501,6 @@ public Atan atan(Operand x) { * * * - * @param data type for {@code z} output * @param y The y value * @param x The x value * @param data type for {@code Atan2} output and operands @@ -538,7 +522,6 @@ public Atan2 atan2(Operand y, Operand x) { * tf.math.atanh(x) ==> [nan -inf -0.54930615 inf 0. 0.54930615 nan nan] * * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Atanh} output and operands * @return a new instance of Atanh @@ -550,7 +533,6 @@ public Atanh atanh(Operand x) { /** * The BesselI0 operation * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code BesselI0} output and operands * @return a new instance of BesselI0 @@ -562,7 +544,6 @@ public BesselI0 besselI0(Operand x) { /** * The BesselI0e operation * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code BesselI0e} output and operands * @return a new instance of BesselI0e @@ -574,7 +555,6 @@ public BesselI0e besselI0e(Operand x) { /** * The BesselI1 operation * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code BesselI1} output and operands * @return a new instance of BesselI1 @@ -586,7 +566,6 @@ public BesselI1 besselI1(Operand x) { /** * The BesselI1e operation * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code BesselI1e} output and operands * @return a new instance of BesselI1e @@ -604,7 +583,6 @@ public BesselI1e besselI1e(Operand x) { *

is the incomplete beta function and \(B(a, b)\) is the complete * beta function. * - * @param data type for {@code z} output * @param a The a value * @param b The b value * @param x The x value @@ -624,7 +602,6 @@ public Betainc betainc(Operand a, Operand b, Operan * {@code i}. *

Values in {@code arr} outside of the range [0, size) are ignored. * - * @param data type for {@code bins} output * @param arr int32 {@code Tensor}. * @param sizeOutput non-negative int32 scalar {@code Tensor}. * @param weights is an int32, int64, float32, or float64 {@code Tensor} with the same @@ -641,7 +618,6 @@ public Bincount bincount(Operand arr, Operand data type for {@code y} output * @param x The x value * @param data type for {@code Ceil} output and operands * @return a new instance of Ceil @@ -667,7 +643,6 @@ public Ceil ceil(Operand x) { * * * - * @param data type for {@code y} output * @param x The x value * @return a new instance of ComplexAbs, with default output types */ @@ -692,7 +667,6 @@ public ComplexAbs complexAbs(Operand x) { * * * - * @param data type for {@code y} output * @param x The x value * @param Tout The value of the Tout attribute * @param data type for {@code ComplexAbs} output and operands @@ -715,7 +689,6 @@ public ComplexAbs complexAbs(Operand x, * tf.conj(input) ==> [-2.25 - 4.75j, 3.25 - 5.75j] * * - * @param data type for {@code output} output * @param input The input value * @param data type for {@code Conj} output and operands * @return a new instance of Conj @@ -735,7 +708,6 @@ public Conj conj(Operand input) { * tf.math.cos(x) ==> [nan -0.91113025 0.87758255 0.5403023 0.36235774 0.48718765 -0.95215535 nan] * * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Cos} output and operands * @return a new instance of Cos @@ -754,7 +726,6 @@ public Cos cos(Operand x) { * tf.math.cosh(x) ==> [inf 4.0515420e+03 1.1276259e+00 1.5430807e+00 1.8106556e+00 3.7621956e+00 1.1013233e+04 inf] * * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Cosh} output and operands * @return a new instance of Cosh @@ -786,7 +757,6 @@ public Cosh cosh(Operand x) { * tf.cumprod([a, b, c], exclusive=True, reverse=True) # => [b * c, c, 1] * * - * @param data type for {@code out} output * @param x A {@code Tensor}. Must be one of the following types: {@code float32}, {@code float64}, * {@code int64}, {@code int32}, {@code uint8}, {@code uint16}, {@code int16}, {@code int8}, {@code complex64}, * {@code complex128}, {@code qint8}, {@code quint8}, {@code qint32}, {@code half}. @@ -824,7 +794,6 @@ public Cumprod cumprod(Operand x, Operand * - * @param data type for {@code out} output * @param x A {@code Tensor}. Must be one of the following types: {@code float32}, {@code float64}, * {@code int64}, {@code int32}, {@code uint8}, {@code uint16}, {@code int16}, {@code int8}, {@code complex64}, * {@code complex128}, {@code qint8}, {@code quint8}, {@code qint32}, {@code half}. @@ -858,7 +827,6 @@ public Cumsum cumsum(Operand x, OperandBy setting the {@code reverse} kwarg to {@code True}, the cumulative log-sum-exp is performed in the * opposite direction. * - * @param data type for {@code out} output * @param x A {@code Tensor}. Must be one of the following types: {@code float16}, {@code float32}, {@code float64}. * @param axis A {@code Tensor} of type {@code int32} (default: 0). Must be in the range * {@code [-rank(x), rank(x))}. @@ -880,7 +848,6 @@ public CumulativeLogsumexp cumulativeLogsumexp(Operand * {@code i}. *

NOTE: {@code math.FloorMod} supports broadcasting. More about broadcasting * here * - * @param data type for {@code z} output * @param x The x value * @param y The y value * @param data type for {@code FloorMod} output and operands @@ -1168,7 +1124,6 @@ public GreaterEqual greaterEqual(Operand x, Operand y) *

Note, above {@code Q(a, x)} ({@code Igammac}) is the upper regularized complete * Gamma function. * - * @param data type for {@code z} output * @param a The a value * @param x The x value * @param data type for {@code Igamma} output and operands @@ -1181,7 +1136,6 @@ public Igamma igamma(Operand a, Operand x) { /** * Computes the gradient of {@code igamma(a, x)} wrt {@code a}. * - * @param data type for {@code z} output * @param a The a value * @param x The x value * @param data type for {@code IgammaGradA} output and operands @@ -1201,7 +1155,6 @@ public IgammaGradA igammaGradA(Operand a, Operand x *

Note, above {@code P(a, x)} ({@code Igamma}) is the lower regularized complete * Gamma function. * - * @param data type for {@code z} output * @param a The a value * @param x The x value * @param data type for {@code Igammac} output and operands @@ -1223,7 +1176,6 @@ public Igammac igammac(Operand a, Operand x) { * tf.imag(input) ==> [4.75, 5.75] * * - * @param data type for {@code output} output * @param input The input value * @return a new instance of Imag, with default output types */ @@ -1243,7 +1195,6 @@ public Imag imag(Operand input) { * tf.imag(input) ==> [4.75, 5.75] * * - * @param data type for {@code output} output * @param input The input value * @param Tout The value of the Tout attribute * @param data type for {@code Imag} output and operands @@ -1267,7 +1218,6 @@ public Imag imag(Operand input, Class * invert_permutation(x) ==> [2, 4, 3, 0, 1] * * - * @param data type for {@code y} output * @param x 1-D. * @param data type for {@code InvertPermutation} output and operands * @return a new instance of InvertPermutation @@ -1388,7 +1338,6 @@ public LessEqual lessEqual(Operand x, Operand y) { * tf.math.lgamma(x) ==> [inf, 0.5723649, 0., 2.4537368, inf, -4.6477685] * * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Lgamma} output and operands * @return a new instance of Lgamma @@ -1406,7 +1355,6 @@ public Lgamma lgamma(Operand x) { * tf.math.log(x) ==> [-inf, -0.6931472, 0. , 1.609438] * * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Log} output and operands * @return a new instance of Log @@ -1424,7 +1372,6 @@ public Log log(Operand x) { * tf.math.log1p(x) ==> [0., 0.4054651, 0.6931472, 1.7917595] * * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Log1p} output and operands * @return a new instance of Log1p @@ -1474,7 +1421,6 @@ public LogicalOr logicalOr(Operand x, Operand y) { * NOTE: {@code math.Maximum} supports broadcasting. More about broadcasting * here * - * @param data type for {@code z} output * @param x The x value * @param y The y value * @param data type for {@code Maximum} output and operands @@ -1491,7 +1437,6 @@ public Maximum maximum(Operand x, Operand y) { * {@code axis}. If {@code keep_dims} is true, the reduced dimensions are * retained with length 1. * - * @param data type for {@code output} output * @param input The tensor to reduce. * @param axis The dimensions to reduce. Must be in the range * {@code [-rank(input), rank(input))}. @@ -1509,7 +1454,6 @@ public Mean mean(Operand input, OperandNOTE: {@code math.Minimum} supports broadcasting. More about broadcasting * here * - * @param data type for {@code z} output * @param x The x value * @param y The y value * @param data type for {@code Minimum} output and operands @@ -1526,7 +1470,6 @@ public Minimum minimum(Operand x, Operand y) { *

NOTE: {@code math.Mod} supports broadcasting. More about broadcasting * here * - * @param data type for {@code z} output * @param x The x value * @param y The y value * @param data type for {@code Mod} output and operands @@ -1541,7 +1484,6 @@ public Mod mod(Operand x, Operand y) { * NOTE: {@code math.Mul} supports broadcasting. More about broadcasting * here * - * @param data type for {@code z} output * @param x The x value * @param y The y value * @param data type for {@code Mul} output and operands @@ -1556,7 +1498,6 @@ public Mul mul(Operand x, Operand y) { * NOTE: {@code math.MulNoNan} supports broadcasting. More about broadcasting * here * - * @param data type for {@code z} output * @param x The x value * @param y The y value * @param data type for {@code MulNoNan} output and operands @@ -1569,7 +1510,6 @@ public MulNoNan mulNoNan(Operand x, Operand y) { /** * The Ndtri operation * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Ndtri} output and operands * @return a new instance of Ndtri @@ -1582,7 +1522,6 @@ public Ndtri ndtri(Operand x) { * Computes numerical negative value element-wise. * I.e., \(y = -x\). * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Neg} output and operands * @return a new instance of Neg @@ -1599,7 +1538,6 @@ public Neg neg(Operand x) { * Equivalent to C++ std::nextafter function. *
{@literal @}end_compatibility * - * @param data type for {@code output} output * @param x1 The x1 value * @param x2 The x2 value * @param data type for {@code NextAfter} output and operands @@ -1632,7 +1570,6 @@ public NotEqual notEqual(Operand x, Operand y, *

where \(\psi(x)\) is the digamma function. * The polygamma function is defined only for non-negative integer orders \a\. * - * @param data type for {@code z} output * @param a The a value * @param x The x value * @param data type for {@code Polygamma} output and operands @@ -1667,7 +1604,6 @@ public PopulationCount populationCount(Operand x) { * tf.pow(x, y) ==> [[256, 65536], [9, 27]] * * - * @param data type for {@code z} output * @param x The x value * @param y The y value * @param data type for {@code Pow} output and operands @@ -1680,7 +1616,6 @@ public Pow pow(Operand x, Operand y) { /** * Returns x + y element-wise, working on quantized buffers. * - * @param data type for {@code z} output * @param x The x value * @param y The y value * @param minX The float value that the lowest quantized {@code x} value represents. @@ -1700,7 +1635,6 @@ public QuantizedAdd quantizedAdd(Operand data type for {@code z} output * @param x The x value * @param y The y value * @param minX The float value that the lowest quantized {@code x} value represents. @@ -1729,7 +1663,6 @@ public QuantizedMul quantizedMul(Operand * - * @param data type for {@code output} output * @param input The input value * @return a new instance of Real, with default output types */ @@ -1749,7 +1682,6 @@ public Real real(Operand input) { * tf.real(input) ==> [-2.25, 3.25] * * - * @param data type for {@code output} output * @param input The input value * @param Tout The value of the Tout attribute * @param data type for {@code Real} output and operands @@ -1765,7 +1697,6 @@ public Real real(Operand input, Class *

NOTE: {@code Div} supports broadcasting. More about broadcasting * here * - * @param data type for {@code z} output * @param x The x value * @param y The y value * @param data type for {@code RealDiv} output and operands @@ -1779,7 +1710,6 @@ public RealDiv realDiv(Operand x, Operand y) { * Computes the reciprocal of x element-wise. * I.e., \(y = 1 / x\). * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Reciprocal} output and operands * @return a new instance of Reciprocal @@ -1793,7 +1723,6 @@ public Reciprocal reciprocal(Operand x) { * Specifically, {@code grad = -dy * y*y}, where {@code y = 1/x}, and {@code dy} * is the corresponding input gradient. * - * @param data type for {@code z} output * @param y The y value * @param dy The dy value * @param data type for {@code ReciprocalGrad} output and operands @@ -1822,7 +1751,6 @@ public RequantizationRangePerChannel requantizationRangePerChannel( /** * Requantizes input with min and max values known per channel. * - * @param data type for {@code output} output * @param input The original input tensor. * @param inputMin The minimum value of the input tensor * @param inputMax The maximum value of the input tensor. @@ -1850,7 +1778,6 @@ public RequantizePerChannel requantizePerChannel( * rint([-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0]) ==> [-2., -2., -0., 0., 2., 2., 2.] * * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Rint} output and operands * @return a new instance of Rint @@ -1864,7 +1791,6 @@ public Rint rint(Operand x) { * Rounds half to even. Also known as bankers rounding. If you want to round * according to the current system rounding mode use std::cint. * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Round} output and operands * @return a new instance of Round @@ -1877,7 +1803,6 @@ public Round round(Operand x) { * Computes reciprocal of square root of x element-wise. * I.e., \(y = 1 / \sqrt{x}\). * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Rsqrt} output and operands * @return a new instance of Rsqrt @@ -1891,7 +1816,6 @@ public Rsqrt rsqrt(Operand x) { * Specifically, {@code grad = dy * -0.5 * y^3}, where {@code y = rsqrt(x)}, and {@code dy} * is the corresponding input gradient. * - * @param data type for {@code z} output * @param y The y value * @param dy The dy value * @param data type for {@code RsqrtGrad} output and operands @@ -1942,7 +1866,6 @@ public RsqrtGrad rsqrtGrad(Operand y, Operand dy) { * * * - * @param data type for {@code output} output * @param data The data value * @param segmentIds A 1-D tensor whose size is equal to the size of {@code data}'s * first dimension. Values should be sorted and can be repeated. @@ -1989,7 +1912,6 @@ public SegmentMax segmentMax(Operand data, * * * - * @param data type for {@code output} output * @param data The data value * @param segmentIds A 1-D tensor whose size is equal to the size of {@code data}'s * first dimension. Values should be sorted and can be repeated. @@ -2044,7 +1966,6 @@ public SegmentMean segmentMean(Operand data, * * * - * @param data type for {@code output} output * @param data The data value * @param segmentIds A 1-D tensor whose size is equal to the size of {@code data}'s * first dimension. Values should be sorted and can be repeated. @@ -2093,7 +2014,6 @@ public SegmentMin segmentMin(Operand data, * * * - * @param data type for {@code output} output * @param data The data value * @param segmentIds A 1-D tensor whose size is equal to the size of {@code data}'s * first dimension. Values should be sorted and can be repeated. @@ -2119,9 +2039,7 @@ public SegmentProd segmentProd(Operand data, * that {@code segment_ids[j] == i}. *

If the sum is empty for a given segment ID {@code i}, {@code output[i] = 0}. *

Note that this op is currently only supported with jit_compile=True. - * * - * @param data type for {@code output} output * @param data The data value * @param segmentIds A 1-D tensor whose size is equal to the size of {@code data}'s * first dimension. Values should be sorted and can be repeated. @@ -2141,7 +2059,6 @@ public SegmentSum segmentSum(Operand data, * Computes sigmoid of {@code x} element-wise. * Specifically, {@code y = 1 / (1 + exp(-x))}. * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Sigmoid} output and operands * @return a new instance of Sigmoid @@ -2155,7 +2072,6 @@ public Sigmoid sigmoid(Operand x) { * Specifically, {@code grad = dy * y * (1 - y)}, where {@code y = sigmoid(x)}, and * {@code dy} is the corresponding input gradient. * - * @param data type for {@code z} output * @param y The y value * @param dy The dy value * @param data type for {@code SigmoidGrad} output and operands @@ -2179,7 +2095,6 @@ public SigmoidGrad sigmoidGrad(Operand y, Operand dy) * * * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Sign} output and operands * @return a new instance of Sign @@ -2198,7 +2113,6 @@ public Sign sign(Operand x) { * tf.math.sin(x) ==> [nan -0.4121185 -0.47942555 0.84147096 0.9320391 -0.87329733 -0.54402107 nan] * * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Sin} output and operands * @return a new instance of Sin @@ -2217,7 +2131,6 @@ public Sin sin(Operand x) { * tf.math.sinh(x) ==> [-inf -4.0515420e+03 -5.2109528e-01 1.1752012e+00 1.5094614e+00 3.6268604e+00 1.1013232e+04 inf] * * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Sinh} output and operands * @return a new instance of Sinh @@ -2231,7 +2144,6 @@ public Sinh sinh(Operand x) { * Creates a Sobol sequence with {@code num_results} samples. Each sample has dimension * {@code dim}. Skips the first {@code skip} samples. * - * @param data type for {@code samples} output * @param dim Positive scalar {@code Tensor} representing each sample's dimension. * @param numResults Positive scalar {@code Tensor} of dtype int32. The number of Sobol points to return * in the output. @@ -2249,7 +2161,6 @@ public SobolSample sobolSample(Operand dim, Operand nu * Creates a Sobol sequence with {@code num_results} samples. Each sample has dimension * {@code dim}. Skips the first {@code skip} samples. * - * @param data type for {@code samples} output * @param dim Positive scalar {@code Tensor} representing each sample's dimension. * @param numResults Positive scalar {@code Tensor} of dtype int32. The number of Sobol points to return * in the output. @@ -2267,7 +2178,6 @@ public SobolSample sobolSample(Operand dim, /** * The Softplus operation * - * @param data type for {@code activations} output * @param features The features value * @param data type for {@code Softplus} output and operands * @return a new instance of Softplus @@ -2279,7 +2189,6 @@ public Softplus softplus(Operand features) { /** * Computes softplus gradients for a softplus operation. * - * @param data type for {@code backprops} output * @param gradients The backpropagated gradients to the corresponding softplus operation. * @param features The features passed as input to the corresponding softplus operation. * @param data type for {@code SoftplusGrad} output and operands @@ -2294,7 +2203,6 @@ public SoftplusGrad softplusGrad(Operand gradients, * Computes square root of x element-wise. * I.e., \(y = \sqrt{x} = x^{1/2}\). * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Sqrt} output and operands * @return a new instance of Sqrt @@ -2308,7 +2216,6 @@ public Sqrt sqrt(Operand x) { * Specifically, {@code grad = dy * 0.5 / y}, where {@code y = sqrt(x)}, and {@code dy} * is the corresponding input gradient. * - * @param data type for {@code z} output * @param y The y value * @param dy The dy value * @param data type for {@code SqrtGrad} output and operands @@ -2322,7 +2229,6 @@ public SqrtGrad sqrtGrad(Operand y, Operand dy) { * Computes square of x element-wise. * I.e., \(y = x * x = x^2\). * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Square} output and operands * @return a new instance of Square @@ -2336,7 +2242,6 @@ public Square square(Operand x) { * NOTE: {@code math.SquaredDifference} supports broadcasting. More about broadcasting * here * - * @param data type for {@code z} output * @param x The x value * @param y The y value * @param data type for {@code SquaredDifference} output and operands @@ -2351,7 +2256,6 @@ public SquaredDifference squaredDifference(Operand x, Op * NOTE: {@code math.Sub} supports broadcasting. More about broadcasting * here * - * @param data type for {@code z} output * @param x The x value * @param y The y value * @param data type for {@code Sub} output and operands @@ -2372,7 +2276,6 @@ public Sub sub(Operand x, Operand y) { * tf.math.tan(x) ==> [nan 0.45231566 -0.5463025 1.5574077 2.572152 -1.7925274 0.32097113 nan] * * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Tan} output and operands * @return a new instance of Tan @@ -2398,7 +2301,6 @@ public Tan tan(Operand x) { * * * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Tanh} output and operands * @return a new instance of Tanh @@ -2412,7 +2314,6 @@ public Tanh tanh(Operand x) { * Specifically, {@code grad = dy * (1 - y*y)}, where {@code y = tanh(x)}, and {@code dy} * is the corresponding input gradient. * - * @param data type for {@code z} output * @param y The y value * @param dy The dy value * @param data type for {@code TanhGrad} output and operands @@ -2431,7 +2332,6 @@ public TanhGrad tanhGrad(Operand y, Operand dy) { *

NOTE: {@code math.TruncateDiv} supports broadcasting. More about broadcasting * here * - * @param data type for {@code z} output * @param x The x value * @param y The y value * @param data type for {@code TruncateDiv} output and operands @@ -2447,7 +2347,6 @@ public TruncateDiv truncateDiv(Operand x, Operand y) *

NOTE: {@code math.TruncateMod} supports broadcasting. More about broadcasting * here * - * @param data type for {@code z} output * @param x The x value * @param y The y value * @param data type for {@code TruncateMod} output and operands @@ -2475,7 +2374,6 @@ public TruncateMod truncateMod(Operand x, Operand y * if {@code operand.quantization_axis} >= 0 and {@code output.quantization_axis} >= 0, * {@code operand.dims} - {@code operand.quantization_axis} must be equal to {@code output.dims} - {@code output.quantization_axis}. * - * @param data type for {@code output} output * @param lhs Must be a quantized tensor. * @param rhs Must be a quantized tensor. * @param lhsScales The float value(s) used as scale factors when quantizing the original data that {@code lhs} represents. @@ -2547,7 +2445,6 @@ public UniformQuantizedAdd uniformQuantizedAdd(Operand * * * - * @param data type for {@code output} output * @param data The data value * @param segmentIds A tensor whose shape is a prefix of {@code data.shape}. * The values must be less than {@code num_segments}. @@ -2594,7 +2491,6 @@ public UnsortedSegmentMax unsortedSegmentMax(Operand d * out-of-bound indices or outputting a tensor with a 0 stored in the first * dimension of its shape if {@code num_segments} is 0. * - * @param data type for {@code output} output * @param data The data value * @param segmentIds A tensor whose shape is a prefix of {@code data.shape}. * The values must be less than {@code num_segments}. @@ -2640,7 +2536,6 @@ public UnsortedSegmentMin unsortedSegmentMin(Operand d * out-of-bound indices or outputting a tensor with a 0 stored in the first * dimension of its shape if {@code num_segments} is 0. * - * @param data type for {@code output} output * @param data The data value * @param segmentIds A tensor whose shape is a prefix of {@code data.shape}. * The values must be less than {@code num_segments}. @@ -2689,7 +2584,6 @@ public UnsortedSegmentProd unsortedSegmentProd(Operand d * * * - * @param data type for {@code output} output * @param data The data value * @param segmentIds A tensor whose shape is a prefix of {@code data.shape}. * The values must be less than {@code num_segments}. @@ -2707,7 +2601,6 @@ public UnsortedSegmentSum unsortedSegmentSum(Operand dat /** * Returns 0 if x == 0, and x / y otherwise, elementwise. * - * @param data type for {@code z} output * @param x The x value * @param y The y value * @param data type for {@code Xdivy} output and operands @@ -2720,7 +2613,6 @@ public Xdivy xdivy(Operand x, Operand y) { /** * Returns 0 if x == 0, and x * log1p(y) otherwise, elementwise. * - * @param data type for {@code z} output * @param x The x value * @param y The y value * @param data type for {@code Xlog1py} output and operands @@ -2733,7 +2625,6 @@ public Xlog1py xlog1py(Operand x, Operand y) { /** * Returns 0 if x == 0, and x * log(y) otherwise, elementwise. * - * @param data type for {@code z} output * @param x The x value * @param y The y value * @param data type for {@code Xlogy} output and operands @@ -2748,7 +2639,6 @@ public Xlogy xlogy(Operand x, Operand y) { * The Hurwitz zeta function is defined as: *

\(\zeta(x, q) = \sum_{n=0}^{\infty} (q + n)^{-x}\) * - * @param data type for {@code z} output * @param x The x value * @param q The q value * @param data type for {@code Zeta} output and operands diff --git a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/MathSpecialOps.java b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/MathSpecialOps.java index 05af5fe921d..e486615af1b 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/MathSpecialOps.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/MathSpecialOps.java @@ -51,7 +51,6 @@ public final class MathSpecialOps { /** * The BesselJ0 operation * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code BesselJ0} output and operands * @return a new instance of BesselJ0 @@ -63,7 +62,6 @@ public BesselJ0 besselJ0(Operand x) { /** * The BesselJ1 operation * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code BesselJ1} output and operands * @return a new instance of BesselJ1 @@ -75,7 +73,6 @@ public BesselJ1 besselJ1(Operand x) { /** * The BesselK0 operation * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code BesselK0} output and operands * @return a new instance of BesselK0 @@ -87,7 +84,6 @@ public BesselK0 besselK0(Operand x) { /** * The BesselK0e operation * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code BesselK0e} output and operands * @return a new instance of BesselK0e @@ -99,7 +95,6 @@ public BesselK0e besselK0e(Operand x) { /** * The BesselK1 operation * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code BesselK1} output and operands * @return a new instance of BesselK1 @@ -111,7 +106,6 @@ public BesselK1 besselK1(Operand x) { /** * The BesselK1e operation * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code BesselK1e} output and operands * @return a new instance of BesselK1e @@ -123,7 +117,6 @@ public BesselK1e besselK1e(Operand x) { /** * The BesselY0 operation * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code BesselY0} output and operands * @return a new instance of BesselY0 @@ -135,7 +128,6 @@ public BesselY0 besselY0(Operand x) { /** * The BesselY1 operation * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code BesselY1} output and operands * @return a new instance of BesselY1 @@ -147,7 +139,6 @@ public BesselY1 besselY1(Operand x) { /** * The Dawsn operation * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Dawsn} output and operands * @return a new instance of Dawsn @@ -159,7 +150,6 @@ public Dawsn dawsn(Operand x) { /** * The Expint operation * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Expint} output and operands * @return a new instance of Expint @@ -171,7 +161,6 @@ public Expint expint(Operand x) { /** * The FresnelCos operation * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code FresnelCos} output and operands * @return a new instance of FresnelCos @@ -183,7 +172,6 @@ public FresnelCos fresnelCos(Operand x) { /** * The FresnelSin operation * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code FresnelSin} output and operands * @return a new instance of FresnelSin @@ -195,7 +183,6 @@ public FresnelSin fresnelSin(Operand x) { /** * The Spence operation * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Spence} output and operands * @return a new instance of Spence diff --git a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/NnOps.java b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/NnOps.java index 2e20b52b946..9859a308562 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/NnOps.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/NnOps.java @@ -155,7 +155,6 @@ public final class NnOps { * Each entry in {@code output} is the mean of the corresponding size {@code ksize} * window in {@code value}. * - * @param data type for {@code output} output * @param value 4-D with shape {@code [batch, height, width, channels]}. * @param ksize The size of the sliding window for each dimension of {@code value}. * @param strides The stride of the sliding window for each dimension of {@code value}. @@ -174,7 +173,6 @@ public AvgPool avgPool(Operand value, List ksize * Each entry in {@code output} is the mean of the corresponding size {@code ksize} window in * {@code value}. * - * @param data type for {@code output} output * @param input Shape {@code [batch, depth, rows, cols, channels]} tensor to pool over. * @param ksize 1-D tensor of length 5. The size of the window for each dimension of * the input tensor. Must have {@code ksize[0] = ksize[4] = 1}. @@ -193,7 +191,6 @@ public AvgPool3d avgPool3d(Operand input, List k /** * Computes gradients of average pooling function. * - * @param data type for {@code output} output * @param origInputShape The original input dimensions. * @param grad Output backprop of shape {@code [batch, depth, rows, cols, channels]}. * @param ksize 1-D tensor of length 5. The size of the window for each dimension of @@ -214,7 +211,6 @@ public AvgPool3dGrad avgPool3dGrad(Operand origIn /** * Computes gradients of the average pooling function. * - * @param data type for {@code output} output * @param origInputShape 1-D. Shape of the original input to {@code avg_pool}. * @param grad 4-D with shape {@code [batch, height, width, channels]}. Gradients w.r.t. * the output of {@code avg_pool}. @@ -235,7 +231,6 @@ public AvgPoolGrad avgPoolGrad(Operand origInputS * Batch normalization. * This op is deprecated. Prefer {@code tf.nn.batch_normalization}. * - * @param data type for {@code result} output * @param t A 4D input Tensor. * @param m A 1D mean Tensor with size matching the last dimension of t. * This is the first output from tf.nn.moments, @@ -264,7 +259,6 @@ public BatchNormWithGlobalNormalization batchNormWithGlobal * Gradients for batch normalization. * This op is deprecated. See {@code tf.nn.batch_normalization}. * - * @param data type for {@code dx} output * @param t A 4D input Tensor. * @param m A 1D mean Tensor with size matching the last dimension of t. * This is the first output from tf.nn.moments, @@ -293,7 +287,6 @@ public BatchNormWithGlobalNormalizationGrad batchNormWithGl * This is a special case of {@code tf.add} where {@code bias} is restricted to be 1-D. * Broadcasting is supported, so {@code value} may have any number of dimensions. * - * @param data type for {@code output} output * @param value Any number of dimensions. * @param bias 1-D with size the last dimension of {@code value}. * @param options carries optional attribute values @@ -311,7 +304,6 @@ public BiasAdd biasAdd(Operand value, Operand bias, * For NHWC data format, the feature dimension is the last. For NCHW data format, * the feature dimension is the third-to-last. * - * @param data type for {@code output} output * @param outBackprop Any number of dimensions. * @param options carries optional attribute values * @param data type for {@code BiasAddGrad} output and operands @@ -345,7 +337,6 @@ public BiasAddGrad biasAddGrad(Operand outBackprop, * all gate-related outputs should be reordered. * * - * @param data type for {@code i} output * @param seqLenMax Maximum time length actually used by this input. Outputs are padded * with zeros beyond this length. * @param x The sequence input to the LSTM, shape (timelen, batch_size, num_inputs). @@ -370,7 +361,6 @@ public BlockLSTM blockLSTM(Operand seqLenMax, Ope * Computes the LSTM cell backward propagation for the entire time sequence. * This implementation is to be used in conjunction of BlockLSTMV2. * - * @param data type for {@code x_grad} output * @param seqLenMax Maximum time length actually used by this input. Outputs are padded * with zeros beyond this length. * @param x The sequence input to the LSTM, shape (timelen, batch_size, num_inputs). @@ -445,7 +435,6 @@ public ComputeAccidentalHits computeAccidentalHits(Operand trueClasses, * General function for computing a N-D convolution. It is required that * {@code 1 <= N <= 3}. * - * @param data type for {@code output} output * @param input Tensor of type T and shape {@code batch_shape + spatial_shape + [in_channels]} in the * case that {@code channels_last_format = true} or shape * {@code batch_shape + [in_channels] + spatial_shape} if {@code channels_last_format = false}. @@ -490,7 +479,6 @@ public Conv conv(Operand input, Operand filter, Lis *

Must have {@code strides[0] = strides[3] = 1}. For the most common case of the same * horizontal and vertices strides, {@code strides = [1, stride, stride, 1]}. * - * @param data type for {@code output} output * @param input A 4-D tensor. The dimension order is interpreted according to the value * of {@code data_format}, see below for details. * @param filter A 4-D tensor of shape @@ -511,7 +499,6 @@ public Conv2d conv2d(Operand input, Operand filter, /** * Computes the gradients of convolution with respect to the filter. * - * @param data type for {@code output} output * @param input 4-D with shape {@code [batch, in_height, in_width, in_channels]}. * @param filterSizes An integer vector representing the tensor shape of {@code filter}, * where {@code filter} is a 4-D @@ -535,7 +522,6 @@ public Conv2dBackpropFilter conv2dBackpropFilter(Operand< /** * Computes the gradients of convolution with respect to the input. * - * @param data type for {@code output} output * @param inputSizes An integer vector representing the shape of {@code input}, * where {@code input} is a 4-D {@code [batch, height, width, channels]} tensor. * @param filter 4-D with shape @@ -563,7 +549,6 @@ public Conv2dBackpropInput conv2dBackpropInput(OperandOur Conv3D implements a form of cross-correlation. * - * @param data type for {@code output} output * @param input Shape {@code [batch, in_depth, in_height, in_width, in_channels]}. * @param filter Shape {@code [filter_depth, filter_height, filter_width, in_channels, out_channels]}. {@code in_channels} must match between {@code input} and {@code filter}. * @param strides 1-D tensor of length 5. The stride of the sliding window for each @@ -581,7 +566,6 @@ public Conv3d conv3d(Operand input, Operand filter, /** * Computes the gradients of 3-D convolution with respect to the filter. * - * @param data type for {@code output} output * @param input Shape {@code [batch, depth, rows, cols, in_channels]}. * @param filterSizes An integer vector representing the tensor shape of {@code filter}, * where {@code filter} is a 5-D @@ -604,7 +588,6 @@ public Conv3dBackpropFilter conv3dBackpropFilter(Operand< /** * Computes the gradients of 3-D convolution with respect to the input. * - * @param data type for {@code output} output * @param inputSizes An integer vector representing the tensor shape of {@code input}, * where {@code input} is a 5-D * {@code [batch, depth, rows, cols, in_channels]} tensor. @@ -632,7 +615,6 @@ public Conv3dBackpropInput conv3dBackpropInput( * "A B" is returned if merge_repeated = True but "A B B B B" is * returned if merge_repeated = False. * - * @param data type for {@code log_probability} output * @param inputs 3-D, shape: {@code (max_time x batch_size x num_classes)}, the logits. * @param sequenceLength A vector containing sequence lengths, size {@code (batch)}. * @param beamWidth A scalar >= 0 (beam search beam width). @@ -658,7 +640,6 @@ public CtcBeamSearchDecoder ctcBeamSearchDecoder(Operand< * time and batch corresponds to the blank, index {@code (num_classes - 1)}, no new * element is emitted. * - * @param data type for {@code log_probability} output * @param inputs 3-D, shape: {@code (max_time x batch_size x num_classes)}, the logits. * @param sequenceLength A vector containing sequence lengths, size {@code (batch_size)}. * @param options carries optional attribute values @@ -675,7 +656,6 @@ public CtcGreedyDecoder ctcGreedyDecoder(Operand input * the gradient. This class performs the softmax operation for you, so inputs * should be e.g. linear projections of outputs by an LSTM. * - * @param data type for {@code loss} output * @param inputs 3-D, shape: {@code (max_time x batch_size x num_classes)}, the logits. * @param labelsIndices The indices of a {@code SparseTensor}. * {@code labels_indices(i, :) == [b, t]} means {@code labels_values(i)} stores the id for @@ -730,7 +710,6 @@ public CtcLoss ctcLoss(Operand inputs, Operand * reserve_space: An opaque tensor that can be used in backprop calculation. It * is only produced if is_training is true. * - * @param data type for {@code output} output * @param input The input value * @param inputH The inputH value * @param inputC The inputC value @@ -795,7 +774,6 @@ public CudnnRNN cudnnRNN(Operand input, Operand inp * params_backprop: The backprop to the params buffer in the forward pass. Has the * same shape as params. * - * @param data type for {@code input_backprop} output * @param input The input value * @param inputH The inputH value * @param inputC The inputC value @@ -852,7 +830,6 @@ public CudnnRNNBackprop cudnnRNNBackprop(Operand input * num_proj: The output dimensionality for the projection matrices. If None or 0, * no projection is performed. * - * @param data type for {@code params} output * @param numLayers The numLayers value * @param numUnits The numUnits value * @param inputSize The inputSize value @@ -900,7 +877,6 @@ public CudnnRNNCanonicalToParams cudnnRNNCanonicalToParam * num_proj: The output dimensionality for the projection matrices. If None or 0, * no projection is performed. * - * @param data type for {@code weights} output * @param numLayers The numLayers value * @param numUnits The numUnits value * @param inputSize The inputSize value @@ -941,7 +917,6 @@ public CudnnRNNParamsToCanonical cudnnRNNParamsToCanonica * CudnnRNNParamsBiases to save and restore them in a way that is compatible * across different runs. * - * @param data type for {@code params_size} output * @param numLayers The numLayers value * @param numUnits The numUnits value * @param inputSize The inputSize value @@ -962,7 +937,6 @@ public CudnnRnnParamsSize cudnnRnnPara * Returns the dimension index in the destination data format given the one in * the source data format. * - * @param data type for {@code y} output * @param x A Tensor with each element as a dimension index in source data format. * Must be in the range [-4, 4). * @param options carries optional attribute values @@ -1006,7 +980,6 @@ public DataFormatDimMap dataFormatDimMap(Operand x, * [1, 2] * * - * @param data type for {@code y} output * @param x Tensor of rank 1 or 2 in source data format. * @param options carries optional attribute values * @param data type for {@code DataFormatVecPermute} output and operands @@ -1094,7 +1067,6 @@ public DataFormatVecPermute dataFormatVecPermute(Operand< * * * - * @param data type for {@code output} output * @param input The input value * @param blockSize The size of the spatial block, same as in Space2Depth. * @param options carries optional attribute values @@ -1125,7 +1097,6 @@ public DepthToSpace depthToSpace(Operand input, Long blo *

Must have {@code strides[0] = strides[3] = 1}. For the most common case of the same * horizontal and vertices strides, {@code strides = [1, stride, stride, 1]}. * - * @param data type for {@code output} output * @param input The input value * @param filter The filter value * @param strides 1-D of length 4. The stride of the sliding window for each dimension @@ -1144,7 +1115,6 @@ public DepthwiseConv2dNative depthwiseConv2dNative(Operan /** * Computes the gradients of depthwise convolution with respect to the filter. * - * @param data type for {@code output} output * @param input 4-D with shape based on {@code data_format}. For example, if * {@code data_format} is 'NHWC' then {@code input} is a 4-D {@code [batch, in_height, in_width, in_channels]} tensor. * @param filterSizes An integer vector representing the tensor shape of {@code filter}, @@ -1170,7 +1140,6 @@ public DepthwiseConv2dNativeBackpropFilter depthwiseConv2 /** * Computes the gradients of depthwise convolution with respect to the input. * - * @param data type for {@code output} output * @param inputSizes An integer vector representing the shape of {@code input}, based * on {@code data_format}. For example, if {@code data_format} is 'NHWC' then * {@code input} is a 4-D {@code [batch, height, width, channels]} tensor. @@ -1217,7 +1186,6 @@ public DepthwiseConv2dNativeBackpropInput depthwiseConv2d *

Note on duality: The dilation of {@code input} by the {@code filter} is equal to the * negation of the erosion of {@code -input} by the reflected {@code filter}. * - * @param data type for {@code output} output * @param input 4-D with shape {@code [batch, in_height, in_width, depth]}. * @param filter 3-D with shape {@code [filter_height, filter_width, depth]}. * @param strides The stride of the sliding window for each dimension of the input @@ -1236,7 +1204,6 @@ public Dilation2d dilation2d(Operand input, Operand /** * Computes the gradient of morphological 2-D dilation with respect to the filter. * - * @param data type for {@code filter_backprop} output * @param input 4-D with shape {@code [batch, in_height, in_width, depth]}. * @param filter 3-D with shape {@code [filter_height, filter_width, depth]}. * @param outBackprop 4-D with shape {@code [batch, out_height, out_width, depth]}. @@ -1257,7 +1224,6 @@ public Dilation2dBackpropFilter dilation2dBackpropFilter( /** * Computes the gradient of morphological 2-D dilation with respect to the input. * - * @param data type for {@code in_backprop} output * @param input 4-D with shape {@code [batch, in_height, in_width, depth]}. * @param filter 3-D with shape {@code [filter_height, filter_width, depth]}. * @param outBackprop 4-D with shape {@code [batch, out_height, out_width, depth]}. @@ -1298,7 +1264,6 @@ public Dilation2dBackpropInput dilation2dBackpropInput(Op *

See Fast and Accurate Deep Network Learning by Exponential Linear Units (ELUs) * * - * @param data type for {@code activations} output * @param features The features value * @param data type for {@code Elu} output and operands * @return a new instance of Elu @@ -1310,7 +1275,6 @@ public Elu elu(Operand features) { /** * Computes gradients for the exponential linear (Elu) operation. * - * @param data type for {@code backprops} output * @param gradients The backpropagated gradients to the corresponding Elu operation. * @param outputs The outputs of the corresponding Elu operation. * @param data type for {@code EluGrad} output and operands @@ -1358,7 +1322,6 @@ public FixedUnigramCandidateSampler fixedUnigramCandidateSampler(Operand * generated, a mean operation is performed instead of a max operation in each * pooling region. * - * @param data type for {@code output} output * @param value 4-D with shape {@code [batch, height, width, channels]}. * @param poolingRatio Pooling ratio for each dimension of {@code value}, currently only * supports row and col dimension and should be >= 1.0. For example, a valid @@ -1383,7 +1346,6 @@ public FractionalAvgPool fractionalAvgPool(Operand val * just need to know the shape of original input tensor, instead of the whole * tensor. * - * @param data type for {@code output} output * @param origInputTensorShape Original input tensor shape for {@code fractional_avg_pool} * @param outBackprop 4-D with shape {@code [batch, height, width, channels]}. Gradients * w.r.t. the output of {@code fractional_avg_pool}. @@ -1431,7 +1393,6 @@ public FractionalAvgPoolGrad fractionalAvgPoolGrad( *

For more details on fractional max pooling, see this paper: * Benjamin Graham, Fractional Max-Pooling * - * @param data type for {@code output} output * @param value 4-D with shape {@code [batch, height, width, channels]}. * @param poolingRatio Pooling ratio for each dimension of {@code value}, currently only * supports row and col dimension and should be >= 1.0. For example, a valid @@ -1451,7 +1412,6 @@ public FractionalMaxPool fractionalMaxPool(Operand val /** * Computes gradient of the FractionalMaxPool function. * - * @param data type for {@code output} output * @param origInput Original input for {@code fractional_max_pool} * @param origOutput Original output for {@code fractional_max_pool} * @param outBackprop 4-D with shape {@code [batch, height, width, channels]}. Gradients @@ -1475,8 +1435,6 @@ public FractionalMaxPoolGrad fractionalMaxPoolGrad(Operan * Note that the size of 4D Tensors are defined by either "NHWC" or "NCHW". * The size of 1D Tensors matches the dimension C of the 4D Tensors. * - * @param data type for {@code y} output - * @param data type for {@code batch_mean} output * @param x A 4D Tensor for input data. * @param scale A 1D Tensor for scaling factor, to scale the normalized x. * @param offset A 1D Tensor for offset, to shift to the normalized x. @@ -1500,8 +1458,6 @@ public FusedBatchNorm fusedBatchNor * Note that the size of 4D Tensors are defined by either "NHWC" or "NCHW". * The size of 1D Tensors matches the dimension C of the 4D Tensors. * - * @param data type for {@code x_backprop} output - * @param data type for {@code scale_backprop} output * @param yBackprop A 4D Tensor for the gradient with respect to y. * @param x A 4D Tensor for input data. * @param scale A 1D Tensor for scaling factor, to scale the normalized x. @@ -1542,7 +1498,6 @@ public FusedBatchNormGrad fusedBatc * will block if multiple versions are being run in parallel. This is because this * operator is primarily an optimization to minimize memory usage. * - * @param data type for {@code output} output * @param input 4-D with shape {@code [batch, in_height, in_width, in_channels]}. * @param paddings A two-column matrix specifying the padding sizes. The number of * rows must be the same as the rank of {@code input}. @@ -1574,7 +1529,6 @@ public FusedPadConv2d fusedPadConv2d(Operand input, * will block if multiple versions are being run in parallel. This is because this * operator is primarily an optimization to minimize memory usage. * - * @param data type for {@code output} output * @param input 4-D with shape {@code [batch, in_height, in_width, in_channels]}. * @param sizeOutput A 1-D int32 Tensor of 2 elements: {@code new_height, new_width}. The * new size for the images. @@ -1637,7 +1591,6 @@ public FusedResizeAndPadConv2d fusedResizeAndPadConv2d(Op * h = (1-u) \circ c + u \circ h_prev * * - * @param data type for {@code r} output * @param x The x value * @param hPrev The hPrev value * @param wRu The wRu value @@ -1728,7 +1681,6 @@ public GRUBlockCell gRUBlockCell(Operand x, Operand * d_b_c = sum of d_c_bar along axis = 0 * * - * @param data type for {@code d_x} output * @param x The x value * @param hPrev The hPrev value * @param wRu The wRu value @@ -1778,7 +1730,6 @@ public InTopK inTopK(Operand predictions, Operand< * Specifically, {@code grad = -dy * y*y}, where {@code y = 1/x}, and {@code dy} * is the corresponding input gradient. * - * @param data type for {@code z} output * @param y The y value * @param dy The dy value * @param data type for {@code InvGrad} output and operands @@ -1791,7 +1742,6 @@ public InvGrad invGrad(Operand y, Operand dy) { /** * Solves a batch of isotonic regression problems. * - * @param data type for {@code output} output * @param input A (batch_size, dim)-tensor holding a batch of inputs. * @return a new instance of IsotonicRegression, with default output types */ @@ -1802,7 +1752,6 @@ public IsotonicRegression isotonicRegression(Operand data type for {@code output} output * @param input A (batch_size, dim)-tensor holding a batch of inputs. * @param outputDtype Dtype of output. * @param data type for {@code IsotonicRegression} output and operands @@ -1820,7 +1769,6 @@ public IsotonicRegression isotonicRegression( * output = sum(t ** 2) / 2 * * - * @param data type for {@code output} output * @param t Typically 2-D, but may have any dimensions. * @param data type for {@code L2Loss} output and operands * @return a new instance of L2Loss @@ -1854,7 +1802,6 @@ public L2Loss l2Loss(Operand t) { * h = co .* o * * - * @param data type for {@code i} output * @param x The input to the LSTM cell, shape (batch_size, num_inputs). * @param csPrev Value of the cell state at previous time step. * @param hPrev Output of the previous cell at previous time step. @@ -1877,7 +1824,6 @@ public LSTMBlockCell lSTMBlockCell(Operand x, Operand< * Computes the LSTM cell backward propagation for 1 timestep. * This implementation is to be used in conjunction of LSTMBlockCell. * - * @param data type for {@code cs_prev_grad} output * @param x The input to the LSTM cell, shape (batch_size, num_inputs). * @param csPrev The previous cell state. * @param hPrev The previous h state. @@ -1908,7 +1854,6 @@ public LSTMBlockCellGrad lSTMBlockCellGrad(Operand x, /** * Computes rectified linear: {@code max(features, features * alpha)}. * - * @param data type for {@code activations} output * @param features The features value * @param options carries optional attribute values * @param data type for {@code LeakyRelu} output and operands @@ -1960,7 +1905,6 @@ public LearnedUnigramCandidateSampler learnedUnigramCandidateSampler(OperandFor details, see Krizhevsky et al., ImageNet classification with deep * convolutional neural networks (NIPS 2012) . * - * @param data type for {@code output} output * @param input 4-D. * @param options carries optional attribute values * @param data type for {@code LRN} output and operands @@ -1974,7 +1918,6 @@ public LocalResponseNormalization localResponseNormalizat /** * Gradients for Local Response Normalization. * - * @param data type for {@code output} output * @param inputGrads 4-D with shape {@code [batch, height, width, channels]}. * @param inputImage 4-D with shape {@code [batch, height, width, channels]}. * @param outputImage 4-D with shape {@code [batch, height, width, channels]}. @@ -1995,7 +1938,6 @@ public LocalResponseNormalizationGrad localResponseNormal * logsoftmax[i, j] = logits[i, j] - log(sum(exp(logits[i]))) * * - * @param data type for {@code logsoftmax} output * @param logits 2-D with shape {@code [batch_size, num_classes]}. * @param data type for {@code LogSoftmax} output and operands * @return a new instance of LogSoftmax @@ -2007,7 +1949,6 @@ public LogSoftmax logSoftmax(Operand logits) { /** * Performs max pooling on the input. * - * @param data type for {@code output} output * @param input 4-D input to pool over. * @param ksize The size of the window for each dimension of the input tensor. * @param strides The stride of the sliding window for each dimension of the @@ -2025,7 +1966,6 @@ public MaxPool maxPool(Operand input, Operand /** * Performs 3D max pooling on the input. * - * @param data type for {@code output} output * @param input Shape {@code [batch, depth, rows, cols, channels]} tensor to pool over. * @param ksize 1-D tensor of length 5. The size of the window for each dimension of * the input tensor. Must have {@code ksize[0] = ksize[4] = 1}. @@ -2044,7 +1984,6 @@ public MaxPool3d maxPool3d(Operand input, List k /** * Computes gradients of 3D max pooling function. * - * @param data type for {@code output} output * @param origInput The original input tensor. * @param origOutput The original output tensor. * @param grad Output backprop of shape {@code [batch, depth, rows, cols, channels]}. @@ -2067,7 +2006,6 @@ public MaxPool3dGrad maxPool3dGrad(Ope /** * Computes second-order gradients of the maxpooling function. * - * @param data type for {@code output} output * @param origInput The original input tensor. * @param origOutput The original output tensor. * @param grad Output backprop of shape {@code [batch, depth, rows, cols, channels]}. @@ -2089,7 +2027,6 @@ public MaxPool3dGradGrad maxPool3dGradGrad(Operand ori /** * Computes gradients of the maxpooling function. * - * @param data type for {@code output} output * @param origInput The original input tensor. * @param origOutput The original output tensor. * @param grad 4-D. Gradients w.r.t. the output of {@code max_pool}. @@ -2110,7 +2047,6 @@ public MaxPoolGrad maxPoolGrad(Operand origInput, Oper /** * Computes second-order gradients of the maxpooling function. * - * @param data type for {@code output} output * @param origInput The original input tensor. * @param origOutput The original output tensor. * @param grad 4-D. Gradients of gradients w.r.t. the input of {@code max_pool}. @@ -2131,7 +2067,6 @@ public MaxPoolGradGrad maxPoolGradGrad(Operand origInp /** * Computes second-order gradients of the maxpooling function. * - * @param data type for {@code output} output * @param input The original input. * @param grad 4-D with shape {@code [batch, height, width, channels]}. Gradients w.r.t. the * input of {@code max_pool}. @@ -2153,7 +2088,6 @@ public MaxPoolGradGradWithArgmax maxPoolGradGradWithArgma /** * Computes gradients of the maxpooling function. * - * @param data type for {@code output} output * @param input The original input. * @param grad 4-D with shape {@code [batch, height, width, channels]}. Gradients w.r.t. the * output of {@code max_pool}. @@ -2183,8 +2117,6 @@ public MaxPoolGradWithArgmax maxPoolGradWithArgmax(Operan * (either negative or too large). This is a bug, but fixing it is difficult to do * in a safe backwards compatible way, especially due to flattening. * - * @param data type for {@code output} output - * @param data type for {@code argmax} output * @param input 4-D with shape {@code [batch, height, width, channels]}. Input to pool over. * @param ksize The size of the window for each dimension of the input tensor. * @param strides The stride of the sliding window for each dimension of the @@ -2210,8 +2142,6 @@ public MaxPoolWithArgmax maxPoolWithArgmax(Operan * (either negative or too large). This is a bug, but fixing it is difficult to do * in a safe backwards compatible way, especially due to flattening. * - * @param data type for {@code output} output - * @param data type for {@code argmax} output * @param input 4-D with shape {@code [batch, height, width, channels]}. Input to pool over. * @param ksize The size of the window for each dimension of the input tensor. * @param strides The stride of the sliding window for each dimension of the @@ -2239,7 +2169,6 @@ public MaxPoolWithArgmax maxPoolWit * values.shape = input.shape[:-1] * * - * @param data type for {@code values} output * @param input 1-D or higher with last dimension at least {@code n+1}. * @param n 0-D. Position of sorted vector to select along the last dimension (along * each row for matrices). Valid range of n is {@code [0, input.shape[:-1])} @@ -2255,7 +2184,6 @@ public NthElement nthElement(Operand input, Operand data type for {@code output} output * @param input 4-D with shape {@code [batch, height, width, channels]}. * @param minInput The float value that the lowest quantized input value represents. * @param maxInput The float value that the highest quantized input value represents. @@ -2278,7 +2206,6 @@ public QuantizedAvgPool quantizedAvgPool(Operand input * This op is deprecated and will be removed in the future. Prefer * {@code tf.nn.batch_normalization}. * - * @param data type for {@code result} output * @param t A 4D input Tensor. * @param tMin The value represented by the lowest quantized input. * @param tMax The value represented by the highest quantized input. @@ -2322,7 +2249,6 @@ public QuantizedBatchNormWithGlobalNormal * Adds Tensor 'bias' to Tensor 'input' for Quantized types. * Broadcasts the values of bias on dimensions 0..N-2 of 'input'. * - * @param data type for {@code output} output * @param input The input value * @param bias A 1D bias Tensor with size matching the last dimension of 'input'. * @param minInput The float value that the lowest quantized input value represents. @@ -2342,7 +2268,6 @@ public QuantizedBiasAdd quantizedBiasAdd(Operand data type for {@code output} output * @param input The input value * @param filter The filter value * @param minInput The minInput value @@ -2367,7 +2292,6 @@ public QuantizedConv2DAndRelu quantizedConv2DAndRelu( /** * The QuantizedConv2DAndReluAndRequantize operation * - * @param data type for {@code output} output * @param input The input value * @param filter The filter value * @param minInput The minInput value @@ -2395,7 +2319,6 @@ public QuantizedConv2DAndReluAndRequantize quantizedConv2 /** * The QuantizedConv2DAndRequantize operation * - * @param data type for {@code output} output * @param input The input value * @param filter The filter value * @param minInput The minInput value @@ -2423,7 +2346,6 @@ public QuantizedConv2DAndRequantize quantizedConv2DAndReq /** * Computes QuantizedConv2D per channel. * - * @param data type for {@code output} output * @param input The original input tensor. * @param filter The original filter tensor. * @param minInput The minimum value of the input tensor @@ -2448,7 +2370,6 @@ public QuantizedConv2DPerChannel quantizedConv2DPerChanne /** * The QuantizedConv2DWithBias operation * - * @param data type for {@code output} output * @param input The input value * @param filter The filter value * @param bias The bias value @@ -2474,7 +2395,6 @@ public QuantizedConv2DWithBias quantizedConv2DWithBias( /** * The QuantizedConv2DWithBiasAndRelu operation * - * @param data type for {@code output} output * @param input The input value * @param filter The filter value * @param bias The bias value @@ -2500,7 +2420,6 @@ public QuantizedConv2DWithBiasAndRelu quantizedConv2DWith /** * The QuantizedConv2DWithBiasAndReluAndRequantize operation * - * @param data type for {@code output} output * @param input The input value * @param filter The filter value * @param bias The bias value @@ -2529,7 +2448,6 @@ public QuantizedConv2DWithBiasAndReluAndRequantize quanti /** * The QuantizedConv2DWithBiasAndRequantize operation * - * @param data type for {@code output} output * @param input The input value * @param filter The filter value * @param bias The bias value @@ -2558,7 +2476,6 @@ public QuantizedConv2DWithBiasAndRequantize quantizedConv /** * The QuantizedConv2DWithBiasSignedSumAndReluAndRequantize operation * - * @param data type for {@code output} output * @param input The input value * @param filter The filter value * @param bias The bias value @@ -2592,7 +2509,6 @@ public QuantizedConv2DWithBiasSignedSumAndReluAndRequantize< /** * The QuantizedConv2DWithBiasSumAndRelu operation * - * @param data type for {@code output} output * @param input The input value * @param filter The filter value * @param bias The bias value @@ -2619,7 +2535,6 @@ public QuantizedConv2DWithBiasSumAndRelu quantizedConv2DW /** * The QuantizedConv2DWithBiasSumAndReluAndRequantize operation * - * @param data type for {@code output} output * @param input The input value * @param filter The filter value * @param bias The bias value @@ -2657,7 +2572,6 @@ public QuantizedConv2DWithBiasSumAndReluAndRequantize qua * This means that you can only interpret the quantized output in the same way, by * taking the returned minimum and maximum values into account. * - * @param data type for {@code output} output * @param input The input value * @param filter filter's input_depth dimension must match input's depth dimensions. * @param minInput The float value that the lowest quantized input value represents. @@ -2682,7 +2596,6 @@ public QuantizedConv2d quantizedConv2d(Operand data type for {@code output} output * @param input The original input tensor. * @param filter The original filter tensor. * @param minInput The float value that the minimum quantized input value represents. @@ -2707,7 +2620,6 @@ public QuantizedDepthwiseConv2D quantizedDepthwiseConv2D( /** * Computes quantized depthwise Conv2D with Bias. * - * @param data type for {@code output} output * @param input The original input tensor. * @param filter The original filter tensor. * @param bias The original bias tensor. @@ -2733,7 +2645,6 @@ public QuantizedDepthwiseConv2DWithBias quantizedDepthwis /** * Computes quantized depthwise Conv2D with Bias and Relu. * - * @param data type for {@code output} output * @param input The original input tensor. * @param filter The original filter tensor. * @param bias The original bias tensor. @@ -2759,7 +2670,6 @@ public QuantizedDepthwiseConv2DWithBiasAndRelu quantizedD /** * Computes quantized depthwise Conv2D with Bias, Relu and Requantize. * - * @param data type for {@code output} output * @param input The original input tensor. * @param filter The original filter tensor. * @param bias The original bias tensor. @@ -2788,7 +2698,6 @@ public QuantizedDepthwiseConv2DWithBiasAndReluAndRequantize< /** * Quantized Instance normalization. * - * @param data type for {@code y} output * @param x A 4D input Tensor. * @param xMin The value represented by the lowest quantized input. * @param xMax The value represented by the highest quantized input. @@ -2804,7 +2713,6 @@ public QuantizedInstanceNorm quantizedInstanceNorm(Operan /** * Produces the max pool of the input tensor for quantized types. * - * @param data type for {@code output} output * @param input The 4D (batch x rows x cols x depth) Tensor to MaxReduce over. * @param minInput The float value that the lowest quantized input value represents. * @param maxInput The float value that the highest quantized input value represents. @@ -2825,7 +2733,6 @@ public QuantizedMaxPool quantizedMaxPool(Operand input /** * Computes Quantized Rectified Linear: {@code max(features, 0)} * - * @param data type for {@code activations} output * @param features The features value * @param minFeatures The float value that the lowest quantized value represents. * @param maxFeatures The float value that the highest quantized value represents. @@ -2841,7 +2748,6 @@ public QuantizedRelu quantizedRelu(Operand data type for {@code activations} output * @param features The features value * @param minFeatures The float value that the lowest quantized value represents. * @param maxFeatures The float value that the highest quantized value represents. @@ -2857,7 +2763,6 @@ public QuantizedRelu6 quantizedRelu6(Operand data type for {@code activations} output * @param features The features value * @param maxValue The maxValue value * @param minFeatures The float value that the lowest quantized value represents. @@ -2885,7 +2790,6 @@ public QuantizedReluX quantizedReluX(Operand * * - * @param data type for {@code activations} output * @param features The features value * @param data type for {@code Relu} output and operands * @return a new instance of Relu @@ -2897,7 +2801,6 @@ public Relu relu(Operand features) { /** * Computes rectified linear 6: {@code min(max(features, 0), 6)}. * - * @param data type for {@code activations} output * @param features The features value * @param data type for {@code Relu6} output and operands * @return a new instance of Relu6 @@ -2909,7 +2812,6 @@ public Relu6 relu6(Operand features) { /** * Computes rectified linear 6 gradients for a Relu6 operation. * - * @param data type for {@code backprops} output * @param gradients The backpropagated gradients to the corresponding Relu6 operation. * @param features The features passed as input to the corresponding Relu6 operation, or * its output; using either one produces the same result. @@ -2923,7 +2825,6 @@ public Relu6Grad relu6Grad(Operand gradients, Operand< /** * Computes rectified linear gradients for a Relu operation. * - * @param data type for {@code backprops} output * @param gradients The backpropagated gradients to the corresponding Relu operation. * @param features The features passed as input to the corresponding Relu operation, OR * the outputs of that operation (both work equivalently). @@ -2942,7 +2843,6 @@ public ReluGrad reluGrad(Operand gradients, Operand * For correct dropout, use {@code tf.contrib.nn.alpha_dropout}. *

See Self-Normalizing Neural Networks * - * @param data type for {@code activations} output * @param features The features value * @param data type for {@code Selu} output and operands * @return a new instance of Selu @@ -2954,7 +2854,6 @@ public Selu selu(Operand features) { /** * Computes gradients for the scaled exponential linear (Selu) operation. * - * @param data type for {@code backprops} output * @param gradients The backpropagated gradients to the corresponding Selu operation. * @param outputs The outputs of the corresponding Selu operation. * @param data type for {@code SeluGrad} output and operands @@ -2971,7 +2870,6 @@ public SeluGrad seluGrad(Operand gradients, Operand * $$softmax[i, j] = exp(logits[i, j]) / sum_j(exp(logits[i, j]))$$ * * - * @param data type for {@code softmax} output * @param logits 2-D with shape {@code [batch_size, num_classes]}. * @param data type for {@code Softmax} output and operands * @return a new instance of Softmax @@ -2984,7 +2882,6 @@ public Softmax softmax(Operand logits) { * Computes softmax cross entropy cost and gradients to backpropagate. * Inputs are the logits, not probabilities. * - * @param data type for {@code loss} output * @param features batch_size x num_classes matrix * @param labels batch_size x num_classes matrix * The caller must ensure that each batch of labels represents a valid @@ -3000,7 +2897,6 @@ public SoftmaxCrossEntropyWithLogits softmaxCrossEntropyW /** * Computes softsign: {@code features / (abs(features) + 1)}. * - * @param data type for {@code activations} output * @param features The features value * @param data type for {@code Softsign} output and operands * @return a new instance of Softsign @@ -3012,7 +2908,6 @@ public Softsign softsign(Operand features) { /** * Computes softsign gradients for a softsign operation. * - * @param data type for {@code backprops} output * @param gradients The backpropagated gradients to the corresponding softsign operation. * @param features The features passed as input to the corresponding softsign operation. * @param data type for {@code SoftsignGrad} output and operands @@ -3090,7 +2985,6 @@ public SoftsignGrad softsignGrad(Operand gradients, *

Among others, this operation is useful for reducing atrous convolution into * regular convolution. * - * @param data type for {@code output} output * @param input 4-D with shape {@code [batch, height, width, depth]}. * @param paddings 2-D tensor of non-negative integers with shape {@code [2, 2]}. It specifies * the padding of the input with zeros across the spatial dimensions as follows: @@ -3182,7 +3076,6 @@ public SpaceToBatch spaceToBatch(Operand input, * [13, 14, 15, 16]]]] * * - * @param data type for {@code output} output * @param input The input value * @param blockSize The size of the spatial block. * @param options carries optional attribute values @@ -3202,7 +3095,6 @@ public SpaceToDepth spaceToDepth(Operand input, Long blo * given row. *

Inputs are the logits, not probabilities. * - * @param data type for {@code loss} output * @param features batch_size x num_classes matrix * @param labels batch_size vector with values in [0, num_classes). * This is the label for the given minibatch entry. @@ -3226,8 +3118,6 @@ public SparseSoftmaxCrossEntropyWithLogits sparseSoftmaxC * *

If two elements are equal, the lower-index element appears first. * - * @param data type for {@code values} output - * @param data type for {@code indices} output * @param input 1-D or higher with last dimension at least {@code k}. * @param k 0-D. Number of top elements to look for along the last dimension (along each * row for matrices). @@ -3252,8 +3142,6 @@ public TopK topK(Operand input, Operand *

If two elements are equal, the lower-index element appears first. * - * @param data type for {@code values} output - * @param data type for {@code indices} output * @param input 1-D or higher with last dimension at least {@code k}. * @param k 0-D. Number of top elements to look for along the last dimension (along each * row for matrices). @@ -3287,7 +3175,6 @@ public TopK topK(Operand input, *

{@code output} is also quantized, using the same formula. * If {@code rhs} is per-tensor quantized, {@code output} must be also per-tensor quantized. * - * @param data type for {@code output} output * @param lhs Must be a quantized tensor, rank >= 3. * @param rhs Must be a quantized tensor, same rank as {@code lhs}. * @param lhsScales The float value(s) used as scale factors when quantizing the original data that {@code lhs} represents. @@ -3358,7 +3245,6 @@ public UniformQuantizedConvolution uni *

{@code rhs} must be quantized Tensor, where its data value is quantized using the formula: * quantized_data = clip(original_data / scale + zero_point, quantization_min_val, quantization_max_val). * - * @param data type for {@code output} output * @param lhs Must be a non-quantized Tensor of {@code Tlhs}, rank >= 3. * @param rhs Must be a quantized Tensor of {@code Trhs}, same rank as {@code lhs}. * @param rhsScales The float value(s) used as scale factors when quantizing the original data that {@code rhs} represents. diff --git a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/Ops.java b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/Ops.java index 93a6a3eb05c..8483a4efb61 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/Ops.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/Ops.java @@ -77,6 +77,7 @@ import org.tensorflow.op.core.BroadcastTo; import org.tensorflow.op.core.Bucketize; import org.tensorflow.op.core.Case; +import org.tensorflow.op.core.CheckPinned; import org.tensorflow.op.core.ClipByValue; import org.tensorflow.op.core.CompositeTensorVariantFromComponents; import org.tensorflow.op.core.CompositeTensorVariantToComponents; @@ -407,10 +408,10 @@ public final class Ops { public final CollectiveOps collective; - public final AudioOps audio; - public final DistributeOps distribute; + public final AudioOps audio; + public final SignalOps signal; public final TrainOps train; @@ -419,10 +420,10 @@ public final class Ops { public final SummaryOps summary; - public final ImageOps image; - public final RaggedOps ragged; + public final ImageOps image; + public final ShapeOps shape; public final IoOps io; @@ -450,14 +451,14 @@ public final class Ops { bitwise = new BitwiseOps(this); debugging = new DebuggingOps(this); collective = new CollectiveOps(this); - audio = new AudioOps(this); distribute = new DistributeOps(this); + audio = new AudioOps(this); signal = new SignalOps(this); train = new TrainOps(this); quantization = new QuantizationOps(this); summary = new SummaryOps(this); - image = new ImageOps(this); ragged = new RaggedOps(this); + image = new ImageOps(this); shape = new ShapeOps(this); io = new IoOps(this); dtypes = new DtypesOps(this); @@ -618,7 +619,6 @@ public Any any(Operand input, Operand axis, Any.Option * See https://arxiv.org/abs/2206.14286 for the algorithm details. * This op is only optimized on TPU currently. * - * @param data type for {@code values} output * @param input Array to search. Must be at least 1-D of the floating type * @param k Specifies the number of min/max-k. * @param options carries optional attribute values @@ -732,7 +732,6 @@ public AssertThat assertThat(Operand condition, Iterable> data * This operation outputs "ref" after the assignment is done. * This makes it easier to chain operations that need to use the reset value. * - * @param data type for {@code output_ref} output * @param ref Should be from a {@code Variable} node. May be uninitialized. * @param value The value to be assigned to the variable. * @param options carries optional attribute values @@ -749,7 +748,6 @@ public Assign assign(Operand ref, Operand value, * This operation outputs "ref" after the update is done. * This makes it easier to chain operations that need to use the reset value. * - * @param data type for {@code output_ref} output * @param ref Should be from a {@code Variable} node. * @param value The value to be added to the variable. * @param options carries optional attribute values @@ -780,7 +778,6 @@ public AssignAddVariableOp assignAddVariableOp(Operand resource * This operation outputs "ref" after the update is done. * This makes it easier to chain operations that need to use the reset value. * - * @param data type for {@code output_ref} output * @param ref Should be from a {@code Variable} node. * @param value The value to be subtracted to the variable. * @param options carries optional attribute values @@ -1027,7 +1024,6 @@ public BatchFunction batchFunction(Iterable> inTensors, * dimension are moved in spatial blocks to the {@code height} and {@code width} dimensions, * followed by cropping along the {@code height} and {@code width} dimensions. * - * @param data type for {@code output} output * @param input 4-D tensor with shape * {@code [batch*block_size*block_size, height_pad/block_size, width_pad/block_size, depth]}. Note that the batch size of the input tensor must be divisible by * {@code block_size * block_size}. @@ -1055,7 +1051,6 @@ public BatchToSpace batchToSpace(Operand input, * optionally cropped according to {@code crops} to produce the output. This is the * reverse of SpaceToBatch. See below for a precise description. * - * @param data type for {@code output} output * @param input N-D with shape {@code input_shape = [batch] + spatial_shape + remaining_shape}, * where spatial_shape has M dimensions. * @param blockShape 1-D with shape {@code [M]}, all values must be >= 1. @@ -1221,7 +1216,6 @@ public BatchToSpaceNd batchToSpaceNd(Operand input, * buffer is made on BE machines when types are of different sizes in order to get * the same casting results as on LE machines. * - * @param data type for {@code output} output * @param input The input value * @param type The value of the type attribute * @param data type for {@code Bitcast} output and operands @@ -1292,7 +1286,6 @@ public Operand booleanMaskUpdate(Operand tensor, Operand * Given {@code s0} and {@code s1}, tensors that represent shapes, compute {@code r0}, the * broadcasted shape. {@code s0}, {@code s1} and {@code r0} are all integer vectors. * - * @param data type for {@code r0} output * @param s0 The s0 value * @param s1 The s1 value * @param data type for {@code BroadcastArgs} output and operands @@ -1307,7 +1300,6 @@ public BroadcastDynamicShape broadcastDynamicShape(Operan * Return the reduction indices for computing gradients of s0 op s1 with broadcast. * This is typically used by gradient computations for a broadcasting operation. * - * @param data type for {@code r0} output * @param s0 The s0 value * @param s1 The s1 value * @param data type for {@code BroadcastGradientArgs} output and operands @@ -1357,7 +1349,6 @@ public BroadcastGradientArgs broadcastGradientArgs(Operan * shape. (In a graph context, {@code broadcast_to} might be fused to * subsequent operation and then be optimized away, however.) * - * @param data type for {@code output} output * @param input A Tensor to broadcast. * @param shape An 1-D {@code int} Tensor. The shape of the desired output. * @param data type for {@code BroadcastTo} output and operands @@ -1451,6 +1442,22 @@ public Case caseOp(Operand branchIndex, Iterable> input, return Case.create(scope, branchIndex, input, Tout, branches, options); } + /** + * Checks whether a tensor is located in host memory pinned for GPU. + * When run: + *

    + *
  • Reports an {@code InvalidArgument} error if {@code tensor} is not in pinned memory.
  • + *
  • Reports a {@code FailedPrecondition} error if not built with CUDA.
  • + *
+ * + * @param tensor The tensor value + * @param data type for {@code CheckPinned} output and operands + * @return a new instance of CheckPinned + */ + public CheckPinned checkPinned(Operand tensor) { + return CheckPinned.create(scope, tensor); + } + /** * Clips tensor values to a specified min and max. * Given a tensor {@code t}, this operation returns a tensor of the same type and @@ -1458,7 +1465,6 @@ public Case caseOp(Operand branchIndex, Iterable> input, * Any values less than {@code clip_value_min} are set to {@code clip_value_min}. Any values * greater than {@code clip_value_max} are set to {@code clip_value_max}. * - * @param data type for {@code output} output * @param t A {@code Tensor}. * @param clipValueMin A 0-D (scalar) {@code Tensor}, or a {@code Tensor} with the same shape * as {@code t}. The minimum value to clip by. @@ -1508,7 +1514,6 @@ public CompositeTensorVariantToComponents compositeTensorVariantToComponents( /** * Concatenates tensors along one dimension. * - * @param data type for {@code output} output * @param values List of {@code N} Tensors to concatenate. Their ranks and types must match, * and their sizes must match in all dimensions except {@code concat_dim}. * @param axis 0-D. The dimension along which to concatenate. Must be in the @@ -1531,14 +1536,13 @@ public Concat concat(Iterable> values, * y = [2, 3, 7] * z = [2, 9, 7] * offsets = concat_offset(1, [x, y, z]) - * [list(off.numpy()) for off in offsets] + * [[a.item() for a in list(off.numpy())] for off in offsets] * [[0, 0, 0], [0, 2, 0], [0, 5, 0]] * * * *

This is typically used by gradient computations for a concat operation. * - * @param data type for {@code offset} output * @param concatDim The dimension along which to concatenate. * @param shape The {@code N} int32 or int64 vectors representing shape of tensors being concatenated. * @param data type for {@code ConcatOffset} output and operands @@ -2262,11 +2266,7 @@ public Constant constant(Class type, Shape shape, ByteDa /** * Create a constant by making an immutable copy of {@code tensor}. {@code tensor} may be closed - * afterwards without issue. - * - *

Note: this endpoint cannot be simply called {@code constant} since it will conflict with - * other endpoints accepting an NdArray in parameter {e.g. {@link #tensorOf(Scope, - * FloatNdArray)}}. + * afterward without issue. * * @param tensor a Tensor holding the constant value * @return a constant of the same data type as `tensor` @@ -2318,7 +2318,6 @@ public ControlTrigger controlTrigger() { /** * The CopyToMesh operation * - * @param data type for {@code output} output * @param input The input value * @param mesh The value of the mesh attribute * @param data type for {@code CopyToMesh} output and operands @@ -2331,7 +2330,6 @@ public CopyToMesh copyToMesh(Operand input, String mesh) /** * The CopyToMeshGrad operation * - * @param data type for {@code output} output * @param input The input value * @param forwardInput The forwardInput value * @param data type for {@code CopyToMeshGrad} output and operands @@ -2345,7 +2343,6 @@ public CopyToMeshGrad copyToMeshGrad(Operand input, /** * Increments 'ref' until it reaches 'limit'. * - * @param data type for {@code output} output * @param ref Should be from a scalar {@code Variable} node. * @param limit If incrementing ref would bring it above limit, instead generates an * 'OutOfRange' error. @@ -2440,7 +2437,6 @@ public DecodeProto decodeProto(Operand bytes, String messageType, /** * Makes a copy of {@code x}. * - * @param data type for {@code y} output * @param x The source tensor of type {@code T}. * @param data type for {@code DeepCopy} output and operands * @return a new instance of DeepCopy @@ -2482,7 +2478,6 @@ public DestroyResourceOp destroyResourceOp(Operand resource, * using control dependencies. *

Outputs the final value of the tensor pointed to by 'ref'. * - * @param data type for {@code value} output * @param ref A reference to the temporary variable tensor. * @param varName Name of the temporary variable, usually the name of the matching * 'TemporaryVariable' op. @@ -2560,7 +2555,6 @@ public DummyMemoryCache dummyMemoryCache() { * * * - * @param data type for {@code outputs} output * @param data The data value * @param partitions Any shape. Indices in the range {@code [0, num_partitions)}. * @param numPartitions The number of partitions to output. @@ -2628,7 +2622,6 @@ public DynamicPartition dynamicPartition(Operand data, * * * - * @param data type for {@code merged} output * @param indices The indices value * @param data The data value * @param data type for {@code DynamicStitch} output and operands @@ -2672,7 +2665,6 @@ public EditDistance editDistance(Operand hypothesisInd * Creates a tensor with the given shape. *

This operation creates a tensor of {@code shape} and {@code dtype}. * - * @param data type for {@code output} output * @param shape 1-D. Represents the shape of the output tensor. * @param dtype The value of the dtype attribute * @param options carries optional attribute values @@ -2778,7 +2770,6 @@ public EncodeProto encodeProto(Operand sizes, Iterable> value * Raises an error if the input tensor's shape does not match the specified shape. * Returns the input tensor otherwise. * - * @param data type for {@code output} output * @param input A tensor, whose shape is to be validated. * @param shape The expected (possibly partially specified) shape of the input tensor. * @param data type for {@code EnsureShape} output and operands @@ -2796,7 +2787,6 @@ public EnsureShape ensureShape(Operand input, Shape shap * it may be changed in the child frame. At most {@code parallel_iterations} iterations * are run in parallel in the child frame. * - * @param data type for {@code output} output * @param data The tensor to be made available to the child frame. * @param frameName The name of the child frame. * @param options carries optional attribute values @@ -2812,7 +2802,6 @@ public Enter enter(Operand data, String frameName, * Exits the current frame to its parent frame. * Exit makes its input {@code data} available to the parent frame. * - * @param data type for {@code output} output * @param data The tensor to be made available to the parent frame. * @param data type for {@code Exit} output and operands * @return a new instance of Exit @@ -2847,7 +2836,6 @@ public Exit exit(Operand data) { *

This operation is related to {@code squeeze()}, which removes dimensions of * size 1. * - * @param data type for {@code output} output * @param input The input value * @param axis 0-D (scalar). Specifies the dimension index at which to * expand the shape of {@code input}. Must be in the range @@ -2863,7 +2851,6 @@ public ExpandDims expandDims(Operand input, /** * Extract {@code patches} from {@code input} and put them in the {@code "depth"} output dimension. 3D extension of {@code extract_image_patches}. * - * @param data type for {@code patches} output * @param input 5-D Tensor with shape {@code [batch, in_planes, in_rows, in_cols, depth]}. * @param ksizes The size of the sliding window for each dimension of {@code input}. * @param strides 1-D of length 5. How far the centers of two consecutive patches are in @@ -2888,7 +2875,6 @@ public ExtractVolumePatches extractVolumePatches(Operand< * function input) or guaranteed not to be used (e.g. if mirroring an * intermediate output needed for the gradient computation of the other branch). * - * @param data type for {@code output} output * @param dtype The type of the output. * @param shape

    *  The purported shape of the output. This is only used for shape inference;
@@ -2934,7 +2920,6 @@ public FileSystemSetConfiguration fileSystemSetConfiguration(Operand sc
    *  based on other runtime Tensors, unlike {@code tf.constant}.
    *  
    *
-   * @param  data type for {@code output} output
    * @param dims 1-D. Represents the shape of the output tensor.
    * @param value 0-D (scalar). Value to fill the returned tensor.
    *  

{@literal @}compatibility(numpy)
@@ -3028,9 +3013,11 @@ public For forOp(Operand start, Operand limit, Operand d *

Note that on CPU, if an out of bound index is found, an error is returned. * On GPU, if an out of bound index is found, a 0 is stored in the * corresponding output value. + *

Note that on TPU, if any dimension of {@code params} is of size 0 then the output will + * be the expected shape filled with zeros. On CPU and GPU an error will be + * returned. *

See also {@code tf.batch_gather} and {@code tf.gather_nd}. * - * @param data type for {@code output} output * @param params The tensor from which to gather values. Must be at least rank * {@code axis + 1}. * @param indices Index tensor. Must be in range {@code [0, params.shape[axis])}. @@ -3068,9 +3055,17 @@ public Gather gather(Operand params, Operand * indices.shape[:-1] + params.shape[indices.shape[-1]:] *

- *

Note that on CPU, if an out of bound index is found, an error is returned. - * On GPU, if an out of bound index is found, a 0 is stored in the - * corresponding output value. + *

If {@code indices} contains any out-of-bound indices, depending on + * {@code bad_indices_policy}, the op will either return an error or ignore the + * out-of-bound indices. {@code bad_indices_policy} can be one of the following values: + *

    + *
  1. "" or "DEFAULT": raises on CPU and ignore on GPU. This is because + * historically on CPU and GPU we handle errors in different ways, and for + * backward compatibility we keep the default behavior.
  2. + *
  3. "ERROR": raises error; GPU does not support this value.
  4. + *
  5. "IGNORE": ignore error and set the corresponding output to 0; + * supported on both CPU and GPU.
  6. + *
*

Some examples below. *

Simple indexing into a matrix: *

@@ -3137,15 +3132,15 @@ public  Gather gather(Operand params, Operand
    *  

See also {@code tf.gather} and {@code tf.batch_gather}. * - * @param data type for {@code output} output * @param params The tensor from which to gather values. * @param indices Index tensor. + * @param options carries optional attribute values * @param data type for {@code GatherNd} output and operands * @return a new instance of GatherNd */ public GatherNd gatherNd(Operand params, - Operand indices) { - return GatherNd.create(scope, params, indices); + Operand indices, GatherNd.Options... options) { + return GatherNd.create(scope, params, indices, options); } /** @@ -3185,7 +3180,6 @@ public GetSessionHandle getSessionHandle(Operand value) { /** * Get the value of the tensor specified by its handle. * - * @param data type for {@code value} output * @param handle The handle for a tensor stored in the session state. * @param dtype The type of the output value. * @param data type for {@code GetSessionTensor} output and operands @@ -3250,7 +3244,6 @@ public Gradients gradients(Iterable> y, IterableReturns the input tensor without modification. * - * @param data type for {@code output} output * @param input The input value * @param data type for {@code GuaranteeConst} output and operands * @return a new instance of GuaranteeConst @@ -3294,7 +3287,6 @@ public HashTable hashTable(Class keyDtype, * sess.run(hist) => [2, 1, 1, 0, 2] *

* - * @param data type for {@code out} output * @param values Numeric {@code Tensor}. * @param valueRange Shape [2] {@code Tensor} of same {@code dtype} as {@code values}. * values <= value_range[0] will be mapped to hist[0], @@ -3325,7 +3317,6 @@ public HistogramFixedWidth histogramFixedWidth(Opera * sess.run(hist) => [2, 1, 1, 0, 2] * * - * @param data type for {@code out} output * @param values Numeric {@code Tensor}. * @param valueRange Shape [2] {@code Tensor} of same {@code dtype} as {@code values}. * values <= value_range[0] will be mapped to hist[0], @@ -3344,7 +3335,6 @@ public HistogramFixedWidth histogramFi /** * Returns a constant tensor on the host. Only for writing C++ tests. * - * @param data type for {@code output} output * @param value Attr {@code value} is the tensor to return. * @param dtype The value of the dtype attribute * @param data type for {@code HostConst} output and operands @@ -3357,7 +3347,6 @@ public HostConst hostConst(Tensor value, Class dtype) { /** * Return a tensor with the same shape and contents as the input tensor or value. * - * @param data type for {@code output} output * @param input The input value * @param data type for {@code Identity} output and operands * @return a new instance of Identity @@ -3425,7 +3414,6 @@ public If ifOp(Operand cond, Iterable> input, * Returns immutable tensor from memory region. * The current implementation memmaps the tensor from a file. * - * @param data type for {@code tensor} output * @param dtype Type of the returned tensor. * @param shape Shape of the returned tensor. * @param memoryRegionName Name of readonly memory region used by the tensor, see @@ -3485,7 +3473,6 @@ public InitializeTableFromTextFile initializeTableFromTextFile( * Computes y = x; y[i, :] += v; return y. * * - * @param data type for {@code y} output * @param x A {@code Tensor} of type T. * @param i A vector. Indices into the left-most dimension of {@code x}. * @param v A {@code Tensor} of type T. Same dimension sizes as x except the first dimension, which must be the same as i's size. @@ -3503,7 +3490,6 @@ public InplaceAdd inplaceAdd(Operand x, Operand * Computes y = x; y[i, :] -= v; return y. * * - * @param data type for {@code y} output * @param x A {@code Tensor} of type T. * @param i A vector. Indices into the left-most dimension of {@code x}. * @param v A {@code Tensor} of type T. Same dimension sizes as x except the first dimension, which must be the same as i's size. @@ -3520,7 +3506,6 @@ public InplaceSub inplaceSub(Operand x, Operand *

Originally this function is mutative however for compilation we make this * operation create / operate on a copy of {@code x}. * - * @param data type for {@code y} output * @param x A tensor of type {@code T}. * @param i A vector. Indices into the left-most dimension of {@code x}. * @param v A {@code Tensor} of type T. Same dimension sizes as x except the first dimension, which must be the same as i's size. @@ -3578,7 +3563,6 @@ public KthOrderStatistic kthOrderStatistic(Operand input, Long k) { * tf.linspace(10.0, 12.0, 3, name="linspace") => [ 10.0 11.0 12.0] * * - * @param data type for {@code output} output * @param start 0-D tensor. First entry in the range. * @param stop 0-D tensor. Last entry in the range. * @param num 0-D tensor. Number of values to generate. @@ -3593,8 +3577,6 @@ public LinSpace linSpace(Operand start, Operand sto /** * Outputs all keys and values in the table. * - * @param data type for {@code keys} output - * @param data type for {@code values} output * @param tableHandle Handle to the table. * @param Tkeys The value of the Tkeys attribute * @param Tvalues The value of the Tvalues attribute @@ -3614,7 +3596,6 @@ public LookupTableExport lookupTableExp *

The scalar {@code default_value} is the value output for keys not present in the * table. It must also be of the same type as the table values. * - * @param data type for {@code values} output * @param tableHandle Handle to the table. * @param keys Any shape. Keys to look up. * @param defaultValue The defaultValue value @@ -3708,7 +3689,6 @@ public LoopCond loopCond(Operand input) { *

result == [[1, 2, 2], * [0, 1, 5]] * - * @param data type for {@code output} output * @param sortedInputs 2-D Tensor where each row is ordered. * @param values 2-D Tensor with the same numbers of rows as {@code sorted_search_values}. Contains * the values that will be searched for in {@code sorted_search_values}. @@ -3736,7 +3716,6 @@ public LowerBound lowerBound(Operand sortedInputs, *

result == [[1, 2, 2], * [0, 1, 5]] * - * @param data type for {@code output} output * @param sortedInputs 2-D Tensor where each row is ordered. * @param values 2-D Tensor with the same numbers of rows as {@code sorted_search_values}. Contains * the values that will be searched for in {@code sorted_search_values}. @@ -3901,7 +3880,6 @@ public MapUnstageNoKey mapUnstageNoKey(Operand indices, * {@code axis}. If {@code keep_dims} is true, the reduced dimensions are * retained with length 1. * - * @param data type for {@code output} output * @param input The tensor to reduce. * @param axis The dimensions to reduce. Must be in the range * {@code [-rank(input), rank(input))}. @@ -3921,7 +3899,6 @@ public Max max(Operand input, Operand{@code Merge} forwards the first tensor to become available to {@code output}, and sets * {@code value_index} to its index in {@code inputs}. * - * @param data type for {@code output} output * @param inputs The input tensors, exactly one of which will become available. * @param data type for {@code Merge} output and operands * @return a new instance of Merge @@ -3937,7 +3914,6 @@ public Merge merge(Iterable> inputs) { * {@code axis}. If {@code keep_dims} is true, the reduced dimensions are * retained with length 1. * - * @param data type for {@code output} output * @param input The tensor to reduce. * @param axis The dimensions to reduce. Must be in the range * {@code [-rank(input), rank(input))}. @@ -3974,7 +3950,6 @@ public Min min(Operand input, Operand * - * @param data type for {@code output} output * @param input The input tensor to be padded. * @param paddings A two-column matrix specifying the padding sizes. The number of * rows must be the same as the rank of {@code input}. @@ -4008,7 +3983,6 @@ public MirrorPad mirrorPad(Operand input, * [11, 28]] * * - * @param data type for {@code output} output * @param input The input tensor to be folded. * @param paddings A two-column matrix specifying the padding sizes. The number of * rows must be the same as the rank of {@code input}. @@ -4187,7 +4161,6 @@ public MutexLock mutexLock(Operand mutex) { * num_devices: The number of devices participating in this reduction. * shared_name: Identifier that shared between ops of the same reduction. * - * @param data type for {@code data} output * @deprecated use {@link org.tensorflow.op.distribute.NcclAllReduce} instead * @param input The input value * @param reduction The value of the reduction attribute @@ -4211,7 +4184,6 @@ public NcclAllReduce ncclAllReduce(Operand input, Stri * output: The same as input. * shape: The shape of the input tensor. * - * @param data type for {@code output} output * @deprecated use {@link org.tensorflow.op.distribute.NcclBroadcast} instead * @param input The input value * @param shape The value of the shape attribute @@ -4232,7 +4204,6 @@ public NcclBroadcast ncclBroadcast(Operand input, Shap * data: the value of the reduction across all {@code num_devices} devices. * reduction: the reduction operation to perform. * - * @param data type for {@code data} output * @deprecated use {@link org.tensorflow.op.distribute.NcclReduce} instead * @param input The input value * @param reduction The value of the reduction attribute @@ -4248,7 +4219,6 @@ public NcclReduce ncclReduce(Iterable> input, /** * Makes its input available to the next iteration. * - * @param data type for {@code output} output * @param data The tensor to be made available to the next iteration. * @param data type for {@code NextIteration} output and operands * @return a new instance of NextIteration @@ -4343,7 +4313,6 @@ public NoOp noOp() { * ] * * - * @param data type for {@code output} output * @param indices A tensor of indices. * @param depth A scalar defining the depth of the one hot dimension. * @param onValue A scalar defining the value to fill in output when {@code indices[j] = i}. @@ -4372,7 +4341,6 @@ public Ones ones(Operand dims, Class /** * Returns a tensor of ones with the same shape and type as x. * - * @param data type for {@code y} output * @param x a tensor of type T. * @param data type for {@code OnesLike} output and operands * @return a new instance of OnesLike @@ -4506,7 +4474,6 @@ public OrderedMapUnstageNoKey orderedMapUnstageNoKey(Operand indices, * [0, 0, 0, 0, 0, 0]] * * - * @param data type for {@code output} output * @param input The input value * @param paddings The paddings value * @param constantValues The constantValues value @@ -4534,7 +4501,6 @@ public Pad pad(Operand input, Operand * will copy pieces of the input into the output as they become available, in * some situations this can provide a performance benefit. * - * @param data type for {@code output} output * @param values Tensors to be concatenated. All must have size 1 in the first dimension * and same shape. * @param shape the final shape of the result; should be equal to the shapes of any input @@ -4602,7 +4568,6 @@ public ParallelConcat parallelConcat(Iterable> v * * * - * @param data type for {@code merged} output * @param indices The indices value * @param data The data value * @param data type for {@code ParallelDynamicStitch} output and operands @@ -4641,7 +4606,6 @@ public PartitionedCall partitionedCall(Iterable> args, * intended as a way to represent a value that will always be fed, and to * provide attrs that enable the fed value to be checked at runtime. * - * @param data type for {@code output} output * @param dtype The type of elements in the tensor. * @param options carries optional attribute values * @param data type for {@code Placeholder} output and operands @@ -4655,7 +4619,6 @@ public Placeholder placeholder(Class dtype, /** * A placeholder op that passes through {@code input} when its output is not fed. * - * @param data type for {@code output} output * @param input The default value to produce when {@code output} is not fed. * @param shape The (possibly partial) shape of the tensor. * @param data type for {@code PlaceholderWithDefault} output and operands @@ -4685,7 +4648,6 @@ public Print print(Operand input, Print.Options... options) { * {@code axis}. If {@code keep_dims} is true, the reduced dimensions are * retained with length 1. * - * @param data type for {@code output} output * @param input The tensor to reduce. * @param axis The dimensions to reduce. Must be in the range * {@code [-rank(input), rank(input))}. @@ -4701,7 +4663,6 @@ public Prod prod(Operand input, Operand data type for {@code output} output * @param tensor The tensor value * @param shape Defines the shape of the output tensor. * @param inputMin The minimum value of the input. @@ -4721,7 +4682,6 @@ public QuantizedReshape quantizedReshape(Operand tensor, * first dimension must match. *

The outputs are deterministic. * - * @param data type for {@code output} output * @param index A scalar tensor or a vector of dtype {@code dtype}. The index (or indices) to be shuffled. Must be within [0, max_index]. * @param seed A tensor of dtype {@code Tseed} and shape [3] or [n, 3]. The random seed. * @param maxIndex A scalar tensor or vector of dtype {@code dtype}. The upper bound(s) of the interval (inclusive). @@ -4746,7 +4706,6 @@ public RandomIndexShuffle randomIndexShuffle(Operand i * tf.range(start, limit, delta) ==> [3, 6, 9, 12, 15] * * - * @param data type for {@code output} output * @param start 0-D (scalar). First entry in the sequence. * @param limit 0-D (scalar). Upper limit of sequence, exclusive. * @param delta 0-D (scalar). Optional. Default is 1. Number that increments {@code start}. @@ -4785,7 +4744,6 @@ public Rank rank(Operand input) { * influenced by any of the writes which depend directly or indirectly on this * operation. * - * @param data type for {@code value} output * @param resource handle to the resource in which to store the variable. * @param dtype the dtype of the value. * @param data type for {@code ReadVariableOp} output and operands @@ -4799,7 +4757,6 @@ public ReadVariableOp readVariableOp(Operand data type for {@code tensor} output * @param tensorType The value of the tensorType attribute * @param tensorName The name of the tensor to receive. * @param sendDevice The name of the device sending the tensor. @@ -4857,7 +4814,6 @@ public ReduceAny reduceAny(Operand input, Operand axis * {@code axis}. If {@code keep_dims} is true, the reduced dimensions are * retained with length 1. * - * @param data type for {@code output} output * @param input The tensor to reduce. * @param axis The dimensions to reduce. Must be in the range * {@code [-rank(input), rank(input))}. @@ -4877,7 +4833,6 @@ public ReduceMax reduceMax(Operand input, * {@code axis}. If {@code keep_dims} is true, the reduced dimensions are * retained with length 1. * - * @param data type for {@code output} output * @param input The tensor to reduce. * @param axis The dimensions to reduce. Must be in the range * {@code [-rank(input), rank(input))}. @@ -4897,7 +4852,6 @@ public ReduceMin reduceMin(Operand input, * {@code axis}. If {@code keep_dims} is true, the reduced dimensions are * retained with length 1. * - * @param data type for {@code output} output * @param input The tensor to reduce. * @param axis The dimensions to reduce. Must be in the range * {@code [-rank(input), rank(input))}. @@ -4917,7 +4871,6 @@ public ReduceProd reduceProd(Operand input, * {@code axis}. If {@code keep_dims} is true, the reduced dimensions are * retained with length 1. * - * @param data type for {@code output} output * @param input The tensor to reduce. * @param axis The dimensions to reduce. Must be in the range * {@code [-rank(input), rank(input))}. @@ -4937,7 +4890,6 @@ public ReduceSum reduceSum(Operand input, Operand data type for {@code output} output * @param data The tensor to be made available to the child frame. * @param frameName The name of the child frame. * @param options carries optional attribute values @@ -4953,7 +4905,6 @@ public RefEnter refEnter(Operand data, String frameName, * Exits the current frame to its parent frame. * Exit makes its input {@code data} available to the parent frame. * - * @param data type for {@code output} output * @param data The tensor to be made available to the parent frame. * @param data type for {@code RefExit} output and operands * @return a new instance of RefExit @@ -4965,7 +4916,6 @@ public RefExit refExit(Operand data) { /** * Return the same ref tensor as the input ref tensor. * - * @param data type for {@code output} output * @param input The input value * @param data type for {@code RefIdentity} output and operands * @return a new instance of RefIdentity @@ -4981,7 +4931,6 @@ public RefIdentity refIdentity(Operand input) { *

{@code Merge} forwards the first tensor for become available to {@code output}, and sets * {@code value_index} to its index in {@code inputs}. * - * @param data type for {@code output} output * @param inputs The input tensors, exactly one of which will become available. * @param data type for {@code RefMerge} output and operands * @return a new instance of RefMerge @@ -4993,7 +4942,6 @@ public RefMerge refMerge(Iterable> inputs) { /** * Makes its input available to the next iteration. * - * @param data type for {@code output} output * @param data The tensor to be made available to the next iteration. * @param data type for {@code RefNextIteration} output and operands * @return a new instance of RefNextIteration @@ -5005,7 +4953,6 @@ public RefNextIteration refNextIteration(Operand data) { /** * Forwards the {@code index}th element of {@code inputs} to {@code output}. * - * @param data type for {@code output} output * @param index A scalar that determines the input that gets selected. * @param inputs A list of ref tensors, one of which will be forwarded to {@code output}. * @param data type for {@code RefSelect} output and operands @@ -5022,7 +4969,6 @@ public RefSelect refSelect(Operand index, * the data goes to {@code output_false}. *

See also {@code Switch} and {@code Merge}. * - * @param data type for {@code output_false} output * @param data The ref tensor to be forwarded to the appropriate output. * @param pred A scalar that specifies which output port will receive data. * @param data type for {@code RefSwitch} output and operands @@ -5035,7 +4981,6 @@ public RefSwitch refSwitch(Operand data, Operand /** * The Relayout operation * - * @param data type for {@code output} output * @param input The input value * @param layout The value of the layout attribute * @param data type for {@code Relayout} output and operands @@ -5048,7 +4993,6 @@ public Relayout relayout(Operand input, String layout) { /** * The RelayoutLike operation * - * @param data type for {@code output} output * @param input The input value * @param layoutInput The layoutInput value * @param data type for {@code RelayoutLike} output and operands @@ -5130,7 +5074,6 @@ public RemoteCall remoteCall(Operand target, Iterable> args, * reshape(t, []) ==> 7 * * - * @param data type for {@code output} output * @param tensor The tensor value * @param shape Defines the shape of the output tensor. * @param data type for {@code Reshape} output and operands @@ -5143,7 +5086,6 @@ public Reshape reshape(Operand tensor, Operand data type for {@code output} output * @param resource Should be from a scalar {@code Variable} node. * @param limit If incrementing ref would bring it above limit, instead generates an * 'OutOfRange' error. @@ -5171,7 +5113,6 @@ public ResourceCountUpTo resourceCountUpTo( * output[i, ..., j, :, ... :] = params[indices[i, ..., j], :, ..., :] * * - * @param data type for {@code output} output * @param resource The resource value * @param indices The indices value * @param dtype The value of the dtype attribute @@ -5187,7 +5128,6 @@ public ResourceGather resourceGather(Operand data type for {@code output} output * @param resource The resource value * @param indices The indices value * @param dtype The value of the dtype attribute @@ -5633,7 +5573,6 @@ public ResourceStridedSliceAssign resourceStridedSliceAssign * [12, 13, 14, 15]]]] * * - * @param data type for {@code output} output * @param tensor Up to 8-D. * @param axis 1-D. The indices of the dimensions to reverse. Must be in the range * {@code [-rank(tensor), rank(tensor))}. @@ -5695,7 +5634,6 @@ public Reverse reverse(Operand tensor, Operand * - * @param data type for {@code output} output * @param input The input to reverse. * @param seqLengths 1-D with length {@code input.dims(batch_dim)} and * {@code max(seq_lengths) <= input.dims(seq_dim)} @@ -5730,7 +5668,6 @@ public ReverseSequence reverseSequence(Operand input, * roll(t, shift=[2, -3], axis=[1, 1]) ==> [[1, 2, 3, 4, 0], [6, 7, 8, 9, 5]] * * - * @param data type for {@code output} output * @param input The input value * @param shift Dimension must be 0-D or 1-D. {@code shift[i]} specifies the number of places by which * elements are shifted positively (towards larger indices) along the dimension @@ -5770,7 +5707,6 @@ public Roll roll(Operand input, Operand * * - * @param data type for {@code output_ref} output * @param ref Should be from a {@code Variable} node. * @param indices A tensor of indices into the first dimension of {@code ref}. * @param updates A tensor of updated values to add to {@code ref}. @@ -5802,7 +5738,6 @@ public ScatterAdd scatterAdd(Operand ref, * the same location, their contributions divide. *

Requires {@code updates.shape = indices.shape + ref.shape[1:]} or {@code updates.shape = []}. * - * @param data type for {@code output_ref} output * @param ref Should be from a {@code Variable} node. * @param indices A tensor of indices into the first dimension of {@code ref}. * @param updates A tensor of values that {@code ref} is divided by. @@ -5837,7 +5772,6 @@ public ScatterDiv scatterDiv(Operand ref, * * * - * @param data type for {@code output_ref} output * @param ref Should be from a {@code Variable} node. * @param indices A tensor of indices into the first dimension of {@code ref}. * @param updates A tensor of updated values to reduce into {@code ref}. @@ -5872,7 +5806,6 @@ public ScatterMax scatterMax(Operand ref, * * * - * @param data type for {@code output_ref} output * @param ref Should be from a {@code Variable} node. * @param indices A tensor of indices into the first dimension of {@code ref}. * @param updates A tensor of updated values to reduce into {@code ref}. @@ -5904,7 +5837,6 @@ public ScatterMin scatterMin(Operand ref, * the same location, their contributions multiply. *

Requires {@code updates.shape = indices.shape + ref.shape[1:]} or {@code updates.shape = []}. * - * @param data type for {@code output_ref} output * @param ref Should be from a {@code Variable} node. * @param indices A tensor of indices into the first dimension of {@code ref}. * @param updates A tensor of updated values to multiply to {@code ref}. @@ -5990,20 +5922,28 @@ public ScatterMul scatterMul(Operand ref, * [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], * [[5, 5, 5, 5], [6, 6, 6, 6], [7, 7, 7, 7], [8, 8, 8, 8]]] * - *

Note that on CPU, if an out of bound index is found, an error is returned. - * On GPU, if an out of bound index is found, the index is ignored. + *

If {@code indices} contains any out-of-bound indices, depending on + * {@code bad_indices_policy}, the op will either return an error or ignore the + * out-of-bound indices. {@code bad_indices_policy} can be one of the following values: + *

    + *
  1. "" or "DEFAULT": raises on CPU and ignore on GPU. This is because + * historically on CPU and GPU we handle errors in different ways, and for + * backward compatibility we keep the default behavior.
  2. + *
  3. "ERROR": raises error; GPU does not support this value.
  4. + *
  5. "IGNORE": ignore the bad indices; supported on both CPU and GPU.
  6. + *
* - * @param data type for {@code output} output * @param indices Tensor of indices. * @param updates Values to scatter into the output tensor. * @param shape 1-D. The shape of the output tensor. + * @param options carries optional attribute values * @param data type for {@code ScatterNd} output and operands * @param data type for {@code ScatterNd} output and operands * @return a new instance of ScatterNd */ public ScatterNd scatterNd(Operand indices, - Operand updates, Operand shape) { - return ScatterNd.create(scope, indices, updates, shape); + Operand updates, Operand shape, ScatterNd.Options... options) { + return ScatterNd.create(scope, indices, updates, shape, options); } /** @@ -6035,7 +5975,6 @@ public ScatterNd scatterNd(Operand in *

See {@code tf.scatter_nd} for more details about how to make updates to * slices. * - * @param data type for {@code output_ref} output * @param ref A mutable Tensor. Should be from a Variable node. * @param indices A Tensor. Must be one of the following types: int32, int64. * A tensor of indices into ref. @@ -6053,7 +5992,6 @@ public ScatterNdAdd scatterNdAdd(Operand ref, /** * Computes element-wise maximum. * - * @param data type for {@code output_ref} output * @param ref A mutable Tensor. Should be from a Variable node. * @param indices A Tensor. Must be one of the following types: int32, int64. * A tensor of indices into ref. @@ -6071,7 +6009,6 @@ public ScatterNdMax scatterNdMax(Operand ref, /** * Computes element-wise minimum. * - * @param data type for {@code output_ref} output * @param ref A mutable Tensor. Should be from a Variable node. * @param indices A Tensor. Must be one of the following types: int32, int64. * A tensor of indices into ref. @@ -6116,18 +6053,19 @@ public ScatterNdMin scatterNdMin(Operand ref, * *

See {@code tf.scatter_nd} for more details about how to make updates to slices. * - * @param data type for {@code output} output * @param input A Tensor. * @param indices A Tensor. Must be one of the following types: {@code int32}, {@code int64}. * A tensor of indices into {@code input}. * @param updates A Tensor. Must have the same type as ref. A tensor of updated values * to add to {@code input}. + * @param options carries optional attribute values * @param data type for {@code ScatterNdNonAliasingAdd} output and operands * @return a new instance of ScatterNdNonAliasingAdd */ public ScatterNdNonAliasingAdd scatterNdNonAliasingAdd(Operand input, - Operand indices, Operand updates) { - return ScatterNdNonAliasingAdd.create(scope, input, indices, updates); + Operand indices, Operand updates, + ScatterNdNonAliasingAdd.Options... options) { + return ScatterNdNonAliasingAdd.create(scope, input, indices, updates, options); } /** @@ -6160,7 +6098,6 @@ public ScatterNdNonAliasingAdd scatterNdNonAliasingAdd(Oper *

See {@code tf.scatter_nd} for more details about how to make updates to * slices. * - * @param data type for {@code output_ref} output * @param ref A mutable Tensor. Should be from a Variable node. * @param indices A Tensor. Must be one of the following types: int32, int64. * A tensor of indices into ref. @@ -6204,7 +6141,6 @@ public ScatterNdSub scatterNdSub(Operand ref, * slices. *

See also {@code tf.scatter_update} and {@code tf.batch_scatter_update}. * - * @param data type for {@code output_ref} output * @param ref A mutable Tensor. Should be from a Variable node. * @param indices A Tensor. Must be one of the following types: int32, int64. * A tensor of indices into ref. @@ -6240,7 +6176,6 @@ public ScatterNdUpdate scatterNdUpdate(Operand ref, * * * - * @param data type for {@code output_ref} output * @param ref Should be from a {@code Variable} node. * @param indices A tensor of indices into the first dimension of {@code ref}. * @param updates A tensor of updated values to subtract from {@code ref}. @@ -6277,7 +6212,6 @@ public ScatterSub scatterSub(Operand ref, * *

See also {@code tf.batch_scatter_update} and {@code tf.scatter_nd_update}. * - * @param data type for {@code output_ref} output * @param ref Should be from a {@code Variable} node. * @param indices A tensor of indices into the first dimension of {@code ref}. * @param updates A tensor of updated values to store in {@code ref}. @@ -6293,7 +6227,6 @@ public ScatterUpdate scatterUpdate(Operand ref, /** * The SelectV2 operation * - * @param data type for {@code output} output * @param condition The condition value * @param t The t value * @param e The e value @@ -6339,8 +6272,6 @@ public Send send(Operand tensor, String tensorName, String send * idx ==> [1, 3, 5] * * - * @param data type for {@code out} output - * @param data type for {@code idx} output * @param x 1-D. Values to keep. * @param y 1-D. Values to remove. * @param data type for {@code ListDiff} output and operands @@ -6369,8 +6300,6 @@ public SetDiff1d setDiff1d(Operand x, Operand * idx ==> [1, 3, 5] * * - * @param data type for {@code out} output - * @param data type for {@code idx} output * @param x 1-D. Values to keep. * @param y 1-D. Values to remove. * @param outIdx The value of the outIdx attribute @@ -6412,7 +6341,6 @@ public SetSize setSize(Operand setIndices, Operand setV * shape(t) ==> [2, 2, 3] * * - * @param data type for {@code output} output * @param input The input value * @return a new instance of Shape, with default output types */ @@ -6429,7 +6357,6 @@ public org.tensorflow.op.core.Shape shape(Operand input * shape(t) ==> [2, 2, 3] * * - * @param data type for {@code output} output * @param input The input value * @param outType The value of the outType attribute * @param data type for {@code Shape} output and operands @@ -6444,7 +6371,6 @@ public org.tensorflow.op.core.Shape shape(Operand data type for {@code output} output * @param input The input value * @return a new instance of ShapeN, with default output types */ @@ -6456,7 +6382,6 @@ public ShapeN shapeN(Iterable> input) { * Returns shape of tensors. * This operation returns N 1-D integer tensors representing shape of {@code input[i]s}. * - * @param data type for {@code output} output * @param input The input value * @param outType The value of the outType attribute * @param data type for {@code ShapeN} output and operands @@ -6477,7 +6402,6 @@ public ShapeN shapeN(Iterable> i * size(t) ==> 12 * * - * @param data type for {@code output} output * @param input The input value * @return a new instance of Size, with default output types */ @@ -6495,7 +6419,6 @@ public Size size(Operand input) { * size(t) ==> 12 * * - * @param data type for {@code output} output * @param input The input value * @param outType The value of the outType attribute * @param data type for {@code Size} output and operands @@ -6525,7 +6448,6 @@ public Skipgram skipgram(String filename, Long batchSize, Skipgram.Options... op *

Requirements: * 0 <= begin[i] <= begin[i] + size[i] <= Di for i in [0, n) * - * @param data type for {@code output} output * @param input The input value * @param begin begin[i] specifies the offset into the 'i'th dimension of * 'input' to slice from. @@ -6545,7 +6467,6 @@ public Slice slice(Operand input, Ope /** * Returns a copy of the input tensor. * - * @param data type for {@code output} output * @param input The input value * @param data type for {@code Snapshot} output and operands * @return a new instance of Snapshot @@ -6653,7 +6574,6 @@ public Snapshot snapshot(Operand input) { *

Among others, this operation is useful for reducing atrous convolution into * regular convolution. * - * @param data type for {@code output} output * @param input N-D with shape {@code input_shape = [batch] + spatial_shape + remaining_shape}, * where spatial_shape has {@code M} dimensions. * @param blockShape 1-D with shape {@code [M]}, all values must be >= 1. @@ -6672,7 +6592,6 @@ public SpaceToBatchNd spaceToBatchNd(Operand input, /** * Splits a tensor into {@code num_split} tensors along one dimension. * - * @param data type for {@code output} output * @param axis 0-D. The dimension along which to split. Must be in the range * {@code [-rank(value), rank(value))}. * @param value The tensor to split. @@ -6688,7 +6607,6 @@ public Split split(Operand axis, Operand value, /** * Splits a tensor into {@code num_split} tensors along one dimension. * - * @param data type for {@code output} output * @param value The tensor to split. * @param sizeSplits list containing the sizes of each output tensor along the split * dimension. Must sum to the dimension of value along split_dim. @@ -6721,7 +6639,6 @@ public SplitV splitV(Operand value, Operand * - * @param data type for {@code output} output * @param input The {@code input} to squeeze. * @param options carries optional attribute values * @param data type for {@code Squeeze} output and operands @@ -6749,7 +6666,6 @@ public Squeeze squeeze(Operand input, Squeeze.Options... * *

This is the opposite of {@code unpack}. * - * @param data type for {@code output} output * @param values Must be of same shape and type. * @param options carries optional attribute values * @param data type for {@code Pack} output and operands @@ -6787,7 +6703,6 @@ public StackCreate stackCreate(Operand maxSize, Class< /** * Pop the element at the top of the stack. * - * @param data type for {@code elem} output * @param handle The handle to a stack. * @param elemType The type of the elem that is popped. * @param data type for {@code StackPopV2} output and operands @@ -6801,7 +6716,6 @@ public StackPop stackPop(Operand handle, /** * Push an element onto the stack. * - * @param data type for {@code output} output * @param handle The handle to a stack. * @param elem The tensor to be pushed onto the stack. * @param options carries optional attribute values @@ -7083,7 +6997,6 @@ public StatelessWhile statelessWhile(Iterable> input, ConcreteFunctio * The values are cast with a deterministic pseudo-random tensor from a uniform distribution generated from user given key, counter, algorithm. Values will saturate if out of the specified integer type range, and will become zero if inputs are NaN. *

The outputs are a deterministic function of {@code input}, {@code key}, {@code counter}, {@code alg}. * - * @param data type for {@code output} output * @param input The operand to stochastically cast to int. * @param key Key for the counter-based RNG algorithm (shape uint64[1]). * @param counter Initial counter for the counter-based RNG algorithm (shape uint64[2] or uint64[1] depending on the algorithm). If a larger vector is given, only the needed portion on the left (i.e. [:N]) will be used. @@ -7151,7 +7064,6 @@ public StochasticCastToInt stochasticCastToInt( * example generation process. * * - * @param data type for {@code output} output * @param input The input value * @param data type for {@code StopGradient} output and operands * @return a new instance of StopGradient @@ -7169,16 +7081,17 @@ public StopGradient stopGradient(Operand input) { * equal to `n`, but this need not be the case. Each range specification entry can be one of the * following: * - *

- An ellipsis (...) using {@link Indices#ellipsis()}. Ellipses are used to imply zero or - * more dimensions of full-dimension selection. For example, {@code stridedSlice(foo, - * Indices.ellipsis()} is the identity slice. + *

- An ellipsis (...) using {@link org.tensorflow.ndarray.index.Indices#ellipsis()}. Ellipses + * are used to imply zero or more dimensions of full-dimension selection. For example, {@code + * stridedSlice(foo, Indices.ellipsis()} is the identity slice. * - *

- A new axis using {@link Indices#newAxis()}. This is used to insert a new shape=1 - * dimension. For example, `{@code stridedSlice(foo, Indices.newAxis())} where {@code foo} is - * shape {@code (3, 4)} produces a {@code (1, 3, 4)} tensor. + *

- A new axis using {@link org.tensorflow.ndarray.index.Indices#newAxis()}. This is used to + * insert a new shape=1 dimension. For example, `{@code stridedSlice(foo, Indices.newAxis())} + * where {@code foo} is shape {@code (3, 4)} produces a {@code (1, 3, 4)} tensor. * - *

- A range {@code begin:end:stride} using {@link Indices#slice(Long, Long, long)} - * Index.slice()} or {@link Indices#all()}. This is used to specify how much to choose from a + *

- A range {@code begin:end:stride} using {@link + * org.tensorflow.ndarray.index.Indices#slice(Long, Long, long)} Index.slice()} or {@link + * org.tensorflow.ndarray.index.Indices#all()}. This is used to specify how much to choose from a * given dimension. {@code stride} can be any integer but 0. {@code begin} is an integer which * represents the index of the first value to select while {@code end} represents the index of the * last value to select (exclusive). Begin and end can be null, in which case the index begins or @@ -7195,10 +7108,11 @@ public StopGradient stopGradient(Operand input) { * elements). For example {@code foo = [1,2,3,4]; stridedSlice(foo, Indices.slice(-2, null, -1)} * is {@code [4,3]}. * - *

- A single index using {@link Indices#at(long)}. This is used to keep only elements that - * have a given index. For example ({@code stridedSlice(foo, Indices.at(2))} on a shape {@code - * (5,6)} tensor produces a shape {@code (6,)} tensor. The dimension can be kept with size one - * using {@link Indices#at(long, boolean)}. + *

- A single index using {@link org.tensorflow.ndarray.index.Indices#at(long)}. This is used + * to keep only elements that have a given index. For example ({@code stridedSlice(foo, + * Indices.at(2))} on a shape {@code (5,6)} tensor produces a shape {@code (6,)} tensor. The + * dimension can be kept with size one using {@link org.tensorflow.ndarray.index.Indices#at(long, + * boolean)}. * *

These semantics generally follow NumPy's indexing semantics, which can be found here: https://numpy.org/doc/stable/reference/arrays.indexing.html @@ -7206,9 +7120,9 @@ public StopGradient stopGradient(Operand input) { *

Requirements: `0 != strides[i] for i in [0, m)` Only one ellipsis. * * @param data type for {@code output()} output - * @param indices The indices to slice. See {@link Indices}. + * @param indices The indices to slice. See {@link org.tensorflow.ndarray.index.Indices}. * @return a new instance of StridedSlice - * @see Indices + * @see org.tensorflow.ndarray.index.Indices */ public StridedSlice stridedSlice(Operand input, Index... indices) { return StridedSliceHelper.stridedSlice(scope, input, indices); @@ -7314,7 +7228,6 @@ public StridedSlice stridedSlice(Operand input, Index... * {@code 0 != strides[i] for i in [0, m)} * {@code ellipsis_mask must be a power of two (only one ellipsis)} * - * @param data type for {@code output} output * @param input The input value * @param begin {@code begin[k]} specifies the offset into the {@code k}th range specification. * The exact dimension this corresponds to will be determined by context. @@ -7351,9 +7264,10 @@ public StridedSlice stridedSlice(Operand * @param data type for {@code outputRef()} output * @param ref the tensor to assign to. * @param value the value to assign. - * @param indices The indices to slice. See {@link Indices}. + * @param indices The indices to slice. See {@link org.tensorflow.ndarray.index.Indices}. * @return a new instance of StridedSliceAssign - * @see org.tensorflow.op.Ops#stridedSlice(Operand, Index...) + * @see org.tensorflow.op.Ops#stridedSlice(org.tensorflow.Operand, + * org.tensorflow.ndarray.index.Index...) */ public StridedSliceAssign stridedSliceAssign(Operand ref, Operand value, Index... indices) { @@ -7368,7 +7282,6 @@ public StridedSliceAssign stridedSliceAssign(Operand ref *

NOTE this op currently does not support broadcasting and so {@code value}'s * shape must be exactly the shape produced by the slice of {@code ref}. * - * @param data type for {@code output_ref} output * @param ref The ref value * @param begin The begin value * @param end The end value @@ -7395,7 +7308,6 @@ public StridedSliceAssign stridedSliceAs * {@code dy} is the input gradient to be propagated and {@code shape} is the * shape of {@code StridedSlice}'s {@code input}. * - * @param data type for {@code output} output * @param shape The shape value * @param begin The begin value * @param end The end value @@ -7419,7 +7331,6 @@ public StridedSliceGrad stridedSliceGrad * {@code axis}. If {@code keep_dims} is true, the reduced dimensions are * retained with length 1. * - * @param data type for {@code output} output * @param input The tensor to reduce. * @param axis The dimensions to reduce. Must be in the range * {@code [-rank(input), rank(input))}. @@ -7438,7 +7349,6 @@ public Sum sum(Operand input, Operand * the data goes to {@code output_false}. *

See also {@code RefSwitch} and {@code Merge}. * - * @param data type for {@code output_false} output * @param data The tensor to be forwarded to the appropriate output. * @param pred A scalar that specifies which output port will receive data. * @param data type for {@code Switch} output and operands @@ -7473,7 +7383,6 @@ public SyncDevice syncDevice() { * var = state_ops.assign_add(var, [[6.0, 7.0]]) * final = state_ops._destroy_temporary_variable(var, var_name=var_name) * - * @param data type for {@code ref} output * @param shape The shape of the variable tensor. * @param dtype The type of elements in the variable tensor. * @param options carries optional attribute values @@ -7524,7 +7433,6 @@ public TensorArrayClose tensorArrayClose(Operand handle) { * *

All elements must have the same shape (excepting the first dimension). * - * @param data type for {@code value} output * @param handle The handle to a TensorArray. * @param flowIn A float scalar that enforces proper chaining of operations. * @param dtype The type of the elem that is returned. @@ -7541,7 +7449,6 @@ public TensorArrayConcat tensorArrayConcat(Operand data type for {@code value} output * @param handle The handle to a TensorArray. * @param indices The locations in the TensorArray from which to read tensor elements. * @param flowIn A float scalar that enforces proper chaining of operations. @@ -7622,7 +7529,6 @@ public TensorArrayGradWithShape tensorArrayGradWithShape(Operand data type for {@code value} output * @param handle The handle value * @param flowIn The flowIn value * @param dtype The value of the dtype attribute @@ -7638,7 +7544,6 @@ public TensorArrayPack tensorArrayPack(Operand han /** * Read an element from the TensorArray into output {@code value}. * - * @param data type for {@code value} output * @param handle The handle to a TensorArray. * @param index The index value * @param flowIn A float scalar that enforces proper chaining of operations. @@ -7750,7 +7655,6 @@ public TensorArrayWrite tensorArrayWrite(Operand handle, Operan * tensor: The concated result. * lengths: Output tensor containing sizes of the 0th dimension of tensors in the list, used for computing the gradient. * - * @param data type for {@code tensor} output * @param inputHandle The inputHandle value * @param elementShape The elementShape value * @param leadingDims The leadingDims value @@ -7783,7 +7687,6 @@ public TensorListConcatLists tensorListConcatLists( * input_handle: the list * element_shape: the shape of elements of the list * - * @param data type for {@code element_shape} output * @param inputHandle The inputHandle value * @param shapeType The value of the shapeType attribute * @param data type for {@code TensorListElementShape} output and operands @@ -7817,7 +7720,6 @@ public TensorListFromTensor tensorListFromTensor(Operand tensor * indices: The indices used to index into the list. * values: The tensor. * - * @param data type for {@code values} output * @param inputHandle The inputHandle value * @param indices The indices value * @param elementShape The elementShape value @@ -7837,7 +7739,6 @@ public TensorListGather tensorListGather( * index: the position in the list from which an element will be retrieved * item: the element at that position * - * @param data type for {@code item} output * @param inputHandle The inputHandle value * @param index The index value * @param elementShape The elementShape value @@ -7871,7 +7772,6 @@ public TensorListLength tensorListLength(Operand inputHandle) { * element_dtype: the type of elements in the list * element_shape: the shape of the output tensor * - * @param data type for {@code tensor} output * @param inputHandle The inputHandle value * @param elementShape The elementShape value * @param elementDtype The value of the elementDtype attribute @@ -8033,7 +7933,6 @@ public TensorListSplit tensorListSplit(Operand tensor, * tensor: the gathered result * num_elements: optional. If not -1, the number of elements in the list. * - * @param data type for {@code tensor} output * @param inputHandle The inputHandle value * @param elementShape The elementShape value * @param elementDtype The value of the elementDtype attribute @@ -8101,7 +8000,6 @@ public TensorMapInsert tensorMapInsert(Operand inputHandle, * key: the key to be looked up * value: the value found from the given key * - * @param data type for {@code value} output * @param inputHandle The inputHandle value * @param key The key value * @param valueDtype The value of the valueDtype attribute @@ -8130,7 +8028,6 @@ public TensorMapSize tensorMapSize(Operand inputHandle) { * input_handle: the input map * keys: the returned Tensor of all keys in the map * - * @param data type for {@code keys} output * @param inputHandle The inputHandle value * @param keyDtype The value of the keyDtype attribute * @param data type for {@code TensorMapStackKeys} output and operands @@ -8201,19 +8098,28 @@ public TensorMapStackKeys tensorMapStackKeys( * * * - *

Note: on CPU, if an out of bound index is found, an error is returned. - * On GPU, if an out of bound index is found, the index is ignored. + *

If {@code indices} contains any out-of-bound indices, depending on + * {@code bad_indices_policy}, the op will either return an error or ignore the + * out-of-bound indices. {@code bad_indices_policy} can be one of the following values: + *

    + *
  1. "" or "DEFAULT": raises on CPU and ignore on GPU. This is because + * historically on CPU and GPU we handle errors in different ways, and for + * backward compatibility we keep the default behavior.
  2. + *
  3. "ERROR": raises error; GPU does not support this value.
  4. + *
  5. "IGNORE": ignore the bad indices; supported on both CPU and GPU.
  6. + *
* - * @param data type for {@code output} output * @param tensor Tensor to copy/update. * @param indices Index tensor. * @param updates Updates to scatter into output. + * @param options carries optional attribute values * @param data type for {@code TensorScatterAdd} output and operands * @return a new instance of TensorScatterNdAdd */ public TensorScatterNdAdd tensorScatterNdAdd(Operand tensor, - Operand indices, Operand updates) { - return TensorScatterNdAdd.create(scope, tensor, indices, updates); + Operand indices, Operand updates, + TensorScatterNdAdd.Options... options) { + return TensorScatterNdAdd.create(scope, tensor, indices, updates, options); } /** @@ -8233,31 +8139,33 @@ public TensorScatterNdAdd tensorScatterNdAdd(Operand ten * *

Refer to {@code tf.tensor_scatter_nd_update} for more details. * - * @param data type for {@code output} output * @param tensor Tensor to update. * @param indices Index tensor. * @param updates Updates to scatter into output. + * @param options carries optional attribute values * @param data type for {@code TensorScatterMax} output and operands * @return a new instance of TensorScatterNdMax */ public TensorScatterNdMax tensorScatterNdMax(Operand tensor, - Operand indices, Operand updates) { - return TensorScatterNdMax.create(scope, tensor, indices, updates); + Operand indices, Operand updates, + TensorScatterNdMax.Options... options) { + return TensorScatterNdMax.create(scope, tensor, indices, updates, options); } /** * The TensorScatterMin operation * - * @param data type for {@code output} output * @param tensor Tensor to update. * @param indices Index tensor. * @param updates Updates to scatter into output. + * @param options carries optional attribute values * @param data type for {@code TensorScatterMin} output and operands * @return a new instance of TensorScatterNdMin */ public TensorScatterNdMin tensorScatterNdMin(Operand tensor, - Operand indices, Operand updates) { - return TensorScatterNdMin.create(scope, tensor, indices, updates); + Operand indices, Operand updates, + TensorScatterNdMin.Options... options) { + return TensorScatterNdMin.create(scope, tensor, indices, updates, options); } /** @@ -8318,16 +8226,17 @@ public TensorScatterNdMin tensorScatterNdMin(Operand ten *

Note that on CPU, if an out of bound index is found, an error is returned. * On GPU, if an out of bound index is found, the index is ignored. * - * @param data type for {@code output} output * @param tensor Tensor to copy/update. * @param indices Index tensor. * @param updates Updates to scatter into output. + * @param options carries optional attribute values * @param data type for {@code TensorScatterSub} output and operands * @return a new instance of TensorScatterNdSub */ public TensorScatterNdSub tensorScatterNdSub(Operand tensor, - Operand indices, Operand updates) { - return TensorScatterNdSub.create(scope, tensor, indices, updates); + Operand indices, Operand updates, + TensorScatterNdSub.Options... options) { + return TensorScatterNdSub.create(scope, tensor, indices, updates, options); } /** @@ -8338,7 +8247,6 @@ public TensorScatterNdSub tensorScatterNdSub(Operand ten * scattered onto an existing tensor (as opposed to a zero-tensor). If the memory * for the existing tensor cannot be re-used, a copy is made and updated. *

If {@code indices} contains duplicates, then we pick the last update for the index. - *

If an out of bound index is found on CPU, an error is returned. *

WARNING: There are some GPU specific semantics for this operation. *

    *
  • If an out of bound index is found, the index is ignored.
  • @@ -8360,18 +8268,29 @@ public TensorScatterNdSub tensorScatterNdSub(Operand ten *
        *  indices.shape[:-1] + tensor.shape[indices.shape[-1]:]
        *  
    + *

    If {@code indices} contains any out-of-bound indices, depending on + * {@code bad_indices_policy}, the op will either return an error or ignore the + * out-of-bound indices. {@code bad_indices_policy} can be one of the following values: + *

      + *
    1. "" or "DEFAULT": raises on CPU and ignore on GPU. This is because + * historically on CPU and GPU we handle errors in different ways, and for + * backward compatibility we keep the default behavior.
    2. + *
    3. "ERROR": raises error; GPU does not support this value.
    4. + *
    5. "IGNORE": ignore the bad indices; supported on both CPU and GPU.
    6. + *
    *

    For usage examples see the python tf.tensor_scatter_nd_update {@link org.tensorflow.op.Ops#tensorScatterNdUpdate} function * - * @param data type for {@code output} output * @param tensor Tensor to copy/update. * @param indices Index tensor. * @param updates Updates to scatter into output. + * @param options carries optional attribute values * @param data type for {@code TensorScatterUpdate} output and operands * @return a new instance of TensorScatterNdUpdate */ public TensorScatterNdUpdate tensorScatterNdUpdate(Operand tensor, - Operand indices, Operand updates) { - return TensorScatterNdUpdate.create(scope, tensor, indices, updates); + Operand indices, Operand updates, + TensorScatterNdUpdate.Options... options) { + return TensorScatterNdUpdate.create(scope, tensor, indices, updates, options); } /** @@ -8382,7 +8301,6 @@ public TensorScatterNdUpdate tensorScatterNdUpdate(Operand< *

    NOTE this op currently does not support broadcasting and so {@code value}'s shape * must be exactly the shape produced by the slice of {@code input}. * - * @param data type for {@code output} output * @param input The input value * @param begin The begin value * @param end The end value @@ -8433,7 +8351,6 @@ public TensorStridedSliceUpdate tensorSt * * * - * @param data type for {@code output} output * @param input Can be of any rank. * @param multiples 1-D. Length must be the same as the number of dimensions in {@code input} * @param data type for {@code Tile} output and operands @@ -8522,7 +8439,6 @@ public TopKWithUnique topKWithUnique(Operand input, Long k) { * assumed to possibly belong to the same batch. If left empty, the op name will * be used as the shared name. * - * @param data type for {@code unbatched_tensor} output * @param batchedTensor The batchedTensor value * @param batchIndex The batchIndex value * @param id The id value @@ -8552,7 +8468,6 @@ public Unbatch unbatch(Operand batchedTensor, Operand data type for {@code batched_grad} output * @param originalInput The originalInput value * @param batchIndex The batchIndex value * @param grad The grad value @@ -8573,7 +8488,6 @@ public UnbatchGrad unbatchGrad(Operand originalInput, * If quantization_axis is -1 (per-tensor quantized), the entire operand is clipped using scalar min, max. * Otherwise (per-channel quantized), the clipping is also done per-channel. * - * @param data type for {@code output} output * @param operand Must be a Tensor of T. * @param min The min value(s) to clip operand. Must be a Tensor of T. * Must be a scalar Tensor if quantization_axis is -1 (per-tensor quantization), otherwise 1D Tensor of size (operand.dim_size(quantization_axis),) (per-axis quantization). @@ -8635,8 +8549,6 @@ public UniformQuantizedClipByValue uniformQuantizedClipBy * idx ==> [0, 1, 1] * * - * @param data type for {@code y} output - * @param data type for {@code idx} output * @param x A {@code Tensor}. * @param axis A {@code Tensor} of type {@code int32} (default: None). The axis of the Tensor to * find the unique elements. @@ -8686,8 +8598,6 @@ public Unique unique(Operand x, Operand * - * @param data type for {@code y} output - * @param data type for {@code idx} output * @param x A {@code Tensor}. * @param axis A {@code Tensor} of type {@code int32} (default: None). The axis of the Tensor to * find the unique elements. @@ -8744,8 +8654,6 @@ public Unique unique(Operand x, * count ==> [1, 2] * * - * @param data type for {@code y} output - * @param data type for {@code idx} output * @param x A {@code Tensor}. * @param axis A {@code Tensor} of type {@code int32} (default: None). The axis of the Tensor to * find the unique elements. @@ -8800,8 +8708,6 @@ public UniqueWithCounts uniqueWithCounts(Operand * count ==> [1, 2] * * - * @param data type for {@code y} output - * @param data type for {@code idx} output * @param x A {@code Tensor}. * @param axis A {@code Tensor} of type {@code int32} (default: None). The axis of the Tensor to * find the unique elements. @@ -8835,7 +8741,6 @@ public UniqueWithCounts uniqueWithCou * Equivalent to np.unravel_index *
    {@literal @}end_compatibility * - * @param data type for {@code output} output * @param indices An 0-D or 1-D {@code int} Tensor whose elements are indices into the * flattened version of an array of dimensions dims. * @param dims An 1-D {@code int} Tensor. The shape of the array to use for unraveling @@ -8859,7 +8764,6 @@ public UnravelIndex unravelIndex(Operand indices, Oper * Etc. *

    This is the opposite of {@code pack}. * - * @param data type for {@code output} output * @param value 1-D or higher, with {@code axis} dimension size equal to {@code num}. * @param num The value of the num attribute * @param options carries optional attribute values @@ -8900,7 +8804,6 @@ public Unstage unstage(List> dtypes, Unstage.Options... o *

    result == [[1, 2, 4], * [0, 2, 5]] * - * @param data type for {@code output} output * @param sortedInputs 2-D Tensor where each row is ordered. * @param values 2-D Tensor with the same numbers of rows as {@code sorted_search_values}. Contains * the values that will be searched for in {@code sorted_search_values}. @@ -8928,7 +8831,6 @@ public UpperBound upperBound(Operand sortedInputs, *

    result == [[1, 2, 4], * [0, 2, 5]] * - * @param data type for {@code output} output * @param sortedInputs 2-D Tensor where each row is ordered. * @param values 2-D Tensor with the same numbers of rows as {@code sorted_search_values}. Contains * the values that will be searched for in {@code sorted_search_values}. @@ -8988,7 +8890,6 @@ public Variable variable(Operand init, Variable.Options. * TODO(zhifengc/mrry): Adds a pointer to a more detail document * about sharing states in tensorflow. * - * @param data type for {@code ref} output * @param shape The shape of the variable tensor. * @param dtype The type of elements in the variable tensor. * @param options carries optional attribute values @@ -9009,7 +8910,6 @@ public Variable variable(Shape shape, Class dtype, * shape(t) ==> [2, 2, 3] * * - * @param data type for {@code output} output * @param input The input value * @return a new instance of VariableShape, with default output types */ @@ -9026,7 +8926,6 @@ public VariableShape variableShape(Operand input) { * shape(t) ==> [2, 2, 3] * * - * @param data type for {@code output} output * @param input The input value * @param outType The value of the outType attribute * @param data type for {@code VariableShape} output and operands @@ -9147,7 +9046,6 @@ public Zeros zeros(Operand dims, Class data type for {@code y} output * @param x a tensor of type T. * @param data type for {@code ZerosLike} output and operands * @return a new instance of ZerosLike diff --git a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/QuantizationOps.java b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/QuantizationOps.java index 99f3648ea27..8bd174ba427 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/QuantizationOps.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/QuantizationOps.java @@ -107,7 +107,6 @@ public final class QuantizationOps { * max_range / max_expected_T); * * - * @param data type for {@code output} output * @param input The input value * @param minRange The minimum scalar value possibly produced for the input. * @param maxRange The maximum scalar value possibly produced for the input. @@ -165,7 +164,6 @@ public Dequantize dequantize(Operand input, * max_range / max_expected_T); * * - * @param data type for {@code output} output * @param input The input value * @param minRange The minimum scalar value possibly produced for the input. * @param maxRange The maximum scalar value possibly produced for the input. @@ -275,6 +273,28 @@ public FakeQuantWithMinMaxArgsGradient fakeQuantWithMinMaxArgsGradient( *

*

This operation has a gradient and thus allows for training {@code min} and {@code max} * values. + *

+ *
+ *
+ *

constant_input = tf.constant([[1.2, -0.3, 0.7], [2.1, 0.5, -1.0]], dtype=tf.float32) + *

min_val = -0.5 + * max_val = 0.8 + * num_bits = 8 + * narrow_range = False #False:for the quantization range [0; 2^num_bits - 1] + *

quantized_data = tf.quantization.fake_quant_with_min_max_vars( + * ... inputs=constant_input, min=min_val, max=max_val, num_bits=num_bits, narrow_range=narrow_range + * ... ) + *

print("Input:\n", constant_input.numpy()) + * Input: + * [[ 1.2 -0.3 0.7] + * [ 2.1 0.5 -1. ]] + * print("Output:\n", quantized_data.numpy()) + * Output: + * [[ 0.8003921 -0.3007843 0.6984313] + * [ 0.8003921 0.4996078 -0.4996078]] + *

+ *
+ *
* * @param inputs The inputs value * @param min The min value @@ -456,7 +476,6 @@ public FakeQuantWithMinMaxVarsPerChannelGradient fakeQuantWithMinMaxVarsPerChann * The legacy default value for this is 0.01, but it is strongly suggested to * set it to 0 for new uses. * - * @param data type for {@code output} output * @param input The input value * @param minRange The minimum value of the quantization range. This value may be adjusted by the * op depending on other parameters. The adjusted value is written to {@code output_min}. @@ -482,7 +501,6 @@ public Quantize quantize(Operand input, * This is almost identical to QuantizeAndDequantizeV2, except that num_bits is a * tensor, so its value can change during training. * - * @param data type for {@code output} output * @param input The input value * @param inputMin The inputMin value * @param inputMax The inputMax value @@ -502,7 +520,6 @@ public QuantizeAndDequantize quantizeAndDequantize(Operan * This is almost identical to QuantizeAndDequantizeV2, except that num_bits is a * tensor, so its value can change during training. * - * @param data type for {@code output} output * @param input The input value * @param inputMin The inputMin value * @param inputMax The inputMax value @@ -522,7 +539,6 @@ public QuantizeAndDequantizeV3 quantizeAndDequantizeV3(Op * This is almost identical to QuantizeAndDequantizeV2, except that it returns a * gradient of 1 for inputs that are within the quantization range, or 0 otherwise. * - * @param data type for {@code output} output * @param input Tensor to quantize and then dequantize. * @param inputMin If {@code range_given == True}, this specifies the minimum input value that needs to * be represented, otherwise it is determined from the min value of the {@code input} @@ -544,7 +560,6 @@ public QuantizeAndDequantizeV4 quantizeAndDequantizeV4(Op * Returns a gradient of 1 for inputs that are within the quantization range, * or 0 otherwise. * - * @param data type for {@code input_backprop} output * @param gradients The gradients value * @param input The input value * @param inputMin The inputMin value @@ -581,7 +596,6 @@ public QuantizeAndDequantizeV4Grad quantizeAndDequantizeV * that output into this operator, we can reduce it from 32 bits down to 8 with * minimal loss of accuracy. * - * @param data type for {@code output} output * @param input The input value * @param inputMin The float value that the minimum quantized input value represents. * @param inputMax The float value that the maximum quantized input value represents. @@ -598,7 +612,6 @@ public QuantizeDownAndShrinkRange quantizeDownAndShrinkRa /** * Concatenates quantized tensors along one dimension. * - * @param data type for {@code output} output * @param concatDim 0-D. The dimension along which to concatenate. Must be in the * range [0, rank(values)). * @param values The {@code N} Tensors to concatenate. Their ranks and types must match, @@ -617,7 +630,6 @@ public QuantizedConcat quantizedConcat(Operand conc /** * The QuantizedMatMulWithBiasAndDequantize operation * - * @param data type for {@code out} output * @param a The a value * @param b The b value * @param bias The bias value @@ -644,7 +656,6 @@ public QuantizedMatMulWithBiasAndDequantize quantizedMatM /** * The QuantizedMatMulWithBiasAndRequantize operation * - * @param data type for {@code out} output * @param a The a value * @param b The b value * @param bias The bias value @@ -694,7 +705,6 @@ public RequantizationRange requantizationRange(Operand input, * {@code input_max} is 1.0f, and we are dealing with {@code quint16} quantized data, then a 0 * value in the 16-bit data should be interpreted as -1.0f, and a 65535 means 1.0f. * - * @param data type for {@code output} output * @param input The input value * @param inputMin The float value that the minimum quantized input value represents. * @param inputMax The float value that the maximum quantized input value represents. @@ -715,7 +725,6 @@ public Requantize requantize(Operand i * Given quantized {@code input} which was quantized using {@code scales} and {@code zero_points}, performs dequantization using the formula: * dequantized_data = (quantized_data - zero_point) * scale. * - * @param data type for {@code output} output * @param input Must be a Tensor of Tin. * @param scales The float value(s) used as scale(s) when quantizing original data that input represents. * Must be a scalar Tensor if quantization_axis is -1 (per-tensor quantization), otherwise 1D Tensor of size (input.dim_size(quantization_axis),) (per-axis quantization). @@ -746,7 +755,6 @@ public UniformDequantize uniformDequantize( * Given {@code input}, {@code scales} and {@code zero_points}, performs quantization using the formula: * quantized_data = floor(input_data * (1.0f / scale) + 0.5f) + zero_point * - * @param data type for {@code output} output * @param input Must be a Tensor of Tin. * @param scales The float value(s) to use as scale(s) to quantize {@code input}. * Must be a scalar Tensor if quantization_axis is -1 (per-tensor quantization), otherwise 1D Tensor of size (input.dim_size(quantization_axis),) (per-axis quantization). @@ -780,7 +788,6 @@ public UniformQuantize uniformQuantize(Operand data type for {@code output} output * @param lhs Must be a 2D Tensor of Tin. * @param rhs Must be a 2D Tensor of Tin. * @param lhsScales The float value(s) used as scale when quantizing original data that lhs represents. @@ -833,7 +840,6 @@ public UniformQuantizedDot uniformQuan * {@code rhs} must be quantized Tensor, where its data value is quantized using the formula: * quantized_data = clip(original_data / scale + zero_point, quantization_min_val, quantization_max_val). * - * @param data type for {@code output} output * @param lhs Must be a 2D Tensor of Tlhs. * @param rhs Must be a 2D Tensor of Trhs. * @param rhsScales The float value(s) used as scale when quantizing original data that rhs represents. @@ -873,7 +879,6 @@ public UniformQuantizedDotHybrid uniformQuantizedDotHybri * i.e. At least one among input_quantization_axis and output_quantization_axis must be -1, or two must be equal. * * - * @param data type for {@code output} output * @param input Must be a Tensor of Tin. * @param inputScales The float value(s) used as scale(s) when quantizing original data that {@code input} represents. * Must be a scalar Tensor if quantization_axis is -1 (per-tensor quantization), otherwise 1D Tensor of size (input.dim_size(quantization_axis),) (per-axis quantization). diff --git a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/RaggedOps.java b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/RaggedOps.java index 83bf63f461f..43b18f0cf57 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/RaggedOps.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/RaggedOps.java @@ -60,7 +60,6 @@ public final class RaggedOps { * {@code i}. *

Values in {@code arr} outside of the range [0, size) are ignored. * - * @param data type for {@code output} output * @param splits 1D int64 {@code Tensor}. * @param values 2D int {@code Tensor}. * @param sizeOutput non-negative int scalar {@code Tensor}. @@ -82,7 +81,6 @@ public RaggedBincount raggedBincount( * Performs sparse-output bin counting for a ragged tensor input. * Counts the number of times each value occurs in the input. * - * @param data type for {@code output_values} output * @param splits Tensor containing the row splits of the ragged tensor to count. * @param values Tensor containing values of the sparse tensor to count. * @param weights A Tensor of the same shape as indices containing per-index weight values. @@ -102,8 +100,6 @@ public RaggedCountSparseOutput raggedCountSparseOutput( * Generates a feature cross from a list of tensors, and returns it as a * RaggedTensor. See {@code tf.ragged.cross} for more details. * - * @param data type for {@code output_values} output - * @param data type for {@code output_row_splits} output * @param raggedValues The values tensor for each RaggedTensor input. * @param raggedRowSplits The row_splits tensor for each RaggedTensor input. * @param sparseIndices The indices tensor for each SparseTensor input. @@ -135,7 +131,6 @@ public RaggedCross raggedCross( /** * The RaggedFillEmptyRows operation * - * @param data type for {@code output_values} output * @param valueRowids The valueRowids value * @param values The values value * @param nrows The nrows value @@ -151,7 +146,6 @@ public RaggedFillEmptyRows raggedFillEmptyRows(Operand data type for {@code d_values} output * @param reverseIndexMap The reverseIndexMap value * @param gradValues The gradValues value * @param data type for {@code RaggedFillEmptyRowsGrad} output and operands @@ -183,8 +177,6 @@ public RaggedFillEmptyRowsGrad raggedFillEmptyRowsGrad( *

(Note: This c++ op is used to implement the higher-level python * {@code tf.ragged.gather} op, which also supports ragged indices.) * - * @param data type for {@code output_nested_splits} output - * @param data type for {@code output_dense_values} output * @param paramsNestedSplits The {@code nested_row_splits} tensors that define the row-partitioning for the * {@code params} RaggedTensor input. * @param paramsDenseValues The {@code flat_values} for the {@code params} RaggedTensor. There was a terminology change @@ -221,8 +213,6 @@ public RaggedGather raggedGather( * The vector inputs must all have the same size. Scalar inputs are broadcast * to match the size of the vector inputs. * - * @param data type for {@code rt_nested_splits} output - * @param data type for {@code rt_dense_values} output * @param starts The starts of each range. * @param limits The limits of each range. * @param deltas The deltas of each range. @@ -250,8 +240,6 @@ public RaggedRange raggedRange(Operand starts, * The vector inputs must all have the same size. Scalar inputs are broadcast * to match the size of the vector inputs. * - * @param data type for {@code rt_nested_splits} output - * @param data type for {@code rt_dense_values} output * @param starts The starts of each range. * @param limits The limits of each range. * @param deltas The deltas of each range. @@ -279,8 +267,6 @@ public RaggedRange raggedRange(Oper * inferred as {@code output_ragged_rank} - {@code rank(encoded_ragged)}. See * {@code RaggedTensorToVariant} for the corresponding encoding logic. * - * @param data type for {@code output_nested_splits} output - * @param data type for {@code output_dense_values} output * @param encodedRagged A {@code variant} Tensor containing encoded {@code RaggedTensor}s. * @param inputRaggedRank The ragged rank of each encoded {@code RaggedTensor} component in the input. If set to * -1, this is inferred as {@code output_ragged_rank} - {@code rank(encoded_ragged)} @@ -310,8 +296,6 @@ public RaggedTensorFromVariant raggedTensorFromVari * inferred as {@code output_ragged_rank} - {@code rank(encoded_ragged)}. See * {@code RaggedTensorToVariant} for the corresponding encoding logic. * - * @param data type for {@code output_nested_splits} output - * @param data type for {@code output_dense_values} output * @param encodedRagged A {@code variant} Tensor containing encoded {@code RaggedTensor}s. * @param inputRaggedRank The ragged rank of each encoded {@code RaggedTensor} component in the input. If set to * -1, this is inferred as {@code output_ragged_rank} - {@code rank(encoded_ragged)} @@ -335,7 +319,6 @@ public RaggedTensorFromVariant ragged * output=SparseTensor(indices=sparse_indices, values=sparse_values, * dense_shape=sparse_dense_shape) * - * @param data type for {@code sparse_values} output * @param rtNestedSplits The {@code row_splits} for the {@code RaggedTensor}. * @param rtDenseValues The {@code flat_values} for the {@code RaggedTensor}. * @param data type for {@code RaggedTensorToSparse} output and operands @@ -365,7 +348,6 @@ public RaggedTensorToSparse raggedTensorToSparse( * is preceded by "FIRST_DIM_SIZE". * * - * @param data type for {@code result} output * @param shape The desired shape of the output tensor. If left unspecified (empty), * the minimal shape required to contain all the elements in the ragged tensor * (the natural shape) will be used. If some dimensions are left unspecified, then @@ -438,7 +420,6 @@ public RaggedTensorToVariant raggedTensorToVariant( * the outer row-splits and the shape of the dense-values that were provided as * inputs to the RaggedTensorToVariant op. * - * @param data type for {@code dense_values_grad} output * @param encodedRaggedGrad A {@code variant} Tensor containing encoded {@code RaggedTensor} gradients. * @param rowSplits Outermost row-splits that were used as input to the RaggedTensorToVariant op. * @param denseValuesShape Shape of the dense_values that was used as an input to the diff --git a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/RandomExperimentalOps.java b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/RandomExperimentalOps.java index 09a2b385b6f..34d3585f270 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/RandomExperimentalOps.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/RandomExperimentalOps.java @@ -49,7 +49,6 @@ public final class RandomExperimentalOps { * *

The outputs are a deterministic function of {@code value}, {@code key}, {@code counter} and {@code alg}. * - * @param data type for {@code output} output * @param value The tensor to be shuffled. * @param key Key for the counter-based RNG algorithm (shape uint64[1]). * @param counter Initial counter for the counter-based RNG algorithm (shape uint64[2] or uint64[1] depending on the algorithm). If a larger vector is given, only the needed portion on the left (i.e. [:N]) will be used. diff --git a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/RandomOps.java b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/RandomOps.java index 3c62a3b57a1..c5ff9a489a0 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/RandomOps.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/RandomOps.java @@ -203,7 +203,6 @@ public LogUniformCandidateSampler logUniformCandidateSampler(Operand tru /** * Draws samples from a multinomial distribution. * - * @param data type for {@code output} output * @param logits 2-D Tensor with shape {@code [batch_size, num_classes]}. Each slice {@code [i, :]} * represents the unnormalized log probabilities for all classes. * @param numSamples 0-D. Number of independent samples to draw for each row slice. @@ -218,7 +217,6 @@ public Multinomial multinomial(Operand logits, /** * Draws samples from a multinomial distribution. * - * @param data type for {@code output} output * @param logits 2-D Tensor with shape {@code [batch_size, num_classes]}. Each slice {@code [i, :]} * represents the unnormalized log probabilities for all classes. * @param numSamples 0-D. Number of independent samples to draw for each row slice. @@ -236,7 +234,6 @@ public Multinomial multinomial(Operand * Non-deterministically generates some integers. * This op may use some OS-provided source of non-determinism (e.g. an RNG), so each execution will give different results. * - * @param data type for {@code output} output * @param shape The shape of the output tensor. * @return a new instance of NonDeterministicInts, with default output types */ @@ -248,7 +245,6 @@ public NonDeterministicInts nonDeterministicInts(Operand data type for {@code output} output * @param shape The shape of the output tensor. * @param dtype The type of the output. * @param data type for {@code NonDeterministicInts} output and operands @@ -264,7 +260,6 @@ public NonDeterministicInts nonDeterministicInts( * scalar which applies to the entire output, or a vector of length shape[0] which * stores the parameters for each batch. * - * @param data type for {@code output} output * @param shape The shape of the output tensor. Batches are indexed by the 0th dimension. * @param means The mean parameter of each batch. * @param stdevs The standard deviation parameter of each batch. Must be greater than 0. @@ -287,7 +282,6 @@ public ParameterizedTruncatedNormal parameterizedTruncate * transformation-rejection from pairs of uniform and normal random variables. * See http://dl.acm.org/citation.cfm?id=358414 * - * @param data type for {@code output} output * @param shape 1-D integer tensor. Shape of independent samples to draw from each * distribution described by the shape parameters given in alpha. * @param alpha A tensor in which each scalar is a "shape" parameter describing the @@ -304,7 +298,6 @@ public RandomGamma randomGamma(Operand /** * Computes the derivative of a Gamma random sample w.r.t. {@code alpha}. * - * @param data type for {@code output} output * @param alpha The alpha value * @param sample The sample value * @param data type for {@code RandomGammaGrad} output and operands @@ -326,7 +319,6 @@ public RandomGammaGrad randomGammaGrad(Operand alpha, * See Donald E. Knuth (1969). Seminumerical Algorithms. The Art of Computer * Programming, Volume 2. Addison Wesley * - * @param data type for {@code output} output * @param shape 1-D integer tensor. Shape of independent samples to draw from each * distribution described by the shape parameters given in rate. * @param rate A tensor in which each scalar is a "rate" parameter describing the @@ -350,7 +342,6 @@ public RandomPoisson randomPoisson(Operand shape, * See Donald E. Knuth (1969). Seminumerical Algorithms. The Art of Computer * Programming, Volume 2. Addison Wesley * - * @param data type for {@code output} output * @param shape 1-D integer tensor. Shape of independent samples to draw from each * distribution described by the shape parameters given in rate. * @param rate A tensor in which each scalar is a "rate" parameter describing the @@ -376,7 +367,6 @@ public RandomPoisson randomPoisson(Operand * - * @param data type for {@code output} output * @param value The tensor to be shuffled. * @param options carries optional attribute values * @param data type for {@code RandomShuffle} output and operands @@ -391,7 +381,6 @@ public RandomShuffle randomShuffle(Operand value, * Outputs random values from a normal distribution. * The generated values will have mean 0 and standard deviation 1. * - * @param data type for {@code output} output * @param shape The shape of the output tensor. * @param dtype The type of the output. * @param options carries optional attribute values @@ -408,7 +397,6 @@ public RandomStandardNormal randomStandardNormal( * The generated values follow a uniform distribution in the range {@code [0, 1)}. The * lower bound 0 is included in the range, while the upper bound 1 is excluded. * - * @param data type for {@code output} output * @param shape The shape of the output tensor. * @param dtype The type of the output. * @param options carries optional attribute values @@ -429,7 +417,6 @@ public RandomUniform randomUniform(Operand data type for {@code output} output * @param shape The shape of the output tensor. * @param minval 0-D. Inclusive lower bound on the generated integers. * @param maxval 0-D. Exclusive upper bound on the generated integers. @@ -491,7 +478,6 @@ public RngSkip rngSkip(Operand resource, Operand algori /** * The StatefulRandomBinomial operation * - * @param data type for {@code output} output * @param resource The resource value * @param algorithm The algorithm value * @param shape The shape value @@ -509,7 +495,6 @@ public StatefulRandomBinomial statefulRandomBinomial /** * The StatefulRandomBinomial operation * - * @param data type for {@code output} output * @param resource The resource value * @param algorithm The algorithm value * @param shape The shape value @@ -530,7 +515,6 @@ public StatefulRandomBinomial stateful * Outputs random values from a normal distribution. * The generated values will have mean 0 and standard deviation 1. * - * @param data type for {@code output} output * @param resource The handle of the resource variable that stores the state of the RNG. * @param algorithm The RNG algorithm. * @param shape The shape of the output tensor. @@ -545,7 +529,6 @@ public StatefulStandardNormal statefulStandardNormal(Operand data type for {@code output} output * @param resource The handle of the resource variable that stores the state of the RNG. * @param algorithm The RNG algorithm. * @param shape The shape of the output tensor. @@ -565,7 +548,6 @@ public StatefulStandardNormal statefulStandardNormal( * deviation 1, except that values whose magnitude is more than 2 standard * deviations from the mean are dropped and re-picked. * - * @param data type for {@code output} output * @param resource The handle of the resource variable that stores the state of the RNG. * @param algorithm The RNG algorithm. * @param shape The shape of the output tensor. @@ -583,7 +565,6 @@ public StatefulTruncatedNormal statefulTruncatedNormal( * deviation 1, except that values whose magnitude is more than 2 standard * deviations from the mean are dropped and re-picked. * - * @param data type for {@code output} output * @param resource The handle of the resource variable that stores the state of the RNG. * @param algorithm The RNG algorithm. * @param shape The shape of the output tensor. @@ -602,7 +583,6 @@ public StatefulTruncatedNormal statefulTruncatedNormal( * The generated values follow a uniform distribution in the range {@code [0, 1)}. The * lower bound 0 is included in the range, while the upper bound 1 is excluded. * - * @param data type for {@code output} output * @param resource The handle of the resource variable that stores the state of the RNG. * @param algorithm The RNG algorithm. * @param shape The shape of the output tensor. @@ -618,7 +598,6 @@ public StatefulUniform statefulUniform(Operand resour * The generated values follow a uniform distribution in the range {@code [0, 1)}. The * lower bound 0 is included in the range, while the upper bound 1 is excluded. * - * @param data type for {@code output} output * @param resource The handle of the resource variable that stores the state of the RNG. * @param algorithm The RNG algorithm. * @param shape The shape of the output tensor. @@ -635,7 +614,6 @@ public StatefulUniform statefulUniform(Operand data type for {@code output} output * @param resource The handle of the resource variable that stores the state of the RNG. * @param algorithm The RNG algorithm. * @param shape The shape of the output tensor. @@ -658,7 +636,6 @@ public StatefulUniformFullInt statefulUniformFullInt( * power of two. The bias is small for values of {@code maxval - minval} significantly * smaller than the range of the output (either {@code 2^32} or {@code 2^64}). * - * @param data type for {@code output} output * @param resource The handle of the resource variable that stores the state of the RNG. * @param algorithm The RNG algorithm. * @param shape The shape of the output tensor. @@ -676,7 +653,6 @@ public StatefulUniformInt statefulUniformInt( /** * Draws samples from a multinomial distribution. * - * @param data type for {@code output} output * @param logits 2-D Tensor with shape {@code [batch_size, num_classes]}. Each slice {@code [i, :]} * represents the unnormalized log probabilities for all classes. * @param numSamples 0-D. Number of independent samples to draw for each row slice. @@ -691,7 +667,6 @@ public StatelessMultinomial statelessMultinomial(Operand data type for {@code output} output * @param logits 2-D Tensor with shape {@code [batch_size, num_classes]}. Each slice {@code [i, :]} * represents the unnormalized log probabilities for all classes. * @param numSamples 0-D. Number of independent samples to draw for each row slice. @@ -709,7 +684,6 @@ public StatelessMultinomial statelessMultinomial( /** * The StatelessParameterizedTruncatedNormal operation * - * @param data type for {@code output} output * @param shape The shape of the output tensor. * @param seed 2 seeds (shape [2]). * @param means The mean parameter of each batch. @@ -731,7 +705,6 @@ public StatelessParameterizedTruncatedNormal statelessPar * Outputs random values from a binomial distribution. *

The outputs are a deterministic function of {@code shape}, {@code seed}, {@code counts}, and {@code probs}. * - * @param data type for {@code output} output * @param shape The shape of the output tensor. * @param seed 2 seeds (shape [2]). * @param counts The counts of the binomial distribution. Must be broadcastable with {@code probs}, @@ -752,7 +725,6 @@ public StatelessRandomBinomial statelessRandomBinomi * Outputs random values from a binomial distribution. *

The outputs are a deterministic function of {@code shape}, {@code seed}, {@code counts}, and {@code probs}. * - * @param data type for {@code output} output * @param shape The shape of the output tensor. * @param seed 2 seeds (shape [2]). * @param counts The counts of the binomial distribution. Must be broadcastable with {@code probs}, @@ -775,7 +747,6 @@ public StatelessRandomBinomial statele * Outputs random values from a gamma distribution. *

The outputs are a deterministic function of the inputs. * - * @param data type for {@code output} output * @param shape The shape of the output tensor. * @param key Key for the counter-based RNG algorithm (shape uint64[1]). * @param counter Initial counter for the counter-based RNG algorithm (shape uint64[2] or uint64[1] depending on the algorithm). If a larger vector is given, only the needed portion on the left (i.e. [:N]) will be used. @@ -830,7 +801,6 @@ public StatelessRandomGetKeyCounterAlg statelessRandomGetKeyCounterAlg( * The generated values will have mean 0 and standard deviation 1. *

The outputs are a deterministic function of {@code shape} and {@code seed}. * - * @param data type for {@code output} output * @param shape The shape of the output tensor. * @param seed 2 seeds (shape [2]). * @return a new instance of StatelessRandomNormal, with default output types @@ -845,7 +815,6 @@ public StatelessRandomNormal statelessRandomNormal(OperandThe outputs are a deterministic function of {@code shape} and {@code seed}. * - * @param data type for {@code output} output * @param shape The shape of the output tensor. * @param seed 2 seeds (shape [2]). * @param dtype The type of the output. @@ -862,7 +831,6 @@ public StatelessRandomNormal statelessRandomNormal( * The generated values will have mean 0 and standard deviation 1. *

The outputs are a deterministic function of {@code shape}, {@code key}, {@code counter} and {@code alg}. * - * @param data type for {@code output} output * @param shape The shape of the output tensor. * @param key Key for the counter-based RNG algorithm (shape uint64[1]). * @param counter Initial counter for the counter-based RNG algorithm (shape uint64[2] or uint64[1] depending on the algorithm). If a larger vector is given, only the needed portion on the left (i.e. [:N]) will be used. @@ -879,7 +847,6 @@ public StatelessRandomNormalV2 statelessRandomNormalV2(OperandThe outputs are a deterministic function of {@code shape}, {@code key}, {@code counter} and {@code alg}. * - * @param data type for {@code output} output * @param shape The shape of the output tensor. * @param key Key for the counter-based RNG algorithm (shape uint64[1]). * @param counter Initial counter for the counter-based RNG algorithm (shape uint64[2] or uint64[1] depending on the algorithm). If a larger vector is given, only the needed portion on the left (i.e. [:N]) will be used. @@ -899,7 +866,6 @@ public StatelessRandomNormalV2 statelessRandomNormalV2( * Outputs random values from a Poisson distribution. *

The outputs are a deterministic function of {@code shape}, {@code seed}, and {@code lam}. * - * @param data type for {@code output} output * @param shape The shape of the output tensor. * @param seed 2 seeds (shape [2]). * @param lam The rate of the Poisson distribution. Shape must match the rightmost dimensions @@ -920,7 +886,6 @@ public StatelessRandomPoisson statelessRandomPoisson( * lower bound 0 is included in the range, while the upper bound 1 is excluded. *

The outputs are a deterministic function of {@code shape} and {@code seed}. * - * @param data type for {@code output} output * @param shape The shape of the output tensor. * @param seed 2 seeds (shape [2]). * @return a new instance of StatelessRandomUniform, with default output types @@ -936,7 +901,6 @@ public StatelessRandomUniform statelessRandomUniform(OperandThe outputs are a deterministic function of {@code shape} and {@code seed}. * - * @param data type for {@code output} output * @param shape The shape of the output tensor. * @param seed 2 seeds (shape [2]). * @param dtype The type of the output. @@ -953,7 +917,6 @@ public StatelessRandomUniform statelessRandomUniform( * The generated values are uniform integers covering the whole range of {@code dtype}. *

The outputs are a deterministic function of {@code shape} and {@code seed}. * - * @param data type for {@code output} output * @param shape The shape of the output tensor. * @param seed 2 seeds (shape [2]). * @param dtype The type of the output. @@ -970,7 +933,6 @@ public StatelessRandomUniformFullInt statelessRandomUnifo * The generated values are uniform integers covering the whole range of {@code dtype}. *

The outputs are a deterministic function of {@code shape}, {@code key}, {@code counter} and {@code alg}. * - * @param data type for {@code output} output * @param shape The shape of the output tensor. * @param key Key for the counter-based RNG algorithm (shape uint64[1]). * @param counter Initial counter for the counter-based RNG algorithm (shape uint64[2] or uint64[1] depending on the algorithm). If a larger vector is given, only the needed portion on the left (i.e. [:N]) will be used. @@ -990,7 +952,6 @@ public StatelessRandomUniformFullIntV2 statelessRandomUni * The generated values follow a uniform distribution in the range {@code [minval, maxval)}. *

The outputs are a deterministic function of {@code shape}, {@code seed}, {@code minval}, and {@code maxval}. * - * @param data type for {@code output} output * @param shape The shape of the output tensor. * @param seed 2 seeds (shape [2]). * @param minval Minimum value (inclusive, scalar). @@ -1009,7 +970,6 @@ public StatelessRandomUniformInt statelessRandomUniformIn * The generated values follow a uniform distribution in the range {@code [minval, maxval)}. *

The outputs are a deterministic function of {@code shape}, {@code key}, {@code counter}, {@code alg}, {@code minval} and {@code maxval}. * - * @param data type for {@code output} output * @param shape The shape of the output tensor. * @param key Key for the counter-based RNG algorithm (shape uint64[1]). * @param counter Initial counter for the counter-based RNG algorithm (shape uint64[2] or uint64[1] depending on the algorithm). If a larger vector is given, only the needed portion on the left (i.e. [:N]) will be used. @@ -1031,7 +991,6 @@ public StatelessRandomUniformIntV2 statelessRandomUniform * lower bound 0 is included in the range, while the upper bound 1 is excluded. *

The outputs are a deterministic function of {@code shape}, {@code key}, {@code counter} and {@code alg}. * - * @param data type for {@code output} output * @param shape The shape of the output tensor. * @param key Key for the counter-based RNG algorithm (shape uint64[1]). * @param counter Initial counter for the counter-based RNG algorithm (shape uint64[2] or uint64[1] depending on the algorithm). If a larger vector is given, only the needed portion on the left (i.e. [:N]) will be used. @@ -1050,7 +1009,6 @@ public StatelessRandomUniformV2 statelessRandomUniformV2( * lower bound 0 is included in the range, while the upper bound 1 is excluded. *

The outputs are a deterministic function of {@code shape}, {@code key}, {@code counter} and {@code alg}. * - * @param data type for {@code output} output * @param shape The shape of the output tensor. * @param key Key for the counter-based RNG algorithm (shape uint64[1]). * @param counter Initial counter for the counter-based RNG algorithm (shape uint64[2] or uint64[1] depending on the algorithm). If a larger vector is given, only the needed portion on the left (i.e. [:N]) will be used. @@ -1072,7 +1030,6 @@ public StatelessRandomUniformV2 statelessRandomUniformV2( * deviations from the mean are dropped and re-picked. *

The outputs are a deterministic function of {@code shape} and {@code seed}. * - * @param data type for {@code output} output * @param shape The shape of the output tensor. * @param seed 2 seeds (shape [2]). * @return a new instance of StatelessTruncatedNormal, with default output types @@ -1089,7 +1046,6 @@ public StatelessTruncatedNormal statelessTruncatedNormal( * deviations from the mean are dropped and re-picked. *

The outputs are a deterministic function of {@code shape} and {@code seed}. * - * @param data type for {@code output} output * @param shape The shape of the output tensor. * @param seed 2 seeds (shape [2]). * @param dtype The type of the output. @@ -1108,7 +1064,6 @@ public StatelessTruncatedNormal statelessTruncatedNormal( * deviations from the mean are dropped and re-picked. *

The outputs are a deterministic function of {@code shape}, {@code key}, {@code counter} and {@code alg}. * - * @param data type for {@code output} output * @param shape The shape of the output tensor. * @param key Key for the counter-based RNG algorithm (shape uint64[1]). * @param counter Initial counter for the counter-based RNG algorithm (shape uint64[2] or uint64[1] depending on the algorithm). If a larger vector is given, only the needed portion on the left (i.e. [:N]) will be used. @@ -1128,7 +1083,6 @@ public StatelessTruncatedNormalV2 statelessTruncatedNormalV2( * deviations from the mean are dropped and re-picked. *

The outputs are a deterministic function of {@code shape}, {@code key}, {@code counter} and {@code alg}. * - * @param data type for {@code output} output * @param shape The shape of the output tensor. * @param key Key for the counter-based RNG algorithm (shape uint64[1]). * @param counter Initial counter for the counter-based RNG algorithm (shape uint64[2] or uint64[1] depending on the algorithm). If a larger vector is given, only the needed portion on the left (i.e. [:N]) will be used. @@ -1176,7 +1130,6 @@ public ThreadUnsafeUnigramCandidateSampler threadUnsafeUnigramCandidateSampler( * deviation 1, except that values whose magnitude is more than 2 standard * deviations from the mean are dropped and re-picked. * - * @param data type for {@code output} output * @param shape The shape of the output tensor. * @param dtype The type of the output. * @param options carries optional attribute values diff --git a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/ShapeOps.java b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/ShapeOps.java index c9cdae676a4..68cb802f86d 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/ShapeOps.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/ShapeOps.java @@ -388,7 +388,8 @@ public Operand tail(Shape shape, Class type) { * shape. * * @param shape the TensorFlow shape - * @param n the number of leading dimensions to get, must be <= than the shape's numDimensions() + * @param n the number of leading dimensions to get, must be less than or equal to the shape's + * numDimensions() * @return a 1-dimensional operand with the dimensions matching the first n dimensions of the * shape */ @@ -401,7 +402,8 @@ public Operand take(Shape shape, Operand n) { * shape. * * @param shape the TensorFlow shape - * @param n the number of leading dimensions to get, must be <= than the shape's numDimensions() + * @param n the number of leading dimensions to get, must be less than or equal to the shape's + * numDimensions() * @param type the shape datatype. * @param the shape datatype. * @return a 1-dimensional operand with the dimensions matching * the first n dimensions of the @@ -416,7 +418,8 @@ public Operand take(Shape shape, Operand n, Class Operand takeLast(Shape shape, Operand * shape. * * @param shape the TensorFlow shape - * @param n the number of leading dimensions to get, must be <= than the shape's numDimensions() + * @param n the number of leading dimensions to get, must be less than or equal to the shape's + * numDimensions() * @param type the shape datatype. * @param the shape datatype. * @return a 1-dimensional operand containing the dimensions matching the last n dimensions of the diff --git a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/SignalOps.java b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/SignalOps.java index 33e2cd4d920..ac5703c264a 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/SignalOps.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/SignalOps.java @@ -125,7 +125,6 @@ public BatchIfft3d batchIfft3d(Operand input) { * Computes the 1-dimensional discrete Fourier transform over the inner-most * dimension of {@code input}. * - * @param data type for {@code output} output * @param input A complex tensor. * @param data type for {@code FFT} output and operands * @return a new instance of Fft @@ -139,7 +138,6 @@ public Fft fft(Operand input) { * Computes the 2-dimensional discrete Fourier transform over the inner-most * 2 dimensions of {@code input}. * - * @param data type for {@code output} output * @param input A complex tensor. * @param data type for {@code FFT2D} output and operands * @return a new instance of Fft2d @@ -153,7 +151,6 @@ public Fft2d fft2d(Operand input) { * Computes the 3-dimensional discrete Fourier transform over the inner-most 3 * dimensions of {@code input}. * - * @param data type for {@code output} output * @param input A complex tensor. * @param data type for {@code FFT3D} output and operands * @return a new instance of Fft3d @@ -173,7 +170,6 @@ public Fft3d fft3d(Operand input) { *

Axes mean the dimensions to perform the transform on. Default is to perform on * all axes. * - * @param data type for {@code output} output * @param input A complex tensor. * @param fftLength An int32 tensor. The FFT length for each dimension. * @param axes An int32 tensor with a same shape as fft_length. Axes to perform the transform. @@ -190,7 +186,6 @@ public FftNd fftNd(Operand input, Operand fftLen * Computes the inverse 1-dimensional discrete Fourier transform over the * inner-most dimension of {@code input}. * - * @param data type for {@code output} output * @param input A complex tensor. * @param data type for {@code IFFT} output and operands * @return a new instance of Ifft @@ -204,7 +199,6 @@ public Ifft ifft(Operand input) { * Computes the inverse 2-dimensional discrete Fourier transform over the * inner-most 2 dimensions of {@code input}. * - * @param data type for {@code output} output * @param input A complex tensor. * @param data type for {@code IFFT2D} output and operands * @return a new instance of Ifft2d @@ -218,7 +212,6 @@ public Ifft2d ifft2d(Operand input) { * Computes the inverse 3-dimensional discrete Fourier transform over the * inner-most 3 dimensions of {@code input}. * - * @param data type for {@code output} output * @param input A complex tensor. * @param data type for {@code IFFT3D} output and operands * @return a new instance of Ifft3d @@ -238,7 +231,6 @@ public Ifft3d ifft3d(Operand input) { *

Axes mean the dimensions to perform the transform on. Default is to perform on * all axes. * - * @param data type for {@code output} output * @param input A complex tensor. * @param fftLength An int32 tensor. The FFT length for each dimension. * @param axes An int32 tensor with a same shape as fft_length. Axes to perform the transform. @@ -264,7 +256,6 @@ public IfftNd ifftNd(Operand input, Operand fftL * than the corresponding dimension of {@code input}, the dimension is cropped. If it is * larger, the dimension is padded with zeros. * - * @param data type for {@code output} output * @param input A complex tensor. * @param fftLength An int32 tensor of shape [1]. The FFT length. * @return a new instance of Irfft, with default output types @@ -287,7 +278,6 @@ public Irfft irfft(Operand input, Operand fft * than the corresponding dimension of {@code input}, the dimension is cropped. If it is * larger, the dimension is padded with zeros. * - * @param data type for {@code output} output * @param input A complex tensor. * @param fftLength An int32 tensor of shape [1]. The FFT length. * @param Treal The value of the Treal attribute @@ -314,7 +304,6 @@ public Irfft irfft(Operand input, * corresponding dimension of {@code input}, the dimension is cropped. If it is larger, * the dimension is padded with zeros. * - * @param data type for {@code output} output * @param input A complex tensor. * @param fftLength An int32 tensor of shape [2]. The FFT length for each dimension. * @return a new instance of Irfft2d, with default output types @@ -338,7 +327,6 @@ public Irfft2d irfft2d(Operand input, Operand * corresponding dimension of {@code input}, the dimension is cropped. If it is larger, * the dimension is padded with zeros. * - * @param data type for {@code output} output * @param input A complex tensor. * @param fftLength An int32 tensor of shape [2]. The FFT length for each dimension. * @param Treal The value of the Treal attribute @@ -365,7 +353,6 @@ public Irfft2d irfft2d(Operand input, * corresponding dimension of {@code input}, the dimension is cropped. If it is larger, * the dimension is padded with zeros. * - * @param data type for {@code output} output * @param input A complex tensor. * @param fftLength An int32 tensor of shape [3]. The FFT length for each dimension. * @return a new instance of Irfft3d, with default output types @@ -389,7 +376,6 @@ public Irfft3d irfft3d(Operand input, Operand * corresponding dimension of {@code input}, the dimension is cropped. If it is larger, * the dimension is padded with zeros. * - * @param data type for {@code output} output * @param input A complex tensor. * @param fftLength An int32 tensor of shape [3]. The FFT length for each dimension. * @param Treal The value of the Treal attribute @@ -413,7 +399,6 @@ public Irfft3d irfft3d(Operand input, *

Axes mean the dimensions to perform the transform on. Default is to perform on * all axes. * - * @param data type for {@code output} output * @param input A complex tensor. * @param fftLength An int32 tensor. The FFT length for each dimension. * @param axes An int32 tensor with a same shape as fft_length. Axes to perform the transform. @@ -436,7 +421,6 @@ public IrfftNd irfftNd(Operand input, Operand *

Axes mean the dimensions to perform the transform on. Default is to perform on * all axes. * - * @param data type for {@code output} output * @param input A complex tensor. * @param fftLength An int32 tensor. The FFT length for each dimension. * @param axes An int32 tensor with a same shape as fft_length. Axes to perform the transform. @@ -460,7 +444,6 @@ public IrfftNd irfftNd(Operand input, * corresponding dimension of {@code input}, the dimension is cropped. If it is larger, * the dimension is padded with zeros. * - * @param data type for {@code output} output * @param input A float32 tensor. * @param fftLength An int32 tensor of shape [1]. The FFT length. * @param Tcomplex The value of the Tcomplex attribute @@ -484,7 +467,6 @@ public Rfft rfft(Operand input, Operand< * corresponding dimension of {@code input}, the dimension is cropped. If it is larger, * the dimension is padded with zeros. * - * @param data type for {@code output} output * @param input A float32 tensor. * @param fftLength An int32 tensor of shape [2]. The FFT length for each dimension. * @param Tcomplex The value of the Tcomplex attribute @@ -508,7 +490,6 @@ public Rfft2d rfft2d(Operand input, * corresponding dimension of {@code input}, the dimension is cropped. If it is larger, * the dimension is padded with zeros. * - * @param data type for {@code output} output * @param input A float32 tensor. * @param fftLength An int32 tensor of shape [3]. The FFT length for each dimension. * @param Tcomplex The value of the Tcomplex attribute @@ -532,7 +513,6 @@ public Rfft3d rfft3d(Operand input, *

Axes mean the dimensions to perform the transform on. Default is to perform on * all axes. * - * @param data type for {@code output} output * @param input A complex tensor. * @param fftLength An int32 tensor. The FFT length for each dimension. * @param axes An int32 tensor with a same shape as fft_length. Axes to perform the transform. diff --git a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/SparseOps.java b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/SparseOps.java index 91726a9a693..f6f83acce58 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/SparseOps.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/SparseOps.java @@ -17,14 +17,18 @@ // package org.tensorflow.op; +import java.util.List; import org.tensorflow.Operand; import org.tensorflow.ndarray.Shape; import org.tensorflow.op.sparse.AddManySparseToTensorsMap; import org.tensorflow.op.sparse.AddSparseToTensorsMap; +import org.tensorflow.op.sparse.ConvertToListOfSparseCoreCooTensors; +import org.tensorflow.op.sparse.ConvertToSparseCoreCsrWrappedCooTensor; import org.tensorflow.op.sparse.DenseCountSparseOutput; import org.tensorflow.op.sparse.DenseToDenseSetOperation; import org.tensorflow.op.sparse.DenseToSparseSetOperation; import org.tensorflow.op.sparse.DeserializeSparse; +import org.tensorflow.op.sparse.GetStatsFromListOfSparseCoreCooTensors; import org.tensorflow.op.sparse.SparseAccumulatorApplyGradient; import org.tensorflow.op.sparse.SparseAccumulatorTakeGradient; import org.tensorflow.op.sparse.SparseAdd; @@ -68,6 +72,7 @@ import org.tensorflow.op.sparse.SparseToSparseSetOperation; import org.tensorflow.op.sparse.TakeManySparseFromTensorsMap; import org.tensorflow.types.TBool; +import org.tensorflow.types.TFloat32; import org.tensorflow.types.TInt32; import org.tensorflow.types.TInt64; import org.tensorflow.types.TString; @@ -151,11 +156,60 @@ public AddSparseToTensorsMap addSparseToTensorsMap(Operand sparseIndices return AddSparseToTensorsMap.create(scope, sparseIndices, sparseValues, sparseShape, options); } + /** + * The ConvertToListOfSparseCoreCooTensors operation + * + * @param indicesOrRowSplits The indicesOrRowSplits value + * @param values The values value + * @param weights The weights value + * @param sampleCount The value of the sampleCount attribute + * @param numScPerChip The value of the numScPerChip attribute + * @param rowOffset The value of the rowOffset attribute + * @param colOffset The value of the colOffset attribute + * @param colShift The value of the colShift attribute + * @param numScShards The value of the numScShards attribute + * @param stackedTableSampleCount The value of the stackedTableSampleCount attribute + * @param combiner The value of the combiner attribute + * @return a new instance of ConvertToListOfSparseCoreCooTensors + */ + public ConvertToListOfSparseCoreCooTensors convertToListOfSparseCoreCooTensors( + Operand indicesOrRowSplits, Operand values, Operand weights, + Long sampleCount, Long numScPerChip, Long rowOffset, Long colOffset, Long colShift, + Long numScShards, Long stackedTableSampleCount, String combiner) { + return ConvertToListOfSparseCoreCooTensors.create(scope, indicesOrRowSplits, values, weights, sampleCount, numScPerChip, rowOffset, colOffset, colShift, numScShards, stackedTableSampleCount, combiner); + } + + /** + * The ConvertToSparseCoreCsrWrappedCooTensor operation + * + * @param sortedRowIdsList The sortedRowIdsList value + * @param sortedColIdsList The sortedColIdsList value + * @param sortedGainsList The sortedGainsList value + * @param idCountsList The idCountsList value + * @param splits The splits value + * @param sampleCountPerSc The value of the sampleCountPerSc attribute + * @param numReplica The value of the numReplica attribute + * @param maxMinibatchesPerSc The value of the maxMinibatchesPerSc attribute + * @param maxIdsPerChipPerSample The value of the maxIdsPerChipPerSample attribute + * @param tableVocabSize The value of the tableVocabSize attribute + * @param featureWidth The value of the featureWidth attribute + * @param tableName The value of the tableName attribute + * @param allowIdDropping The value of the allowIdDropping attribute + * @return a new instance of ConvertToSparseCoreCsrWrappedCooTensor + */ + public ConvertToSparseCoreCsrWrappedCooTensor convertToSparseCoreCsrWrappedCooTensor( + Iterable> sortedRowIdsList, Iterable> sortedColIdsList, + Iterable> sortedGainsList, Iterable> idCountsList, + Operand splits, Long sampleCountPerSc, Long numReplica, Long maxMinibatchesPerSc, + Long maxIdsPerChipPerSample, Long tableVocabSize, Long featureWidth, String tableName, + Boolean allowIdDropping) { + return ConvertToSparseCoreCsrWrappedCooTensor.create(scope, sortedRowIdsList, sortedColIdsList, sortedGainsList, idCountsList, splits, sampleCountPerSc, numReplica, maxMinibatchesPerSc, maxIdsPerChipPerSample, tableVocabSize, featureWidth, tableName, allowIdDropping); + } + /** * Performs sparse-output bin counting for a tf.tensor input. * Counts the number of times each value occurs in the input. * - * @param data type for {@code output_values} output * @param values Tensor containing data to count. * @param weights A Tensor of the same shape as indices containing per-index weight values. May * also be the empty tensor if no weights are used. @@ -179,7 +233,6 @@ public DenseCountSparseOutput denseCountSparseOutput( * dimension contains the result of {@code set_operation} applied to the corresponding * {@code [0...n-1]} dimension of {@code set}. * - * @param data type for {@code result_values} output * @param set1 {@code Tensor} with rank {@code n}. 1st {@code n-1} dimensions must be the same as {@code set2}. * Dimension {@code n} contains values in a set, duplicates are allowed but ignored. * @param set2 {@code Tensor} with rank {@code n}. 1st {@code n-1} dimensions must be the same as {@code set1}. @@ -209,7 +262,6 @@ public DenseToDenseSetOperation denseToDenseSetOperation(Op * dimension contains the result of {@code set_operation} applied to the corresponding * {@code [0...n-1]} dimension of {@code set}. * - * @param data type for {@code result_values} output * @param set1 {@code Tensor} with rank {@code n}. 1st {@code n-1} dimensions must be the same as {@code set2}. * Dimension {@code n} contains values in a set, duplicates are allowed but ignored. * @param set2Indices 2D {@code Tensor}, indices of a {@code SparseTensor}. Must be in row-major @@ -272,7 +324,6 @@ public DenseToSparseSetOperation denseToSparseSetOperation( * shape = [2 50] * * - * @param data type for {@code sparse_values} output * @param serializedSparse The serialized {@code SparseTensor} objects. The last dimension * must have 3 columns. * @param dtype The {@code dtype} of the serialized {@code SparseTensor} objects. @@ -284,6 +335,29 @@ public DeserializeSparse deserializeSparse( return DeserializeSparse.create(scope, serializedSparse, dtype); } + /** + * The GetStatsFromListOfSparseCoreCooTensors operation + * + * @param rowIdsList The rowIdsList value + * @param colIdsList The colIdsList value + * @param gainsList The gainsList value + * @param sampleCountList The value of the sampleCountList attribute + * @param colOffsetList The value of the colOffsetList attribute + * @param numReplica The value of the numReplica attribute + * @param tableVocabSize The value of the tableVocabSize attribute + * @param featureWidth The value of the featureWidth attribute + * @param numScPerChip The value of the numScPerChip attribute + * @param tableName The value of the tableName attribute + * @return a new instance of GetStatsFromListOfSparseCoreCooTensors + */ + public GetStatsFromListOfSparseCoreCooTensors getStatsFromListOfSparseCoreCooTensors( + Iterable> rowIdsList, Iterable> colIdsList, + Iterable> gainsList, List sampleCountList, List colOffsetList, + Long numReplica, Long tableVocabSize, Long featureWidth, Long numScPerChip, + String tableName) { + return GetStatsFromListOfSparseCoreCooTensors.create(scope, rowIdsList, colIdsList, gainsList, sampleCountList, colOffsetList, numReplica, tableVocabSize, featureWidth, numScPerChip, tableName); + } + /** * Applies a sparse gradient to a given accumulator. * Does not add if local_step is smaller than the accumulator's @@ -317,7 +391,6 @@ public SparseAccumulatorApplyGradient sparseAccumulatorApplyGradient(Operand data type for {@code values} output * @param handle The handle to a SparseConditionalAccumulator. * @param numRequired Number of gradients required before we return an aggregate. * @param dtype The data type of accumulated gradients. Needs to correspond to the type @@ -344,7 +417,6 @@ public SparseAccumulatorTakeGradient sparseAccumulatorTakeG * only for a positive value. *

In the following shapes, {@code nnz} is the count after taking {@code thresh} into account. * - * @param data type for {@code sum_values} output * @param aIndices 2-D. The {@code indices} of the first {@code SparseTensor}, size {@code [nnz, ndims]} Matrix. * @param aValues 1-D. The {@code values} of the first {@code SparseTensor}, size {@code [nnz]} Vector. * @param aShape 1-D. The {@code shape} of the first {@code SparseTensor}, size {@code [ndims]} Vector. @@ -369,7 +441,6 @@ public SparseAdd sparseAdd(Operand aIndices, Operan * non-empty values of the sum, and outputs the gradients w.r.t. the non-empty * values of A and B. * - * @param data type for {@code a_val_grad} output * @param backpropValGrad 1-D with shape {@code [nnz(sum)]}. The gradient with respect to * the non-empty values of the sum. * @param aIndices 2-D. The {@code indices} of the {@code SparseTensor} A, size {@code [nnz(A), ndims]}. @@ -393,7 +464,6 @@ public SparseAddGrad sparseAddGrad(Operand backpropValGr * {@code i}. *

Values in {@code arr} outside of the range [0, size) are ignored. * - * @param data type for {@code output} output * @param indices 2D int64 {@code Tensor}. * @param values 1D int {@code Tensor}. * @param denseShape 1D int64 {@code Tensor}. @@ -452,7 +522,6 @@ public SparseBincount sparseBincount( * [b c ] [ ] [b c ] * * - * @param data type for {@code output_values} output * @param indices 2-D. Indices of each input {@code SparseTensor}. * @param values 1-D. Non-empty values of each {@code SparseTensor}. * @param shapes 1-D. Shapes of each {@code SparseTensor}. @@ -490,7 +559,6 @@ public SparseConditionalAccumulator sparseConditionalAccumulat * Performs sparse-output bin counting for a sparse tensor input. * Counts the number of times each value occurs in the input. * - * @param data type for {@code output_values} output * @param indices Tensor containing the indices of the sparse tensor to count. * @param values Tensor containing values of the sparse tensor to count. * @param denseShape Tensor containing the dense shape of the sparse tensor to count. @@ -624,7 +692,6 @@ public SparseCrossHashed sparseCrossHashed(Iterable> indices, * indices and shape, but possibly with different non-zero values. The output of * this Op is the resultant non-zero values. * - * @param data type for {@code output} output * @param spIndices 2-D. {@code N x R} matrix with the indices of non-empty values in a * SparseTensor, possibly not in canonical ordering. * @param spValues 1-D. {@code N} non-empty values corresponding to {@code sp_indices}. @@ -643,7 +710,6 @@ public SparseDenseCwiseAdd sparseDenseCwiseAdd(OperandLimitation: this Op only broadcasts the dense side to the sparse side, but not * the other direction. * - * @param data type for {@code output} output * @param spIndices 2-D. {@code N x R} matrix with the indices of non-empty values in a * SparseTensor, possibly not in canonical ordering. * @param spValues 1-D. {@code N} non-empty values corresponding to {@code sp_indices}. @@ -665,7 +731,6 @@ public SparseDenseCwiseDiv sparseDenseCwiseDiv(OperandLimitation: this Op only broadcasts the dense side to the sparse side, but not * the other direction. * - * @param data type for {@code output} output * @param spIndices 2-D. {@code N x R} matrix with the indices of non-empty values in a * SparseTensor, possibly not in canonical ordering. * @param spValues 1-D. {@code N} non-empty values corresponding to {@code sp_indices}. @@ -716,7 +781,6 @@ public SparseDenseCwiseMul sparseDenseCwiseMul(Operand * - * @param data type for {@code output_values} output * @param indices 2-D. the indices of the sparse tensor. * @param values 1-D. the values of the sparse tensor. * @param denseShape 1-D. the shape of the sparse tensor. @@ -741,7 +805,6 @@ public SparseFillEmptyRows sparseFillEmptyRows(Operand data type for {@code d_values} output * @param reverseIndexMap 1-D. The reverse index map from SparseFillEmptyRows. * @param gradValues 1-D. The gradients from backprop. * @param data type for {@code SparseFillEmptyRowsGrad} output and operands @@ -786,7 +849,6 @@ public SparseMatMul sparseMatMul(Operand a, Operand data type for {@code output} output * @param inputIndices 2-D. {@code N x R} matrix with the indices of non-empty values in a * SparseTensor, possibly not in canonical ordering. * @param inputValues 1-D. {@code N} non-empty values corresponding to {@code input_indices}. @@ -815,7 +877,6 @@ public SparseReduceMax sparseReduceMax(Operand in * with a single element is returned. Additionally, the axes can be negative, * which are interpreted according to the indexing rules in Python. * - * @param data type for {@code output_values} output * @param inputIndices 2-D. {@code N x R} matrix with the indices of non-empty values in a * SparseTensor, possibly not in canonical ordering. * @param inputValues 1-D. {@code N} non-empty values corresponding to {@code input_indices}. @@ -844,7 +905,6 @@ public SparseReduceMaxSparse sparseReduceMaxSparse( * with a single element is returned. Additionally, the axes can be negative, * which are interpreted according to the indexing rules in Python. * - * @param data type for {@code output} output * @param inputIndices 2-D. {@code N x R} matrix with the indices of non-empty values in a * SparseTensor, possibly not in canonical ordering. * @param inputValues 1-D. {@code N} non-empty values corresponding to {@code input_indices}. @@ -873,7 +933,6 @@ public SparseReduceSum sparseReduceSum(Operand inpu * with a single element is returned. Additionally, the axes can be negative, * which are interpreted according to the indexing rules in Python. * - * @param data type for {@code output_values} output * @param inputIndices 2-D. {@code N x R} matrix with the indices of non-empty values in a * SparseTensor, possibly not in canonical ordering. * @param inputValues 1-D. {@code N} non-empty values corresponding to {@code input_indices}. @@ -898,7 +957,6 @@ public SparseReduceSumSparse sparseReduceSumSparse( *

If the tensor has rank {@code R} and {@code N} non-empty values, {@code input_indices} has * shape {@code [N, R]}, input_values has length {@code N}, and input_shape has length {@code R}. * - * @param data type for {@code output_values} output * @param inputIndices 2-D. {@code N x R} matrix with the indices of non-empty values in a * SparseTensor, possibly not in canonical ordering. * @param inputValues 1-D. {@code N} non-empty values corresponding to {@code input_indices}. @@ -943,7 +1001,6 @@ public SparseReshape sparseReshape(Operand inputIndices, Operand *

Like {@code SegmentMean}, but {@code segment_ids} can have rank less than {@code data}'s first * dimension, selecting a subset of dimension 0, specified by {@code indices}. * - * @param data type for {@code output} output * @param data The data value * @param indices A 1-D tensor. Has same rank as {@code segment_ids}. * @param segmentIds A 1-D tensor. Values should be sorted and can be repeated. @@ -963,8 +1020,6 @@ public SparseSegmentMean sparseSegmentMean(Operand dat * value is the number of unique indexes in "indices". Also returns vector * "sorted_unique_indices" containing the corresponding indexes from "indices". * - * @param data type for {@code output} output - * @param data type for {@code sorted_unique_indices} output * @param grad gradient propagated to the SparseSegmentMean op. * @param indices indices passed to the corresponding SparseSegmentMean op. * @param segmentIds segment_ids passed to the corresponding SparseSegmentMean op. @@ -987,7 +1042,6 @@ public SparseSegmentMeanGrad sparse * the section on segmentation * for an explanation of segments. * - * @param data type for {@code output} output * @param data The data value * @param indices A 1-D tensor. Has same rank as {@code segment_ids}. * @param segmentIds A 1-D tensor. Values should be sorted and can be repeated. @@ -1007,7 +1061,6 @@ public SparseSegmentMeanWithNumSegments sparseSegmentMean * N is the size of the segment being reduced. *

See {@code tf.sparse.segment_sum} for usage examples. * - * @param data type for {@code output} output * @param data The data value * @param indices A 1-D tensor. Has same rank as {@code segment_ids}. * @param segmentIds A 1-D tensor. Values should be sorted and can be repeated. @@ -1027,8 +1080,6 @@ public SparseSegmentSqrtN sparseSegmentSqrtN(Operand d * value is the number of unique indexes in "indices". Also returns vector * "sorted_unique_indices" containing the corresponding indexes from "indices". * - * @param data type for {@code output} output - * @param data type for {@code sorted_unique_indices} output * @param grad gradient propagated to the SparseSegmentSqrtN op. * @param indices indices passed to the corresponding SparseSegmentSqrtN op. * @param segmentIds segment_ids passed to the corresponding SparseSegmentSqrtN op. @@ -1052,7 +1103,6 @@ public SparseSegmentSqrtNGrad spars * the section on segmentation * for an explanation of segments. * - * @param data type for {@code output} output * @param data The data value * @param indices A 1-D tensor. Has same rank as {@code segment_ids}. * @param segmentIds A 1-D tensor. Values should be sorted and can be repeated. @@ -1097,7 +1147,6 @@ public SparseSegmentSqrtNWithNumSegments sparseSegmentSqr * tf.segment_sum(c, tf.constant([0, 0, 1])) * * - * @param data type for {@code output} output * @param data The data value * @param indices A 1-D tensor. Has same rank as {@code segment_ids}. * @param segmentIds A 1-D tensor. Values should be sorted and can be repeated. @@ -1117,8 +1166,6 @@ public SparseSegmentSum sparseSegmentSum(Operand data, * value is the number of unique indexes in "indices". Also returns vector * "sorted_unique_indices" containing the corresponding indexes from "indices". * - * @param data type for {@code output} output - * @param data type for {@code sorted_unique_indices} output * @param grad gradient propagated to the SparseSegmentSum op. * @param indices indices passed to the corresponding SparseSegmentSum op. * @param segmentIds segment_ids passed to the corresponding SparseSegmentSum op. @@ -1160,7 +1207,6 @@ public SparseSegmentSumGrad sparseS * # [ 0 0 0 0]] * * - * @param data type for {@code output} output * @param data The data value * @param indices A 1-D tensor. Has same rank as {@code segment_ids}. * @param segmentIds A 1-D tensor. Values should be sorted and can be repeated. @@ -1194,7 +1240,6 @@ public SparseSegmentSumWithNumSegments sparseSegmentSumWi * [ ] * * - * @param data type for {@code output_values} output * @param indices 2-D tensor represents the indices of the sparse tensor. * @param values 1-D tensor represents the values of the sparse tensor. * @param shape 1-D. tensor represents the shape of the sparse tensor. @@ -1216,7 +1261,6 @@ public SparseSlice sparseSlice(Operand indices, Ope * the sliced {@code SparseTensor}, and outputs the gradients w.r.t. * the non-empty values of input {@code SparseTensor}. * - * @param data type for {@code val_grad} output * @param backpropValGrad 1-D. The gradient with respect to * the non-empty values of the sliced {@code SparseTensor}. * @param inputIndices 2-D. The {@code indices} of the input {@code SparseTensor}. @@ -1245,7 +1289,6 @@ public SparseSliceGrad sparseSliceGrad(Operand backpropV *

Hence, the {@code SparseTensor} result has exactly the same non-zero indices and * shape. * - * @param data type for {@code output} output * @param spIndices 2-D. {@code NNZ x R} matrix with the indices of non-empty values in a * SparseTensor, in canonical ordering. * @param spValues 1-D. {@code NNZ} non-empty values corresponding to {@code sp_indices}. @@ -1262,7 +1305,6 @@ public SparseSoftmax sparseSoftmax(Operand spIndi * Returns the element-wise max of two SparseTensors. * Assumes the two SparseTensors have the same shape, i.e., no broadcasting. * - * @param data type for {@code output_values} output * @param aIndices 2-D. {@code N x R} matrix with the indices of non-empty values in a * SparseTensor, in the canonical lexicographic ordering. * @param aValues 1-D. {@code N} non-empty values corresponding to {@code a_indices}. @@ -1283,7 +1325,6 @@ public SparseSparseMaximum sparseSparseMaximum(Operand data type for {@code output_values} output * @param aIndices 2-D. {@code N x R} matrix with the indices of non-empty values in a * SparseTensor, in the canonical lexicographic ordering. * @param aValues 1-D. {@code N} non-empty values corresponding to {@code a_indices}. @@ -1321,7 +1362,6 @@ public SparseSparseMinimum sparseSparseMinimum(Operand * - * @param data type for {@code output_values} output * @param splitDim 0-D. The dimension along which to split. Must be in the range * {@code [0, rank(shape))}. * @param indices 2-D tensor represents the indices of the sparse tensor. @@ -1342,7 +1382,6 @@ public SparseSplit sparseSplit(Operand splitDim, * Adds up a {@code SparseTensor} and a dense {@code Tensor}, producing a dense {@code Tensor}. * This Op does not require {@code a_indices} be sorted in standard lexicographic order. * - * @param data type for {@code output} output * @param aIndices 2-D. The {@code indices} of the {@code SparseTensor}, with shape {@code [nnz, ndims]}. * @param aValues 1-D. The {@code values} of the {@code SparseTensor}, with shape {@code [nnz]}. * @param aShape 1-D. The {@code shape} of the {@code SparseTensor}, with shape {@code [ndims]}. @@ -1367,7 +1406,6 @@ public SparseTensorDenseAdd sparseTensor * A should be sorted in order of increasing dimension 1 (i.e., "column major" * order instead of "row major" order). * - * @param data type for {@code product} output * @param aIndices 2-D. The {@code indices} of the {@code SparseTensor}, size {@code [nnz, 2]} Matrix. * @param aValues 1-D. The {@code values} of the {@code SparseTensor}, size {@code [nnz]} Vector. * @param aShape 1-D. The {@code shape} of the {@code SparseTensor}, size {@code [2]} Vector. @@ -1401,7 +1439,6 @@ public SparseTensorDenseMatMul sparseTensorDenseMatMul( * contain any repeats. If {@code validate_indices} is true, these properties * are checked during execution. * - * @param data type for {@code dense} output * @param sparseIndices 0-D, 1-D, or 2-D. {@code sparse_indices[i]} contains the complete * index where {@code sparse_values[i]} will be placed. * @param outputShape 1-D. Shape of the dense output tensor. @@ -1441,7 +1478,6 @@ public SparseToDense sparseToDense( * dimension contains the result of {@code set_operation} applied to the corresponding * {@code [0...n-1]} dimension of {@code set}. * - * @param data type for {@code result_values} output * @param set1Indices 2D {@code Tensor}, indices of a {@code SparseTensor}. Must be in row-major * order. * @param set1Values 1D {@code Tensor}, values of a {@code SparseTensor}. Must be in row-major @@ -1511,7 +1547,6 @@ public SparseToSparseSetOperation sparseToSparseSetOperatio * shape = [2 50] * * - * @param data type for {@code sparse_values} output * @param sparseHandles 1-D, The {@code N} serialized {@code SparseTensor} objects. * Shape: {@code [N]}. * @param dtype The {@code dtype} of the {@code SparseTensor} objects stored in the diff --git a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/StringsOps.java b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/StringsOps.java index b7d38d58553..56a82c2dbf6 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/StringsOps.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/StringsOps.java @@ -260,7 +260,6 @@ public StringLength stringLength(Operand input, StringLength.Options... * strings and outputs a ragged tensor with 1 ragged dimension containing ngrams * of that string, joined along the innermost axis. * - * @param data type for {@code ngrams_splits} output * @param data The values tensor of the ragged string tensor to make ngrams out of. Must be a * 1D string tensor. * @param dataSplits The splits tensor of the ragged string tensor to make ngrams out of. @@ -510,7 +509,6 @@ public ToHashBucketStrong toHashBucketStrong(Operand input, Long numBuc * * * - * @param data type for {@code output} output * @param stringTensor The stringTensor value * @return a new instance of ToNumber, with default output types */ @@ -533,7 +531,6 @@ public ToNumber toNumber(Operand stringTensor) { * * * - * @param data type for {@code output} output * @param stringTensor The stringTensor value * @param outType The numeric type to interpret each string in {@code string_tensor} as. * @param data type for {@code StringToNumber} output and operands @@ -559,7 +556,6 @@ public ToNumber toNumber(Operand stringTensor, C * string (in row-major order). * * - * @param data type for {@code row_splits} output * @param input The text to be decoded. Can have any shape. Note that the output is flattened * to a vector of char values. * @param inputEncoding Text encoding of the input strings. This is any of the encodings supported @@ -588,7 +584,6 @@ public UnicodeDecode unicodeDecode(Operand input, String inputE * string (in row-major order). * * - * @param data type for {@code row_splits} output * @param input The text to be decoded. Can have any shape. Note that the output is flattened * to a vector of char values. * @param inputEncoding Text encoding of the input strings. This is any of the encodings supported @@ -623,7 +618,6 @@ public UnicodeDecode unicodeDecode(Operand input * string (in row-major order). * * - * @param data type for {@code row_splits} output * @param input The text to be decoded. Can have any shape. Note that the output is flattened * to a vector of char values. * @param inputEncoding Text encoding of the input strings. This is any of the encodings supported @@ -656,7 +650,6 @@ public UnicodeDecodeWithOffsets unicodeDecodeWithOffsets(Operand * * - * @param data type for {@code row_splits} output * @param input The text to be decoded. Can have any shape. Note that the output is flattened * to a vector of char values. * @param inputEncoding Text encoding of the input strings. This is any of the encodings supported diff --git a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/TpuOps.java b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/TpuOps.java index 59a9f973858..f6ea8e12178 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/TpuOps.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/TpuOps.java @@ -26,8 +26,6 @@ import org.tensorflow.op.tpu.CompilationResult; import org.tensorflow.op.tpu.Compile; import org.tensorflow.op.tpu.CompileSucceededAssert; -import org.tensorflow.op.tpu.ComputeDedupDataSize; -import org.tensorflow.op.tpu.ComputeDedupDataTupleMask; import org.tensorflow.op.tpu.ConfigureAndInitializeGlobalTPU; import org.tensorflow.op.tpu.ConfigureDistributedTPU; import org.tensorflow.op.tpu.ConfigureTPUEmbedding; @@ -52,6 +50,7 @@ import org.tensorflow.op.tpu.FinalizeTPUEmbedding; import org.tensorflow.op.tpu.GetMinibatchSplitsWithPhysicalReplica; import org.tensorflow.op.tpu.GetMinibatchesInCsrWithPhysicalReplica; +import org.tensorflow.op.tpu.GetTpuTaskId; import org.tensorflow.op.tpu.GlobalIterId; import org.tensorflow.op.tpu.InfeedDequeue; import org.tensorflow.op.tpu.InfeedDequeueTuple; @@ -158,7 +157,6 @@ public final class TpuOps { *

replica 0's output: {@code [[A], [C]]} * replica 1's output: {@code [[B], [D]]} * - * @param data type for {@code output} output * @param input The local input to the sum. * @param groupAssignment An int32 tensor with shape * [num_groups, num_replicas_per_group]. {@code group_assignment[i]} represents the @@ -242,32 +240,6 @@ public CompileSucceededAssert compileSucceededAssert(Operand compilatio return CompileSucceededAssert.create(scope, compilationStatus); } - /** - * An op computes the size of the deduplication data from embedding core and returns the updated config. - * This op is to compute size of the deduplication data so to provide this - * information to the op that computes the tuple mask of deduplication data can - * have static output shape. - * - * @param config Serialized TPUEmbeddingConfiguration proto. - * @return a new instance of ComputeDedupDataSize - */ - public ComputeDedupDataSize computeDedupDataSize(String config) { - return ComputeDedupDataSize.create(scope, config); - } - - /** - * An op computes tuple mask of deduplication data from embedding core. - * The deduplication data receiving from embedding core is a Tensor with - * type=DT_VARIANT. The tensor itself is an XLA nested tuple, whose elements are - * rank 1 tensors. This op is to represents types and length of these elements. - * - * @param config Serialized TPUEmbeddingConfiguration proto. - * @return a new instance of ComputeDedupDataTupleMask - */ - public ComputeDedupDataTupleMask computeDedupDataTupleMask(String config) { - return ComputeDedupDataTupleMask.create(scope, config); - } - /** * An op that sets up the centralized structures for a distributed TPU system. * @@ -365,7 +337,6 @@ public ConvertToCooTensor convertToCooTensor(Operand indicesOrRowSplits, * and {@code B, D, F, H} as group 1. Thus we get the outputs: * {@code [A+C+E+G, B+D+F+H, A+C+E+G, B+D+F+H, A+C+E+G, B+D+F+H, A+C+E+G, B+D+F+H]}. * - * @param data type for {@code output} output * @param input The local input to the sum. * @param groupAssignment An int32 tensor with shape * [num_groups, num_replicas_per_group]. {@code group_assignment[i]} represents the @@ -789,6 +760,16 @@ public GetMinibatchesInCsrWithPhysicalReplica getMinibatchesInCsrWithPhysicalRep return GetMinibatchesInCsrWithPhysicalReplica.create(scope, programKey, rowIds, colIds, gains, splits, idCounts, sampleCount, numReplica, maxMinibatchesPerSc, maxIdsPerChipPerSample, tableVocabSize, featureWidth, numScPerChip, tableName, miniBatchInCsr); } + /** + * An op returns the TPU task ID from TPU topology. + * This op is to return the TPU task ID from TPU topology. + * + * @return a new instance of GetTpuTaskId + */ + public GetTpuTaskId getTpuTaskId() { + return GetTpuTaskId.create(scope); + } + /** * The GlobalIterId operation * @@ -801,7 +782,6 @@ public GlobalIterId globalIterId() { /** * A placeholder op for a value that will be fed into the computation. * - * @param data type for {@code output} output * @param dtype The type of elements in the tensor. * @param shape The shape of the tensor. * @param data type for {@code InfeedDequeue} output and operands @@ -1252,7 +1232,6 @@ public OrdinalSelector ordinalSelector() { * Retrieves a single tensor from the computation outfeed. * This operation will block indefinitely until data is available. * - * @param data type for {@code output} output * @param dtype The type of elements in the tensor. * @param shape The shape of the tensor. * @param options carries optional attribute values @@ -1302,7 +1281,6 @@ public OutfeedDequeueTupleV2 outfeedDequeueTupleV2(Operand deviceOrdinal * tensor allowing dynamic outfeed. * This operation will block indefinitely until data is available. * - * @param data type for {@code output} output * @param deviceOrdinal An int scalar tensor, representing the TPU device to use. This should be -1 when * the Op is running on a TPU device, and >= 0 when the Op is running on the CPU * device. @@ -1355,7 +1333,6 @@ public PartitionedCall partitionedCall(Iterable> args, Operand data type for {@code output} output * @param inputs A list of partitioned inputs which must have the same shape. * @param partitionDims A list of integers describing how each dimension is partitioned. Emptiness * indicates the inputs are replicated. @@ -1372,7 +1349,6 @@ public PartitionedInput partitionedInput(Iterable data type for {@code output} output * @param inputs A tensor which represents the full shape of partitioned tensors. * @param numSplits The value of the numSplits attribute * @param partitionDims A list of integers describing how each dimension is partitioned. Emptiness @@ -1454,7 +1430,6 @@ public ReplicateMetadata replicateMetadata(Long numReplicas, * *

The above computation has a replicated input of two replicas. * - * @param data type for {@code output} output * @param inputs The inputs value * @param options carries optional attribute values * @param data type for {@code TPUReplicatedInput} output and operands @@ -1476,7 +1451,6 @@ public ReplicatedInput replicatedInput(Iterable> * *

The above computation has a replicated output of two replicas. * - * @param data type for {@code outputs} output * @param input The input value * @param numReplicas The value of the numReplicas attribute * @param data type for {@code TPUReplicatedOutput} output and operands @@ -1784,8 +1758,6 @@ public ShutdownTPUSystem shutdownTPUSystem() { * values. This op is to split these values into two groups for two types, and * construct each group as one tensor to return. * - * @param data type for {@code integer_tensor} output - * @param data type for {@code float_tensor} output * @param input An XLA tuple including integer and float elements as deduplication data tuple. * @param integerType integer_tensor type. Allowed types: int32, int64, uint32, uint64. * @param floatType float_tensor type. Allowed types: half, bfloat16, float. @@ -1913,7 +1885,6 @@ public TPUReplicateMetadata tPUReplicateMetadata(Long numReplicas, * *

The above computation has a replicated input of two replicas. * - * @param data type for {@code output} output * @deprecated use {@link org.tensorflow.op.tpu.ReplicatedInput} instead * @param inputs The inputs value * @param options carries optional attribute values @@ -1937,7 +1908,6 @@ public TPUReplicatedInput tPUReplicatedInput(Iterable *

The above computation has a replicated output of two replicas. * - * @param data type for {@code outputs} output * @deprecated use {@link org.tensorflow.op.tpu.ReplicatedOutput} instead * @param input The input value * @param numReplicas The value of the numReplicas attribute diff --git a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/TrainOps.java b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/TrainOps.java index 0442b896828..3ee5b8de813 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/TrainOps.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/TrainOps.java @@ -166,7 +166,6 @@ public AccumulatorSetGlobalStep accumulatorSetGlobalStep(Operand handle * the accumulated gradients. Also automatically increments the recorded * global_step in the accumulator by 1, and resets the aggregate to 0. * - * @param data type for {@code average} output * @param handle The handle to an accumulator. * @param numRequired Number of gradients required before we return an aggregate. * @param dtype The data type of accumulated gradients. Needs to correspond to the type @@ -185,7 +184,6 @@ public AccumulatorTakeGradient accumulatorTakeGradient( * v_t <- max(beta2 * v_{t-1}, abs(g)) * variable <- variable - learning_rate / (1 - beta1^t) * m_t / (v_t + epsilon) * - * @param data type for {@code out} output * @param var Should be from a Variable(). * @param m Should be from a Variable(). * @param v Should be from a Variable(). @@ -212,7 +210,6 @@ public ApplyAdaMax applyAdaMax(Operand var, Operand m * update_accum = rho() * update_accum + (1 - rho()) * update.square(); * var -= update; * - * @param data type for {@code out} output * @param var Should be from a Variable(). * @param accum Should be from a Variable(). * @param accumUpdate Should be from a Variable(). @@ -235,7 +232,6 @@ public ApplyAdadelta applyAdadelta(Operand var, Operand< * accum += grad * grad * var -= lr * grad * (1 / sqrt(accum)) * - * @param data type for {@code out} output * @param var Should be from a Variable(). * @param accum Should be from a Variable(). * @param lr Scaling factor. Must be a scalar. @@ -252,7 +248,6 @@ public ApplyAdagrad applyAdagrad(Operand var, Operand /** * Update '*var' according to the proximal adagrad scheme. * - * @param data type for {@code out} output * @param var Should be from a Variable(). * @param gradientAccumulator Should be from a Variable(). * @param gradientSquaredAccumulator Should be from a Variable(). @@ -277,7 +272,6 @@ public ApplyAdagradDa applyAdagradDa(Operand var, * accum += grad * grad * var -= lr * grad * (1 / sqrt(accum)) * - * @param data type for {@code out} output * @param var Should be from a Variable(). * @param accum Should be from a Variable(). * @param lr Scaling factor. Must be a scalar. @@ -299,7 +293,6 @@ public ApplyAdagradV2 applyAdagradV2(Operand var, Operan * $$v_t := \beta_2 \cdot v_{t-1} + (1 - \beta_2) \cdot g^2$$ * $$\text{var} := \begin{cases} \text{var} - (m_t \beta_1 + g \cdot (1 - \beta_1))\cdot\text{lr}_t/(\sqrt{v_t} + \epsilon), &\text{if use_nesterov}\\ \text{var} - m_t \cdot \text{lr}_t /(\sqrt{v_t} + \epsilon), &\text{otherwise} \end{cases}$$ * - * @param data type for {@code out} output * @param var Should be from a Variable(). * @param m Should be from a Variable(). * @param v Should be from a Variable(). @@ -326,7 +319,6 @@ public ApplyAdam applyAdam(Operand var, Operand m, Op * update <- (alpha + sign_decay * sign(g) *sign(m)) * g * variable <- variable - lr_t * update * - * @param data type for {@code out} output * @param var Should be from a Variable(). * @param m Should be from a Variable(). * @param lr Scaling factor. Must be a scalar. @@ -361,7 +353,6 @@ public ApplyAddSign applyAddSign(Operand var, Operand * mom <- momentum * mom_{t-1} + lr * grad / sqrt(ms - mg * mg + epsilon) * var <- var - mom * - * @param data type for {@code out} output * @param var Should be from a Variable(). * @param mg Should be from a Variable(). * @param ms Should be from a Variable(). @@ -392,7 +383,6 @@ public ApplyCenteredRmsProp applyCenteredRmsProp(Operand * var = (sign(linear) * l1 - linear) / quadratic if |linear| > l1 else 0.0 * accum = accum_new * - * @param data type for {@code out} output * @param var Should be from a Variable(). * @param accum Should be from a Variable(). * @param linear Should be from a Variable(). @@ -415,7 +405,6 @@ public ApplyFtrl applyFtrl(Operand var, Operand accum /** * Update '*var' by subtracting 'alpha' * 'delta' from it. * - * @param data type for {@code out} output * @param var Should be from a Variable(). * @param alpha Scaling factor. Must be a scalar. * @param delta The change. @@ -434,7 +423,6 @@ public ApplyGradientDescent applyGradientDescent(Operand *

accum = accum * momentum + grad * var -= lr * accum * - * @param data type for {@code out} output * @param var Should be from a Variable(). * @param accum Should be from a Variable(). * @param lr Scaling factor. Must be a scalar. @@ -455,7 +443,6 @@ public ApplyMomentum applyMomentum(Operand var, Operand< * update <- exp(logbase * sign_decay * sign(g) * sign(m_t)) * g * variable <- variable - lr_t * update * - * @param data type for {@code out} output * @param var Should be from a Variable(). * @param m Should be from a Variable(). * @param lr Scaling factor. Must be a scalar. @@ -479,7 +466,6 @@ public ApplyPowerSign applyPowerSign(Operand var, Operan * prox_v = var - lr * grad * (1 / sqrt(accum)) * var = sign(prox_v)/(1+lrl2) * max{|prox_v|-lrl1,0} * - * @param data type for {@code out} output * @param var Should be from a Variable(). * @param accum Should be from a Variable(). * @param lr Scaling factor. Must be a scalar. @@ -501,7 +487,6 @@ public ApplyProximalAdagrad applyProximalAdagrad(Operand * prox_v = var - alpha * delta * var = sign(prox_v)/(1+alphal2) * max{|prox_v|-alphal1,0} * - * @param data type for {@code out} output * @param var Should be from a Variable(). * @param alpha Scaling factor. Must be a scalar. * @param l1 L1 regularization. Must be a scalar. @@ -528,7 +513,6 @@ public ApplyProximalGradientDescent applyProximalGradientDe * mom <- momentum * mom_{t-1} + lr * grad / sqrt(ms + epsilon) * var <- var - mom * - * @param data type for {@code out} output * @param var Should be from a Variable(). * @param ms Should be from a Variable(). * @param mom Should be from a Variable(). @@ -570,7 +554,6 @@ public ApplyRmsProp applyRmsProp(Operand var, Operand * about broadcasting * here . * - * @param data type for {@code output} output * @param x 2-D or higher with shape {@code [..., r_x, c_x]}. * @param y 2-D or higher with shape {@code [..., r_y, c_y]}. * @param Tout If not spcified, Tout is the same type to input type. @@ -717,7 +700,6 @@ public NegTrain negTrain(Operand wIn, Operand wOut, Operand< * op exists to prevent subtle bugs from silently returning unimplemented * gradients in some corner cases. * - * @param data type for {@code output} output * @param input any tensor. * @param options carries optional attribute values * @param data type for {@code PreventGradient} output and operands @@ -776,7 +758,6 @@ public ResourceAccumulatorSetGlobalStep resourceAccumulatorSetGlobalStep( * the accumulated gradients. Also automatically increments the recorded * global_step in the accumulator by 1, and resets the aggregate to 0. * - * @param data type for {@code average} output * @param handle The handle to an accumulator. * @param numRequired Number of gradients required before we return an aggregate. * @param dtype The data type of accumulated gradients. Needs to correspond to the type @@ -1535,7 +1516,6 @@ public Restore restore(Operand prefix, Operand tensorNames, *

The {@code shape_and_slice} input has the same format as the * elements of the {@code shapes_and_slices} input of the {@code SaveSlices} op. * - * @param data type for {@code tensor} output * @param filePattern Must have a single element. The pattern of the files from * which we read the tensor. * @param tensorName Must have a single element. The name of the tensor to be @@ -1687,7 +1667,6 @@ public SdcaShrinkL1 sdcaShrinkL1(Iterable> weights, Float l1, /** * var: Should be from a Variable(). * - * @param data type for {@code out} output * @param var The var value * @param accum Should be from a Variable(). * @param accumUpdate : Should be from a Variable(). @@ -1712,7 +1691,6 @@ public SparseApplyAdadelta sparseApplyAdadelta(Operand v * $$accum += grad * grad$$ * $$var -= lr * grad * (1 / sqrt(accum))$$ * - * @param data type for {@code out} output * @param var Should be from a Variable(). * @param accum Should be from a Variable(). * @param lr Learning rate. Must be a scalar. @@ -1732,7 +1710,6 @@ public SparseApplyAdagrad sparseApplyAdagrad(Operand var /** * Update entries in '*var' and '*accum' according to the proximal adagrad scheme. * - * @param data type for {@code out} output * @param var Should be from a Variable(). * @param gradientAccumulator Should be from a Variable(). * @param gradientSquaredAccumulator Should be from a Variable(). @@ -1769,7 +1746,6 @@ public SparseApplyAdagradDa sparseApplyAdagradDa(Operand * $$mom <- momentum * mom_{t-1} + lr * grad / sqrt(ms + epsilon)$$ * $$var <- var - mom$$ * - * @param data type for {@code out} output * @param var Should be from a Variable(). * @param mg Should be from a Variable(). * @param ms Should be from a Variable(). @@ -1802,7 +1778,6 @@ public SparseApplyCenteredRmsProp sparseApplyCenteredRmsPro * var = (sign(linear) * l1 - linear) / quadratic if |linear| > l1 else 0.0 * accum = accum_new * - * @param data type for {@code out} output * @param var Should be from a Variable(). * @param accum Should be from a Variable(). * @param linear Should be from a Variable(). @@ -1831,7 +1806,6 @@ public SparseApplyFtrl sparseApplyFtrl(Operand var, Oper *

$$accum = accum * momentum + grad$$ * $$var -= lr * accum$$ * - * @param data type for {@code out} output * @param var Should be from a Variable(). * @param accum Should be from a Variable(). * @param lr Learning rate. Must be a scalar. @@ -1856,7 +1830,6 @@ public SparseApplyMomentum sparseApplyMomentum(Operand v * $$prox_v -= lr * grad * (1 / sqrt(accum))$$ * $$var = sign(prox_v)/(1+lrl2) * max{|prox_v|-lrl1,0}$$ * - * @param data type for {@code out} output * @param var Should be from a Variable(). * @param accum Should be from a Variable(). * @param lr Learning rate. Must be a scalar. @@ -1880,7 +1853,6 @@ public SparseApplyProximalAdagrad sparseApplyProximalAdagra * $$prox_v = var - alpha * grad$$ * $$var = sign(prox_v)/(1+alphal2) * max{|prox_v|-alphal1,0}$$ * - * @param data type for {@code out} output * @param var Should be from a Variable(). * @param alpha Scaling factor. Must be a scalar. * @param l1 L1 regularization. Must be a scalar. @@ -1908,7 +1880,6 @@ public SparseApplyProximalGradientDescent sparseApplyProxim * $$mom <- momentum * mom_{t-1} + lr * grad / sqrt(ms + epsilon)$$ * $$var <- var - mom$$ * - * @param data type for {@code out} output * @param var Should be from a Variable(). * @param ms Should be from a Variable(). * @param mom Should be from a Variable(). @@ -1960,7 +1931,6 @@ public SymbolicGradient symbolicGradient(Iterable> input, * along each dimension, {@code train.TileGrad} takes in {@code multiples} and aggregates * each repeated tile of {@code input} into {@code output}. * - * @param data type for {@code output} output * @param input The input value * @param multiples The multiples value * @param data type for {@code TileGrad} output and operands diff --git a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/XlaOps.java b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/XlaOps.java index 75f9104ce4b..22a2ef5ae85 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/XlaOps.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/annotations/org/tensorflow/op/XlaOps.java @@ -27,9 +27,6 @@ import org.tensorflow.op.xla.SplitND; import org.tensorflow.op.xla.XlaHostCompute; import org.tensorflow.op.xla.XlaRecvFromHost; -import org.tensorflow.op.xla.XlaRecvTPUEmbeddingActivations; -import org.tensorflow.op.xla.XlaRecvTPUEmbeddingDeduplicationData; -import org.tensorflow.op.xla.XlaSendTPUEmbeddingGradients; import org.tensorflow.op.xla.XlaSendToHost; import org.tensorflow.op.xla.XlaSparseCoreAdagrad; import org.tensorflow.op.xla.XlaSparseCoreAdagradMomentum; @@ -95,18 +92,8 @@ public final class XlaOps { * * * @param resource Resource variable for concatenated input tensors across all dimensions. - * } - * in_arg { - * name: "inputs" - * description: <<END - * Input tensor slices in row-major order to merge across all dimensions. All + * @param inputs Input tensor slices in row-major order to merge across all dimensions. All * inputs must have the same shape. - * } - * out_arg { - * name: "output" - * description: <<END - * Output tensor formed from merging input slices based on num_concats defined. - * @param inputs The inputs value * @param numConcats Number of ways to merge per dimension. * @param options carries optional attribute values * @return a new instance of AssignVariableConcatND @@ -149,14 +136,8 @@ public AssignVariableConcatND assignVariableConcatND(Operand re * [8, 9, 10]] * * - * @param data type for {@code output} output * @param inputs Input tensor slices in row-major order to merge across all dimensions. All * inputs must have the same shape. - * } - * out_arg { - * name: "output" - * description: <<END - * Output tensor formed from merging input slices based on num_concats defined. * @param numConcats Number of ways to merge per dimension. * @param options carries optional attribute values * @param data type for {@code XlaConcatND} output and operands @@ -199,13 +180,7 @@ public ConcatND concatND(Iterable> inputs, List< * [0, 0]] * * - * @param data type for {@code outputs} output * @param resource Resource variable of input tensor to split across all dimensions. - * } - * out_arg { - * name: "outputs" - * description: <<END - * Output slices based on input and num_splits defined, in row-major order. * @param T The value of the T attribute * @param N The value of the N attribute * @param numSplits Number of ways to split per dimension. Shape dimensions must be evenly @@ -252,13 +227,7 @@ public ReadVariableSplitND readVariableSplitND( * [0, 0]] * * - * @param data type for {@code outputs} output * @param input Input tensor to split across all dimensions. - * } - * out_arg { - * name: "outputs" - * description: <<END - * Output slices based on input and num_splits defined, in row-major order. * @param N The value of the N attribute * @param numSplits Number of ways to split per dimension. Shape dimensions must be evenly * divisible. @@ -298,7 +267,6 @@ public XlaHostCompute xlaHostCompute(Iterable> inputs, * shape: shape for output. * key: A unique identifier for this region used to match up host transfers. * - * @param data type for {@code output} output * @param Toutput The value of the Toutput attribute * @param shape The value of the shape attribute * @param key The value of the key attribute @@ -310,76 +278,6 @@ public XlaRecvFromHost xlaRecvFromHost(Class Toutput, Sh return XlaRecvFromHost.create(scope, Toutput, shape, key); } - /** - * An op that receives embedding activations on the TPU. - * The TPU system performs the embedding lookups and aggregations. The results of - * these aggregations are visible to the Tensorflow Graph as the outputs of a - * XlaRecvTPUEmbeddingActivations Op. This op returns a list containing one - * Tensor of activations per table specified in the model. - * - * @param deduplicationData A Tensor with type=DT_VARIANT containing the deduplication - * data. The tensor is an XLA nested tuple containing N elements (where N is - * the ratio of the number of embedding to tensor cores per TPU chip). Each - * element of the nested tuple is a tuple of rank 1 tensors. Each tensor either - * contains indices (DT_UINT32) for embedding lookup on the TensorCore or - * weights (DT_FLOAT) to apply to the output of the embedding lookup operation. - * @param numTables The number of output activation tensors. If feature descriptor is - * present in the tpu embedding config, it is equal to the number of features - * otherwise equal to number of embedding tables in the model. - * @param config Serialized TPUEmbeddingConfiguration proto. - * @return a new instance of XlaRecvTPUEmbeddingActivations - */ - public XlaRecvTPUEmbeddingActivations xlaRecvTPUEmbeddingActivations( - Operand deduplicationData, Long numTables, String config) { - return XlaRecvTPUEmbeddingActivations.create(scope, deduplicationData, numTables, config); - } - - /** - * Receives deduplication data (indices and weights) from the embedding core. - * The deduplication data is a Tensor with type=DT_VARIANT. The tensor itself is an - * XLA nested tuple containing N elements (where N is the ratio of the number of - * embedding to tensor cores per TPU chip). Each element of the nested tuple is a - * tuple of rank 1 tensors. Each tensor either contains indices (DT_UINT32) for - * embedding lookup on the TensorCore or weights (DT_FLOAT) to apply to the output - * of the embedding lookup operation. - * - * @param config Serialized TPUEmbeddingConfiguration proto. - * @return a new instance of XlaRecvTPUEmbeddingDeduplicationData - */ - public XlaRecvTPUEmbeddingDeduplicationData xlaRecvTPUEmbeddingDeduplicationData(String config) { - return XlaRecvTPUEmbeddingDeduplicationData.create(scope, config); - } - - /** - * An op that performs gradient updates of embedding tables. - * The gradients argument is a TensorList having the same length and shapes as the - * return value of XlaRecvTPUEmbeddingActivations, but contains gradients of the - * model's loss with respect to the embedding activations. The embedding tables are - * updated from these gradients via the optimizer specified in the - * TPUEmbeddingConfiguration proto given to tpu.initialize_system. - * - * @param gradients A TensorList of gradients with which to update embedding tables. - * @param learningRates A TensorList of learning rates used for updating the embedding - * tables via the optimizer. The length of the TensorList must be equal to the - * number of dynamic learning rate tags specified in the - * TPUEmbeddingConfiguration proto. - * @param deduplicationData A Tensor with type=DT_VARIANT containing the deduplication - * data. The tensor is an XLA nested tuple containing N elements (where N is - * the ratio of the number of embedding to tensor cores per TPU chip). Each - * element of the nested tuple is a tuple of rank 1 tensors. Each tensor either - * contains indices (DT_UINT32) for embedding lookup on the TensorCore or - * weights (DT_FLOAT) to apply to the output of the embedding lookup operation. - * @param config Serialized TPUEmbeddingConfiguration proto. - * @param options carries optional attribute values - * @return a new instance of XlaSendTPUEmbeddingGradients - */ - public XlaSendTPUEmbeddingGradients xlaSendTPUEmbeddingGradients( - Iterable> gradients, Iterable> learningRates, - Operand deduplicationData, String config, - XlaSendTPUEmbeddingGradients.Options... options) { - return XlaSendTPUEmbeddingGradients.create(scope, gradients, learningRates, deduplicationData, config, options); - } - /** * An op to send a tensor to the host. * input: the tensor that will be sent to the host. diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/bitwise/BitwiseAnd.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/bitwise/BitwiseAnd.java index 34789dce80c..7fea36a03b3 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/bitwise/BitwiseAnd.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/bitwise/BitwiseAnd.java @@ -52,8 +52,6 @@ * res = bitwise_ops.bitwise_and(lhs, rhs) * tf.assert_equal(tf.cast(res, tf.float32), exp) # TRUE * - * - * @param data type for {@code z} output */ @OpMetadata( opType = BitwiseAnd.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/bitwise/BitwiseOr.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/bitwise/BitwiseOr.java index afa384f6e38..1e57451698b 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/bitwise/BitwiseOr.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/bitwise/BitwiseOr.java @@ -52,8 +52,6 @@ * res = bitwise_ops.bitwise_or(lhs, rhs) * tf.assert_equal(tf.cast(res, tf.float32), exp) # TRUE * - * - * @param data type for {@code z} output */ @OpMetadata( opType = BitwiseOr.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/bitwise/BitwiseXor.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/bitwise/BitwiseXor.java index dc26dc145aa..52953422482 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/bitwise/BitwiseXor.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/bitwise/BitwiseXor.java @@ -52,8 +52,6 @@ * res = bitwise_ops.bitwise_xor(lhs, rhs) * tf.assert_equal(tf.cast(res, tf.float32), exp) # TRUE * - * - * @param data type for {@code z} output */ @OpMetadata( opType = BitwiseXor.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/bitwise/Invert.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/bitwise/Invert.java index a2d9a985bae..8dcb5a72de7 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/bitwise/Invert.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/bitwise/Invert.java @@ -73,8 +73,6 @@ * expected = tf.constant([dtype.max - x for x in inputs], dtype=tf.float32) * tf.assert_equal(tf.cast(inverted, tf.float32), tf.cast(expected, tf.float32)) * - * - * @param data type for {@code y} output */ @OpMetadata( opType = Invert.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/bitwise/LeftShift.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/bitwise/LeftShift.java index 5874dc12979..ccf41c473f8 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/bitwise/LeftShift.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/bitwise/LeftShift.java @@ -63,8 +63,6 @@ * bitwise_ops.left_shift(lhs, rhs) * # <tf.Tensor: shape=(4,), dtype=int8, numpy=array([ -2, 64, 101, 32], dtype=int8)> * - * - * @param data type for {@code z} output */ @OpMetadata( opType = LeftShift.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/bitwise/RightShift.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/bitwise/RightShift.java index 22c95c81136..6c1407b9d19 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/bitwise/RightShift.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/bitwise/RightShift.java @@ -65,8 +65,6 @@ * bitwise_ops.right_shift(lhs, rhs) * # <tf.Tensor: shape=(4,), dtype=int8, numpy=array([ -2, 64, 101, 32], dtype=int8)> * - * - * @param data type for {@code z} output */ @OpMetadata( opType = RightShift.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/collective/CollectiveAllToAll.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/collective/CollectiveAllToAll.java index 99ccff79289..9c513486b9b 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/collective/CollectiveAllToAll.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/collective/CollectiveAllToAll.java @@ -37,8 +37,6 @@ /** * Mutually exchanges multiple tensors of identical type and shape. - * - * @param data type for {@code data} output */ @OpMetadata( opType = CollectiveAllToAll.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/collective/CollectiveBcastRecv.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/collective/CollectiveBcastRecv.java index 332b5dcf9ab..a66995e4d4e 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/collective/CollectiveBcastRecv.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/collective/CollectiveBcastRecv.java @@ -38,8 +38,6 @@ /** * Receives a tensor value broadcast from another device. - * - * @param data type for {@code data} output */ @OpMetadata( opType = CollectiveBcastRecv.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/collective/CollectiveBcastSend.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/collective/CollectiveBcastSend.java index ee495b56951..df7a315413f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/collective/CollectiveBcastSend.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/collective/CollectiveBcastSend.java @@ -36,8 +36,6 @@ /** * Broadcasts a tensor value to one or more other devices. - * - * @param data type for {@code data} output */ @OpMetadata( opType = CollectiveBcastSend.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/collective/CollectiveGather.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/collective/CollectiveGather.java index d3997e8743f..57a2b134ff6 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/collective/CollectiveGather.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/collective/CollectiveGather.java @@ -41,8 +41,6 @@ * {@code is_stateless} means each op does not need control dependencies to other * collective ops. In this case, keys that are unique at runtime * (e.g. {@code instance_key}) should be used to distinguish collective groups. - * - * @param data type for {@code data} output */ @OpMetadata( opType = CollectiveGather.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/collective/CollectivePermute.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/collective/CollectivePermute.java index 9fd029facf3..380a949a664 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/collective/CollectivePermute.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/collective/CollectivePermute.java @@ -40,8 +40,6 @@ *

For example, suppose there are 4 TPU instances: {@code [A, B, C, D]}. Passing * source_target_pairs={@code [[0,1],[1,2],[2,3],[3,0]]} gets the outputs: * {@code [D, A, B, C]}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = CollectivePermute.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/collective/CollectiveReduce.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/collective/CollectiveReduce.java index 7eab3bb0f17..8f6c26778e1 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/collective/CollectiveReduce.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/collective/CollectiveReduce.java @@ -37,8 +37,6 @@ /** * Mutually reduces multiple tensors of identical type and shape. - * - * @param data type for {@code data} output */ @OpMetadata( opType = CollectiveReduce.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/collective/CollectiveReduceScatter.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/collective/CollectiveReduceScatter.java index 5ab06edf273..8b89dbaf183 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/collective/CollectiveReduceScatter.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/collective/CollectiveReduceScatter.java @@ -41,8 +41,6 @@ * {@code is_stateless} means each op does not need control dependencies to other * collective ops. In this case, keys that are unique at runtime * (e.g. {@code instance_key}) should be used to distinguish collective groups. - * - * @param data type for {@code data} output */ @OpMetadata( opType = CollectiveReduceScatter.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ApproxTopK.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ApproxTopK.java index 1daca9f077e..48f4f94315b 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ApproxTopK.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ApproxTopK.java @@ -38,8 +38,6 @@ * Returns min/max k values and their indices of the input operand in an approximate manner. * See https://arxiv.org/abs/2206.14286 for the algorithm details. * This op is only optimized on TPU currently. - * - * @param data type for {@code values} output */ @OpMetadata( opType = ApproxTopK.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Assign.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Assign.java index a8001c6103a..e49f3eafacc 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Assign.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Assign.java @@ -37,8 +37,6 @@ * Update 'ref' by assigning 'value' to it. * This operation outputs "ref" after the assignment is done. * This makes it easier to chain operations that need to use the reset value. - * - * @param data type for {@code output_ref} output */ @OpMetadata( opType = Assign.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/AssignAdd.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/AssignAdd.java index 2b6f78046ca..848231d569a 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/AssignAdd.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/AssignAdd.java @@ -37,8 +37,6 @@ * Update 'ref' by adding 'value' to it. * This operation outputs "ref" after the update is done. * This makes it easier to chain operations that need to use the reset value. - * - * @param data type for {@code output_ref} output */ @OpMetadata( opType = AssignAdd.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/AssignSub.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/AssignSub.java index 162fc069e92..cc96d634945 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/AssignSub.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/AssignSub.java @@ -37,8 +37,6 @@ * Update 'ref' by subtracting 'value' from it. * This operation outputs "ref" after the update is done. * This makes it easier to chain operations that need to use the reset value. - * - * @param data type for {@code output_ref} output */ @OpMetadata( opType = AssignSub.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/BatchFunction.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/BatchFunction.java index d544fdeca5a..577f213f47d 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/BatchFunction.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/BatchFunction.java @@ -163,6 +163,12 @@ public static BatchFunction create(Scope scope, Iterable> inTensors, if (opts.lowPriorityMaxEnqueuedBatches != null) { opBuilder.setAttr("low_priority_max_enqueued_batches", opts.lowPriorityMaxEnqueuedBatches); } + if (opts.mixedPriorityPolicy != null) { + opBuilder.setAttr("mixed_priority_policy", opts.mixedPriorityPolicy); + } + if (opts.batchPaddingPolicy != null) { + opBuilder.setAttr("batch_padding_policy", opts.batchPaddingPolicy); + } if (opts.enableLargeBatchSplitting != null) { opBuilder.setAttr("enable_large_batch_splitting", opts.enableLargeBatchSplitting); } @@ -291,6 +297,26 @@ public static Options lowPriorityMaxEnqueuedBatches(Long lowPriorityMaxEnqueuedB return new Options().lowPriorityMaxEnqueuedBatches(lowPriorityMaxEnqueuedBatches); } + /** + * Sets the mixedPriorityPolicy option. + * + * @param mixedPriorityPolicy the mixedPriorityPolicy option + * @return this Options instance. + */ + public static Options mixedPriorityPolicy(String mixedPriorityPolicy) { + return new Options().mixedPriorityPolicy(mixedPriorityPolicy); + } + + /** + * Sets the batchPaddingPolicy option. + * + * @param batchPaddingPolicy the batchPaddingPolicy option + * @return this Options instance. + */ + public static Options batchPaddingPolicy(String batchPaddingPolicy) { + return new Options().batchPaddingPolicy(batchPaddingPolicy); + } + /** * Sets the enableLargeBatchSplitting option. * @@ -339,6 +365,10 @@ public static class Options { private Long lowPriorityMaxEnqueuedBatches; + private String mixedPriorityPolicy; + + private String batchPaddingPolicy; + private Boolean enableLargeBatchSplitting; private Options() { @@ -475,6 +505,28 @@ public Options lowPriorityMaxEnqueuedBatches(Long lowPriorityMaxEnqueuedBatches) return this; } + /** + * Sets the mixedPriorityPolicy option. + * + * @param mixedPriorityPolicy the mixedPriorityPolicy option + * @return this Options instance. + */ + public Options mixedPriorityPolicy(String mixedPriorityPolicy) { + this.mixedPriorityPolicy = mixedPriorityPolicy; + return this; + } + + /** + * Sets the batchPaddingPolicy option. + * + * @param batchPaddingPolicy the batchPaddingPolicy option + * @return this Options instance. + */ + public Options batchPaddingPolicy(String batchPaddingPolicy) { + this.batchPaddingPolicy = batchPaddingPolicy; + return this; + } + /** * Sets the enableLargeBatchSplitting option. * @@ -571,6 +623,16 @@ public static class Inputs extends RawOpInputs { */ public final long lowPriorityMaxEnqueuedBatches; + /** + * The mixedPriorityPolicy attribute + */ + public final String mixedPriorityPolicy; + + /** + * The batchPaddingPolicy attribute + */ + public final String batchPaddingPolicy; + /** * the types of tensors to be batched. */ @@ -593,7 +655,7 @@ public static class Inputs extends RawOpInputs { public final boolean enableLargeBatchSplitting; public Inputs(GraphOperation op) { - super(new BatchFunction(op), op, Arrays.asList("num_batch_threads", "max_batch_size", "batch_timeout_micros", "max_enqueued_batches", "allowed_batch_sizes", "container", "shared_name", "batching_queue", "low_priority_max_batch_size", "low_priority_batch_timeout_micros", "low_priority_allowed_batch_sizes", "low_priority_max_enqueued_batches", "Tin", "Tcaptured", "Tout", "enable_large_batch_splitting")); + super(new BatchFunction(op), op, Arrays.asList("num_batch_threads", "max_batch_size", "batch_timeout_micros", "max_enqueued_batches", "allowed_batch_sizes", "container", "shared_name", "batching_queue", "low_priority_max_batch_size", "low_priority_batch_timeout_micros", "low_priority_allowed_batch_sizes", "low_priority_max_enqueued_batches", "mixed_priority_policy", "batch_padding_policy", "Tin", "Tcaptured", "Tout", "enable_large_batch_splitting")); int inputIndex = 0; int inTensorsLength = op.inputListLength("in_tensors"); inTensors = Arrays.asList((Operand[]) op.inputList(inputIndex, inTensorsLength)); @@ -613,6 +675,8 @@ public Inputs(GraphOperation op) { lowPriorityBatchTimeoutMicros = op.attributes().getAttrInt("low_priority_batch_timeout_micros"); lowPriorityAllowedBatchSizes = op.attributes().getAttrIntList("low_priority_allowed_batch_sizes"); lowPriorityMaxEnqueuedBatches = op.attributes().getAttrInt("low_priority_max_enqueued_batches"); + mixedPriorityPolicy = op.attributes().getAttrString("mixed_priority_policy"); + batchPaddingPolicy = op.attributes().getAttrString("batch_padding_policy"); Tin = op.attributes().getAttrTypeList("Tin"); Tcaptured = op.attributes().getAttrTypeList("Tcaptured"); Tout = op.attributes().getAttrTypeList("Tout"); diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/BatchToSpace.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/BatchToSpace.java index 889bd521e0d..09fa1d49bcb 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/BatchToSpace.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/BatchToSpace.java @@ -42,8 +42,6 @@ * this op outputs a copy of the input tensor where values from the {@code batch} * dimension are moved in spatial blocks to the {@code height} and {@code width} dimensions, * followed by cropping along the {@code height} and {@code width} dimensions. - * - * @param data type for {@code output} output */ @OpMetadata( opType = BatchToSpace.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/BatchToSpaceNd.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/BatchToSpaceNd.java index c7cf592d517..65a98188342 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/BatchToSpaceNd.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/BatchToSpaceNd.java @@ -42,8 +42,6 @@ * the input. The spatial dimensions of this intermediate result are then * optionally cropped according to {@code crops} to produce the output. This is the * reverse of SpaceToBatch. See below for a precise description. - * - * @param data type for {@code output} output */ @OpMetadata( opType = BatchToSpaceNd.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Bitcast.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Bitcast.java index c1bd2421b15..82a2a99d295 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Bitcast.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Bitcast.java @@ -96,8 +96,6 @@ * endian orderings will give different results. A copy from input buffer to output * buffer is made on BE machines when types are of different sizes in order to get * the same casting results as on LE machines. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Bitcast.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/BroadcastDynamicShape.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/BroadcastDynamicShape.java index 96cfa009842..165e7e12b9a 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/BroadcastDynamicShape.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/BroadcastDynamicShape.java @@ -37,8 +37,6 @@ * Return the shape of s0 op s1 with broadcast. * Given {@code s0} and {@code s1}, tensors that represent shapes, compute {@code r0}, the * broadcasted shape. {@code s0}, {@code s1} and {@code r0} are all integer vectors. - * - * @param data type for {@code r0} output */ @OpMetadata( opType = BroadcastDynamicShape.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/BroadcastGradientArgs.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/BroadcastGradientArgs.java index fe9cf0e7039..f29d66c8de6 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/BroadcastGradientArgs.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/BroadcastGradientArgs.java @@ -36,8 +36,6 @@ /** * Return the reduction indices for computing gradients of s0 op s1 with broadcast. * This is typically used by gradient computations for a broadcasting operation. - * - * @param data type for {@code r0} output */ @OpMetadata( opType = BroadcastGradientArgs.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/BroadcastTo.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/BroadcastTo.java index d9ada9ae323..f27247cd37a 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/BroadcastTo.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/BroadcastTo.java @@ -72,8 +72,6 @@ * The newly-created tensor takes the full memory of the broadcasted * shape. (In a graph context, {@code broadcast_to} might be fused to * subsequent operation and then be optimized away, however.) - * - * @param data type for {@code output} output */ @OpMetadata( opType = BroadcastTo.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/CheckPinned.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/CheckPinned.java new file mode 100644 index 00000000000..2708bcad2bf --- /dev/null +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/CheckPinned.java @@ -0,0 +1,115 @@ +/* Copyright 2018-2023 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. +=======================================================================*/ + +// This class has been generated, DO NOT EDIT! + +package org.tensorflow.op.core; + +import java.util.Arrays; +import org.tensorflow.GraphOperation; +import org.tensorflow.Operand; +import org.tensorflow.Operation; +import org.tensorflow.OperationBuilder; +import org.tensorflow.Output; +import org.tensorflow.op.RawOp; +import org.tensorflow.op.RawOpInputs; +import org.tensorflow.op.Scope; +import org.tensorflow.op.annotation.Endpoint; +import org.tensorflow.op.annotation.OpInputsMetadata; +import org.tensorflow.op.annotation.OpMetadata; +import org.tensorflow.op.annotation.Operator; +import org.tensorflow.proto.DataType; +import org.tensorflow.types.family.TType; + +/** + * Checks whether a tensor is located in host memory pinned for GPU. + * When run: + *

    + *
  • Reports an {@code InvalidArgument} error if {@code tensor} is not in pinned memory.
  • + *
  • Reports a {@code FailedPrecondition} error if not built with CUDA.
  • + *
+ */ +@OpMetadata( + opType = CheckPinned.OP_NAME, + inputsClass = CheckPinned.Inputs.class +) +@Operator +public final class CheckPinned extends RawOp implements Operand { + /** + * The name of this op, as known by TensorFlow core engine + */ + public static final String OP_NAME = "CheckPinned"; + + private Output output; + + public CheckPinned(Operation operation) { + super(operation, OP_NAME); + int outputIdx = 0; + output = operation.output(outputIdx++); + } + + /** + * Factory method to create a class wrapping a new CheckPinned operation. + * + * @param scope current scope + * @param tensor The tensor value + * @param data type for {@code CheckPinned} output and operands + * @return a new instance of CheckPinned + */ + @Endpoint( + describeByClass = true + ) + public static CheckPinned create(Scope scope, Operand tensor) { + OperationBuilder opBuilder = scope.opBuilder(OP_NAME, "CheckPinned"); + opBuilder.addInput(tensor.asOutput()); + return new CheckPinned<>(opBuilder.build()); + } + + /** + * Gets output. + * + * @return output. + */ + public Output output() { + return output; + } + + @Override + public Output asOutput() { + return output; + } + + @OpInputsMetadata( + outputsClass = CheckPinned.class + ) + public static class Inputs extends RawOpInputs> { + /** + * The tensor input + */ + public final Operand tensor; + + /** + * The T attribute + */ + public final DataType T; + + public Inputs(GraphOperation op) { + super(new CheckPinned<>(op), op, Arrays.asList("T")); + int inputIndex = 0; + tensor = (Operand) op.input(inputIndex++); + T = op.attributes().getAttrType("T"); + } + } +} diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ClipByValue.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ClipByValue.java index 4477b0d4924..2ae7185a7e5 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ClipByValue.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ClipByValue.java @@ -39,8 +39,6 @@ * shape as {@code t} with its values clipped to {@code clip_value_min} and {@code clip_value_max}. * Any values less than {@code clip_value_min} are set to {@code clip_value_min}. Any values * greater than {@code clip_value_max} are set to {@code clip_value_max}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = ClipByValue.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Concat.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Concat.java index 894b3a574be..cf3b735f4be 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Concat.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Concat.java @@ -37,8 +37,6 @@ /** * Concatenates tensors along one dimension. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Concat.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ConcatOffset.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ConcatOffset.java index df14b30a11b..9b9a8d813c3 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ConcatOffset.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ConcatOffset.java @@ -47,14 +47,12 @@ * y = [2, 3, 7] * z = [2, 9, 7] * offsets = concat_offset(1, [x, y, z]) - * [list(off.numpy()) for off in offsets] + * [[a.item() for a in list(off.numpy())] for off in offsets] * [[0, 0, 0], [0, 2, 0], [0, 5, 0]] * * * *

This is typically used by gradient computations for a concat operation. - * - * @param data type for {@code offset} output */ @OpMetadata( opType = ConcatOffset.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Copy.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Copy.java index 9b55fac9069..a04de48877b 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Copy.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Copy.java @@ -42,8 +42,6 @@ * deep-copying. See the documentation of Debug* ops for more details. *

Unlike the CopyHost Op, this op does not have HostMemory constraint on its * input or output. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Copy.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/CopyHost.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/CopyHost.java index 59af18c8b33..055c9d878bf 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/CopyHost.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/CopyHost.java @@ -40,8 +40,6 @@ * gRPC gating status, the output will simply forward the input tensor without * deep-copying. See the documentation of Debug* ops for more details. *

Unlike the Copy Op, this op has HostMemory constraint on its input or output. - * - * @param data type for {@code output} output */ @OpMetadata( opType = CopyHost.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/CopyToMesh.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/CopyToMesh.java index f83d6c6ad61..166d4613d54 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/CopyToMesh.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/CopyToMesh.java @@ -35,8 +35,6 @@ /** * The CopyToMesh operation - * - * @param data type for {@code output} output */ @OpMetadata( opType = CopyToMesh.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/CopyToMeshGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/CopyToMeshGrad.java index fa3467cd849..095d5b5d7ce 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/CopyToMeshGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/CopyToMeshGrad.java @@ -35,8 +35,6 @@ /** * The CopyToMeshGrad operation - * - * @param data type for {@code output} output */ @OpMetadata( opType = CopyToMeshGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/CountUpTo.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/CountUpTo.java index 7a81a4419e6..0f404fa1419 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/CountUpTo.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/CountUpTo.java @@ -35,8 +35,6 @@ /** * Increments 'ref' until it reaches 'limit'. - * - * @param data type for {@code output} output */ @OpMetadata( opType = CountUpTo.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/DeepCopy.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/DeepCopy.java index ca15dbb9a55..f0b9b3927a8 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/DeepCopy.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/DeepCopy.java @@ -35,8 +35,6 @@ /** * Makes a copy of {@code x}. - * - * @param data type for {@code y} output */ @OpMetadata( opType = DeepCopy.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/DestroyTemporaryVariable.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/DestroyTemporaryVariable.java index cc8f2bafb2f..876a1e46ee5 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/DestroyTemporaryVariable.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/DestroyTemporaryVariable.java @@ -41,8 +41,6 @@ * This is typically achieved by chaining the ref through each assign op, or by * using control dependencies. *

Outputs the final value of the tensor pointed to by 'ref'. - * - * @param data type for {@code value} output */ @OpMetadata( opType = DestroyTemporaryVariable.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/DynamicPartition.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/DynamicPartition.java index b851e0cccdf..d7d7bf7c328 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/DynamicPartition.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/DynamicPartition.java @@ -78,8 +78,6 @@ * * * - * - * @param data type for {@code outputs} output */ @OpMetadata( opType = DynamicPartition.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/DynamicStitch.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/DynamicStitch.java index 9aba2968627..d160ab8255c 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/DynamicStitch.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/DynamicStitch.java @@ -90,8 +90,6 @@ *

* *
- * - * @param data type for {@code merged} output */ @OpMetadata( opType = DynamicStitch.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Empty.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Empty.java index 02c76780ba2..6f7d74d94e5 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Empty.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Empty.java @@ -38,8 +38,6 @@ /** * Creates a tensor with the given shape. *

This operation creates a tensor of {@code shape} and {@code dtype}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Empty.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/EnsureShape.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/EnsureShape.java index 131285dc0e6..bbada3714ac 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/EnsureShape.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/EnsureShape.java @@ -38,8 +38,6 @@ * Ensures that the tensor's shape matches the expected shape. * Raises an error if the input tensor's shape does not match the specified shape. * Returns the input tensor otherwise. - * - * @param data type for {@code output} output */ @OpMetadata( opType = EnsureShape.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Enter.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Enter.java index baed3b18053..309e5700eb1 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Enter.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Enter.java @@ -40,8 +40,6 @@ * {@code is_constant} is true, {@code output} is a constant in the child frame; otherwise * it may be changed in the child frame. At most {@code parallel_iterations} iterations * are run in parallel in the child frame. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Enter.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Exit.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Exit.java index c1535016b59..8dea6a66fe6 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Exit.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Exit.java @@ -36,8 +36,6 @@ /** * Exits the current frame to its parent frame. * Exit makes its input {@code data} available to the parent frame. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Exit.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ExpandDims.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ExpandDims.java index bf17427d228..0f0e030b71d 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ExpandDims.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ExpandDims.java @@ -59,8 +59,6 @@ *

{@code -1-input.dims() <= dim <= input.dims()} *

This operation is related to {@code squeeze()}, which removes dimensions of * size 1. - * - * @param data type for {@code output} output */ @OpMetadata( opType = ExpandDims.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ExtractVolumePatches.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ExtractVolumePatches.java index 12afb6060b3..350c416e235 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ExtractVolumePatches.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ExtractVolumePatches.java @@ -36,8 +36,6 @@ /** * Extract {@code patches} from {@code input} and put them in the {@code "depth"} output dimension. 3D extension of {@code extract_image_patches}. - * - * @param data type for {@code patches} output */ @OpMetadata( opType = ExtractVolumePatches.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/FakeParam.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/FakeParam.java index ee07de5268d..79e63958dda 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/FakeParam.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/FakeParam.java @@ -40,8 +40,6 @@ * valid output when run, so must either be removed (e.g. replaced with a * function input) or guaranteed not to be used (e.g. if mirroring an * intermediate output needed for the gradient computation of the other branch). - * - * @param data type for {@code output} output */ @OpMetadata( opType = FakeParam.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Fill.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Fill.java index 5ba5931795e..8634981f57c 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Fill.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Fill.java @@ -53,8 +53,6 @@ *

  • Because {@code tf.fill} evaluates at graph runtime, it supports dynamic shapes * based on other runtime Tensors, unlike {@code tf.constant}.
  • * - * - * @param data type for {@code output} output */ @OpMetadata( opType = Fill.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Gather.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Gather.java index 1b1e3f888ee..43e09807b66 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Gather.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Gather.java @@ -57,9 +57,10 @@ *

    Note that on CPU, if an out of bound index is found, an error is returned. * On GPU, if an out of bound index is found, a 0 is stored in the * corresponding output value. + *

    Note that on TPU, if any dimension of {@code params} is of size 0 then the output will + * be the expected shape filled with zeros. On CPU and GPU an error will be + * returned. *

    See also {@code tf.batch_gather} and {@code tf.gather_nd}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Gather.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/GatherNd.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/GatherNd.java index b1a05118129..755bf4e7905 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/GatherNd.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/GatherNd.java @@ -57,9 +57,17 @@ *

      * indices.shape[:-1] + params.shape[indices.shape[-1]:]
      * 
    - *

    Note that on CPU, if an out of bound index is found, an error is returned. - * On GPU, if an out of bound index is found, a 0 is stored in the - * corresponding output value. + *

    If {@code indices} contains any out-of-bound indices, depending on + * {@code bad_indices_policy}, the op will either return an error or ignore the + * out-of-bound indices. {@code bad_indices_policy} can be one of the following values: + *

      + *
    1. "" or "DEFAULT": raises on CPU and ignore on GPU. This is because + * historically on CPU and GPU we handle errors in different ways, and for + * backward compatibility we keep the default behavior.
    2. + *
    3. "ERROR": raises error; GPU does not support this value.
    4. + *
    5. "IGNORE": ignore error and set the corresponding output to 0; + * supported on both CPU and GPU.
    6. + *
    *

    Some examples below. *

    Simple indexing into a matrix: *

    @@ -125,8 +133,6 @@
      *     output = [['b0', 'b1'], ['d0', 'c1']]
      * 
    *

    See also {@code tf.gather} and {@code tf.batch_gather}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = GatherNd.OP_NAME, @@ -153,6 +159,7 @@ public GatherNd(Operation operation) { * @param scope current scope * @param params The tensor from which to gather values. * @param indices Index tensor. + * @param options carries optional attribute values * @param data type for {@code GatherNd} output and operands * @return a new instance of GatherNd */ @@ -160,13 +167,30 @@ public GatherNd(Operation operation) { describeByClass = true ) public static GatherNd create(Scope scope, Operand params, - Operand indices) { + Operand indices, Options... options) { OperationBuilder opBuilder = scope.opBuilder(OP_NAME, "GatherNd"); opBuilder.addInput(params.asOutput()); opBuilder.addInput(indices.asOutput()); + if (options != null) { + for (Options opts : options) { + if (opts.badIndicesPolicy != null) { + opBuilder.setAttr("bad_indices_policy", opts.badIndicesPolicy); + } + } + } return new GatherNd<>(opBuilder.build()); } + /** + * Sets the badIndicesPolicy option. + * + * @param badIndicesPolicy the badIndicesPolicy option + * @return this Options instance. + */ + public static Options badIndicesPolicy(String badIndicesPolicy) { + return new Options().badIndicesPolicy(badIndicesPolicy); + } + /** * Gets output. * Values from {@code params} gathered from indices given by {@code indices}, with @@ -182,6 +206,27 @@ public Output asOutput() { return output; } + /** + * Optional attributes for {@link org.tensorflow.op.core.GatherNd} + */ + public static class Options { + private String badIndicesPolicy; + + private Options() { + } + + /** + * Sets the badIndicesPolicy option. + * + * @param badIndicesPolicy the badIndicesPolicy option + * @return this Options instance. + */ + public Options badIndicesPolicy(String badIndicesPolicy) { + this.badIndicesPolicy = badIndicesPolicy; + return this; + } + } + @OpInputsMetadata( outputsClass = GatherNd.class ) @@ -206,13 +251,19 @@ public static class Inputs extends RawOpInputs> { */ public final DataType Tindices; + /** + * The badIndicesPolicy attribute + */ + public final String badIndicesPolicy; + public Inputs(GraphOperation op) { - super(new GatherNd<>(op), op, Arrays.asList("Tparams", "Tindices")); + super(new GatherNd<>(op), op, Arrays.asList("Tparams", "Tindices", "bad_indices_policy")); int inputIndex = 0; params = (Operand) op.input(inputIndex++); indices = (Operand) op.input(inputIndex++); Tparams = op.attributes().getAttrType("Tparams"); Tindices = op.attributes().getAttrType("Tindices"); + badIndicesPolicy = op.attributes().getAttrString("bad_indices_policy"); } } } diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/GetSessionTensor.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/GetSessionTensor.java index a2445004e6d..0cccfb42045 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/GetSessionTensor.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/GetSessionTensor.java @@ -37,8 +37,6 @@ /** * Get the value of the tensor specified by its handle. - * - * @param data type for {@code value} output */ @OpMetadata( opType = GetSessionTensor.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/GuaranteeConst.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/GuaranteeConst.java index 8839f77471f..c4235de8ff2 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/GuaranteeConst.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/GuaranteeConst.java @@ -39,8 +39,6 @@ *

    Only accepts value typed tensors as inputs and rejects resource variable handles * as input. *

    Returns the input tensor without modification. - * - * @param data type for {@code output} output */ @OpMetadata( opType = GuaranteeConst.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/HistogramFixedWidth.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/HistogramFixedWidth.java index 0846ac056c0..782cfc69f05 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/HistogramFixedWidth.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/HistogramFixedWidth.java @@ -51,8 +51,6 @@ * variables.global_variables_initializer().run() * sess.run(hist) => [2, 1, 1, 0, 2] * - * - * @param data type for {@code out} output */ @OpMetadata( opType = HistogramFixedWidth.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/HostConst.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/HostConst.java index 8aa7bf2e13c..82f5ef8f295 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/HostConst.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/HostConst.java @@ -37,8 +37,6 @@ /** * Returns a constant tensor on the host. Only for writing C++ tests. - * - * @param data type for {@code output} output */ @OpMetadata( opType = HostConst.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Identity.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Identity.java index 12c84344373..d0729ab93da 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Identity.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Identity.java @@ -35,8 +35,6 @@ /** * Return a tensor with the same shape and contents as the input tensor or value. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Identity.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ImmutableConst.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ImmutableConst.java index 47cbe749ee9..12d647268ba 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ImmutableConst.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ImmutableConst.java @@ -38,8 +38,6 @@ /** * Returns immutable tensor from memory region. * The current implementation memmaps the tensor from a file. - * - * @param data type for {@code tensor} output */ @OpMetadata( opType = ImmutableConst.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/InplaceAdd.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/InplaceAdd.java index c42388fc55c..78f37851589 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/InplaceAdd.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/InplaceAdd.java @@ -39,8 +39,6 @@ *

      * Computes y = x; y[i, :] += v; return y.
      * 
    - * - * @param data type for {@code y} output */ @OpMetadata( opType = InplaceAdd.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/InplaceSub.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/InplaceSub.java index a39bf6d741b..31d0287aab2 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/InplaceSub.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/InplaceSub.java @@ -40,8 +40,6 @@ * * Computes y = x; y[i, :] -= v; return y. * - * - * @param data type for {@code y} output */ @OpMetadata( opType = InplaceSub.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/InplaceUpdate.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/InplaceUpdate.java index 8aecb6edf8c..d34e0f15011 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/InplaceUpdate.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/InplaceUpdate.java @@ -39,8 +39,6 @@ * Computes {@code x[i, :] = v; return x}. *

    Originally this function is mutative however for compilation we make this * operation create / operate on a copy of {@code x}. - * - * @param data type for {@code y} output */ @OpMetadata( opType = InplaceUpdate.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/LinSpace.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/LinSpace.java index 3473ddf487e..317eb054e29 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/LinSpace.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/LinSpace.java @@ -42,8 +42,6 @@ *

      * tf.linspace(10.0, 12.0, 3, name="linspace") => [ 10.0  11.0  12.0]
      * 
    - * - * @param data type for {@code output} output */ @OpMetadata( opType = LinSpace.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/LookupTableExport.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/LookupTableExport.java index 7406671423c..7546b26f8f4 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/LookupTableExport.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/LookupTableExport.java @@ -36,10 +36,6 @@ /** * Outputs all keys and values in the table. - * - * @param data type for {@code keys} output - * - * @param data type for {@code values} output */ @OpMetadata( opType = LookupTableExport.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/LookupTableFind.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/LookupTableFind.java index b097f2ee81d..1155c94662f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/LookupTableFind.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/LookupTableFind.java @@ -39,8 +39,6 @@ * The output {@code values} is of the type of the table values. *

    The scalar {@code default_value} is the value output for keys not present in the * table. It must also be of the same type as the table values. - * - * @param data type for {@code values} output */ @OpMetadata( opType = LookupTableFind.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/LowerBound.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/LowerBound.java index 8cf633e2d7f..2a4b761a8fd 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/LowerBound.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/LowerBound.java @@ -51,8 +51,6 @@ *

    result = LowerBound(sorted_sequence, values) *

    result == [[1, 2, 2], * [0, 1, 5]] - * - * @param data type for {@code output} output */ @OpMetadata( opType = LowerBound.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Max.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Max.java index fb03ee5c942..04c4f1481d3 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Max.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Max.java @@ -39,8 +39,6 @@ * {@code keep_dims} is true, the rank of the tensor is reduced by 1 for each entry in * {@code axis}. If {@code keep_dims} is true, the reduced dimensions are * retained with length 1. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Max.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Merge.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Merge.java index 7e4c77434b9..f5a189c9c58 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Merge.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Merge.java @@ -41,8 +41,6 @@ * It is usually combined with {@code Switch} to implement branching. *

    {@code Merge} forwards the first tensor to become available to {@code output}, and sets * {@code value_index} to its index in {@code inputs}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Merge.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Min.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Min.java index f3db8fedac0..89ac31b5854 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Min.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Min.java @@ -39,8 +39,6 @@ * {@code keep_dims} is true, the rank of the tensor is reduced by 1 for each entry in * {@code axis}. If {@code keep_dims} is true, the reduced dimensions are * retained with length 1. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Min.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/MirrorPad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/MirrorPad.java index e63036ec117..751bec8fd66 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/MirrorPad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/MirrorPad.java @@ -57,8 +57,6 @@ * [5, 4, 4, 5, 6, 6, 5] * [5, 4, 4, 5, 6, 6, 5]] * - * - * @param data type for {@code output} output */ @OpMetadata( opType = MirrorPad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/MirrorPadGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/MirrorPadGrad.java index 64235a34e0a..d1286e4bd89 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/MirrorPadGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/MirrorPadGrad.java @@ -50,8 +50,6 @@ * pad(t, paddings) ==> [[ 1, 5] * [11, 28]] * - * - * @param data type for {@code output} output */ @OpMetadata( opType = MirrorPadGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/NcclAllReduce.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/NcclAllReduce.java index d49045a1bad..5e8f5709b65 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/NcclAllReduce.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/NcclAllReduce.java @@ -46,8 +46,6 @@ * num_devices: The number of devices participating in this reduction. * shared_name: Identifier that shared between ops of the same reduction. * - * @param data type for {@code data} output - * * @deprecated use {@link org.tensorflow.op.distribute.NcclAllReduce} instead */ @OpMetadata( diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/NcclBroadcast.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/NcclBroadcast.java index 4d5c2d771de..5e6c2a583ef 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/NcclBroadcast.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/NcclBroadcast.java @@ -43,8 +43,6 @@ * output: The same as input. * shape: The shape of the input tensor. * - * @param data type for {@code output} output - * * @deprecated use {@link org.tensorflow.op.distribute.NcclBroadcast} instead */ @OpMetadata( diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/NcclReduce.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/NcclReduce.java index 8b050aba7e3..cd3dea3af6f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/NcclReduce.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/NcclReduce.java @@ -43,8 +43,6 @@ * data: the value of the reduction across all {@code num_devices} devices. * reduction: the reduction operation to perform. * - * @param data type for {@code data} output - * * @deprecated use {@link org.tensorflow.op.distribute.NcclReduce} instead */ @OpMetadata( diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/NextIteration.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/NextIteration.java index 33e50ce1b5d..1f0f73c672f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/NextIteration.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/NextIteration.java @@ -35,8 +35,6 @@ /** * Makes its input available to the next iteration. - * - * @param data type for {@code output} output */ @OpMetadata( opType = NextIteration.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/OneHot.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/OneHot.java index 09f55f7eaff..8ed3c25bd8e 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/OneHot.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/OneHot.java @@ -111,8 +111,6 @@ * [0.0, 0.0, 0.0] // one_hot(-1) * ] * - * - * @param data type for {@code output} output */ @OpMetadata( opType = OneHot.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/OnesLike.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/OnesLike.java index b69df0d0952..51178e062f4 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/OnesLike.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/OnesLike.java @@ -35,8 +35,6 @@ /** * Returns a tensor of ones with the same shape and type as x. - * - * @param data type for {@code y} output */ @OpMetadata( opType = OnesLike.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Pad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Pad.java index d80e87f0f2d..60ddbcf6817 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Pad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Pad.java @@ -56,8 +56,6 @@ * [0, 0, 2, 2, 0, 0] * [0, 0, 0, 0, 0, 0]] * - * - * @param data type for {@code output} output */ @OpMetadata( opType = Pad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ParallelConcat.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ParallelConcat.java index c5cbde1618c..b12c3b896aa 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ParallelConcat.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ParallelConcat.java @@ -50,8 +50,6 @@ * that the input shapes be known during graph construction. Parallel concat * will copy pieces of the input into the output as they become available, in * some situations this can provide a performance benefit. - * - * @param data type for {@code output} output */ @OpMetadata( opType = ParallelConcat.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ParallelDynamicStitch.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ParallelDynamicStitch.java index a23c3d135a8..c9fd16880ca 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ParallelDynamicStitch.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ParallelDynamicStitch.java @@ -89,8 +89,6 @@ *

    * *
    - * - * @param data type for {@code merged} output */ @OpMetadata( opType = ParallelDynamicStitch.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Placeholder.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Placeholder.java index 634500dcfc0..f4c450973da 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Placeholder.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Placeholder.java @@ -40,8 +40,6 @@ * N.B. This operation will fail with an error if it is executed. It is * intended as a way to represent a value that will always be fed, and to * provide attrs that enable the fed value to be checked at runtime. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Placeholder.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/PlaceholderWithDefault.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/PlaceholderWithDefault.java index 9604ea0a92a..202d4cc476c 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/PlaceholderWithDefault.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/PlaceholderWithDefault.java @@ -36,8 +36,6 @@ /** * A placeholder op that passes through {@code input} when its output is not fed. - * - * @param data type for {@code output} output */ @OpMetadata( opType = PlaceholderWithDefault.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Prod.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Prod.java index 71c7f986eb6..3f1c696a0bc 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Prod.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Prod.java @@ -40,8 +40,6 @@ * {@code keep_dims} is true, the rank of the tensor is reduced by 1 for each entry in * {@code axis}. If {@code keep_dims} is true, the reduced dimensions are * retained with length 1. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Prod.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/QuantizedReshape.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/QuantizedReshape.java index 6e92b83bf89..84816c6893f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/QuantizedReshape.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/QuantizedReshape.java @@ -37,8 +37,6 @@ /** * Reshapes a quantized tensor as per the Reshape op. - * - * @param data type for {@code output} output */ @OpMetadata( opType = QuantizedReshape.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RandomIndexShuffle.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RandomIndexShuffle.java index 68cd7f9f0eb..76538abf9cb 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RandomIndexShuffle.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RandomIndexShuffle.java @@ -39,8 +39,6 @@ *

    If multiple inputs are vectors (matrix in case of seed) then the size of the * first dimension must match. *

    The outputs are deterministic. - * - * @param data type for {@code output} output */ @OpMetadata( opType = RandomIndexShuffle.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Range.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Range.java index 0699bd59b09..702214095a5 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Range.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Range.java @@ -44,8 +44,6 @@ * # 'delta' is 3 * tf.range(start, limit, delta) ==> [3, 6, 9, 12, 15] * - * - * @param data type for {@code output} output */ @OpMetadata( opType = Range.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ReadVariableOp.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ReadVariableOp.java index 236991942ee..f57c2781c3f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ReadVariableOp.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ReadVariableOp.java @@ -41,8 +41,6 @@ * writes on which this operation depends directly or indirectly, and to not be * influenced by any of the writes which depend directly or indirectly on this * operation. - * - * @param data type for {@code value} output */ @OpMetadata( opType = ReadVariableOp.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Recv.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Recv.java index 1853328543d..5b3caab37b8 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Recv.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Recv.java @@ -36,8 +36,6 @@ /** * Receives the named tensor from send_device on recv_device. - * - * @param data type for {@code tensor} output */ @OpMetadata( opType = Recv.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ReduceMax.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ReduceMax.java index 529841fd5fa..dca6c6a5ffc 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ReduceMax.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ReduceMax.java @@ -39,8 +39,6 @@ * {@code keep_dims} is true, the rank of the tensor is reduced by 1 for each entry in * {@code axis}. If {@code keep_dims} is true, the reduced dimensions are * retained with length 1. - * - * @param data type for {@code output} output */ @OpMetadata( opType = ReduceMax.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ReduceMin.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ReduceMin.java index f349357096b..a7e544cfaab 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ReduceMin.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ReduceMin.java @@ -39,8 +39,6 @@ * {@code keep_dims} is true, the rank of the tensor is reduced by 1 for each entry in * {@code axis}. If {@code keep_dims} is true, the reduced dimensions are * retained with length 1. - * - * @param data type for {@code output} output */ @OpMetadata( opType = ReduceMin.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ReduceProd.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ReduceProd.java index 49008ad1a36..3dc53ad9c58 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ReduceProd.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ReduceProd.java @@ -40,8 +40,6 @@ * {@code keep_dims} is true, the rank of the tensor is reduced by 1 for each entry in * {@code axis}. If {@code keep_dims} is true, the reduced dimensions are * retained with length 1. - * - * @param data type for {@code output} output */ @OpMetadata( opType = ReduceProd.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ReduceSum.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ReduceSum.java index 05851e60764..bbe161f9210 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ReduceSum.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ReduceSum.java @@ -40,8 +40,6 @@ * {@code keep_dims} is true, the rank of the tensor is reduced by 1 for each entry in * {@code axis}. If {@code keep_dims} is true, the reduced dimensions are * retained with length 1. - * - * @param data type for {@code output} output */ @OpMetadata( opType = ReduceSum.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RefEnter.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RefEnter.java index 888c0ee977b..218092a2563 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RefEnter.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RefEnter.java @@ -39,8 +39,6 @@ * {@code is_constant} is true, {@code output} is a constant in the child frame; otherwise * it may be changed in the child frame. At most {@code parallel_iterations} iterations * are run in parallel in the child frame. - * - * @param data type for {@code output} output */ @OpMetadata( opType = RefEnter.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RefExit.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RefExit.java index c23ff2d03d7..9a840da2c3d 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RefExit.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RefExit.java @@ -36,8 +36,6 @@ /** * Exits the current frame to its parent frame. * Exit makes its input {@code data} available to the parent frame. - * - * @param data type for {@code output} output */ @OpMetadata( opType = RefExit.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RefIdentity.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RefIdentity.java index 53d515be8e1..c3bb004b548 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RefIdentity.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RefIdentity.java @@ -35,8 +35,6 @@ /** * Return the same ref tensor as the input ref tensor. - * - * @param data type for {@code output} output */ @OpMetadata( opType = RefIdentity.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RefMerge.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RefMerge.java index 9354cb2847b..4baf6cc6260 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RefMerge.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RefMerge.java @@ -41,8 +41,6 @@ * It is usually combined with {@code Switch} to implement branching. *

    {@code Merge} forwards the first tensor for become available to {@code output}, and sets * {@code value_index} to its index in {@code inputs}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = RefMerge.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RefNextIteration.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RefNextIteration.java index 5c7f1d2c4b7..ef647c70cd6 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RefNextIteration.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RefNextIteration.java @@ -35,8 +35,6 @@ /** * Makes its input available to the next iteration. - * - * @param data type for {@code output} output */ @OpMetadata( opType = RefNextIteration.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RefSelect.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RefSelect.java index 02c6ddc8e2f..d7ffa33956e 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RefSelect.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RefSelect.java @@ -37,8 +37,6 @@ /** * Forwards the {@code index}th element of {@code inputs} to {@code output}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = RefSelect.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RefSwitch.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RefSwitch.java index 04a2d4811ab..2e97b2bbcad 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RefSwitch.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RefSwitch.java @@ -39,8 +39,6 @@ * If {@code pred} is true, the {@code data} input is forwarded to {@code output_true}. Otherwise, * the data goes to {@code output_false}. *

    See also {@code Switch} and {@code Merge}. - * - * @param data type for {@code output_false} output */ @OpMetadata( opType = RefSwitch.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Relayout.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Relayout.java index 959987e6200..503d3cfe42a 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Relayout.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Relayout.java @@ -35,8 +35,6 @@ /** * The Relayout operation - * - * @param data type for {@code output} output */ @OpMetadata( opType = Relayout.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RelayoutLike.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RelayoutLike.java index 7fd8a91fb8b..499cb8d6c72 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RelayoutLike.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/RelayoutLike.java @@ -35,8 +35,6 @@ /** * The RelayoutLike operation - * - * @param data type for {@code output} output */ @OpMetadata( opType = RelayoutLike.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Reshape.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Reshape.java index 4b1ce466a7d..54c0aba057e 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Reshape.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Reshape.java @@ -90,8 +90,6 @@ * # shape `[]` reshapes to a scalar * reshape(t, []) ==> 7 * - * - * @param data type for {@code output} output */ @OpMetadata( opType = Reshape.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ResourceCountUpTo.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ResourceCountUpTo.java index f8e5cf5abef..0ca0faa179e 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ResourceCountUpTo.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ResourceCountUpTo.java @@ -37,8 +37,6 @@ /** * Increments variable pointed to by 'resource' until it reaches 'limit'. - * - * @param data type for {@code output} output */ @OpMetadata( opType = ResourceCountUpTo.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ResourceGather.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ResourceGather.java index 5dff2d95dc2..c458bacea4c 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ResourceGather.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ResourceGather.java @@ -49,8 +49,6 @@ * # Higher rank indices * output[i, ..., j, :, ... :] = params[indices[i, ..., j], :, ..., :] * - * - * @param data type for {@code output} output */ @OpMetadata( opType = ResourceGather.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ResourceGatherNd.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ResourceGatherNd.java index 1a86a282ab9..f9c6b72b544 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ResourceGatherNd.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ResourceGatherNd.java @@ -37,8 +37,6 @@ /** * The ResourceGatherNd operation - * - * @param data type for {@code output} output */ @OpMetadata( opType = ResourceGatherNd.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ResourceScatterNdAdd.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ResourceScatterNdAdd.java index 4c1d9d3820c..ee6c1cf7d61 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ResourceScatterNdAdd.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ResourceScatterNdAdd.java @@ -103,6 +103,9 @@ public static ResourceScatterNdAdd create(Scope scope, Operand if (opts.useLocking != null) { opBuilder.setAttr("use_locking", opts.useLocking); } + if (opts.badIndicesPolicy != null) { + opBuilder.setAttr("bad_indices_policy", opts.badIndicesPolicy); + } } } return new ResourceScatterNdAdd(opBuilder.build()); @@ -120,12 +123,24 @@ public static Options useLocking(Boolean useLocking) { return new Options().useLocking(useLocking); } + /** + * Sets the badIndicesPolicy option. + * + * @param badIndicesPolicy the badIndicesPolicy option + * @return this Options instance. + */ + public static Options badIndicesPolicy(String badIndicesPolicy) { + return new Options().badIndicesPolicy(badIndicesPolicy); + } + /** * Optional attributes for {@link org.tensorflow.op.core.ResourceScatterNdAdd} */ public static class Options { private Boolean useLocking; + private String badIndicesPolicy; + private Options() { } @@ -141,6 +156,17 @@ public Options useLocking(Boolean useLocking) { this.useLocking = useLocking; return this; } + + /** + * Sets the badIndicesPolicy option. + * + * @param badIndicesPolicy the badIndicesPolicy option + * @return this Options instance. + */ + public Options badIndicesPolicy(String badIndicesPolicy) { + this.badIndicesPolicy = badIndicesPolicy; + return this; + } } @OpInputsMetadata( @@ -181,8 +207,13 @@ public static class Inputs extends RawOpInputs { */ public final boolean useLocking; + /** + * The badIndicesPolicy attribute + */ + public final String badIndicesPolicy; + public Inputs(GraphOperation op) { - super(new ResourceScatterNdAdd(op), op, Arrays.asList("T", "Tindices", "use_locking")); + super(new ResourceScatterNdAdd(op), op, Arrays.asList("T", "Tindices", "use_locking", "bad_indices_policy")); int inputIndex = 0; ref = (Operand) op.input(inputIndex++); indices = (Operand) op.input(inputIndex++); @@ -190,6 +221,7 @@ public Inputs(GraphOperation op) { T = op.attributes().getAttrType("T"); Tindices = op.attributes().getAttrType("Tindices"); useLocking = op.attributes().getAttrBool("use_locking"); + badIndicesPolicy = op.attributes().getAttrString("bad_indices_policy"); } } } diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ResourceScatterNdMax.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ResourceScatterNdMax.java index 193d4c7dfda..379843a67c7 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ResourceScatterNdMax.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ResourceScatterNdMax.java @@ -77,6 +77,9 @@ public static ResourceScatterNdMax create(Scope scope, Operand if (opts.useLocking != null) { opBuilder.setAttr("use_locking", opts.useLocking); } + if (opts.badIndicesPolicy != null) { + opBuilder.setAttr("bad_indices_policy", opts.badIndicesPolicy); + } } } return new ResourceScatterNdMax(opBuilder.build()); @@ -94,12 +97,24 @@ public static Options useLocking(Boolean useLocking) { return new Options().useLocking(useLocking); } + /** + * Sets the badIndicesPolicy option. + * + * @param badIndicesPolicy the badIndicesPolicy option + * @return this Options instance. + */ + public static Options badIndicesPolicy(String badIndicesPolicy) { + return new Options().badIndicesPolicy(badIndicesPolicy); + } + /** * Optional attributes for {@link org.tensorflow.op.core.ResourceScatterNdMax} */ public static class Options { private Boolean useLocking; + private String badIndicesPolicy; + private Options() { } @@ -115,6 +130,17 @@ public Options useLocking(Boolean useLocking) { this.useLocking = useLocking; return this; } + + /** + * Sets the badIndicesPolicy option. + * + * @param badIndicesPolicy the badIndicesPolicy option + * @return this Options instance. + */ + public Options badIndicesPolicy(String badIndicesPolicy) { + this.badIndicesPolicy = badIndicesPolicy; + return this; + } } @OpInputsMetadata( @@ -155,8 +181,13 @@ public static class Inputs extends RawOpInputs { */ public final boolean useLocking; + /** + * The badIndicesPolicy attribute + */ + public final String badIndicesPolicy; + public Inputs(GraphOperation op) { - super(new ResourceScatterNdMax(op), op, Arrays.asList("T", "Tindices", "use_locking")); + super(new ResourceScatterNdMax(op), op, Arrays.asList("T", "Tindices", "use_locking", "bad_indices_policy")); int inputIndex = 0; ref = (Operand) op.input(inputIndex++); indices = (Operand) op.input(inputIndex++); @@ -164,6 +195,7 @@ public Inputs(GraphOperation op) { T = op.attributes().getAttrType("T"); Tindices = op.attributes().getAttrType("Tindices"); useLocking = op.attributes().getAttrBool("use_locking"); + badIndicesPolicy = op.attributes().getAttrString("bad_indices_policy"); } } } diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ResourceScatterNdMin.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ResourceScatterNdMin.java index 9a1023916fd..ba46417abba 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ResourceScatterNdMin.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ResourceScatterNdMin.java @@ -77,6 +77,9 @@ public static ResourceScatterNdMin create(Scope scope, Operand if (opts.useLocking != null) { opBuilder.setAttr("use_locking", opts.useLocking); } + if (opts.badIndicesPolicy != null) { + opBuilder.setAttr("bad_indices_policy", opts.badIndicesPolicy); + } } } return new ResourceScatterNdMin(opBuilder.build()); @@ -94,12 +97,24 @@ public static Options useLocking(Boolean useLocking) { return new Options().useLocking(useLocking); } + /** + * Sets the badIndicesPolicy option. + * + * @param badIndicesPolicy the badIndicesPolicy option + * @return this Options instance. + */ + public static Options badIndicesPolicy(String badIndicesPolicy) { + return new Options().badIndicesPolicy(badIndicesPolicy); + } + /** * Optional attributes for {@link org.tensorflow.op.core.ResourceScatterNdMin} */ public static class Options { private Boolean useLocking; + private String badIndicesPolicy; + private Options() { } @@ -115,6 +130,17 @@ public Options useLocking(Boolean useLocking) { this.useLocking = useLocking; return this; } + + /** + * Sets the badIndicesPolicy option. + * + * @param badIndicesPolicy the badIndicesPolicy option + * @return this Options instance. + */ + public Options badIndicesPolicy(String badIndicesPolicy) { + this.badIndicesPolicy = badIndicesPolicy; + return this; + } } @OpInputsMetadata( @@ -155,8 +181,13 @@ public static class Inputs extends RawOpInputs { */ public final boolean useLocking; + /** + * The badIndicesPolicy attribute + */ + public final String badIndicesPolicy; + public Inputs(GraphOperation op) { - super(new ResourceScatterNdMin(op), op, Arrays.asList("T", "Tindices", "use_locking")); + super(new ResourceScatterNdMin(op), op, Arrays.asList("T", "Tindices", "use_locking", "bad_indices_policy")); int inputIndex = 0; ref = (Operand) op.input(inputIndex++); indices = (Operand) op.input(inputIndex++); @@ -164,6 +195,7 @@ public Inputs(GraphOperation op) { T = op.attributes().getAttrType("T"); Tindices = op.attributes().getAttrType("Tindices"); useLocking = op.attributes().getAttrBool("use_locking"); + badIndicesPolicy = op.attributes().getAttrString("bad_indices_policy"); } } } diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ResourceScatterNdSub.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ResourceScatterNdSub.java index 4c321416231..f39e42e742b 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ResourceScatterNdSub.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ResourceScatterNdSub.java @@ -103,6 +103,9 @@ public static ResourceScatterNdSub create(Scope scope, Operand if (opts.useLocking != null) { opBuilder.setAttr("use_locking", opts.useLocking); } + if (opts.badIndicesPolicy != null) { + opBuilder.setAttr("bad_indices_policy", opts.badIndicesPolicy); + } } } return new ResourceScatterNdSub(opBuilder.build()); @@ -120,12 +123,24 @@ public static Options useLocking(Boolean useLocking) { return new Options().useLocking(useLocking); } + /** + * Sets the badIndicesPolicy option. + * + * @param badIndicesPolicy the badIndicesPolicy option + * @return this Options instance. + */ + public static Options badIndicesPolicy(String badIndicesPolicy) { + return new Options().badIndicesPolicy(badIndicesPolicy); + } + /** * Optional attributes for {@link org.tensorflow.op.core.ResourceScatterNdSub} */ public static class Options { private Boolean useLocking; + private String badIndicesPolicy; + private Options() { } @@ -141,6 +156,17 @@ public Options useLocking(Boolean useLocking) { this.useLocking = useLocking; return this; } + + /** + * Sets the badIndicesPolicy option. + * + * @param badIndicesPolicy the badIndicesPolicy option + * @return this Options instance. + */ + public Options badIndicesPolicy(String badIndicesPolicy) { + this.badIndicesPolicy = badIndicesPolicy; + return this; + } } @OpInputsMetadata( @@ -181,8 +207,13 @@ public static class Inputs extends RawOpInputs { */ public final boolean useLocking; + /** + * The badIndicesPolicy attribute + */ + public final String badIndicesPolicy; + public Inputs(GraphOperation op) { - super(new ResourceScatterNdSub(op), op, Arrays.asList("T", "Tindices", "use_locking")); + super(new ResourceScatterNdSub(op), op, Arrays.asList("T", "Tindices", "use_locking", "bad_indices_policy")); int inputIndex = 0; ref = (Operand) op.input(inputIndex++); indices = (Operand) op.input(inputIndex++); @@ -190,6 +221,7 @@ public Inputs(GraphOperation op) { T = op.attributes().getAttrType("T"); Tindices = op.attributes().getAttrType("Tindices"); useLocking = op.attributes().getAttrBool("use_locking"); + badIndicesPolicy = op.attributes().getAttrString("bad_indices_policy"); } } } diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ResourceScatterNdUpdate.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ResourceScatterNdUpdate.java index 1a21fa30916..588d923c05a 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ResourceScatterNdUpdate.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ResourceScatterNdUpdate.java @@ -104,6 +104,9 @@ public static ResourceScatterNdUpdate create(Scope scope, Operand { */ public final boolean useLocking; + /** + * The badIndicesPolicy attribute + */ + public final String badIndicesPolicy; + public Inputs(GraphOperation op) { - super(new ResourceScatterNdUpdate(op), op, Arrays.asList("T", "Tindices", "use_locking")); + super(new ResourceScatterNdUpdate(op), op, Arrays.asList("T", "Tindices", "use_locking", "bad_indices_policy")); int inputIndex = 0; ref = (Operand) op.input(inputIndex++); indices = (Operand) op.input(inputIndex++); @@ -191,6 +222,7 @@ public Inputs(GraphOperation op) { T = op.attributes().getAttrType("T"); Tindices = op.attributes().getAttrType("Tindices"); useLocking = op.attributes().getAttrBool("use_locking"); + badIndicesPolicy = op.attributes().getAttrString("bad_indices_policy"); } } } diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Reverse.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Reverse.java index 65a6ac9ab0c..711b7148209 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Reverse.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Reverse.java @@ -76,8 +76,6 @@ * [16, 17, 18, 19], * [12, 13, 14, 15]]]] * - * - * @param data type for {@code output} output */ @OpMetadata( opType = Reverse.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ReverseSequence.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ReverseSequence.java index b7eb3fb25a2..e18f16874f0 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ReverseSequence.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ReverseSequence.java @@ -84,8 +84,6 @@ * output[3:, :, 2, :, ...] = input[3:, :, 2, :, ...] * output[2:, :, 3, :, ...] = input[2:, :, 3, :, ...] * - * - * @param data type for {@code output} output */ @OpMetadata( opType = ReverseSequence.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Roll.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Roll.java index a2f04750d53..e190730b970 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Roll.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Roll.java @@ -54,8 +54,6 @@ * # 't' is [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]] * roll(t, shift=[2, -3], axis=[1, 1]) ==> [[1, 2, 3, 4, 0], [6, 7, 8, 9, 5]] * - * - * @param data type for {@code output} output */ @OpMetadata( opType = Roll.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterAdd.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterAdd.java index bc66b56b3d1..9f0bc6a526f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterAdd.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterAdd.java @@ -55,8 +55,6 @@ *

    * *
    - * - * @param data type for {@code output_ref} output */ @OpMetadata( opType = ScatterAdd.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterDiv.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterDiv.java index 083f4de2a81..902d11400e5 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterDiv.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterDiv.java @@ -52,8 +52,6 @@ *

    Duplicate entries are handled correctly: if multiple {@code indices} reference * the same location, their contributions divide. *

    Requires {@code updates.shape = indices.shape + ref.shape[1:]} or {@code updates.shape = []}. - * - * @param data type for {@code output_ref} output */ @OpMetadata( opType = ScatterDiv.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterMax.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterMax.java index 162556fb11c..9b761e52419 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterMax.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterMax.java @@ -54,8 +54,6 @@ *

    * *
    - * - * @param data type for {@code output_ref} output */ @OpMetadata( opType = ScatterMax.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterMin.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterMin.java index 4264f92bc7e..7f725ad19d0 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterMin.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterMin.java @@ -54,8 +54,6 @@ *
    * *
    - * - * @param data type for {@code output_ref} output */ @OpMetadata( opType = ScatterMin.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterMul.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterMul.java index 7fb20e9d36e..ae8bbca9670 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterMul.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterMul.java @@ -52,8 +52,6 @@ *

    Duplicate entries are handled correctly: if multiple {@code indices} reference * the same location, their contributions multiply. *

    Requires {@code updates.shape = indices.shape + ref.shape[1:]} or {@code updates.shape = []}. - * - * @param data type for {@code output_ref} output */ @OpMetadata( opType = ScatterMul.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterNd.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterNd.java index 34487ebf9d7..ad6bcd00a16 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterNd.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterNd.java @@ -107,10 +107,16 @@ * [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], * [[5, 5, 5, 5], [6, 6, 6, 6], [7, 7, 7, 7], [8, 8, 8, 8]]] * - *

    Note that on CPU, if an out of bound index is found, an error is returned. - * On GPU, if an out of bound index is found, the index is ignored. - * - * @param data type for {@code output} output + *

    If {@code indices} contains any out-of-bound indices, depending on + * {@code bad_indices_policy}, the op will either return an error or ignore the + * out-of-bound indices. {@code bad_indices_policy} can be one of the following values: + *

      + *
    1. "" or "DEFAULT": raises on CPU and ignore on GPU. This is because + * historically on CPU and GPU we handle errors in different ways, and for + * backward compatibility we keep the default behavior.
    2. + *
    3. "ERROR": raises error; GPU does not support this value.
    4. + *
    5. "IGNORE": ignore the bad indices; supported on both CPU and GPU.
    6. + *
    */ @OpMetadata( opType = ScatterNd.OP_NAME, @@ -138,6 +144,7 @@ public ScatterNd(Operation operation) { * @param indices Tensor of indices. * @param updates Values to scatter into the output tensor. * @param shape 1-D. The shape of the output tensor. + * @param options carries optional attribute values * @param data type for {@code ScatterNd} output and operands * @param data type for {@code ScatterNd} output and operands * @return a new instance of ScatterNd @@ -146,14 +153,31 @@ public ScatterNd(Operation operation) { describeByClass = true ) public static ScatterNd create(Scope scope, - Operand indices, Operand updates, Operand shape) { + Operand indices, Operand updates, Operand shape, Options... options) { OperationBuilder opBuilder = scope.opBuilder(OP_NAME, "ScatterNd"); opBuilder.addInput(indices.asOutput()); opBuilder.addInput(updates.asOutput()); opBuilder.addInput(shape.asOutput()); + if (options != null) { + for (Options opts : options) { + if (opts.badIndicesPolicy != null) { + opBuilder.setAttr("bad_indices_policy", opts.badIndicesPolicy); + } + } + } return new ScatterNd<>(opBuilder.build()); } + /** + * Sets the badIndicesPolicy option. + * + * @param badIndicesPolicy the badIndicesPolicy option + * @return this Options instance. + */ + public static Options badIndicesPolicy(String badIndicesPolicy) { + return new Options().badIndicesPolicy(badIndicesPolicy); + } + /** * Gets output. * A new tensor with the given shape and updates applied according @@ -169,6 +193,27 @@ public Output asOutput() { return output; } + /** + * Optional attributes for {@link org.tensorflow.op.core.ScatterNd} + */ + public static class Options { + private String badIndicesPolicy; + + private Options() { + } + + /** + * Sets the badIndicesPolicy option. + * + * @param badIndicesPolicy the badIndicesPolicy option + * @return this Options instance. + */ + public Options badIndicesPolicy(String badIndicesPolicy) { + this.badIndicesPolicy = badIndicesPolicy; + return this; + } + } + @OpInputsMetadata( outputsClass = ScatterNd.class ) @@ -198,14 +243,20 @@ public static class Inputs extends RawOpInpu */ public final DataType Tindices; + /** + * The badIndicesPolicy attribute + */ + public final String badIndicesPolicy; + public Inputs(GraphOperation op) { - super(new ScatterNd<>(op), op, Arrays.asList("T", "Tindices")); + super(new ScatterNd<>(op), op, Arrays.asList("T", "Tindices", "bad_indices_policy")); int inputIndex = 0; indices = (Operand) op.input(inputIndex++); updates = (Operand) op.input(inputIndex++); shape = (Operand) op.input(inputIndex++); T = op.attributes().getAttrType("T"); Tindices = op.attributes().getAttrType("Tindices"); + badIndicesPolicy = op.attributes().getAttrString("bad_indices_policy"); } } } diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterNdAdd.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterNdAdd.java index aef9eed4a32..257dce25682 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterNdAdd.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterNdAdd.java @@ -62,8 +62,6 @@ * *

    See {@code tf.scatter_nd} for more details about how to make updates to * slices. - * - * @param data type for {@code output_ref} output */ @OpMetadata( opType = ScatterNdAdd.OP_NAME, @@ -111,6 +109,9 @@ public static ScatterNdAdd create(Scope scope, Operand r if (opts.useLocking != null) { opBuilder.setAttr("use_locking", opts.useLocking); } + if (opts.badIndicesPolicy != null) { + opBuilder.setAttr("bad_indices_policy", opts.badIndicesPolicy); + } } } return new ScatterNdAdd<>(opBuilder.build()); @@ -128,6 +129,16 @@ public static Options useLocking(Boolean useLocking) { return new Options().useLocking(useLocking); } + /** + * Sets the badIndicesPolicy option. + * + * @param badIndicesPolicy the badIndicesPolicy option + * @return this Options instance. + */ + public static Options badIndicesPolicy(String badIndicesPolicy) { + return new Options().badIndicesPolicy(badIndicesPolicy); + } + /** * Gets outputRef. * Same as ref. Returned as a convenience for operations that want @@ -149,6 +160,8 @@ public Output asOutput() { public static class Options { private Boolean useLocking; + private String badIndicesPolicy; + private Options() { } @@ -164,6 +177,17 @@ public Options useLocking(Boolean useLocking) { this.useLocking = useLocking; return this; } + + /** + * Sets the badIndicesPolicy option. + * + * @param badIndicesPolicy the badIndicesPolicy option + * @return this Options instance. + */ + public Options badIndicesPolicy(String badIndicesPolicy) { + this.badIndicesPolicy = badIndicesPolicy; + return this; + } } @OpInputsMetadata( @@ -204,8 +228,13 @@ public static class Inputs extends RawOpInputs> */ public final boolean useLocking; + /** + * The badIndicesPolicy attribute + */ + public final String badIndicesPolicy; + public Inputs(GraphOperation op) { - super(new ScatterNdAdd<>(op), op, Arrays.asList("T", "Tindices", "use_locking")); + super(new ScatterNdAdd<>(op), op, Arrays.asList("T", "Tindices", "use_locking", "bad_indices_policy")); int inputIndex = 0; ref = (Operand) op.input(inputIndex++); indices = (Operand) op.input(inputIndex++); @@ -213,6 +242,7 @@ public Inputs(GraphOperation op) { T = op.attributes().getAttrType("T"); Tindices = op.attributes().getAttrType("Tindices"); useLocking = op.attributes().getAttrBool("use_locking"); + badIndicesPolicy = op.attributes().getAttrString("bad_indices_policy"); } } } diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterNdMax.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterNdMax.java index 0adccafee2a..a7ebdf162d6 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterNdMax.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterNdMax.java @@ -36,8 +36,6 @@ /** * Computes element-wise maximum. - * - * @param data type for {@code output_ref} output */ @OpMetadata( opType = ScatterNdMax.OP_NAME, @@ -85,6 +83,9 @@ public static ScatterNdMax create(Scope scope, Operand r if (opts.useLocking != null) { opBuilder.setAttr("use_locking", opts.useLocking); } + if (opts.badIndicesPolicy != null) { + opBuilder.setAttr("bad_indices_policy", opts.badIndicesPolicy); + } } } return new ScatterNdMax<>(opBuilder.build()); @@ -102,6 +103,16 @@ public static Options useLocking(Boolean useLocking) { return new Options().useLocking(useLocking); } + /** + * Sets the badIndicesPolicy option. + * + * @param badIndicesPolicy the badIndicesPolicy option + * @return this Options instance. + */ + public static Options badIndicesPolicy(String badIndicesPolicy) { + return new Options().badIndicesPolicy(badIndicesPolicy); + } + /** * Gets outputRef. * Same as ref. Returned as a convenience for operations that want @@ -123,6 +134,8 @@ public Output asOutput() { public static class Options { private Boolean useLocking; + private String badIndicesPolicy; + private Options() { } @@ -138,6 +151,17 @@ public Options useLocking(Boolean useLocking) { this.useLocking = useLocking; return this; } + + /** + * Sets the badIndicesPolicy option. + * + * @param badIndicesPolicy the badIndicesPolicy option + * @return this Options instance. + */ + public Options badIndicesPolicy(String badIndicesPolicy) { + this.badIndicesPolicy = badIndicesPolicy; + return this; + } } @OpInputsMetadata( @@ -178,8 +202,13 @@ public static class Inputs extends RawOpInputs> */ public final boolean useLocking; + /** + * The badIndicesPolicy attribute + */ + public final String badIndicesPolicy; + public Inputs(GraphOperation op) { - super(new ScatterNdMax<>(op), op, Arrays.asList("T", "Tindices", "use_locking")); + super(new ScatterNdMax<>(op), op, Arrays.asList("T", "Tindices", "use_locking", "bad_indices_policy")); int inputIndex = 0; ref = (Operand) op.input(inputIndex++); indices = (Operand) op.input(inputIndex++); @@ -187,6 +216,7 @@ public Inputs(GraphOperation op) { T = op.attributes().getAttrType("T"); Tindices = op.attributes().getAttrType("Tindices"); useLocking = op.attributes().getAttrBool("use_locking"); + badIndicesPolicy = op.attributes().getAttrString("bad_indices_policy"); } } } diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterNdMin.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterNdMin.java index d2780381fcb..3ade02671ed 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterNdMin.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterNdMin.java @@ -36,8 +36,6 @@ /** * Computes element-wise minimum. - * - * @param data type for {@code output_ref} output */ @OpMetadata( opType = ScatterNdMin.OP_NAME, @@ -85,6 +83,9 @@ public static ScatterNdMin create(Scope scope, Operand r if (opts.useLocking != null) { opBuilder.setAttr("use_locking", opts.useLocking); } + if (opts.badIndicesPolicy != null) { + opBuilder.setAttr("bad_indices_policy", opts.badIndicesPolicy); + } } } return new ScatterNdMin<>(opBuilder.build()); @@ -102,6 +103,16 @@ public static Options useLocking(Boolean useLocking) { return new Options().useLocking(useLocking); } + /** + * Sets the badIndicesPolicy option. + * + * @param badIndicesPolicy the badIndicesPolicy option + * @return this Options instance. + */ + public static Options badIndicesPolicy(String badIndicesPolicy) { + return new Options().badIndicesPolicy(badIndicesPolicy); + } + /** * Gets outputRef. * Same as ref. Returned as a convenience for operations that want @@ -123,6 +134,8 @@ public Output asOutput() { public static class Options { private Boolean useLocking; + private String badIndicesPolicy; + private Options() { } @@ -138,6 +151,17 @@ public Options useLocking(Boolean useLocking) { this.useLocking = useLocking; return this; } + + /** + * Sets the badIndicesPolicy option. + * + * @param badIndicesPolicy the badIndicesPolicy option + * @return this Options instance. + */ + public Options badIndicesPolicy(String badIndicesPolicy) { + this.badIndicesPolicy = badIndicesPolicy; + return this; + } } @OpInputsMetadata( @@ -178,8 +202,13 @@ public static class Inputs extends RawOpInputs> */ public final boolean useLocking; + /** + * The badIndicesPolicy attribute + */ + public final String badIndicesPolicy; + public Inputs(GraphOperation op) { - super(new ScatterNdMin<>(op), op, Arrays.asList("T", "Tindices", "use_locking")); + super(new ScatterNdMin<>(op), op, Arrays.asList("T", "Tindices", "use_locking", "bad_indices_policy")); int inputIndex = 0; ref = (Operand) op.input(inputIndex++); indices = (Operand) op.input(inputIndex++); @@ -187,6 +216,7 @@ public Inputs(GraphOperation op) { T = op.attributes().getAttrType("T"); Tindices = op.attributes().getAttrType("Tindices"); useLocking = op.attributes().getAttrBool("use_locking"); + badIndicesPolicy = op.attributes().getAttrString("bad_indices_policy"); } } } diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterNdNonAliasingAdd.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterNdNonAliasingAdd.java index 4d29ef748d8..c152dadc35e 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterNdNonAliasingAdd.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterNdNonAliasingAdd.java @@ -63,8 +63,6 @@ * [1, 13, 3, 14, 14, 6, 7, 20] * *

    See {@code tf.scatter_nd} for more details about how to make updates to slices. - * - * @param data type for {@code output} output */ @OpMetadata( opType = ScatterNdNonAliasingAdd.OP_NAME, @@ -94,6 +92,7 @@ public ScatterNdNonAliasingAdd(Operation operation) { * A tensor of indices into {@code input}. * @param updates A Tensor. Must have the same type as ref. A tensor of updated values * to add to {@code input}. + * @param options carries optional attribute values * @param data type for {@code ScatterNdNonAliasingAdd} output and operands * @return a new instance of ScatterNdNonAliasingAdd */ @@ -101,14 +100,31 @@ public ScatterNdNonAliasingAdd(Operation operation) { describeByClass = true ) public static ScatterNdNonAliasingAdd create(Scope scope, Operand input, - Operand indices, Operand updates) { + Operand indices, Operand updates, Options... options) { OperationBuilder opBuilder = scope.opBuilder(OP_NAME, "ScatterNdNonAliasingAdd"); opBuilder.addInput(input.asOutput()); opBuilder.addInput(indices.asOutput()); opBuilder.addInput(updates.asOutput()); + if (options != null) { + for (Options opts : options) { + if (opts.badIndicesPolicy != null) { + opBuilder.setAttr("bad_indices_policy", opts.badIndicesPolicy); + } + } + } return new ScatterNdNonAliasingAdd<>(opBuilder.build()); } + /** + * Sets the badIndicesPolicy option. + * + * @param badIndicesPolicy the badIndicesPolicy option + * @return this Options instance. + */ + public static Options badIndicesPolicy(String badIndicesPolicy) { + return new Options().badIndicesPolicy(badIndicesPolicy); + } + /** * Gets output. * A {@code Tensor} with the same shape as {@code input}, containing values of {@code input} @@ -124,6 +140,27 @@ public Output asOutput() { return output; } + /** + * Optional attributes for {@link org.tensorflow.op.core.ScatterNdNonAliasingAdd} + */ + public static class Options { + private String badIndicesPolicy; + + private Options() { + } + + /** + * Sets the badIndicesPolicy option. + * + * @param badIndicesPolicy the badIndicesPolicy option + * @return this Options instance. + */ + public Options badIndicesPolicy(String badIndicesPolicy) { + this.badIndicesPolicy = badIndicesPolicy; + return this; + } + } + @OpInputsMetadata( outputsClass = ScatterNdNonAliasingAdd.class ) @@ -155,14 +192,20 @@ public static class Inputs extends RawOpInputs(op), op, Arrays.asList("T", "Tindices")); + super(new ScatterNdNonAliasingAdd<>(op), op, Arrays.asList("T", "Tindices", "bad_indices_policy")); int inputIndex = 0; input = (Operand) op.input(inputIndex++); indices = (Operand) op.input(inputIndex++); updates = (Operand) op.input(inputIndex++); T = op.attributes().getAttrType("T"); Tindices = op.attributes().getAttrType("Tindices"); + badIndicesPolicy = op.attributes().getAttrString("bad_indices_policy"); } } } diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterNdSub.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterNdSub.java index b2018d27511..21654611e88 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterNdSub.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterNdSub.java @@ -63,8 +63,6 @@ * *

    See {@code tf.scatter_nd} for more details about how to make updates to * slices. - * - * @param data type for {@code output_ref} output */ @OpMetadata( opType = ScatterNdSub.OP_NAME, @@ -112,6 +110,9 @@ public static ScatterNdSub create(Scope scope, Operand r if (opts.useLocking != null) { opBuilder.setAttr("use_locking", opts.useLocking); } + if (opts.badIndicesPolicy != null) { + opBuilder.setAttr("bad_indices_policy", opts.badIndicesPolicy); + } } } return new ScatterNdSub<>(opBuilder.build()); @@ -129,6 +130,16 @@ public static Options useLocking(Boolean useLocking) { return new Options().useLocking(useLocking); } + /** + * Sets the badIndicesPolicy option. + * + * @param badIndicesPolicy the badIndicesPolicy option + * @return this Options instance. + */ + public static Options badIndicesPolicy(String badIndicesPolicy) { + return new Options().badIndicesPolicy(badIndicesPolicy); + } + /** * Gets outputRef. * Same as ref. Returned as a convenience for operations that want @@ -150,6 +161,8 @@ public Output asOutput() { public static class Options { private Boolean useLocking; + private String badIndicesPolicy; + private Options() { } @@ -165,6 +178,17 @@ public Options useLocking(Boolean useLocking) { this.useLocking = useLocking; return this; } + + /** + * Sets the badIndicesPolicy option. + * + * @param badIndicesPolicy the badIndicesPolicy option + * @return this Options instance. + */ + public Options badIndicesPolicy(String badIndicesPolicy) { + this.badIndicesPolicy = badIndicesPolicy; + return this; + } } @OpInputsMetadata( @@ -205,8 +229,13 @@ public static class Inputs extends RawOpInputs> */ public final boolean useLocking; + /** + * The badIndicesPolicy attribute + */ + public final String badIndicesPolicy; + public Inputs(GraphOperation op) { - super(new ScatterNdSub<>(op), op, Arrays.asList("T", "Tindices", "use_locking")); + super(new ScatterNdSub<>(op), op, Arrays.asList("T", "Tindices", "use_locking", "bad_indices_policy")); int inputIndex = 0; ref = (Operand) op.input(inputIndex++); indices = (Operand) op.input(inputIndex++); @@ -214,6 +243,7 @@ public Inputs(GraphOperation op) { T = op.attributes().getAttrType("T"); Tindices = op.attributes().getAttrType("Tindices"); useLocking = op.attributes().getAttrBool("use_locking"); + badIndicesPolicy = op.attributes().getAttrString("bad_indices_policy"); } } } diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterNdUpdate.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterNdUpdate.java index 56427f20fac..5bf1e30fe35 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterNdUpdate.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterNdUpdate.java @@ -62,8 +62,6 @@ *

    See {@code tf.scatter_nd} for more details about how to make updates to * slices. *

    See also {@code tf.scatter_update} and {@code tf.batch_scatter_update}. - * - * @param data type for {@code output_ref} output */ @OpMetadata( opType = ScatterNdUpdate.OP_NAME, @@ -111,6 +109,9 @@ public static ScatterNdUpdate create(Scope scope, Operand(opBuilder.build()); @@ -128,6 +129,16 @@ public static Options useLocking(Boolean useLocking) { return new Options().useLocking(useLocking); } + /** + * Sets the badIndicesPolicy option. + * + * @param badIndicesPolicy the badIndicesPolicy option + * @return this Options instance. + */ + public static Options badIndicesPolicy(String badIndicesPolicy) { + return new Options().badIndicesPolicy(badIndicesPolicy); + } + /** * Gets outputRef. * Same as ref. Returned as a convenience for operations that want to @@ -149,6 +160,8 @@ public Output asOutput() { public static class Options { private Boolean useLocking; + private String badIndicesPolicy; + private Options() { } @@ -164,6 +177,17 @@ public Options useLocking(Boolean useLocking) { this.useLocking = useLocking; return this; } + + /** + * Sets the badIndicesPolicy option. + * + * @param badIndicesPolicy the badIndicesPolicy option + * @return this Options instance. + */ + public Options badIndicesPolicy(String badIndicesPolicy) { + this.badIndicesPolicy = badIndicesPolicy; + return this; + } } @OpInputsMetadata( @@ -204,8 +228,13 @@ public static class Inputs extends RawOpInputs(op), op, Arrays.asList("T", "Tindices", "use_locking")); + super(new ScatterNdUpdate<>(op), op, Arrays.asList("T", "Tindices", "use_locking", "bad_indices_policy")); int inputIndex = 0; ref = (Operand) op.input(inputIndex++); indices = (Operand) op.input(inputIndex++); @@ -213,6 +242,7 @@ public Inputs(GraphOperation op) { T = op.attributes().getAttrType("T"); Tindices = op.attributes().getAttrType("Tindices"); useLocking = op.attributes().getAttrBool("use_locking"); + badIndicesPolicy = op.attributes().getAttrString("bad_indices_policy"); } } } diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterSub.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterSub.java index 06d274ff356..4686a81470f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterSub.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterSub.java @@ -54,8 +54,6 @@ *

    * *
    - * - * @param data type for {@code output_ref} output */ @OpMetadata( opType = ScatterSub.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterUpdate.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterUpdate.java index 711cbf7485f..60e22039589 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterUpdate.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ScatterUpdate.java @@ -57,8 +57,6 @@ * * *

    See also {@code tf.batch_scatter_update} and {@code tf.scatter_nd_update}. - * - * @param data type for {@code output_ref} output */ @OpMetadata( opType = ScatterUpdate.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Select.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Select.java index 71caff86d14..c88ea468f39 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Select.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Select.java @@ -36,8 +36,6 @@ /** * The SelectV2 operation - * - * @param data type for {@code output} output */ @OpMetadata( opType = Select.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/SetDiff1d.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/SetDiff1d.java index 61af8e762a2..562b2088b93 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/SetDiff1d.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/SetDiff1d.java @@ -54,10 +54,6 @@ * out ==> [2, 4, 6] * idx ==> [1, 3, 5] * - * - * @param data type for {@code out} output - * - * @param data type for {@code idx} output */ @OpMetadata( opType = SetDiff1d.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Shape.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Shape.java index 4f9f9115847..2f7592fbc03 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Shape.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Shape.java @@ -44,8 +44,6 @@ * # 't' is [[[1, 1, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]]] * shape(t) ==> [2, 2, 3] * - * - * @param data type for {@code output} output */ @OpMetadata( opType = Shape.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ShapeN.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ShapeN.java index b56a39452d5..b53a00a1a82 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ShapeN.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ShapeN.java @@ -41,8 +41,6 @@ /** * Returns shape of tensors. * This operation returns N 1-D integer tensors representing shape of {@code input[i]s}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = ShapeN.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Size.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Size.java index 1ad02bc0f9b..2be90850900 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Size.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Size.java @@ -45,8 +45,6 @@ * # 't' is [[[1, 1,, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]]]] * size(t) ==> 12 * - * - * @param data type for {@code output} output */ @OpMetadata( opType = Size.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Slice.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Slice.java index b53cae539a0..37a168fb6f7 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Slice.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Slice.java @@ -41,8 +41,6 @@ * 'begin'. *

    Requirements: * 0 <= begin[i] <= begin[i] + size[i] <= Di for i in [0, n) - * - * @param data type for {@code output} output */ @OpMetadata( opType = Slice.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Snapshot.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Snapshot.java index d8b1ed563d9..bafca31221f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Snapshot.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Snapshot.java @@ -35,8 +35,6 @@ /** * Returns a copy of the input tensor. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Snapshot.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/SpaceToBatchNd.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/SpaceToBatchNd.java index d56e6ef8709..2a366e46641 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/SpaceToBatchNd.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/SpaceToBatchNd.java @@ -132,8 +132,6 @@ * *

    Among others, this operation is useful for reducing atrous convolution into * regular convolution. - * - * @param data type for {@code output} output */ @OpMetadata( opType = SpaceToBatchNd.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Split.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Split.java index f6a01ed1950..dc4fad88677 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Split.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Split.java @@ -38,8 +38,6 @@ /** * Splits a tensor into {@code num_split} tensors along one dimension. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Split.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/SplitV.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/SplitV.java index 8d1beb3fc5b..cc0525e9645 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/SplitV.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/SplitV.java @@ -39,8 +39,6 @@ /** * Splits a tensor into {@code num_split} tensors along one dimension. - * - * @param data type for {@code output} output */ @OpMetadata( opType = SplitV.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Squeeze.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Squeeze.java index 3ccc9dff638..52155b47d43 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Squeeze.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Squeeze.java @@ -50,8 +50,6 @@ * # 't' is a tensor of shape [1, 2, 1, 3, 1, 1] * shape(squeeze(t, [2, 4])) ==> [1, 2, 3, 1] * - * - * @param data type for {@code output} output */ @OpMetadata( opType = Squeeze.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Stack.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Stack.java index 0022997321a..976a86955b3 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Stack.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Stack.java @@ -51,8 +51,6 @@ * pack([x, y, z], axis=1) => [[1, 2, 3], [4, 5, 6]] * *

    This is the opposite of {@code unpack}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Stack.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/StackPop.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/StackPop.java index a6a3021ce14..502cfcc8c06 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/StackPop.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/StackPop.java @@ -36,8 +36,6 @@ /** * Pop the element at the top of the stack. - * - * @param data type for {@code elem} output */ @OpMetadata( opType = StackPop.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/StackPush.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/StackPush.java index c43aa1de30e..f9f05ff1912 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/StackPush.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/StackPush.java @@ -35,8 +35,6 @@ /** * Push an element onto the stack. - * - * @param data type for {@code output} output */ @OpMetadata( opType = StackPush.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/StochasticCastToInt.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/StochasticCastToInt.java index 29da2cb9a53..a06a2c8017d 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/StochasticCastToInt.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/StochasticCastToInt.java @@ -40,8 +40,6 @@ * Stochastically cast a given tensor from floats to ints. * The values are cast with a deterministic pseudo-random tensor from a uniform distribution generated from user given key, counter, algorithm. Values will saturate if out of the specified integer type range, and will become zero if inputs are NaN. *

    The outputs are a deterministic function of {@code input}, {@code key}, {@code counter}, {@code alg}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = StochasticCastToInt.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/StopGradient.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/StopGradient.java index c2086cb3e92..fb486c42253 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/StopGradient.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/StopGradient.java @@ -85,8 +85,6 @@ *

  • Adversarial training, where no backprop should happen through the adversarial * example generation process.
  • * - * - * @param data type for {@code output} output */ @OpMetadata( opType = StopGradient.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/StridedSlice.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/StridedSlice.java index 6b8953f7995..ec55dae1c24 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/StridedSlice.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/StridedSlice.java @@ -133,8 +133,6 @@ *

    Requirements: * {@code 0 != strides[i] for i in [0, m)} * {@code ellipsis_mask must be a power of two (only one ellipsis)} - * - * @param data type for {@code output} output */ @OpMetadata( opType = StridedSlice.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/StridedSliceAssign.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/StridedSliceAssign.java index b2ab8d606e2..2911a675905 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/StridedSliceAssign.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/StridedSliceAssign.java @@ -41,8 +41,6 @@ * {@code begin}, {@code end}, {@code strides}, etc. work exactly as in {@code StridedSlice}. *

    NOTE this op currently does not support broadcasting and so {@code value}'s * shape must be exactly the shape produced by the slice of {@code ref}. - * - * @param data type for {@code output_ref} output */ @OpMetadata( opType = StridedSliceAssign.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/StridedSliceGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/StridedSliceGrad.java index 2a234c9ab7a..fcd7518dd87 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/StridedSliceGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/StridedSliceGrad.java @@ -43,8 +43,6 @@ *

    Arguments are the same as StridedSliceGrad with the exception that * {@code dy} is the input gradient to be propagated and {@code shape} is the * shape of {@code StridedSlice}'s {@code input}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = StridedSliceGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Sum.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Sum.java index 15957ea2189..abcdb1ee9ef 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Sum.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Sum.java @@ -40,8 +40,6 @@ * {@code keep_dims} is true, the rank of the tensor is reduced by 1 for each entry in * {@code axis}. If {@code keep_dims} is true, the reduced dimensions are * retained with length 1. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Sum.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/SwitchCond.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/SwitchCond.java index c6a8f810467..c6842c9ab87 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/SwitchCond.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/SwitchCond.java @@ -39,8 +39,6 @@ * If {@code pred} is true, the {@code data} input is forwarded to {@code output_true}. Otherwise, * the data goes to {@code output_false}. *

    See also {@code RefSwitch} and {@code Merge}. - * - * @param data type for {@code output_false} output */ @OpMetadata( opType = SwitchCond.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TemporaryVariable.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TemporaryVariable.java index 3e8c8a70ec8..d66021bb728 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TemporaryVariable.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TemporaryVariable.java @@ -48,8 +48,6 @@ * var = state_ops.assign(var, [[4.0, 5.0]]) * var = state_ops.assign_add(var, [[6.0, 7.0]]) * final = state_ops._destroy_temporary_variable(var, var_name=var_name) - * - * @param data type for {@code ref} output */ @OpMetadata( opType = TemporaryVariable.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorArrayConcat.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorArrayConcat.java index b3dbc08ef3e..75ba48a0102 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorArrayConcat.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorArrayConcat.java @@ -48,8 +48,6 @@ * (n0 + n1 + ... + n(T-1) x d0 x d1 x ...) * *

    All elements must have the same shape (excepting the first dimension). - * - * @param data type for {@code value} output */ @OpMetadata( opType = TensorArrayConcat.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorArrayGather.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorArrayGather.java index 0f7fd351089..60d8b437b00 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorArrayGather.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorArrayGather.java @@ -40,8 +40,6 @@ /** * Gather specific elements from the TensorArray into output {@code value}. * All elements selected by {@code indices} must have the same shape. - * - * @param data type for {@code value} output */ @OpMetadata( opType = TensorArrayGather.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorArrayPack.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorArrayPack.java index 6e52e6ef906..d1cf5c89e65 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorArrayPack.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorArrayPack.java @@ -39,8 +39,6 @@ /** * The TensorArrayPack operation - * - * @param data type for {@code value} output */ @OpMetadata( opType = TensorArrayPack.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorArrayRead.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorArrayRead.java index 6765205c463..f5a0aa073a7 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorArrayRead.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorArrayRead.java @@ -38,8 +38,6 @@ /** * Read an element from the TensorArray into output {@code value}. - * - * @param data type for {@code value} output */ @OpMetadata( opType = TensorArrayRead.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorListConcat.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorListConcat.java index 664783a09c5..70ef65f9314 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorListConcat.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorListConcat.java @@ -48,8 +48,6 @@ * is not already set. * tensor: The concated result. * lengths: Output tensor containing sizes of the 0th dimension of tensors in the list, used for computing the gradient. - * - * @param data type for {@code tensor} output */ @OpMetadata( opType = TensorListConcat.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorListElementShape.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorListElementShape.java index d955a6a636d..6190f9c1c01 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorListElementShape.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorListElementShape.java @@ -39,8 +39,6 @@ * The shape of the elements of the given list, as a tensor. * input_handle: the list * element_shape: the shape of elements of the list - * - * @param data type for {@code element_shape} output */ @OpMetadata( opType = TensorListElementShape.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorListGather.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorListGather.java index 27a627b4759..ac725c72b97 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorListGather.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorListGather.java @@ -42,8 +42,6 @@ *

    input_handle: The input tensor list. * indices: The indices used to index into the list. * values: The tensor. - * - * @param data type for {@code values} output */ @OpMetadata( opType = TensorListGather.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorListGetItem.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorListGetItem.java index 1ea76d2101e..244704b5754 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorListGetItem.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorListGetItem.java @@ -40,8 +40,6 @@ * input_handle: the list * index: the position in the list from which an element will be retrieved * item: the element at that position - * - * @param data type for {@code item} output */ @OpMetadata( opType = TensorListGetItem.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorListPopBack.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorListPopBack.java index ee7a5cde1c9..af805e71f9b 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorListPopBack.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorListPopBack.java @@ -42,8 +42,6 @@ * tensor: the withdrawn last element of the list * element_dtype: the type of elements in the list * element_shape: the shape of the output tensor - * - * @param data type for {@code tensor} output */ @OpMetadata( opType = TensorListPopBack.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorListStack.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorListStack.java index fec4f942658..2d058b8e00d 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorListStack.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorListStack.java @@ -41,8 +41,6 @@ *

    input_handle: the input list * tensor: the gathered result * num_elements: optional. If not -1, the number of elements in the list. - * - * @param data type for {@code tensor} output */ @OpMetadata( opType = TensorListStack.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorMapLookup.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorMapLookup.java index dccdc1ee996..a3e8b54e888 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorMapLookup.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorMapLookup.java @@ -39,8 +39,6 @@ * input_handle: the input map * key: the key to be looked up * value: the value found from the given key - * - * @param data type for {@code value} output */ @OpMetadata( opType = TensorMapLookup.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorMapStackKeys.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorMapStackKeys.java index b2a217c98e6..8942b2f9f8b 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorMapStackKeys.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorMapStackKeys.java @@ -38,8 +38,6 @@ * Returns a Tensor stack of all keys in a tensor map. * input_handle: the input map * keys: the returned Tensor of all keys in the map - * - * @param data type for {@code keys} output */ @OpMetadata( opType = TensorMapStackKeys.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorScatterNdAdd.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorScatterNdAdd.java index a72a1defde1..77d1dd111d5 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorScatterNdAdd.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorScatterNdAdd.java @@ -94,10 +94,16 @@ * * * - *

    Note: on CPU, if an out of bound index is found, an error is returned. - * On GPU, if an out of bound index is found, the index is ignored. - * - * @param data type for {@code output} output + *

    If {@code indices} contains any out-of-bound indices, depending on + * {@code bad_indices_policy}, the op will either return an error or ignore the + * out-of-bound indices. {@code bad_indices_policy} can be one of the following values: + *

      + *
    1. "" or "DEFAULT": raises on CPU and ignore on GPU. This is because + * historically on CPU and GPU we handle errors in different ways, and for + * backward compatibility we keep the default behavior.
    2. + *
    3. "ERROR": raises error; GPU does not support this value.
    4. + *
    5. "IGNORE": ignore the bad indices; supported on both CPU and GPU.
    6. + *
    */ @OpMetadata( opType = TensorScatterNdAdd.OP_NAME, @@ -125,6 +131,7 @@ public TensorScatterNdAdd(Operation operation) { * @param tensor Tensor to copy/update. * @param indices Index tensor. * @param updates Updates to scatter into output. + * @param options carries optional attribute values * @param data type for {@code TensorScatterAdd} output and operands * @return a new instance of TensorScatterNdAdd */ @@ -132,14 +139,31 @@ public TensorScatterNdAdd(Operation operation) { describeByClass = true ) public static TensorScatterNdAdd create(Scope scope, Operand tensor, - Operand indices, Operand updates) { + Operand indices, Operand updates, Options... options) { OperationBuilder opBuilder = scope.opBuilder(OP_NAME, "TensorScatterNdAdd"); opBuilder.addInput(tensor.asOutput()); opBuilder.addInput(indices.asOutput()); opBuilder.addInput(updates.asOutput()); + if (options != null) { + for (Options opts : options) { + if (opts.badIndicesPolicy != null) { + opBuilder.setAttr("bad_indices_policy", opts.badIndicesPolicy); + } + } + } return new TensorScatterNdAdd<>(opBuilder.build()); } + /** + * Sets the badIndicesPolicy option. + * + * @param badIndicesPolicy the badIndicesPolicy option + * @return this Options instance. + */ + public static Options badIndicesPolicy(String badIndicesPolicy) { + return new Options().badIndicesPolicy(badIndicesPolicy); + } + /** * Gets output. * A new tensor copied from tensor and updates added according to the indices. @@ -154,6 +178,27 @@ public Output asOutput() { return output; } + /** + * Optional attributes for {@link org.tensorflow.op.core.TensorScatterNdAdd} + */ + public static class Options { + private String badIndicesPolicy; + + private Options() { + } + + /** + * Sets the badIndicesPolicy option. + * + * @param badIndicesPolicy the badIndicesPolicy option + * @return this Options instance. + */ + public Options badIndicesPolicy(String badIndicesPolicy) { + this.badIndicesPolicy = badIndicesPolicy; + return this; + } + } + @OpInputsMetadata( outputsClass = TensorScatterNdAdd.class ) @@ -183,14 +228,20 @@ public static class Inputs extends RawOpInputs(op), op, Arrays.asList("T", "Tindices")); + super(new TensorScatterNdAdd<>(op), op, Arrays.asList("T", "Tindices", "bad_indices_policy")); int inputIndex = 0; tensor = (Operand) op.input(inputIndex++); indices = (Operand) op.input(inputIndex++); updates = (Operand) op.input(inputIndex++); T = op.attributes().getAttrType("T"); Tindices = op.attributes().getAttrType("Tindices"); + badIndicesPolicy = op.attributes().getAttrString("bad_indices_policy"); } } } diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorScatterNdMax.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorScatterNdMax.java index ceddda24a20..cbf9b2dd471 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorScatterNdMax.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorScatterNdMax.java @@ -50,8 +50,6 @@ * * *

    Refer to {@code tf.tensor_scatter_nd_update} for more details. - * - * @param data type for {@code output} output */ @OpMetadata( opType = TensorScatterNdMax.OP_NAME, @@ -79,6 +77,7 @@ public TensorScatterNdMax(Operation operation) { * @param tensor Tensor to update. * @param indices Index tensor. * @param updates Updates to scatter into output. + * @param options carries optional attribute values * @param data type for {@code TensorScatterMax} output and operands * @return a new instance of TensorScatterNdMax */ @@ -86,14 +85,31 @@ public TensorScatterNdMax(Operation operation) { describeByClass = true ) public static TensorScatterNdMax create(Scope scope, Operand tensor, - Operand indices, Operand updates) { + Operand indices, Operand updates, Options... options) { OperationBuilder opBuilder = scope.opBuilder(OP_NAME, "TensorScatterNdMax"); opBuilder.addInput(tensor.asOutput()); opBuilder.addInput(indices.asOutput()); opBuilder.addInput(updates.asOutput()); + if (options != null) { + for (Options opts : options) { + if (opts.badIndicesPolicy != null) { + opBuilder.setAttr("bad_indices_policy", opts.badIndicesPolicy); + } + } + } return new TensorScatterNdMax<>(opBuilder.build()); } + /** + * Sets the badIndicesPolicy option. + * + * @param badIndicesPolicy the badIndicesPolicy option + * @return this Options instance. + */ + public static Options badIndicesPolicy(String badIndicesPolicy) { + return new Options().badIndicesPolicy(badIndicesPolicy); + } + /** * Gets output. * A new tensor copied from tensor whose values are element-wise maximum between tensor and updates according to the indices. @@ -108,6 +124,27 @@ public Output asOutput() { return output; } + /** + * Optional attributes for {@link org.tensorflow.op.core.TensorScatterNdMax} + */ + public static class Options { + private String badIndicesPolicy; + + private Options() { + } + + /** + * Sets the badIndicesPolicy option. + * + * @param badIndicesPolicy the badIndicesPolicy option + * @return this Options instance. + */ + public Options badIndicesPolicy(String badIndicesPolicy) { + this.badIndicesPolicy = badIndicesPolicy; + return this; + } + } + @OpInputsMetadata( outputsClass = TensorScatterNdMax.class ) @@ -137,14 +174,20 @@ public static class Inputs extends RawOpInputs(op), op, Arrays.asList("T", "Tindices")); + super(new TensorScatterNdMax<>(op), op, Arrays.asList("T", "Tindices", "bad_indices_policy")); int inputIndex = 0; tensor = (Operand) op.input(inputIndex++); indices = (Operand) op.input(inputIndex++); updates = (Operand) op.input(inputIndex++); T = op.attributes().getAttrType("T"); Tindices = op.attributes().getAttrType("Tindices"); + badIndicesPolicy = op.attributes().getAttrString("bad_indices_policy"); } } } diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorScatterNdMin.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorScatterNdMin.java index b6da07b4c31..7db99c551d1 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorScatterNdMin.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorScatterNdMin.java @@ -36,8 +36,6 @@ /** * The TensorScatterMin operation - * - * @param data type for {@code output} output */ @OpMetadata( opType = TensorScatterNdMin.OP_NAME, @@ -65,6 +63,7 @@ public TensorScatterNdMin(Operation operation) { * @param tensor Tensor to update. * @param indices Index tensor. * @param updates Updates to scatter into output. + * @param options carries optional attribute values * @param data type for {@code TensorScatterMin} output and operands * @return a new instance of TensorScatterNdMin */ @@ -72,14 +71,31 @@ public TensorScatterNdMin(Operation operation) { describeByClass = true ) public static TensorScatterNdMin create(Scope scope, Operand tensor, - Operand indices, Operand updates) { + Operand indices, Operand updates, Options... options) { OperationBuilder opBuilder = scope.opBuilder(OP_NAME, "TensorScatterNdMin"); opBuilder.addInput(tensor.asOutput()); opBuilder.addInput(indices.asOutput()); opBuilder.addInput(updates.asOutput()); + if (options != null) { + for (Options opts : options) { + if (opts.badIndicesPolicy != null) { + opBuilder.setAttr("bad_indices_policy", opts.badIndicesPolicy); + } + } + } return new TensorScatterNdMin<>(opBuilder.build()); } + /** + * Sets the badIndicesPolicy option. + * + * @param badIndicesPolicy the badIndicesPolicy option + * @return this Options instance. + */ + public static Options badIndicesPolicy(String badIndicesPolicy) { + return new Options().badIndicesPolicy(badIndicesPolicy); + } + /** * Gets output. * A new tensor copied from tensor whose values are element-wise minimum between tensor and updates according to the indices. @@ -94,6 +110,27 @@ public Output asOutput() { return output; } + /** + * Optional attributes for {@link org.tensorflow.op.core.TensorScatterNdMin} + */ + public static class Options { + private String badIndicesPolicy; + + private Options() { + } + + /** + * Sets the badIndicesPolicy option. + * + * @param badIndicesPolicy the badIndicesPolicy option + * @return this Options instance. + */ + public Options badIndicesPolicy(String badIndicesPolicy) { + this.badIndicesPolicy = badIndicesPolicy; + return this; + } + } + @OpInputsMetadata( outputsClass = TensorScatterNdMin.class ) @@ -123,14 +160,20 @@ public static class Inputs extends RawOpInputs(op), op, Arrays.asList("T", "Tindices")); + super(new TensorScatterNdMin<>(op), op, Arrays.asList("T", "Tindices", "bad_indices_policy")); int inputIndex = 0; tensor = (Operand) op.input(inputIndex++); indices = (Operand) op.input(inputIndex++); updates = (Operand) op.input(inputIndex++); T = op.attributes().getAttrType("T"); Tindices = op.attributes().getAttrType("Tindices"); + badIndicesPolicy = op.attributes().getAttrString("bad_indices_policy"); } } } diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorScatterNdSub.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorScatterNdSub.java index 3623707e77e..095e0428962 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorScatterNdSub.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorScatterNdSub.java @@ -91,8 +91,6 @@ * *

    Note that on CPU, if an out of bound index is found, an error is returned. * On GPU, if an out of bound index is found, the index is ignored. - * - * @param data type for {@code output} output */ @OpMetadata( opType = TensorScatterNdSub.OP_NAME, @@ -120,6 +118,7 @@ public TensorScatterNdSub(Operation operation) { * @param tensor Tensor to copy/update. * @param indices Index tensor. * @param updates Updates to scatter into output. + * @param options carries optional attribute values * @param data type for {@code TensorScatterSub} output and operands * @return a new instance of TensorScatterNdSub */ @@ -127,14 +126,31 @@ public TensorScatterNdSub(Operation operation) { describeByClass = true ) public static TensorScatterNdSub create(Scope scope, Operand tensor, - Operand indices, Operand updates) { + Operand indices, Operand updates, Options... options) { OperationBuilder opBuilder = scope.opBuilder(OP_NAME, "TensorScatterNdSub"); opBuilder.addInput(tensor.asOutput()); opBuilder.addInput(indices.asOutput()); opBuilder.addInput(updates.asOutput()); + if (options != null) { + for (Options opts : options) { + if (opts.badIndicesPolicy != null) { + opBuilder.setAttr("bad_indices_policy", opts.badIndicesPolicy); + } + } + } return new TensorScatterNdSub<>(opBuilder.build()); } + /** + * Sets the badIndicesPolicy option. + * + * @param badIndicesPolicy the badIndicesPolicy option + * @return this Options instance. + */ + public static Options badIndicesPolicy(String badIndicesPolicy) { + return new Options().badIndicesPolicy(badIndicesPolicy); + } + /** * Gets output. * A new tensor copied from tensor and updates subtracted according to the indices. @@ -149,6 +165,27 @@ public Output asOutput() { return output; } + /** + * Optional attributes for {@link org.tensorflow.op.core.TensorScatterNdSub} + */ + public static class Options { + private String badIndicesPolicy; + + private Options() { + } + + /** + * Sets the badIndicesPolicy option. + * + * @param badIndicesPolicy the badIndicesPolicy option + * @return this Options instance. + */ + public Options badIndicesPolicy(String badIndicesPolicy) { + this.badIndicesPolicy = badIndicesPolicy; + return this; + } + } + @OpInputsMetadata( outputsClass = TensorScatterNdSub.class ) @@ -178,14 +215,20 @@ public static class Inputs extends RawOpInputs(op), op, Arrays.asList("T", "Tindices")); + super(new TensorScatterNdSub<>(op), op, Arrays.asList("T", "Tindices", "bad_indices_policy")); int inputIndex = 0; tensor = (Operand) op.input(inputIndex++); indices = (Operand) op.input(inputIndex++); updates = (Operand) op.input(inputIndex++); T = op.attributes().getAttrType("T"); Tindices = op.attributes().getAttrType("Tindices"); + badIndicesPolicy = op.attributes().getAttrString("bad_indices_policy"); } } } diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorScatterNdUpdate.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorScatterNdUpdate.java index 3c53fca7eab..96323c0db29 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorScatterNdUpdate.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorScatterNdUpdate.java @@ -42,7 +42,6 @@ * scattered onto an existing tensor (as opposed to a zero-tensor). If the memory * for the existing tensor cannot be re-used, a copy is made and updated. *

    If {@code indices} contains duplicates, then we pick the last update for the index. - *

    If an out of bound index is found on CPU, an error is returned. *

    WARNING: There are some GPU specific semantics for this operation. *

      *
    • If an out of bound index is found, the index is ignored.
    • @@ -64,9 +63,17 @@ *
        * indices.shape[:-1] + tensor.shape[indices.shape[-1]:]
        * 
      + *

      If {@code indices} contains any out-of-bound indices, depending on + * {@code bad_indices_policy}, the op will either return an error or ignore the + * out-of-bound indices. {@code bad_indices_policy} can be one of the following values: + *

        + *
      1. "" or "DEFAULT": raises on CPU and ignore on GPU. This is because + * historically on CPU and GPU we handle errors in different ways, and for + * backward compatibility we keep the default behavior.
      2. + *
      3. "ERROR": raises error; GPU does not support this value.
      4. + *
      5. "IGNORE": ignore the bad indices; supported on both CPU and GPU.
      6. + *
      *

      For usage examples see the python tf.tensor_scatter_nd_update {@link org.tensorflow.op.Ops#tensorScatterNdUpdate} function - * - * @param data type for {@code output} output */ @OpMetadata( opType = TensorScatterNdUpdate.OP_NAME, @@ -94,6 +101,7 @@ public TensorScatterNdUpdate(Operation operation) { * @param tensor Tensor to copy/update. * @param indices Index tensor. * @param updates Updates to scatter into output. + * @param options carries optional attribute values * @param data type for {@code TensorScatterUpdate} output and operands * @return a new instance of TensorScatterNdUpdate */ @@ -101,14 +109,31 @@ public TensorScatterNdUpdate(Operation operation) { describeByClass = true ) public static TensorScatterNdUpdate create(Scope scope, Operand tensor, - Operand indices, Operand updates) { + Operand indices, Operand updates, Options... options) { OperationBuilder opBuilder = scope.opBuilder(OP_NAME, "TensorScatterNdUpdate"); opBuilder.addInput(tensor.asOutput()); opBuilder.addInput(indices.asOutput()); opBuilder.addInput(updates.asOutput()); + if (options != null) { + for (Options opts : options) { + if (opts.badIndicesPolicy != null) { + opBuilder.setAttr("bad_indices_policy", opts.badIndicesPolicy); + } + } + } return new TensorScatterNdUpdate<>(opBuilder.build()); } + /** + * Sets the badIndicesPolicy option. + * + * @param badIndicesPolicy the badIndicesPolicy option + * @return this Options instance. + */ + public static Options badIndicesPolicy(String badIndicesPolicy) { + return new Options().badIndicesPolicy(badIndicesPolicy); + } + /** * Gets output. * A new tensor with the given shape and updates applied according @@ -124,6 +149,27 @@ public Output asOutput() { return output; } + /** + * Optional attributes for {@link org.tensorflow.op.core.TensorScatterNdUpdate} + */ + public static class Options { + private String badIndicesPolicy; + + private Options() { + } + + /** + * Sets the badIndicesPolicy option. + * + * @param badIndicesPolicy the badIndicesPolicy option + * @return this Options instance. + */ + public Options badIndicesPolicy(String badIndicesPolicy) { + this.badIndicesPolicy = badIndicesPolicy; + return this; + } + } + @OpInputsMetadata( outputsClass = TensorScatterNdUpdate.class ) @@ -153,14 +199,20 @@ public static class Inputs extends RawOpInputs(op), op, Arrays.asList("T", "Tindices")); + super(new TensorScatterNdUpdate<>(op), op, Arrays.asList("T", "Tindices", "bad_indices_policy")); int inputIndex = 0; tensor = (Operand) op.input(inputIndex++); indices = (Operand) op.input(inputIndex++); updates = (Operand) op.input(inputIndex++); T = op.attributes().getAttrType("T"); Tindices = op.attributes().getAttrType("Tindices"); + badIndicesPolicy = op.attributes().getAttrString("bad_indices_policy"); } } } diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorStridedSliceUpdate.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorStridedSliceUpdate.java index 23b2d386a05..de80c141d72 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorStridedSliceUpdate.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/TensorStridedSliceUpdate.java @@ -41,8 +41,6 @@ * {@code strides} etc. work exactly as in {@code StridedSlice}. *

      NOTE this op currently does not support broadcasting and so {@code value}'s shape * must be exactly the shape produced by the slice of {@code input}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = TensorStridedSliceUpdate.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Tile.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Tile.java index c9a58b9158c..7339fdbb3de 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Tile.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Tile.java @@ -67,8 +67,6 @@ * * * - * - * @param data type for {@code output} output */ @OpMetadata( opType = Tile.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Unbatch.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Unbatch.java index a49747c48ca..fa4c04f3c27 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Unbatch.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Unbatch.java @@ -53,8 +53,6 @@ * shared_name: Instances of Unbatch with the same container and shared_name are * assumed to possibly belong to the same batch. If left empty, the op name will * be used as the shared name. - * - * @param data type for {@code unbatched_tensor} output */ @OpMetadata( opType = Unbatch.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/UnbatchGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/UnbatchGrad.java index 912e08c3a6b..25418f3986f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/UnbatchGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/UnbatchGrad.java @@ -49,8 +49,6 @@ * shared_name: Instances of UnbatchGrad with the same container and shared_name * are assumed to possibly belong to the same batch. If left empty, the op name * will be used as the shared name. - * - * @param data type for {@code batched_grad} output */ @OpMetadata( opType = UnbatchGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/UniformQuantizedClipByValue.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/UniformQuantizedClipByValue.java index ca3c5dfdd14..f1a4eb739d1 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/UniformQuantizedClipByValue.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/UniformQuantizedClipByValue.java @@ -40,8 +40,6 @@ * Given quantized {@code operand} which was quantized using {@code scales} and {@code zero_points}, performs clip by value using {@code min} and {@code max} values. * If quantization_axis is -1 (per-tensor quantized), the entire operand is clipped using scalar min, max. * Otherwise (per-channel quantized), the clipping is also done per-channel. - * - * @param data type for {@code output} output */ @OpMetadata( opType = UniformQuantizedClipByValue.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Unique.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Unique.java index c4324a9f324..4d17cf9f141 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Unique.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Unique.java @@ -74,10 +74,6 @@ * [2, 0]] * idx ==> [0, 1, 1] * - * - * @param data type for {@code y} output - * - * @param data type for {@code idx} output */ @OpMetadata( opType = Unique.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/UniqueWithCounts.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/UniqueWithCounts.java index 80a1804887f..8046082f95b 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/UniqueWithCounts.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/UniqueWithCounts.java @@ -78,10 +78,6 @@ * idx ==> [0, 1, 1] * count ==> [1, 2] * - * - * @param data type for {@code y} output - * - * @param data type for {@code idx} output */ @OpMetadata( opType = UniqueWithCounts.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/UnravelIndex.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/UnravelIndex.java index 5393635bc69..ec7c8f8c6e9 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/UnravelIndex.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/UnravelIndex.java @@ -52,8 +52,6 @@ *

      {@literal @}compatibility(numpy)
      * Equivalent to np.unravel_index *
      {@literal @}end_compatibility - * - * @param data type for {@code output} output */ @OpMetadata( opType = UnravelIndex.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Unstack.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Unstack.java index fd20a76940d..64c8de23911 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Unstack.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Unstack.java @@ -46,8 +46,6 @@ * and each tensor in {@code output} will have shape {@code (A, C, D)}. * Etc. *

      This is the opposite of {@code pack}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Unstack.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/UpperBound.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/UpperBound.java index d5e939ffde6..78e45391c8a 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/UpperBound.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/UpperBound.java @@ -51,8 +51,6 @@ *

      result = UpperBound(sorted_sequence, values) *

      result == [[1, 2, 4], * [0, 2, 5]] - * - * @param data type for {@code output} output */ @OpMetadata( opType = UpperBound.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Variable.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Variable.java index a0febf9c223..d8b09bfddde 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Variable.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/Variable.java @@ -40,8 +40,6 @@ * Outputs a ref to the tensor state so it may be read or modified. * TODO(zhifengc/mrry): Adds a pointer to a more detail document * about sharing states in tensorflow. - * - * @param data type for {@code ref} output */ @OpMetadata( opType = Variable.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/VariableShape.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/VariableShape.java index 3f94b9efbd6..abfd8d7c504 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/VariableShape.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/VariableShape.java @@ -44,8 +44,6 @@ * # 't' is [[[1, 1, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]]] * shape(t) ==> [2, 2, 3] * - * - * @param data type for {@code output} output */ @OpMetadata( opType = VariableShape.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ZerosLike.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ZerosLike.java index 792a37d112c..497cf5128b8 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ZerosLike.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/core/ZerosLike.java @@ -35,8 +35,6 @@ /** * Returns a tensor of zeros with the same shape and type as x. - * - * @param data type for {@code y} output */ @OpMetadata( opType = ZerosLike.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/data/GlobalShuffleDataset.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/data/GlobalShuffleDataset.java new file mode 100644 index 00000000000..19ec4cd2e96 --- /dev/null +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/data/GlobalShuffleDataset.java @@ -0,0 +1,230 @@ +/* Copyright 2018-2023 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. +=======================================================================*/ + +// This class has been generated, DO NOT EDIT! + +package org.tensorflow.op.data; + +import java.util.Arrays; +import java.util.List; +import org.tensorflow.GraphOperation; +import org.tensorflow.Operand; +import org.tensorflow.Operation; +import org.tensorflow.OperationBuilder; +import org.tensorflow.Output; +import org.tensorflow.ndarray.Shape; +import org.tensorflow.op.Operands; +import org.tensorflow.op.RawOp; +import org.tensorflow.op.RawOpInputs; +import org.tensorflow.op.Scope; +import org.tensorflow.op.annotation.Endpoint; +import org.tensorflow.op.annotation.OpInputsMetadata; +import org.tensorflow.op.annotation.OpMetadata; +import org.tensorflow.proto.DataType; +import org.tensorflow.types.TInt64; +import org.tensorflow.types.family.TType; + +/** + * The GlobalShuffleDataset operation + */ +@OpMetadata( + opType = GlobalShuffleDataset.OP_NAME, + inputsClass = GlobalShuffleDataset.Inputs.class +) +public final class GlobalShuffleDataset extends RawOp implements Operand { + /** + * The name of this op, as known by TensorFlow core engine + */ + public static final String OP_NAME = "GlobalShuffleDataset"; + + private Output handle; + + @SuppressWarnings("unchecked") + public GlobalShuffleDataset(Operation operation) { + super(operation, OP_NAME); + int outputIdx = 0; + handle = operation.output(outputIdx++); + } + + /** + * Factory method to create a class wrapping a new GlobalShuffleDataset operation. + * + * @param scope current scope + * @param inputDataset The inputDataset value + * @param seed The seed value + * @param seed2 The seed2 value + * @param seedGenerator The seedGenerator value + * @param outputTypes The value of the outputTypes attribute + * @param outputShapes The value of the outputShapes attribute + * @param options carries optional attribute values + * @return a new instance of GlobalShuffleDataset + */ + @Endpoint( + describeByClass = true + ) + public static GlobalShuffleDataset create(Scope scope, Operand inputDataset, + Operand seed, Operand seed2, Operand seedGenerator, + List> outputTypes, List outputShapes, Options... options) { + OperationBuilder opBuilder = scope.opBuilder(OP_NAME, "GlobalShuffleDataset"); + opBuilder.addInput(inputDataset.asOutput()); + opBuilder.addInput(seed.asOutput()); + opBuilder.addInput(seed2.asOutput()); + opBuilder.addInput(seedGenerator.asOutput()); + opBuilder.setAttr("output_types", Operands.toDataTypes(outputTypes)); + Shape[] outputShapesArray = new Shape[outputShapes.size()]; + for (int i = 0 ; i < outputShapesArray.length ; i++) { + outputShapesArray[i] = outputShapes.get(i); + } + opBuilder.setAttr("output_shapes", outputShapesArray); + if (options != null) { + for (Options opts : options) { + if (opts.reshuffleEachIteration != null) { + opBuilder.setAttr("reshuffle_each_iteration", opts.reshuffleEachIteration); + } + if (opts.metadata != null) { + opBuilder.setAttr("metadata", opts.metadata); + } + } + } + return new GlobalShuffleDataset(opBuilder.build()); + } + + /** + * Sets the reshuffleEachIteration option. + * + * @param reshuffleEachIteration the reshuffleEachIteration option + * @return this Options instance. + */ + public static Options reshuffleEachIteration(Boolean reshuffleEachIteration) { + return new Options().reshuffleEachIteration(reshuffleEachIteration); + } + + /** + * Sets the metadata option. + * + * @param metadata the metadata option + * @return this Options instance. + */ + public static Options metadata(String metadata) { + return new Options().metadata(metadata); + } + + /** + * Gets handle. + * + * @return handle. + */ + public Output handle() { + return handle; + } + + @Override + @SuppressWarnings("unchecked") + public Output asOutput() { + return (Output) handle; + } + + /** + * Optional attributes for {@link org.tensorflow.op.data.GlobalShuffleDataset} + */ + public static class Options { + private Boolean reshuffleEachIteration; + + private String metadata; + + private Options() { + } + + /** + * Sets the reshuffleEachIteration option. + * + * @param reshuffleEachIteration the reshuffleEachIteration option + * @return this Options instance. + */ + public Options reshuffleEachIteration(Boolean reshuffleEachIteration) { + this.reshuffleEachIteration = reshuffleEachIteration; + return this; + } + + /** + * Sets the metadata option. + * + * @param metadata the metadata option + * @return this Options instance. + */ + public Options metadata(String metadata) { + this.metadata = metadata; + return this; + } + } + + @OpInputsMetadata( + outputsClass = GlobalShuffleDataset.class + ) + public static class Inputs extends RawOpInputs { + /** + * The inputDataset input + */ + public final Operand inputDataset; + + /** + * The seed input + */ + public final Operand seed; + + /** + * The seed2 input + */ + public final Operand seed2; + + /** + * The seedGenerator input + */ + public final Operand seedGenerator; + + /** + * The reshuffleEachIteration attribute + */ + public final boolean reshuffleEachIteration; + + /** + * The outputTypes attribute + */ + public final DataType[] outputTypes; + + /** + * The outputShapes attribute + */ + public final Shape[] outputShapes; + + /** + * The metadata attribute + */ + public final String metadata; + + public Inputs(GraphOperation op) { + super(new GlobalShuffleDataset(op), op, Arrays.asList("reshuffle_each_iteration", "output_types", "output_shapes", "metadata")); + int inputIndex = 0; + inputDataset = (Operand) op.input(inputIndex++); + seed = (Operand) op.input(inputIndex++); + seed2 = (Operand) op.input(inputIndex++); + seedGenerator = (Operand) op.input(inputIndex++); + reshuffleEachIteration = op.attributes().getAttrBool("reshuffle_each_iteration"); + outputTypes = op.attributes().getAttrTypeList("output_types"); + outputShapes = op.attributes().getAttrShapeList("output_shapes"); + metadata = op.attributes().getAttrString("metadata"); + } + } +} diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/data/IndexFlatMapDataset.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/data/IndexFlatMapDataset.java new file mode 100644 index 00000000000..b5d3f116ad5 --- /dev/null +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/data/IndexFlatMapDataset.java @@ -0,0 +1,224 @@ +/* Copyright 2018-2023 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. +=======================================================================*/ + +// This class has been generated, DO NOT EDIT! + +package org.tensorflow.op.data; + +import java.util.Arrays; +import java.util.List; +import org.tensorflow.ConcreteFunction; +import org.tensorflow.GraphOperation; +import org.tensorflow.Operand; +import org.tensorflow.Operation; +import org.tensorflow.OperationBuilder; +import org.tensorflow.Output; +import org.tensorflow.ndarray.Shape; +import org.tensorflow.op.Operands; +import org.tensorflow.op.RawOp; +import org.tensorflow.op.RawOpInputs; +import org.tensorflow.op.Scope; +import org.tensorflow.op.annotation.Endpoint; +import org.tensorflow.op.annotation.OpInputsMetadata; +import org.tensorflow.op.annotation.OpMetadata; +import org.tensorflow.op.annotation.Operator; +import org.tensorflow.proto.DataType; +import org.tensorflow.types.TInt64; +import org.tensorflow.types.family.TType; + +/** + * The IndexFlatMapDataset operation + */ +@OpMetadata( + opType = IndexFlatMapDataset.OP_NAME, + inputsClass = IndexFlatMapDataset.Inputs.class +) +@Operator( + group = "data" +) +public final class IndexFlatMapDataset extends RawOp implements Operand { + /** + * The name of this op, as known by TensorFlow core engine + */ + public static final String OP_NAME = "IndexFlatMapDataset"; + + private Output handle; + + @SuppressWarnings("unchecked") + public IndexFlatMapDataset(Operation operation) { + super(operation, OP_NAME); + int outputIdx = 0; + handle = operation.output(outputIdx++); + } + + /** + * Factory method to create a class wrapping a new IndexFlatMapDataset operation. + * + * @param scope current scope + * @param inputDataset The inputDataset value + * @param mapFuncOtherArgs The mapFuncOtherArgs value + * @param indexMapFuncOtherArgs The indexMapFuncOtherArgs value + * @param outputCardinality The outputCardinality value + * @param mapFunc The value of the mapFunc attribute + * @param indexMapFunc The value of the indexMapFunc attribute + * @param outputTypes The value of the outputTypes attribute + * @param outputShapes The value of the outputShapes attribute + * @param options carries optional attribute values + * @return a new instance of IndexFlatMapDataset + */ + @Endpoint( + describeByClass = true + ) + public static IndexFlatMapDataset create(Scope scope, Operand inputDataset, + Iterable> mapFuncOtherArgs, Iterable> indexMapFuncOtherArgs, + Operand outputCardinality, ConcreteFunction mapFunc, ConcreteFunction indexMapFunc, + List> outputTypes, List outputShapes, Options... options) { + OperationBuilder opBuilder = scope.opBuilder(OP_NAME, "IndexFlatMapDataset"); + opBuilder.addInput(inputDataset.asOutput()); + opBuilder.addInputList(Operands.asOutputs(mapFuncOtherArgs)); + opBuilder.addInputList(Operands.asOutputs(indexMapFuncOtherArgs)); + opBuilder.addInput(outputCardinality.asOutput()); + opBuilder.setAttr("map_func", mapFunc); + opBuilder.setAttr("index_map_func", indexMapFunc); + opBuilder.setAttr("output_types", Operands.toDataTypes(outputTypes)); + Shape[] outputShapesArray = new Shape[outputShapes.size()]; + for (int i = 0 ; i < outputShapesArray.length ; i++) { + outputShapesArray[i] = outputShapes.get(i); + } + opBuilder.setAttr("output_shapes", outputShapesArray); + if (options != null) { + for (Options opts : options) { + if (opts.metadata != null) { + opBuilder.setAttr("metadata", opts.metadata); + } + } + } + return new IndexFlatMapDataset(opBuilder.build()); + } + + /** + * Sets the metadata option. + * + * @param metadata the metadata option + * @return this Options instance. + */ + public static Options metadata(String metadata) { + return new Options().metadata(metadata); + } + + /** + * Gets handle. + * + * @return handle. + */ + public Output handle() { + return handle; + } + + @Override + @SuppressWarnings("unchecked") + public Output asOutput() { + return (Output) handle; + } + + /** + * Optional attributes for {@link org.tensorflow.op.data.IndexFlatMapDataset} + */ + public static class Options { + private String metadata; + + private Options() { + } + + /** + * Sets the metadata option. + * + * @param metadata the metadata option + * @return this Options instance. + */ + public Options metadata(String metadata) { + this.metadata = metadata; + return this; + } + } + + @OpInputsMetadata( + outputsClass = IndexFlatMapDataset.class + ) + public static class Inputs extends RawOpInputs { + /** + * The inputDataset input + */ + public final Operand inputDataset; + + /** + * The mapFuncOtherArgs input + */ + public final Iterable> mapFuncOtherArgs; + + /** + * The indexMapFuncOtherArgs input + */ + public final Iterable> indexMapFuncOtherArgs; + + /** + * The outputCardinality input + */ + public final Operand outputCardinality; + + /** + * The TmapFuncArgs attribute + */ + public final DataType[] TmapFuncArgs; + + /** + * The TindexMapFuncArgs attribute + */ + public final DataType[] TindexMapFuncArgs; + + /** + * The outputTypes attribute + */ + public final DataType[] outputTypes; + + /** + * The outputShapes attribute + */ + public final Shape[] outputShapes; + + /** + * The metadata attribute + */ + public final String metadata; + + public Inputs(GraphOperation op) { + super(new IndexFlatMapDataset(op), op, Arrays.asList("Tmap_func_args", "Tindex_map_func_args", "output_types", "output_shapes", "metadata")); + int inputIndex = 0; + inputDataset = (Operand) op.input(inputIndex++); + int mapFuncOtherArgsLength = op.inputListLength("map_func_other_args"); + mapFuncOtherArgs = Arrays.asList((Operand[]) op.inputList(inputIndex, mapFuncOtherArgsLength)); + inputIndex += mapFuncOtherArgsLength; + int indexMapFuncOtherArgsLength = op.inputListLength("index_map_func_other_args"); + indexMapFuncOtherArgs = Arrays.asList((Operand[]) op.inputList(inputIndex, indexMapFuncOtherArgsLength)); + inputIndex += indexMapFuncOtherArgsLength; + outputCardinality = (Operand) op.input(inputIndex++); + TmapFuncArgs = op.attributes().getAttrTypeList("Tmap_func_args"); + TindexMapFuncArgs = op.attributes().getAttrTypeList("Tindex_map_func_args"); + outputTypes = op.attributes().getAttrTypeList("output_types"); + outputShapes = op.attributes().getAttrShapeList("output_shapes"); + metadata = op.attributes().getAttrString("metadata"); + } + } +} diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/data/IteratorGetModelProto.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/data/IteratorGetModelProto.java new file mode 100644 index 00000000000..1ad0de4c183 --- /dev/null +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/data/IteratorGetModelProto.java @@ -0,0 +1,102 @@ +/* Copyright 2018-2023 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. +=======================================================================*/ + +// This class has been generated, DO NOT EDIT! + +package org.tensorflow.op.data; + +import java.util.Arrays; +import org.tensorflow.GraphOperation; +import org.tensorflow.Operand; +import org.tensorflow.Operation; +import org.tensorflow.OperationBuilder; +import org.tensorflow.Output; +import org.tensorflow.op.RawOp; +import org.tensorflow.op.RawOpInputs; +import org.tensorflow.op.Scope; +import org.tensorflow.op.annotation.Endpoint; +import org.tensorflow.op.annotation.OpInputsMetadata; +import org.tensorflow.op.annotation.OpMetadata; +import org.tensorflow.types.TString; +import org.tensorflow.types.family.TType; + +/** + * Returns the serialized model proto of an iterator resource. + * Returns the serialized model proto of an iterator resource. + */ +@OpMetadata( + opType = IteratorGetModelProto.OP_NAME, + inputsClass = IteratorGetModelProto.Inputs.class +) +public final class IteratorGetModelProto extends RawOp implements Operand { + /** + * The name of this op, as known by TensorFlow core engine + */ + public static final String OP_NAME = "IteratorGetModelProto"; + + private Output modelProto; + + public IteratorGetModelProto(Operation operation) { + super(operation, OP_NAME); + int outputIdx = 0; + modelProto = operation.output(outputIdx++); + } + + /** + * Factory method to create a class wrapping a new IteratorGetModelProto operation. + * + * @param scope current scope + * @param iterator An resource from an dataset iterator. + * @return a new instance of IteratorGetModelProto + */ + @Endpoint( + describeByClass = true + ) + public static IteratorGetModelProto create(Scope scope, Operand iterator) { + OperationBuilder opBuilder = scope.opBuilder(OP_NAME, "IteratorGetModelProto"); + opBuilder.addInput(iterator.asOutput()); + return new IteratorGetModelProto(opBuilder.build()); + } + + /** + * Gets modelProto. + * A serialized model proto. + * @return modelProto. + */ + public Output modelProto() { + return modelProto; + } + + @Override + public Output asOutput() { + return modelProto; + } + + @OpInputsMetadata( + outputsClass = IteratorGetModelProto.class + ) + public static class Inputs extends RawOpInputs { + /** + * An resource from an dataset iterator. + */ + public final Operand iterator; + + public Inputs(GraphOperation op) { + super(new IteratorGetModelProto(op), op, Arrays.asList()); + int inputIndex = 0; + iterator = (Operand) op.input(inputIndex++); + } + } +} diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/data/LeakyReluGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/data/LeakyReluGrad.java index a42cc0f51d2..131903f2fc1 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/data/LeakyReluGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/data/LeakyReluGrad.java @@ -35,8 +35,6 @@ /** * Computes rectified linear gradients for a LeakyRelu operation. - * - * @param data type for {@code backprops} output */ @OpMetadata( opType = LeakyReluGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/data/MapDataset.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/data/MapDataset.java index 6e8ca298f38..4b6e7355a51 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/data/MapDataset.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/data/MapDataset.java @@ -98,6 +98,9 @@ public static MapDataset create(Scope scope, Operand inputDatas if (opts.preserveCardinality != null) { opBuilder.setAttr("preserve_cardinality", opts.preserveCardinality); } + if (opts.forceSynchronous != null) { + opBuilder.setAttr("force_synchronous", opts.forceSynchronous); + } if (opts.metadata != null) { opBuilder.setAttr("metadata", opts.metadata); } @@ -126,6 +129,16 @@ public static Options preserveCardinality(Boolean preserveCardinality) { return new Options().preserveCardinality(preserveCardinality); } + /** + * Sets the forceSynchronous option. + * + * @param forceSynchronous the forceSynchronous option + * @return this Options instance. + */ + public static Options forceSynchronous(Boolean forceSynchronous) { + return new Options().forceSynchronous(forceSynchronous); + } + /** * Sets the metadata option. * @@ -159,6 +172,8 @@ public static class Options { private Boolean preserveCardinality; + private Boolean forceSynchronous; + private String metadata; private Options() { @@ -186,6 +201,17 @@ public Options preserveCardinality(Boolean preserveCardinality) { return this; } + /** + * Sets the forceSynchronous option. + * + * @param forceSynchronous the forceSynchronous option + * @return this Options instance. + */ + public Options forceSynchronous(Boolean forceSynchronous) { + this.forceSynchronous = forceSynchronous; + return this; + } + /** * Sets the metadata option. * @@ -237,13 +263,18 @@ public static class Inputs extends RawOpInputs { */ public final boolean preserveCardinality; + /** + * The forceSynchronous attribute + */ + public final boolean forceSynchronous; + /** * The metadata attribute */ public final String metadata; public Inputs(GraphOperation op) { - super(new MapDataset(op), op, Arrays.asList("Targuments", "output_types", "output_shapes", "use_inter_op_parallelism", "preserve_cardinality", "metadata")); + super(new MapDataset(op), op, Arrays.asList("Targuments", "output_types", "output_shapes", "use_inter_op_parallelism", "preserve_cardinality", "force_synchronous", "metadata")); int inputIndex = 0; inputDataset = (Operand) op.input(inputIndex++); int otherArgumentsLength = op.inputListLength("other_arguments"); @@ -254,6 +285,7 @@ public Inputs(GraphOperation op) { outputShapes = op.attributes().getAttrShapeList("output_shapes"); useInterOpParallelism = op.attributes().getAttrBool("use_inter_op_parallelism"); preserveCardinality = op.attributes().getAttrBool("preserve_cardinality"); + forceSynchronous = op.attributes().getAttrBool("force_synchronous"); metadata = op.attributes().getAttrString("metadata"); } } diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/data/ParallelMapDataset.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/data/ParallelMapDataset.java index 68e97058b5c..6b783929411 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/data/ParallelMapDataset.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/data/ParallelMapDataset.java @@ -107,6 +107,9 @@ public static ParallelMapDataset create(Scope scope, Operand in if (opts.preserveCardinality != null) { opBuilder.setAttr("preserve_cardinality", opts.preserveCardinality); } + if (opts.useUnboundedThreadpool != null) { + opBuilder.setAttr("use_unbounded_threadpool", opts.useUnboundedThreadpool); + } if (opts.metadata != null) { opBuilder.setAttr("metadata", opts.metadata); } @@ -145,6 +148,16 @@ public static Options preserveCardinality(Boolean preserveCardinality) { return new Options().preserveCardinality(preserveCardinality); } + /** + * Sets the useUnboundedThreadpool option. + * + * @param useUnboundedThreadpool the useUnboundedThreadpool option + * @return this Options instance. + */ + public static Options useUnboundedThreadpool(Boolean useUnboundedThreadpool) { + return new Options().useUnboundedThreadpool(useUnboundedThreadpool); + } + /** * Sets the metadata option. * @@ -180,6 +193,8 @@ public static class Options { private Boolean preserveCardinality; + private Boolean useUnboundedThreadpool; + private String metadata; private Options() { @@ -218,6 +233,17 @@ public Options preserveCardinality(Boolean preserveCardinality) { return this; } + /** + * Sets the useUnboundedThreadpool option. + * + * @param useUnboundedThreadpool the useUnboundedThreadpool option + * @return this Options instance. + */ + public Options useUnboundedThreadpool(Boolean useUnboundedThreadpool) { + this.useUnboundedThreadpool = useUnboundedThreadpool; + return this; + } + /** * Sets the metadata option. * @@ -280,13 +306,18 @@ public static class Inputs extends RawOpInputs { */ public final boolean preserveCardinality; + /** + * The useUnboundedThreadpool attribute + */ + public final boolean useUnboundedThreadpool; + /** * The metadata attribute */ public final String metadata; public Inputs(GraphOperation op) { - super(new ParallelMapDataset(op), op, Arrays.asList("Targuments", "output_types", "output_shapes", "use_inter_op_parallelism", "deterministic", "preserve_cardinality", "metadata")); + super(new ParallelMapDataset(op), op, Arrays.asList("Targuments", "output_types", "output_shapes", "use_inter_op_parallelism", "deterministic", "preserve_cardinality", "use_unbounded_threadpool", "metadata")); int inputIndex = 0; inputDataset = (Operand) op.input(inputIndex++); int otherArgumentsLength = op.inputListLength("other_arguments"); @@ -299,6 +330,7 @@ public Inputs(GraphOperation op) { useInterOpParallelism = op.attributes().getAttrBool("use_inter_op_parallelism"); deterministic = op.attributes().getAttrString("deterministic"); preserveCardinality = op.attributes().getAttrBool("preserve_cardinality"); + useUnboundedThreadpool = op.attributes().getAttrBool("use_unbounded_threadpool"); metadata = op.attributes().getAttrString("metadata"); } } diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/data/WeightedFlatMapDataset.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/data/WeightedFlatMapDataset.java new file mode 100644 index 00000000000..2f97c1e168c --- /dev/null +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/data/WeightedFlatMapDataset.java @@ -0,0 +1,186 @@ +/* Copyright 2018-2023 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. +=======================================================================*/ + +// This class has been generated, DO NOT EDIT! + +package org.tensorflow.op.data; + +import java.util.Arrays; +import java.util.List; +import org.tensorflow.GraphOperation; +import org.tensorflow.Operand; +import org.tensorflow.Operation; +import org.tensorflow.OperationBuilder; +import org.tensorflow.Output; +import org.tensorflow.ndarray.Shape; +import org.tensorflow.op.Operands; +import org.tensorflow.op.RawOp; +import org.tensorflow.op.RawOpInputs; +import org.tensorflow.op.Scope; +import org.tensorflow.op.annotation.Endpoint; +import org.tensorflow.op.annotation.OpInputsMetadata; +import org.tensorflow.op.annotation.OpMetadata; +import org.tensorflow.proto.DataType; +import org.tensorflow.types.TFloat64; +import org.tensorflow.types.family.TType; + +/** + * The WeightedFlatMapDataset operation + */ +@OpMetadata( + opType = WeightedFlatMapDataset.OP_NAME, + inputsClass = WeightedFlatMapDataset.Inputs.class +) +public final class WeightedFlatMapDataset extends RawOp implements Operand { + /** + * The name of this op, as known by TensorFlow core engine + */ + public static final String OP_NAME = "WeightedFlatMapDataset"; + + private Output handle; + + @SuppressWarnings("unchecked") + public WeightedFlatMapDataset(Operation operation) { + super(operation, OP_NAME); + int outputIdx = 0; + handle = operation.output(outputIdx++); + } + + /** + * Factory method to create a class wrapping a new WeightedFlatMapDataset operation. + * + * @param scope current scope + * @param inputDatasets The inputDatasets value + * @param weights The weights value + * @param outputTypes The value of the outputTypes attribute + * @param outputShapes The value of the outputShapes attribute + * @param options carries optional attribute values + * @return a new instance of WeightedFlatMapDataset + */ + @Endpoint( + describeByClass = true + ) + public static WeightedFlatMapDataset create(Scope scope, + Iterable> inputDatasets, Iterable> weights, + List> outputTypes, List outputShapes, Options... options) { + OperationBuilder opBuilder = scope.opBuilder(OP_NAME, "WeightedFlatMapDataset"); + opBuilder.addInputList(Operands.asOutputs(inputDatasets)); + opBuilder.addInputList(Operands.asOutputs(weights)); + opBuilder.setAttr("output_types", Operands.toDataTypes(outputTypes)); + Shape[] outputShapesArray = new Shape[outputShapes.size()]; + for (int i = 0 ; i < outputShapesArray.length ; i++) { + outputShapesArray[i] = outputShapes.get(i); + } + opBuilder.setAttr("output_shapes", outputShapesArray); + if (options != null) { + for (Options opts : options) { + if (opts.metadata != null) { + opBuilder.setAttr("metadata", opts.metadata); + } + } + } + return new WeightedFlatMapDataset(opBuilder.build()); + } + + /** + * Sets the metadata option. + * + * @param metadata the metadata option + * @return this Options instance. + */ + public static Options metadata(String metadata) { + return new Options().metadata(metadata); + } + + /** + * Gets handle. + * + * @return handle. + */ + public Output handle() { + return handle; + } + + @Override + @SuppressWarnings("unchecked") + public Output asOutput() { + return (Output) handle; + } + + /** + * Optional attributes for {@link org.tensorflow.op.data.WeightedFlatMapDataset} + */ + public static class Options { + private String metadata; + + private Options() { + } + + /** + * Sets the metadata option. + * + * @param metadata the metadata option + * @return this Options instance. + */ + public Options metadata(String metadata) { + this.metadata = metadata; + return this; + } + } + + @OpInputsMetadata( + outputsClass = WeightedFlatMapDataset.class + ) + public static class Inputs extends RawOpInputs { + /** + * The inputDatasets input + */ + public final Iterable> inputDatasets; + + /** + * The weights input + */ + public final Iterable> weights; + + /** + * The outputTypes attribute + */ + public final DataType[] outputTypes; + + /** + * The outputShapes attribute + */ + public final Shape[] outputShapes; + + /** + * The metadata attribute + */ + public final String metadata; + + public Inputs(GraphOperation op) { + super(new WeightedFlatMapDataset(op), op, Arrays.asList("output_types", "output_shapes", "metadata")); + int inputIndex = 0; + int inputDatasetsLength = op.inputListLength("input_datasets"); + inputDatasets = Arrays.asList((Operand[]) op.inputList(inputIndex, inputDatasetsLength)); + inputIndex += inputDatasetsLength; + int weightsLength = op.inputListLength("weights"); + weights = Arrays.asList((Operand[]) op.inputList(inputIndex, weightsLength)); + inputIndex += weightsLength; + outputTypes = op.attributes().getAttrTypeList("output_types"); + outputShapes = op.attributes().getAttrShapeList("output_shapes"); + metadata = op.attributes().getAttrString("metadata"); + } + } +} diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/data/experimental/MapDataset.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/data/experimental/MapDataset.java index f02bba6e46a..7c8cfafc8f4 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/data/experimental/MapDataset.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/data/experimental/MapDataset.java @@ -98,6 +98,9 @@ public static MapDataset create(Scope scope, Operand inputDatas if (opts.preserveCardinality != null) { opBuilder.setAttr("preserve_cardinality", opts.preserveCardinality); } + if (opts.forceSynchronous != null) { + opBuilder.setAttr("force_synchronous", opts.forceSynchronous); + } } } return new MapDataset(opBuilder.build()); @@ -123,6 +126,16 @@ public static Options preserveCardinality(Boolean preserveCardinality) { return new Options().preserveCardinality(preserveCardinality); } + /** + * Sets the forceSynchronous option. + * + * @param forceSynchronous the forceSynchronous option + * @return this Options instance. + */ + public static Options forceSynchronous(Boolean forceSynchronous) { + return new Options().forceSynchronous(forceSynchronous); + } + /** * Gets handle. * @@ -146,6 +159,8 @@ public static class Options { private Boolean preserveCardinality; + private Boolean forceSynchronous; + private Options() { } @@ -170,6 +185,17 @@ public Options preserveCardinality(Boolean preserveCardinality) { this.preserveCardinality = preserveCardinality; return this; } + + /** + * Sets the forceSynchronous option. + * + * @param forceSynchronous the forceSynchronous option + * @return this Options instance. + */ + public Options forceSynchronous(Boolean forceSynchronous) { + this.forceSynchronous = forceSynchronous; + return this; + } } @OpInputsMetadata( @@ -211,8 +237,13 @@ public static class Inputs extends RawOpInputs { */ public final boolean preserveCardinality; + /** + * The forceSynchronous attribute + */ + public final boolean forceSynchronous; + public Inputs(GraphOperation op) { - super(new MapDataset(op), op, Arrays.asList("Targuments", "output_types", "output_shapes", "use_inter_op_parallelism", "preserve_cardinality")); + super(new MapDataset(op), op, Arrays.asList("Targuments", "output_types", "output_shapes", "use_inter_op_parallelism", "preserve_cardinality", "force_synchronous")); int inputIndex = 0; inputDataset = (Operand) op.input(inputIndex++); int otherArgumentsLength = op.inputListLength("other_arguments"); @@ -223,6 +254,7 @@ public Inputs(GraphOperation op) { outputShapes = op.attributes().getAttrShapeList("output_shapes"); useInterOpParallelism = op.attributes().getAttrBool("use_inter_op_parallelism"); preserveCardinality = op.attributes().getAttrBool("preserve_cardinality"); + forceSynchronous = op.attributes().getAttrBool("force_synchronous"); } } } diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/debugging/CheckNumerics.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/debugging/CheckNumerics.java index d1aae3e74ad..86215fa9a9c 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/debugging/CheckNumerics.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/debugging/CheckNumerics.java @@ -39,8 +39,6 @@ * that are not a number (NaN) or infinity (Inf). Otherwise, returns the input * tensor. Unlike CheckNumerics (V1), CheckNumericsV2 distinguishes -Inf and +Inf * in the errors it throws. - * - * @param data type for {@code output} output */ @OpMetadata( opType = CheckNumerics.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/debugging/DebugGradientIdentity.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/debugging/DebugGradientIdentity.java index 37f2fec7d91..776a971ef27 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/debugging/DebugGradientIdentity.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/debugging/DebugGradientIdentity.java @@ -37,8 +37,6 @@ * This op is hidden from public in Python. It is used by TensorFlow Debugger to * register gradient tensors for gradient debugging. * This op operates on non-reference-type tensors. - * - * @param data type for {@code output} output */ @OpMetadata( opType = DebugGradientIdentity.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/debugging/DebugGradientRefIdentity.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/debugging/DebugGradientRefIdentity.java index 5071299a66a..76a9e9029ca 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/debugging/DebugGradientRefIdentity.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/debugging/DebugGradientRefIdentity.java @@ -37,8 +37,6 @@ * This op is hidden from public in Python. It is used by TensorFlow Debugger to * register gradient tensors for gradient debugging. * This op operates on reference-type tensors. - * - * @param data type for {@code output} output */ @OpMetadata( opType = DebugGradientRefIdentity.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/debugging/DebugIdentity.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/debugging/DebugIdentity.java index 63c7105e3c8..10edd71d4b1 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/debugging/DebugIdentity.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/debugging/DebugIdentity.java @@ -36,8 +36,6 @@ /** * Provides an identity mapping of the non-Ref type input tensor for debugging. * Provides an identity mapping of the non-Ref type input tensor for debugging. - * - * @param data type for {@code output} output */ @OpMetadata( opType = DebugIdentity.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/debugging/DebugNumericsSummary.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/debugging/DebugNumericsSummary.java index ec63e9da708..4ff0f11c7bc 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/debugging/DebugNumericsSummary.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/debugging/DebugNumericsSummary.java @@ -40,8 +40,6 @@ * Computes a numeric summary of the input tensor. The shape of the output * depends on the tensor_debug_mode attribute. * This op is used internally by TensorFlow Debugger (tfdbg) v2. - * - * @param data type for {@code output} output */ @OpMetadata( opType = DebugNumericsSummary.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/distribute/NcclAllReduce.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/distribute/NcclAllReduce.java index c5416746198..7cc17dd9d36 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/distribute/NcclAllReduce.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/distribute/NcclAllReduce.java @@ -45,8 +45,6 @@ * reduction: the reduction operation to perform. * num_devices: The number of devices participating in this reduction. * shared_name: Identifier that shared between ops of the same reduction. - * - * @param data type for {@code data} output */ @OpMetadata( opType = NcclAllReduce.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/distribute/NcclBroadcast.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/distribute/NcclBroadcast.java index 3824d6a10dd..41a2050e44f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/distribute/NcclBroadcast.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/distribute/NcclBroadcast.java @@ -42,8 +42,6 @@ *

      input: The input to the broadcast. * output: The same as input. * shape: The shape of the input tensor. - * - * @param data type for {@code output} output */ @OpMetadata( opType = NcclBroadcast.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/distribute/NcclReduce.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/distribute/NcclReduce.java index 2a80593be6c..8fcf62bf4cc 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/distribute/NcclReduce.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/distribute/NcclReduce.java @@ -42,8 +42,6 @@ *

      input: The input to the reduction. * data: the value of the reduction across all {@code num_devices} devices. * reduction: the reduction operation to perform. - * - * @param data type for {@code data} output */ @OpMetadata( opType = NcclReduce.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/dtypes/Cast.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/dtypes/Cast.java index 806ad99e2ea..af516490d88 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/dtypes/Cast.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/dtypes/Cast.java @@ -36,8 +36,6 @@ /** * Cast x of type SrcT to y of DstT. - * - * @param data type for {@code y} output */ @OpMetadata( opType = Cast.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/dtypes/Complex.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/dtypes/Complex.java index 6b0a717157c..0da2678549f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/dtypes/Complex.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/dtypes/Complex.java @@ -48,8 +48,6 @@ * # tensor `imag` is [4.75, 5.75] * tf.complex(real, imag) ==> [[2.25 + 4.75j], [3.25 + 5.75j]] * - * - * @param data type for {@code out} output */ @OpMetadata( opType = Complex.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/AdjustContrast.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/AdjustContrast.java index 0a6a141c036..123c74afd50 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/AdjustContrast.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/AdjustContrast.java @@ -43,8 +43,6 @@ *

      For each channel, the Op first computes the mean of the image pixels in the * channel and then adjusts each component of each pixel to * {@code (x - mean) * contrast_factor + mean}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = AdjustContrast.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/AdjustHue.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/AdjustHue.java index 45fe50175c4..b0001085638 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/AdjustHue.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/AdjustHue.java @@ -41,8 +41,6 @@ *

      The input image is considered in the RGB colorspace. Conceptually, the RGB * colors are first mapped into HSV. A delta is then applied all the hue values, * and then remapped back to RGB colorspace. - * - * @param data type for {@code output} output */ @OpMetadata( opType = AdjustHue.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/AdjustSaturation.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/AdjustSaturation.java index a7fea42d8fb..5f0c063dc1d 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/AdjustSaturation.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/AdjustSaturation.java @@ -41,8 +41,6 @@ *

      The input image is considered in the RGB colorspace. Conceptually, the RGB * colors are first mapped into HSV. A scale is then applied all the saturation * values, and then remapped back to RGB colorspace. - * - * @param data type for {@code output} output */ @OpMetadata( opType = AdjustSaturation.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/CropAndResizeGradImage.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/CropAndResizeGradImage.java index 59e98a3252d..e639b0f2cb7 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/CropAndResizeGradImage.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/CropAndResizeGradImage.java @@ -38,8 +38,6 @@ /** * Computes the gradient of the crop_and_resize op wrt the input image tensor. - * - * @param data type for {@code output} output */ @OpMetadata( opType = CropAndResizeGradImage.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/DecodeImage.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/DecodeImage.java index ae91e89973a..a5c7ee7845e 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/DecodeImage.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/DecodeImage.java @@ -53,8 +53,6 @@ * unoccupied areas (in the first frame) with zeros (black). For frames after the * first frame that does not occupy the entire canvas, it uses the previous * frame to fill the unoccupied areas. - * - * @param data type for {@code image} output */ @OpMetadata( opType = DecodeImage.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/DecodePng.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/DecodePng.java index db44c3b3146..dd6384caf7c 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/DecodePng.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/DecodePng.java @@ -51,8 +51,6 @@ * of color channels. *

      This op also supports decoding JPEGs and non-animated GIFs since the interface * is the same, though it is cleaner to use {@code tf.io.decode_image}. - * - * @param data type for {@code image} output */ @OpMetadata( opType = DecodePng.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/DrawBoundingBoxes.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/DrawBoundingBoxes.java index 8033cecb4c9..56c64a5e50c 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/DrawBoundingBoxes.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/DrawBoundingBoxes.java @@ -45,8 +45,6 @@ * box is {@code [0.1, 0.2, 0.5, 0.9]}, the upper-left and bottom-right coordinates of * the bounding box will be {@code (40, 10)} to {@code (100, 50)} (in (x,y) coordinates). *

      Parts of the bounding box may fall outside the image. - * - * @param data type for {@code output} output */ @OpMetadata( opType = DrawBoundingBoxes.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ExtractImagePatches.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ExtractImagePatches.java index 69492ac2873..54395a44acc 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ExtractImagePatches.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ExtractImagePatches.java @@ -36,8 +36,6 @@ /** * Extract {@code patches} from {@code images} and put them in the "depth" output dimension. - * - * @param data type for {@code patches} output */ @OpMetadata( opType = ExtractImagePatches.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ExtractJpegShape.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ExtractJpegShape.java index 368fe5cfd02..4ca887e7e72 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ExtractJpegShape.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ExtractJpegShape.java @@ -39,8 +39,6 @@ /** * Extract the shape information of a JPEG-encoded image. * This op only parses the image header, so it is much faster than DecodeJpeg. - * - * @param data type for {@code image_shape} output */ @OpMetadata( opType = ExtractJpegShape.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/HsvToRgb.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/HsvToRgb.java index 6e32b95ca11..abd3d53d884 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/HsvToRgb.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/HsvToRgb.java @@ -39,8 +39,6 @@ * value of the pixels. The output is only well defined if the value in {@code images} * are in {@code [0,1]}. *

      See {@code rgb_to_hsv} for a description of the HSV encoding. - * - * @param data type for {@code output} output */ @OpMetadata( opType = HsvToRgb.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ImageProjectiveTransformV2.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ImageProjectiveTransformV2.java index 572b3e59d16..cef590ad519 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ImageProjectiveTransformV2.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ImageProjectiveTransformV2.java @@ -42,8 +42,6 @@ * {@code (x', y') = ((a0 x + a1 y + a2) / k, (b0 x + b1 y + b2) / k)}, where * {@code k = c0 x + c1 y + 1}. If the transformed point lays outside of the input * image, the output pixel is set to 0. - * - * @param data type for {@code transformed_images} output */ @OpMetadata( opType = ImageProjectiveTransformV2.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ImageProjectiveTransformV3.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ImageProjectiveTransformV3.java index 2c448fc9397..59f06c2b982 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ImageProjectiveTransformV3.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ImageProjectiveTransformV3.java @@ -42,8 +42,6 @@ * {@code (x', y') = ((a0 x + a1 y + a2) / k, (b0 x + b1 y + b2) / k)}, where * {@code k = c0 x + c1 y + 1}. If the transformed point lays outside of the input * image, the output pixel is set to fill_value. - * - * @param data type for {@code transformed_images} output */ @OpMetadata( opType = ImageProjectiveTransformV3.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/NonMaxSuppression.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/NonMaxSuppression.java index 65c6f7f7f2a..f682bfd1f5a 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/NonMaxSuppression.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/NonMaxSuppression.java @@ -58,8 +58,6 @@ * of other overlapping boxes instead of directly causing them to be pruned. * To enable this Soft-NMS mode, set the {@code soft_nms_sigma} parameter to be * larger than 0. - * - * @param data type for {@code selected_scores} output */ @OpMetadata( opType = NonMaxSuppression.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/QuantizedResizeBilinear.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/QuantizedResizeBilinear.java index def6ca5246e..94b4e077416 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/QuantizedResizeBilinear.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/QuantizedResizeBilinear.java @@ -38,8 +38,6 @@ /** * Resize quantized {@code images} to {@code size} using quantized bilinear interpolation. * Input images and output images must be quantized types. - * - * @param data type for {@code resized_images} output */ @OpMetadata( opType = QuantizedResizeBilinear.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/RandomCrop.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/RandomCrop.java index 966401d271c..063b7b8f529 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/RandomCrop.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/RandomCrop.java @@ -41,8 +41,6 @@ *

      This Op picks a random location in {@code image} and crops a {@code height} by {@code width} * rectangle from that location. The random location is picked so the cropped * area will fit inside the original image. - * - * @param data type for {@code output} output */ @OpMetadata( opType = RandomCrop.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ResizeBicubicGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ResizeBicubicGrad.java index 16d5af61802..c04fe6d13e0 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ResizeBicubicGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ResizeBicubicGrad.java @@ -36,8 +36,6 @@ /** * Computes the gradient of bicubic interpolation. - * - * @param data type for {@code output} output */ @OpMetadata( opType = ResizeBicubicGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ResizeBilinearGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ResizeBilinearGrad.java index dbd172bfbf2..166d6b46de6 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ResizeBilinearGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ResizeBilinearGrad.java @@ -36,8 +36,6 @@ /** * Computes the gradient of bilinear interpolation. - * - * @param data type for {@code output} output */ @OpMetadata( opType = ResizeBilinearGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ResizeNearestNeighbor.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ResizeNearestNeighbor.java index 1fc40174782..355ac564de1 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ResizeNearestNeighbor.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ResizeNearestNeighbor.java @@ -36,8 +36,6 @@ /** * Resize {@code images} to {@code size} using nearest neighbor interpolation. - * - * @param data type for {@code resized_images} output */ @OpMetadata( opType = ResizeNearestNeighbor.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ResizeNearestNeighborGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ResizeNearestNeighborGrad.java index 485aa4ba63b..36df9e12b2d 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ResizeNearestNeighborGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ResizeNearestNeighborGrad.java @@ -36,8 +36,6 @@ /** * Computes the gradient of nearest neighbor interpolation. - * - * @param data type for {@code output} output */ @OpMetadata( opType = ResizeNearestNeighborGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/RgbToHsv.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/RgbToHsv.java index 3709f0bd4f7..be3c84d9b66 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/RgbToHsv.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/RgbToHsv.java @@ -56,8 +56,6 @@ * * * - * - * @param data type for {@code output} output */ @OpMetadata( opType = RgbToHsv.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/SampleDistortedBoundingBox.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/SampleDistortedBoundingBox.java index 152f96ce75f..a7378278309 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/SampleDistortedBoundingBox.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/SampleDistortedBoundingBox.java @@ -70,8 +70,6 @@ * {@code use_image_if_no_bounding_boxes = true} will assume there is a single implicit * bounding box covering the whole image. If {@code use_image_if_no_bounding_boxes} is * false and no bounding boxes are supplied, an error is raised. - * - * @param data type for {@code begin} output */ @OpMetadata( opType = SampleDistortedBoundingBox.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ScaleAndTranslateGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ScaleAndTranslateGrad.java index 55dae2a4ae8..1749d046b37 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ScaleAndTranslateGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/ScaleAndTranslateGrad.java @@ -36,8 +36,6 @@ /** * The ScaleAndTranslateGrad operation - * - * @param data type for {@code output} output */ @OpMetadata( opType = ScaleAndTranslateGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/StatelessSampleDistortedBoundingBox.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/StatelessSampleDistortedBoundingBox.java index ac9dfdfe74d..31c4de5388d 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/StatelessSampleDistortedBoundingBox.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/image/StatelessSampleDistortedBoundingBox.java @@ -95,8 +95,6 @@ * {@code use_image_if_no_bounding_boxes = true} will assume there is a single implicit * bounding box covering the whole image. If {@code use_image_if_no_bounding_boxes} is * false and no bounding boxes are supplied, an error is raised. - * - * @param data type for {@code begin} output */ @OpMetadata( opType = StatelessSampleDistortedBoundingBox.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/io/DecodePaddedRaw.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/io/DecodePaddedRaw.java index 0ef81b9eff2..07eac6679d4 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/io/DecodePaddedRaw.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/io/DecodePaddedRaw.java @@ -38,8 +38,6 @@ /** * Reinterpret the bytes of a string as a vector of numbers. - * - * @param data type for {@code output} output */ @OpMetadata( opType = DecodePaddedRaw.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/io/DecodeRaw.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/io/DecodeRaw.java index 068d203c2b0..217c843796f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/io/DecodeRaw.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/io/DecodeRaw.java @@ -37,8 +37,6 @@ /** * Reinterpret the bytes of a string as a vector of numbers. - * - * @param data type for {@code output} output */ @OpMetadata( opType = DecodeRaw.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/io/DeserializeManySparse.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/io/DeserializeManySparse.java index 1ff234ea6b6..9704bd78d15 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/io/DeserializeManySparse.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/io/DeserializeManySparse.java @@ -77,8 +77,6 @@ * values = [1, 2, 3, 4, 5] * shape = [2 50] * - * - * @param data type for {@code sparse_values} output */ @OpMetadata( opType = DeserializeManySparse.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/io/ParseTensor.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/io/ParseTensor.java index 66a64b13c0b..039ff1546f0 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/io/ParseTensor.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/io/ParseTensor.java @@ -37,8 +37,6 @@ /** * Transforms a serialized tensorflow.TensorProto proto into a Tensor. - * - * @param data type for {@code output} output */ @OpMetadata( opType = ParseTensor.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/io/SerializeManySparse.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/io/SerializeManySparse.java index b0e447608f3..70f9327d112 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/io/SerializeManySparse.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/io/SerializeManySparse.java @@ -44,8 +44,6 @@ * {@code SparseTensor} objects going into each row of {@code serialized_sparse} will have * rank {@code R-1}. *

      The minibatch size {@code N} is extracted from {@code sparse_shape[0]}. - * - * @param data type for {@code serialized_sparse} output */ @OpMetadata( opType = SerializeManySparse.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/io/SerializeSparse.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/io/SerializeSparse.java index 2f450dcf3bd..b0c2b5935bf 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/io/SerializeSparse.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/io/SerializeSparse.java @@ -38,8 +38,6 @@ /** * Serialize a {@code SparseTensor} into a {@code [3]} {@code Tensor} object. - * - * @param data type for {@code serialized_sparse} output */ @OpMetadata( opType = SerializeSparse.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BandPart.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BandPart.java index 34f179ed2b0..a521e77b040 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BandPart.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BandPart.java @@ -65,8 +65,6 @@ * tf.linalg.band_part(input, -1, 0) ==> Lower triangular part. * tf.linalg.band_part(input, 0, 0) ==> Diagonal. * - * - * @param data type for {@code band} output */ @OpMetadata( opType = BandPart.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BandedTriangularSolve.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BandedTriangularSolve.java index 9dc6dba4348..532d4fe148b 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BandedTriangularSolve.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BandedTriangularSolve.java @@ -35,8 +35,6 @@ /** * The BandedTriangularSolve operation - * - * @param data type for {@code output} output */ @OpMetadata( opType = BandedTriangularSolve.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchCholesky.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchCholesky.java index 0016839b211..b43cf15b48e 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchCholesky.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchCholesky.java @@ -35,8 +35,6 @@ /** * The BatchCholesky operation - * - * @param data type for {@code output} output */ @OpMetadata( opType = BatchCholesky.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchCholeskyGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchCholeskyGrad.java index d9ce332f7e2..5e917e740b8 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchCholeskyGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchCholeskyGrad.java @@ -35,8 +35,6 @@ /** * The BatchCholeskyGrad operation - * - * @param data type for {@code output} output */ @OpMetadata( opType = BatchCholeskyGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixBandPart.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixBandPart.java index 55e8a0d6a75..99cb57ff97f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixBandPart.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixBandPart.java @@ -36,8 +36,6 @@ /** * The BatchMatrixBandPart operation - * - * @param data type for {@code band} output */ @OpMetadata( opType = BatchMatrixBandPart.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixDeterminant.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixDeterminant.java index c50a706e073..7f1bd32a749 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixDeterminant.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixDeterminant.java @@ -35,8 +35,6 @@ /** * The BatchMatrixDeterminant operation - * - * @param data type for {@code output} output */ @OpMetadata( opType = BatchMatrixDeterminant.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixDiag.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixDiag.java index bba3cae6292..edc731b1f36 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixDiag.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixDiag.java @@ -35,8 +35,6 @@ /** * The BatchMatrixDiag operation - * - * @param data type for {@code output} output */ @OpMetadata( opType = BatchMatrixDiag.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixDiagPart.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixDiagPart.java index 63e7e0e3026..ac379b960aa 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixDiagPart.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixDiagPart.java @@ -35,8 +35,6 @@ /** * The BatchMatrixDiagPart operation - * - * @param data type for {@code diagonal} output */ @OpMetadata( opType = BatchMatrixDiagPart.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixInverse.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixInverse.java index 081dab67e8b..009deec3658 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixInverse.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixInverse.java @@ -35,8 +35,10 @@ /** * The BatchMatrixInverse operation - * - * @param data type for {@code output} output + * DEPRECATED: This operation is deprecated and will be removed in a future version. + * Use tf.linalg.inv instead. + *

      Computes the inverse of one or more square invertible matrices or their + * adjoints (conjugate transposes). */ @OpMetadata( opType = BatchMatrixInverse.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixSetDiag.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixSetDiag.java index 67a97a485c0..eaea0c7db31 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixSetDiag.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixSetDiag.java @@ -35,8 +35,6 @@ /** * The BatchMatrixSetDiag operation - * - * @param data type for {@code output} output */ @OpMetadata( opType = BatchMatrixSetDiag.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixSolve.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixSolve.java index dc65bb1dce1..5b6749c53e4 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixSolve.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixSolve.java @@ -35,8 +35,6 @@ /** * The BatchMatrixSolve operation - * - * @param data type for {@code output} output */ @OpMetadata( opType = BatchMatrixSolve.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixSolveLs.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixSolveLs.java index 801c5262946..7cb6714696f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixSolveLs.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixSolveLs.java @@ -36,8 +36,6 @@ /** * The BatchMatrixSolveLs operation - * - * @param data type for {@code output} output */ @OpMetadata( opType = BatchMatrixSolveLs.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixTriangularSolve.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixTriangularSolve.java index ae63e405dd7..d7b326bae21 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixTriangularSolve.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchMatrixTriangularSolve.java @@ -35,8 +35,6 @@ /** * The BatchMatrixTriangularSolve operation - * - * @param data type for {@code output} output */ @OpMetadata( opType = BatchMatrixTriangularSolve.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchSelfAdjointEig.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchSelfAdjointEig.java index 1d6588ac785..637625bd5db 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchSelfAdjointEig.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchSelfAdjointEig.java @@ -35,8 +35,6 @@ /** * The BatchSelfAdjointEigV2 operation - * - * @param data type for {@code e} output */ @OpMetadata( opType = BatchSelfAdjointEig.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchSvd.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchSvd.java index cf723ceeedc..a2411601e63 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchSvd.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/BatchSvd.java @@ -35,8 +35,6 @@ /** * The BatchSvd operation - * - * @param data type for {@code s} output */ @OpMetadata( opType = BatchSvd.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Cholesky.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Cholesky.java index 294a41889da..ef6d0ca1a3d 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Cholesky.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Cholesky.java @@ -45,8 +45,6 @@ *

      Note: The gradient computation on GPU is faster for large matrices but * not for large batch dimensions when the submatrices are small. In this * case it might be faster to use the CPU. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Cholesky.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/CholeskyGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/CholeskyGrad.java index f2529b61318..ce7975bbb29 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/CholeskyGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/CholeskyGrad.java @@ -37,8 +37,6 @@ * 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. - * - * @param data type for {@code output} output */ @OpMetadata( opType = CholeskyGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/ConjugateTranspose.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/ConjugateTranspose.java index e14f2e71ef9..561e4fecbf1 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/ConjugateTranspose.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/ConjugateTranspose.java @@ -39,8 +39,6 @@ * The output {@code y} has the same rank as {@code x}. The shapes of {@code x} and {@code y} satisfy: * {@code y.shape[i] == x.shape[perm[i]] for i in [0, 1, ..., rank(x) - 1]} * {@code y[i,j,k,...,s,t,u] == conj(x[perm[i], perm[j], perm[k],...,perm[s], perm[t], perm[u]])} - * - * @param data type for {@code y} output */ @OpMetadata( opType = ConjugateTranspose.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Cross.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Cross.java index 68ee2a65439..5c942c1e41b 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Cross.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Cross.java @@ -38,8 +38,6 @@ * {@code a} and {@code b} must be the same shape; they can either be simple 3-element vectors, * or any shape where the innermost dimension is 3. In the latter case, each pair * of corresponding 3-element vectors is cross-multiplied independently. - * - * @param data type for {@code product} output */ @OpMetadata( opType = Cross.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Det.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Det.java index 62aafcde736..d63118c9f73 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Det.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Det.java @@ -38,8 +38,6 @@ * The input is a tensor of shape {@code [..., M, M]} whose inner-most 2 dimensions * form square matrices. The output is a tensor containing the determinants * for all input submatrices {@code [..., :, :]}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Det.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Eig.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Eig.java index 783950dfde9..3276bbb78fe 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Eig.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Eig.java @@ -46,8 +46,6 @@ * e, v = eig(a) * e = eig(a, compute_v=False) * - * - * @param data type for {@code e} output */ @OpMetadata( opType = Eig.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Einsum.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Einsum.java index 51d3eeb3fa6..5b57bad8aa4 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Einsum.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Einsum.java @@ -99,8 +99,6 @@ * supported by {@code numpy.einsum}. *
      {@literal @}end_compatibility *

    - * - * @param data type for {@code output} output */ @OpMetadata( opType = Einsum.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/EuclideanNorm.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/EuclideanNorm.java index ab6f58f4885..f544381e1a7 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/EuclideanNorm.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/EuclideanNorm.java @@ -40,8 +40,6 @@ * {@code keep_dims} is true, the rank of the tensor is reduced by 1 for each entry in * {@code axis}. If {@code keep_dims} is true, the reduced dimensions are * retained with length 1. - * - * @param data type for {@code output} output */ @OpMetadata( opType = EuclideanNorm.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Inv.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Inv.java index 6b02bc2a059..93338f1df07 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Inv.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Inv.java @@ -42,8 +42,6 @@ *

    If a matrix is not invertible there is no guarantee what the op does. It * may detect the condition and raise an exception or it may simply return a * garbage result. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Inv.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/LogMatrixDeterminant.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/LogMatrixDeterminant.java index 298e01306db..a144ac2d31c 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/LogMatrixDeterminant.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/LogMatrixDeterminant.java @@ -43,8 +43,6 @@ * The {@code log_abs_determinant} is computed as {@code det(P)*sum(log(diag(LU)))} where {@code LU} * is the {@code LU} decomposition of the input and {@code P} is the corresponding * permutation matrix. - * - * @param data type for {@code sign} output */ @OpMetadata( opType = LogMatrixDeterminant.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Lu.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Lu.java index 480ed23e696..9063fab1875 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Lu.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Lu.java @@ -51,10 +51,6 @@ *

    P represents a permutation matrix encoded as a list of indices each between {@code 0} * and {@code M-1}, inclusive. If P_mat denotes the permutation matrix corresponding to * P, then the L, U and P satisfies P_mat * input = L * U. - * - * @param data type for {@code lu} output - * - * @param data type for {@code p} output */ @OpMetadata( opType = Lu.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatMul.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatMul.java index a592a65396a..c817cbc9037 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatMul.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatMul.java @@ -41,8 +41,6 @@ * true). *

    Note: The default kernel implementation for MatMul on GPUs uses * cublas. - * - * @param data type for {@code product} output */ @OpMetadata( opType = MatMul.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatrixDiag.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatrixDiag.java index 0a292c9d1b1..5241708f71a 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatrixDiag.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatrixDiag.java @@ -116,8 +116,6 @@ * [1, 9], * [9, 2]] * - * - * @param data type for {@code output} output */ @OpMetadata( opType = MatrixDiag.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatrixDiagPart.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatrixDiagPart.java index 084c946193e..a818b134cbe 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatrixDiagPart.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatrixDiagPart.java @@ -96,8 +96,6 @@ * [3, 4, 9], * [4, 3, 8]]] * - * - * @param data type for {@code diagonal} output */ @OpMetadata( opType = MatrixDiagPart.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatrixDiagPartV3.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatrixDiagPartV3.java index d4794ab7571..c6ecab46bab 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatrixDiagPartV3.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatrixDiagPartV3.java @@ -126,8 +126,6 @@ * [4, 3, 8]]] * * - * - * @param data type for {@code diagonal} output */ @OpMetadata( opType = MatrixDiagPartV3.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatrixDiagV3.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatrixDiagV3.java index 943b92e2c95..67b5b3b74b0 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatrixDiagV3.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatrixDiagV3.java @@ -144,8 +144,6 @@ * [9, 2]] * * - * - * @param data type for {@code output} output */ @OpMetadata( opType = MatrixDiagV3.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatrixExponential.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatrixExponential.java index 961f57037f4..9332cd02b3e 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatrixExponential.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatrixExponential.java @@ -35,8 +35,6 @@ /** * Deprecated, use python implementation tf.linalg.matrix_exponential. - * - * @param data type for {@code output} output */ @OpMetadata( opType = MatrixExponential.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatrixLogarithm.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatrixLogarithm.java index b3876d3a572..f1529a1c264 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatrixLogarithm.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatrixLogarithm.java @@ -46,8 +46,6 @@ *

    The input is a tensor of shape {@code [..., M, M]} whose inner-most 2 dimensions * form square matrices. The output is a tensor of the same shape as the input * containing the exponential for all input submatrices {@code [..., :, :]}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = MatrixLogarithm.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatrixSetDiag.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatrixSetDiag.java index 0ae2c206569..1ec3a1444f5 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatrixSetDiag.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatrixSetDiag.java @@ -132,8 +132,6 @@ * [7, 4, 2, 4]]] * * - * - * @param data type for {@code output} output */ @OpMetadata( opType = MatrixSetDiag.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatrixSolveLs.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatrixSolveLs.java index 3b340034827..d0601c6ee57 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatrixSolveLs.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/MatrixSolveLs.java @@ -66,8 +66,6 @@ * least-squares solution, even when \(A\) is rank deficient. This path is * typically 6-7 times slower than the fast path. If {@code fast} is {@code False} then * {@code l2_regularizer} is ignored. - * - * @param data type for {@code output} output */ @OpMetadata( opType = MatrixSolveLs.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Qr.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Qr.java index 9e73edaf6b8..037f024d04b 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Qr.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Qr.java @@ -47,8 +47,6 @@ * q, r = qr(a) * q_full, r_full = qr(a, full_matrices=True) * - * - * @param data type for {@code q} output */ @OpMetadata( opType = Qr.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/QuantizedMatMul.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/QuantizedMatMul.java index 93ca4112092..d3136668a39 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/QuantizedMatMul.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/QuantizedMatMul.java @@ -41,8 +41,6 @@ * {@code a} (after being transposed if {@code transpose_a} is non-zero) must match the * outer dimension of {@code b} (after being transposed if {@code transposed_b} is * non-zero). - * - * @param data type for {@code out} output */ @OpMetadata( opType = QuantizedMatMul.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/QuantizedMatMulWithBias.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/QuantizedMatMulWithBias.java index 4ff470d2594..0cc43361bf4 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/QuantizedMatMulWithBias.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/QuantizedMatMulWithBias.java @@ -43,8 +43,6 @@ * match the outer dimension of {@code b} (after being transposed if {@code transposed_b} is * non-zero). Then do broadcast add operation with bias values on the matrix * multiplication result. The bias size must match inner dimension of {@code b}. - * - * @param data type for {@code out} output */ @OpMetadata( opType = QuantizedMatMulWithBias.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/QuantizedMatMulWithBiasAndRelu.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/QuantizedMatMulWithBiasAndRelu.java index ad1182c50de..eee116597b9 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/QuantizedMatMulWithBiasAndRelu.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/QuantizedMatMulWithBiasAndRelu.java @@ -44,8 +44,6 @@ * non-zero). Then do broadcast add operation with bias values on the matrix * multiplication result. The bias size must match inner dimension of {@code b}. Then do * relu activation to get non-negative result. - * - * @param data type for {@code out} output */ @OpMetadata( opType = QuantizedMatMulWithBiasAndRelu.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/QuantizedMatMulWithBiasAndReluAndRequantize.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/QuantizedMatMulWithBiasAndReluAndRequantize.java index 91eefc72f1b..82bdde439f1 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/QuantizedMatMulWithBiasAndReluAndRequantize.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/QuantizedMatMulWithBiasAndReluAndRequantize.java @@ -45,8 +45,6 @@ * multiplication result. The bias size must match inner dimension of {@code b}. Then do * relu activation to get non-negative result. Then do requantize operation to get * final uint8 result. - * - * @param data type for {@code out} output */ @OpMetadata( opType = QuantizedMatMulWithBiasAndReluAndRequantize.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/SelfAdjointEig.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/SelfAdjointEig.java index 2d64ddb4dda..75c06a99f2a 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/SelfAdjointEig.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/SelfAdjointEig.java @@ -45,8 +45,6 @@ * e, v = self_adjoint_eig(a) * e = self_adjoint_eig(a, compute_v=False) * - * - * @param data type for {@code e} output */ @OpMetadata( opType = SelfAdjointEig.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Solve.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Solve.java index a0f41eda3f5..d1057183227 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Solve.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Solve.java @@ -41,8 +41,6 @@ * satisfies {@code matrix[..., :, :] * output[..., :, :] = rhs[..., :, :]}. * If {@code adjoint} is {@code True} then each output matrix satisfies * {@code adjoint(matrix[..., :, :]) * output[..., :, :] = rhs[..., :, :]}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Solve.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Sqrtm.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Sqrtm.java index 224688c8e1d..cf48c52605a 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Sqrtm.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Sqrtm.java @@ -47,8 +47,6 @@ *

    The input is a tensor of shape {@code [..., M, M]} whose inner-most 2 dimensions * form square matrices. The output is a tensor of the same shape as the input * containing the matrix square root for all input submatrices {@code [..., :, :]}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Sqrtm.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Svd.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Svd.java index b17b01cf88e..b11eafdccfc 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Svd.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Svd.java @@ -45,8 +45,6 @@ * s, u, v = svd(a) * s, _, _ = svd(a, compute_uv=False) * - * - * @param data type for {@code s} output */ @OpMetadata( opType = Svd.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/TensorDiag.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/TensorDiag.java index 6292194a118..69ee9258392 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/TensorDiag.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/TensorDiag.java @@ -48,8 +48,6 @@ * [0, 0, 3, 0] * [0, 0, 0, 4]] * - * - * @param data type for {@code output} output */ @OpMetadata( opType = TensorDiag.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/TensorDiagPart.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/TensorDiagPart.java index ae21a73b071..838a036f84b 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/TensorDiagPart.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/TensorDiagPart.java @@ -49,8 +49,6 @@ * * tf.diag_part(input) ==> [1, 2, 3, 4] * - * - * @param data type for {@code diagonal} output */ @OpMetadata( opType = TensorDiagPart.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Transpose.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Transpose.java index 65f22dfe32b..712576c0989 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Transpose.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/Transpose.java @@ -38,8 +38,6 @@ * Shuffle dimensions of x according to a permutation. * The output {@code y} has the same rank as {@code x}. The shapes of {@code x} and {@code y} satisfy: * {@code y.shape[i] == x.shape[perm[i]] for i in [0, 1, ..., rank(x) - 1]} - * - * @param data type for {@code y} output */ @OpMetadata( opType = Transpose.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/TriangularSolve.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/TriangularSolve.java index 891f4e1f608..026fbfb70bf 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/TriangularSolve.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/TriangularSolve.java @@ -77,8 +77,6 @@ * # [4. ], * # [1.9999999]], dtype=float32)> * - * - * @param data type for {@code output} output */ @OpMetadata( opType = TriangularSolve.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/TridiagonalMatMul.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/TridiagonalMatMul.java index bd69ed483e4..a6122dabc83 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/TridiagonalMatMul.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/TridiagonalMatMul.java @@ -36,8 +36,6 @@ /** * Calculate product with tridiagonal matrix. * Calculates product of two matrices, where left matrix is a tridiagonal matrix. - * - * @param data type for {@code output} output */ @OpMetadata( opType = TridiagonalMatMul.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/TridiagonalSolve.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/TridiagonalSolve.java index 57c0864ef7d..6b0a890d12e 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/TridiagonalSolve.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/TridiagonalSolve.java @@ -42,8 +42,6 @@ * pivoting, depending on {@code partial_pivoting} attribute. On GPU, Nvidia's cuSPARSE * library is used: https://docs.nvidia.com/cuda/cusparse/index.html#gtsv * Partial pivoting is not yet supported by XLA backends. - * - * @param data type for {@code output} output */ @OpMetadata( opType = TridiagonalSolve.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/sparse/CSRSparseMatrixComponents.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/sparse/CSRSparseMatrixComponents.java index 27d77557bfb..7fd47c7c6f5 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/sparse/CSRSparseMatrixComponents.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/sparse/CSRSparseMatrixComponents.java @@ -39,8 +39,6 @@ * Reads out the CSR components at batch {@code index}. * This op is meant only for debugging / testing, and its interface is not expected * to be stable. - * - * @param data type for {@code values} output */ @OpMetadata( opType = CSRSparseMatrixComponents.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/sparse/CSRSparseMatrixToDense.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/sparse/CSRSparseMatrixToDense.java index 51bed06f6ba..97fb87d7250 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/sparse/CSRSparseMatrixToDense.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/sparse/CSRSparseMatrixToDense.java @@ -36,8 +36,6 @@ /** * Convert a (possibly batched) CSRSparseMatrix to dense. - * - * @param data type for {@code dense_output} output */ @OpMetadata( opType = CSRSparseMatrixToDense.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/sparse/CSRSparseMatrixToSparseTensor.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/sparse/CSRSparseMatrixToSparseTensor.java index 5c111887894..ad365783cea 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/sparse/CSRSparseMatrixToSparseTensor.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/sparse/CSRSparseMatrixToSparseTensor.java @@ -37,8 +37,6 @@ /** * Converts a (possibly batched) CSRSparesMatrix to a SparseTensor. - * - * @param data type for {@code values} output */ @OpMetadata( opType = CSRSparseMatrixToSparseTensor.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/sparse/SparseMatrixMatMul.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/sparse/SparseMatrixMatMul.java index 2de2e93ec3b..5d9ed9bbbf2 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/sparse/SparseMatrixMatMul.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/linalg/sparse/SparseMatrixMatMul.java @@ -56,8 +56,6 @@ * C = conjugate(transpose(A . B)) = conjugate(transpose(B)) . * conjugate(transpose(A)) * - * - * @param data type for {@code output} output */ @OpMetadata( opType = SparseMatrixMatMul.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Abs.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Abs.java index ef53c5f5693..0f4ee840704 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Abs.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Abs.java @@ -38,8 +38,6 @@ * Given a tensor {@code x}, this operation returns a tensor containing the absolute * value of each element in {@code x}. For example, if x is an input element and y is * an output element, this operation computes \(y = |x|\). - * - * @param data type for {@code y} output */ @OpMetadata( opType = Abs.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/AccumulateN.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/AccumulateN.java index 61d1df63943..3a0e466e8cd 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/AccumulateN.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/AccumulateN.java @@ -43,8 +43,6 @@ * storage is proportional to the output size rather than the inputs size. *

    Unlike the original {@code accumulate_n}, {@code accumulate_n_v2} is differentiable. *

    Returns a {@code Tensor} of same shape and type as the elements of {@code inputs}. - * - * @param data type for {@code sum} output */ @OpMetadata( opType = AccumulateN.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Acos.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Acos.java index 078326e1891..915e5b98b63 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Acos.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Acos.java @@ -37,8 +37,6 @@ * Computes acos of x element-wise. * Provided an input tensor, the {@code tf.math.acos} operation returns the inverse cosine of each element of the tensor. If {@code y = tf.math.cos(x)} then, {@code x = tf.math.acos(y)}. *

    Input range is {@code [-1, 1]} and the output has a range of {@code [0, pi]}. - * - * @param data type for {@code y} output */ @OpMetadata( opType = Acos.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Acosh.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Acosh.java index 60edbd7880f..8ade37b1990 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Acosh.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Acosh.java @@ -41,8 +41,6 @@ * x = tf.constant([-2, -0.5, 1, 1.2, 200, 10000, float("inf")]) * tf.math.acosh(x) ==> [nan nan 0. 0.62236255 5.9914584 9.903487 inf] * - * - * @param data type for {@code y} output */ @OpMetadata( opType = Acosh.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Add.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Add.java index 4f32acd9ee1..61db4d2e4ec 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Add.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Add.java @@ -39,8 +39,6 @@ * here *

    Given two input tensors, the {@code tf.add} operation computes the sum for every element in the tensor. *

    Both input and output have a range {@code (-inf, inf)}. - * - * @param data type for {@code z} output */ @OpMetadata( opType = Add.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/AddN.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/AddN.java index 6cd47212eef..f2ef9209796 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/AddN.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/AddN.java @@ -41,8 +41,6 @@ * x = [9, 7, 10] * tf.math.add_n(x) ==> 26 * - * - * @param data type for {@code sum} output */ @OpMetadata( opType = AddN.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Angle.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Angle.java index a9c7814636f..6ad1ff84bba 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Angle.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Angle.java @@ -51,8 +51,6 @@ *

    {@literal @}compatibility(numpy)
    * Equivalent to np.angle. *
    {@literal @}end_compatibility - * - * @param data type for {@code output} output */ @OpMetadata( opType = Angle.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/ArgMax.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/ArgMax.java index 5a7b5adec69..c222f3d54d5 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/ArgMax.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/ArgMax.java @@ -48,8 +48,6 @@ * # c = 4 * # here a[4] = 166.32 which is the largest element of a across axis 0 * - * - * @param data type for {@code output} output */ @OpMetadata( opType = ArgMax.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/ArgMin.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/ArgMin.java index ff138655b1f..41aa45a10ad 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/ArgMin.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/ArgMin.java @@ -48,8 +48,6 @@ * # c = 0 * # here a[0] = 1 which is the smallest element of a across axis 0 * - * - * @param data type for {@code output} output */ @OpMetadata( opType = ArgMin.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Asin.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Asin.java index 050107db969..810aeb5fa3b 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Asin.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Asin.java @@ -47,8 +47,6 @@ * * tf.math.asin(y) # [1.047, 0.785] = x * - * - * @param data type for {@code y} output */ @OpMetadata( opType = Asin.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Asinh.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Asinh.java index d4170db292a..918518f2b82 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Asinh.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Asinh.java @@ -42,8 +42,6 @@ * x = tf.constant([-float("inf"), -2, -0.5, 1, 1.2, 200, 10000, float("inf")]) * tf.math.asinh(x) ==> [-inf -1.4436355 -0.4812118 0.8813736 1.0159732 5.991471 9.903487 inf] * - * - * @param data type for {@code y} output */ @OpMetadata( opType = Asinh.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Atan.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Atan.java index aab73783c10..8979ab75d9e 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Atan.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Atan.java @@ -47,8 +47,6 @@ * * tf.math.atan(y) # [1.047, 0.785] = x * - * - * @param data type for {@code y} output */ @OpMetadata( opType = Atan.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Atan2.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Atan2.java index dfff4a48676..2d566d3cc22 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Atan2.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Atan2.java @@ -51,8 +51,6 @@ * * * - * - * @param data type for {@code z} output */ @OpMetadata( opType = Atan2.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Atanh.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Atanh.java index ea5729193bf..c4dd0f1ead2 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Atanh.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Atanh.java @@ -44,8 +44,6 @@ * x = tf.constant([-float("inf"), -1, -0.5, 1, 0, 0.5, 10, float("inf")]) * tf.math.atanh(x) ==> [nan -inf -0.54930615 inf 0. 0.54930615 nan nan] * - * - * @param data type for {@code y} output */ @OpMetadata( opType = Atanh.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/BesselI0.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/BesselI0.java index d3782706f20..945d2107a39 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/BesselI0.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/BesselI0.java @@ -35,8 +35,6 @@ /** * The BesselI0 operation - * - * @param data type for {@code y} output */ @OpMetadata( opType = BesselI0.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/BesselI0e.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/BesselI0e.java index eec8b3281a3..7e27d3e4263 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/BesselI0e.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/BesselI0e.java @@ -35,8 +35,6 @@ /** * The BesselI0e operation - * - * @param data type for {@code y} output */ @OpMetadata( opType = BesselI0e.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/BesselI1.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/BesselI1.java index bb59dc19f5c..28304567e86 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/BesselI1.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/BesselI1.java @@ -35,8 +35,6 @@ /** * The BesselI1 operation - * - * @param data type for {@code y} output */ @OpMetadata( opType = BesselI1.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/BesselI1e.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/BesselI1e.java index fe929e32eb1..df3b3f937e8 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/BesselI1e.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/BesselI1e.java @@ -35,8 +35,6 @@ /** * The BesselI1e operation - * - * @param data type for {@code y} output */ @OpMetadata( opType = BesselI1e.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Betainc.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Betainc.java index f7b9904c100..1a895c89f00 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Betainc.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Betainc.java @@ -41,8 +41,6 @@ *

    \(B(x; a, b) = \int_0^x t^{a-1} (1 - t)^{b-1} dt\) *

    is the incomplete beta function and \(B(a, b)\) is the complete * beta function. - * - * @param data type for {@code z} output */ @OpMetadata( opType = Betainc.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Bincount.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Bincount.java index 6e78f0799fc..463dc277eae 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Bincount.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Bincount.java @@ -42,8 +42,6 @@ * the value in {@code weights} at each index where the corresponding value in {@code arr} is * {@code i}. *

    Values in {@code arr} outside of the range [0, size) are ignored. - * - * @param data type for {@code bins} output */ @OpMetadata( opType = Bincount.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Ceil.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Ceil.java index 3db46461d7c..1a69b94a8e4 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Ceil.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Ceil.java @@ -35,8 +35,6 @@ /** * Returns element-wise smallest integer not less than x. - * - * @param data type for {@code y} output */ @OpMetadata( opType = Ceil.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/ComplexAbs.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/ComplexAbs.java index 798b2a9cb1a..9461d599888 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/ComplexAbs.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/ComplexAbs.java @@ -52,8 +52,6 @@ * * * - * - * @param data type for {@code y} output */ @OpMetadata( opType = ComplexAbs.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Conj.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Conj.java index 266da810658..d46b7f2ae5b 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Conj.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Conj.java @@ -45,8 +45,6 @@ * # tensor 'input' is [-2.25 + 4.75j, 3.25 + 5.75j] * tf.conj(input) ==> [-2.25 - 4.75j, 3.25 - 5.75j] * - * - * @param data type for {@code output} output */ @OpMetadata( opType = Conj.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Cos.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Cos.java index 0ab0152ff02..b6b5b9595c5 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Cos.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Cos.java @@ -43,8 +43,6 @@ * x = tf.constant([-float("inf"), -9, -0.5, 1, 1.2, 200, 10000, float("inf")]) * tf.math.cos(x) ==> [nan -0.91113025 0.87758255 0.5403023 0.36235774 0.48718765 -0.95215535 nan] * - * - * @param data type for {@code y} output */ @OpMetadata( opType = Cos.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Cosh.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Cosh.java index 76a98abe533..391d2efd7ab 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Cosh.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Cosh.java @@ -42,8 +42,6 @@ * x = tf.constant([-float("inf"), -9, -0.5, 1, 1.2, 2, 10, float("inf")]) * tf.math.cosh(x) ==> [inf 4.0515420e+03 1.1276259e+00 1.5430807e+00 1.8106556e+00 3.7621956e+00 1.1013233e+04 inf] * - * - * @param data type for {@code y} output */ @OpMetadata( opType = Cosh.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Cumprod.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Cumprod.java index 3e901959c5d..90bdcdc0038 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Cumprod.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Cumprod.java @@ -56,8 +56,6 @@ *

      * tf.cumprod([a, b, c], exclusive=True, reverse=True)  # => [b * c, c, 1]
      * 
    - * - * @param data type for {@code out} output */ @OpMetadata( opType = Cumprod.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Cumsum.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Cumsum.java index 12b3346db25..ff8dca235c9 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Cumsum.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Cumsum.java @@ -56,8 +56,6 @@ *
      * tf.cumsum([a, b, c], exclusive=True, reverse=True)  # => [b + c, c, 0]
      * 
    - * - * @param data type for {@code out} output */ @OpMetadata( opType = Cumsum.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/CumulativeLogsumexp.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/CumulativeLogsumexp.java index 52595f56eea..f7367703a41 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/CumulativeLogsumexp.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/CumulativeLogsumexp.java @@ -51,8 +51,6 @@ * floating point type is used instead. *

    By setting the {@code reverse} kwarg to {@code True}, the cumulative log-sum-exp is performed in the * opposite direction. - * - * @param data type for {@code out} output */ @OpMetadata( opType = CumulativeLogsumexp.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/DenseBincount.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/DenseBincount.java index ff9a38ba24d..808be372c5f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/DenseBincount.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/DenseBincount.java @@ -41,8 +41,6 @@ * the value in {@code weights} at each index where the corresponding value in {@code arr} is * {@code i}. *

    Values in {@code arr} outside of the range [0, size) are ignored. - * - * @param data type for {@code output} output */ @OpMetadata( opType = DenseBincount.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Digamma.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Digamma.java index 37117f4e1b8..3a48d548bd4 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Digamma.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Digamma.java @@ -36,8 +36,6 @@ /** * Computes Psi, the derivative of Lgamma (the log of the absolute value of * {@code Gamma(x)}), element-wise. - * - * @param data type for {@code y} output */ @OpMetadata( opType = Digamma.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Div.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Div.java index 62a15f37da7..8ad37113d3f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Div.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Div.java @@ -37,8 +37,6 @@ * Returns x / y element-wise. * NOTE: {@code math.Div} supports broadcasting. More about broadcasting * here - * - * @param data type for {@code z} output */ @OpMetadata( opType = Div.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/DivNoNan.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/DivNoNan.java index bb098cfdf14..43047bad3c6 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/DivNoNan.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/DivNoNan.java @@ -37,8 +37,6 @@ * Returns 0 if the denominator is zero. * NOTE: {@code math.DivNoNan} supports broadcasting. More about broadcasting * here - * - * @param data type for {@code z} output */ @OpMetadata( opType = DivNoNan.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Erf.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Erf.java index 1e2046e2892..ef607d7778b 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Erf.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Erf.java @@ -35,8 +35,6 @@ /** * Computes the Gauss error function of {@code x} element-wise. In statistics, for non-negative values of $x$, the error function has the following interpretation: for a random variable $Y$ that is normally distributed with mean 0 and variance $1/\sqrt{2}$, $erf(x)$ is the probability that $Y$ falls in the range $[−x, x]$. - * - * @param data type for {@code y} output */ @OpMetadata( opType = Erf.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Erfc.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Erfc.java index b8d11327b94..25fdbcd648c 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Erfc.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Erfc.java @@ -35,8 +35,6 @@ /** * Computes the complementary error function of {@code x} element-wise. - * - * @param data type for {@code y} output */ @OpMetadata( opType = Erfc.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Exp.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Exp.java index 1a5c7456b51..fe1d6ed1515 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Exp.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Exp.java @@ -56,8 +56,6 @@ * x = tf.constant(1 + 1j) * tf.math.exp(x) ==> 1.4686939399158851+2.2873552871788423j * - * - * @param data type for {@code y} output */ @OpMetadata( opType = Exp.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Expm1.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Expm1.java index a6f8f64ab43..b9c80edf84b 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Expm1.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Expm1.java @@ -47,8 +47,6 @@ * x = tf.constant(1 + 1j) * tf.math.expm1(x) ==> (0.46869393991588515+2.2873552871788423j) * - * - * @param data type for {@code y} output */ @OpMetadata( opType = Expm1.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Floor.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Floor.java index bb9dbc4aa32..27ed6af66ac 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Floor.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Floor.java @@ -35,8 +35,6 @@ /** * Returns element-wise largest integer not greater than x. - * - * @param data type for {@code y} output */ @OpMetadata( opType = Floor.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/FloorDiv.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/FloorDiv.java index 47887e1a4dd..61d57ac8c4f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/FloorDiv.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/FloorDiv.java @@ -37,8 +37,6 @@ * Returns x // y element-wise. * NOTE: {@code math.FloorDiv} supports broadcasting. More about broadcasting * here - * - * @param data type for {@code z} output */ @OpMetadata( opType = FloorDiv.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/FloorMod.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/FloorMod.java index 58c90f87123..b41e5d112b2 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/FloorMod.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/FloorMod.java @@ -40,8 +40,6 @@ * {@code floor(x / y) * y + floormod(x, y) = x}, regardless of the signs of x and y. *

    NOTE: {@code math.FloorMod} supports broadcasting. More about broadcasting * here - * - * @param data type for {@code z} output */ @OpMetadata( opType = FloorMod.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Igamma.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Igamma.java index 4f116ba6e63..224c434af9f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Igamma.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Igamma.java @@ -42,8 +42,6 @@ *

    is the lower incomplete Gamma function. *

    Note, above {@code Q(a, x)} ({@code Igammac}) is the upper regularized complete * Gamma function. - * - * @param data type for {@code z} output */ @OpMetadata( opType = Igamma.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/IgammaGradA.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/IgammaGradA.java index f9e7aced432..a3c6c4f20ad 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/IgammaGradA.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/IgammaGradA.java @@ -35,8 +35,6 @@ /** * Computes the gradient of {@code igamma(a, x)} wrt {@code a}. - * - * @param data type for {@code z} output */ @OpMetadata( opType = IgammaGradA.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Igammac.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Igammac.java index 1cc0549ad00..80f2545ce69 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Igammac.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Igammac.java @@ -42,8 +42,6 @@ *

    is the upper incomplete Gamma function. *

    Note, above {@code P(a, x)} ({@code Igamma}) is the lower regularized complete * Gamma function. - * - * @param data type for {@code z} output */ @OpMetadata( opType = Igammac.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Imag.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Imag.java index fe04cd17336..509de2b8c7b 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Imag.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Imag.java @@ -47,8 +47,6 @@ * # tensor 'input' is [-2.25 + 4.75j, 3.25 + 5.75j] * tf.imag(input) ==> [4.75, 5.75] * - * - * @param data type for {@code output} output */ @OpMetadata( opType = Imag.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/InvertPermutation.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/InvertPermutation.java index 3035d46e60c..a466109898c 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/InvertPermutation.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/InvertPermutation.java @@ -46,8 +46,6 @@ * # tensor `x` is [3, 4, 0, 2, 1] * invert_permutation(x) ==> [2, 4, 3, 0, 1] * - * - * @param data type for {@code y} output */ @OpMetadata( opType = InvertPermutation.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Lgamma.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Lgamma.java index d8c6b4889a2..4c5aea1de84 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Lgamma.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Lgamma.java @@ -42,8 +42,6 @@ * x = tf.constant([0, 0.5, 1, 4.5, -4, -5.6]) * tf.math.lgamma(x) ==> [inf, 0.5723649, 0., 2.4537368, inf, -4.6477685] * - * - * @param data type for {@code y} output */ @OpMetadata( opType = Lgamma.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Log.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Log.java index 32ee589536a..911ab61ff0c 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Log.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Log.java @@ -41,8 +41,6 @@ * x = tf.constant([0, 0.5, 1, 5]) * tf.math.log(x) ==> [-inf, -0.6931472, 0. , 1.609438] * - * - * @param data type for {@code y} output */ @OpMetadata( opType = Log.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Log1p.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Log1p.java index f280d8b0062..05fe31ad376 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Log1p.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Log1p.java @@ -41,8 +41,6 @@ * x = tf.constant([0, 0.5, 1, 5]) * tf.math.log1p(x) ==> [0., 0.4054651, 0.6931472, 1.7917595] * - * - * @param data type for {@code y} output */ @OpMetadata( opType = Log1p.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Maximum.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Maximum.java index c46c8c6e384..0c864b79f5e 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Maximum.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Maximum.java @@ -37,8 +37,6 @@ * Returns the max of x and y (i.e. x > y ? x : y) element-wise. * NOTE: {@code math.Maximum} supports broadcasting. More about broadcasting * here - * - * @param data type for {@code z} output */ @OpMetadata( opType = Maximum.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Mean.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Mean.java index 94de9fc5bd4..9018aa2bd6d 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Mean.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Mean.java @@ -40,8 +40,6 @@ * {@code keep_dims} is true, the rank of the tensor is reduced by 1 for each entry in * {@code axis}. If {@code keep_dims} is true, the reduced dimensions are * retained with length 1. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Mean.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Minimum.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Minimum.java index 588bcb3328b..b516ee5c302 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Minimum.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Minimum.java @@ -37,8 +37,6 @@ * Returns the min of x and y (i.e. x < y ? x : y) element-wise. * NOTE: {@code math.Minimum} supports broadcasting. More about broadcasting * here - * - * @param data type for {@code z} output */ @OpMetadata( opType = Minimum.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Mod.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Mod.java index d318de97c9c..60ccc32e855 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Mod.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Mod.java @@ -39,8 +39,6 @@ * {@code tf.truncatediv(x, y) * y + truncate_mod(x, y) = x}. *

    NOTE: {@code math.Mod} supports broadcasting. More about broadcasting * here - * - * @param data type for {@code z} output */ @OpMetadata( opType = Mod.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Mul.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Mul.java index d7466085ada..d18a48a6472 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Mul.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Mul.java @@ -37,8 +37,6 @@ * Returns x * y element-wise. * NOTE: {@code math.Mul} supports broadcasting. More about broadcasting * here - * - * @param data type for {@code z} output */ @OpMetadata( opType = Mul.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/MulNoNan.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/MulNoNan.java index 85429b70ca1..7e85f94c31d 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/MulNoNan.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/MulNoNan.java @@ -37,8 +37,6 @@ * Returns x * y element-wise. Returns zero if y is zero, even if x if infinite or NaN. * NOTE: {@code math.MulNoNan} supports broadcasting. More about broadcasting * here - * - * @param data type for {@code z} output */ @OpMetadata( opType = MulNoNan.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Ndtri.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Ndtri.java index 37d1ffb8fc9..2c9b4f4719f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Ndtri.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Ndtri.java @@ -35,8 +35,6 @@ /** * The Ndtri operation - * - * @param data type for {@code y} output */ @OpMetadata( opType = Ndtri.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Neg.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Neg.java index e0ec5783144..e11b274470a 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Neg.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Neg.java @@ -36,8 +36,6 @@ /** * Computes numerical negative value element-wise. * I.e., \(y = -x\). - * - * @param data type for {@code y} output */ @OpMetadata( opType = Neg.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/NextAfter.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/NextAfter.java index 45ff3a179ca..fef32810db3 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/NextAfter.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/NextAfter.java @@ -40,8 +40,6 @@ *

    {@literal @}compatibility(cpp)
    * Equivalent to C++ std::nextafter function. *
    {@literal @}end_compatibility - * - * @param data type for {@code output} output */ @OpMetadata( opType = NextAfter.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Polygamma.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Polygamma.java index b2fb442489b..f391fef2335 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Polygamma.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Polygamma.java @@ -39,8 +39,6 @@ *

    \(\psi^{(a)}(x) = \frac{d^a}{dx^a} \psi(x)\) *

    where \(\psi(x)\) is the digamma function. * The polygamma function is defined only for non-negative integer orders \a\. - * - * @param data type for {@code z} output */ @OpMetadata( opType = Polygamma.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Pow.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Pow.java index f50532e8d62..3a8f8acbb7a 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Pow.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Pow.java @@ -42,8 +42,6 @@ * # tensor 'y' is [[8, 16], [2, 3]] * tf.pow(x, y) ==> [[256, 65536], [9, 27]] * - * - * @param data type for {@code z} output */ @OpMetadata( opType = Pow.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/QuantizedAdd.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/QuantizedAdd.java index ad59711dca9..cf02c4ad713 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/QuantizedAdd.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/QuantizedAdd.java @@ -37,8 +37,6 @@ /** * Returns x + y element-wise, working on quantized buffers. - * - * @param data type for {@code z} output */ @OpMetadata( opType = QuantizedAdd.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/QuantizedMul.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/QuantizedMul.java index 6b5c3d05579..b9f1e5b062c 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/QuantizedMul.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/QuantizedMul.java @@ -37,8 +37,6 @@ /** * Returns x * y element-wise, working on quantized buffers. - * - * @param data type for {@code z} output */ @OpMetadata( opType = QuantizedMul.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Real.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Real.java index 6217269b474..c85e0d73861 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Real.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Real.java @@ -47,8 +47,6 @@ * # tensor 'input' is [-2.25 + 4.75j, 3.25 + 5.75j] * tf.real(input) ==> [-2.25, 3.25] * - * - * @param data type for {@code output} output */ @OpMetadata( opType = Real.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/RealDiv.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/RealDiv.java index c1aceba76d3..fb2e7e77d33 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/RealDiv.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/RealDiv.java @@ -38,8 +38,6 @@ * If {@code x} and {@code y} are reals, this will return the floating-point division. *

    NOTE: {@code Div} supports broadcasting. More about broadcasting * here - * - * @param data type for {@code z} output */ @OpMetadata( opType = RealDiv.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Reciprocal.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Reciprocal.java index 97ae15f6015..c0e6b9c573a 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Reciprocal.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Reciprocal.java @@ -36,8 +36,6 @@ /** * Computes the reciprocal of x element-wise. * I.e., \(y = 1 / x\). - * - * @param data type for {@code y} output */ @OpMetadata( opType = Reciprocal.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/ReciprocalGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/ReciprocalGrad.java index 13b7b7592ab..9d1c672629f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/ReciprocalGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/ReciprocalGrad.java @@ -37,8 +37,6 @@ * Computes the gradient for the inverse of {@code x} wrt its input. * Specifically, {@code grad = -dy * y*y}, where {@code y = 1/x}, and {@code dy} * is the corresponding input gradient. - * - * @param data type for {@code z} output */ @OpMetadata( opType = ReciprocalGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/RequantizePerChannel.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/RequantizePerChannel.java index c2a71d1d594..f6dcf220ade 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/RequantizePerChannel.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/RequantizePerChannel.java @@ -37,8 +37,6 @@ /** * Requantizes input with min and max values known per channel. - * - * @param data type for {@code output} output */ @OpMetadata( opType = RequantizePerChannel.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Rint.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Rint.java index 716bc8be07b..62a48d4ecd0 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Rint.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Rint.java @@ -43,8 +43,6 @@ * rint(0.5000001) ==> 1.0 * rint([-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0]) ==> [-2., -2., -0., 0., 2., 2., 2.] * - * - * @param data type for {@code y} output */ @OpMetadata( opType = Rint.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Round.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Round.java index d8a5aff3d2d..0e7441efeb1 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Round.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Round.java @@ -37,8 +37,6 @@ * Rounds the values of a tensor to the nearest integer, element-wise. * Rounds half to even. Also known as bankers rounding. If you want to round * according to the current system rounding mode use std::cint. - * - * @param data type for {@code y} output */ @OpMetadata( opType = Round.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Rsqrt.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Rsqrt.java index 12ce75ef035..3d438f10f12 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Rsqrt.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Rsqrt.java @@ -36,8 +36,6 @@ /** * Computes reciprocal of square root of x element-wise. * I.e., \(y = 1 / \sqrt{x}\). - * - * @param data type for {@code y} output */ @OpMetadata( opType = Rsqrt.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/RsqrtGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/RsqrtGrad.java index f92da40a82b..90fc4892083 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/RsqrtGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/RsqrtGrad.java @@ -37,8 +37,6 @@ * Computes the gradient for the rsqrt of {@code x} wrt its input. * Specifically, {@code grad = dy * -0.5 * y^3}, where {@code y = rsqrt(x)}, and {@code dy} * is the corresponding input gradient. - * - * @param data type for {@code z} output */ @OpMetadata( opType = RsqrtGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SegmentMax.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SegmentMax.java index 1939c7a4d3a..44ec468eaf4 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SegmentMax.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SegmentMax.java @@ -73,8 +73,6 @@ * * * - * - * @param data type for {@code output} output */ @OpMetadata( opType = SegmentMax.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SegmentMean.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SegmentMean.java index 7d0e2af1606..2e69b2bb8b5 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SegmentMean.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SegmentMean.java @@ -64,8 +64,6 @@ * * * - * - * @param data type for {@code output} output */ @OpMetadata( opType = SegmentMean.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SegmentMin.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SegmentMin.java index cb5a312d3ff..9dce52fceed 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SegmentMin.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SegmentMin.java @@ -73,8 +73,6 @@ * * * - * - * @param data type for {@code output} output */ @OpMetadata( opType = SegmentMin.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SegmentProd.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SegmentProd.java index 87738a1ac3a..77fd53d92a0 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SegmentProd.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SegmentProd.java @@ -66,8 +66,6 @@ * * * - * - * @param data type for {@code output} output */ @OpMetadata( opType = SegmentProd.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SegmentSum.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SegmentSum.java index 578d159e289..c47c3acd24f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SegmentSum.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SegmentSum.java @@ -44,9 +44,6 @@ * that {@code segment_ids[j] == i}. *

    If the sum is empty for a given segment ID {@code i}, {@code output[i] = 0}. *

    Note that this op is currently only supported with jit_compile=True. - * - * - * @param data type for {@code output} output */ @OpMetadata( opType = SegmentSum.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Sigmoid.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Sigmoid.java index bd93a0303eb..8e71006a2c0 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Sigmoid.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Sigmoid.java @@ -36,8 +36,6 @@ /** * Computes sigmoid of {@code x} element-wise. * Specifically, {@code y = 1 / (1 + exp(-x))}. - * - * @param data type for {@code y} output */ @OpMetadata( opType = Sigmoid.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SigmoidGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SigmoidGrad.java index 8f4b7cfe45c..a85b754cc61 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SigmoidGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SigmoidGrad.java @@ -37,8 +37,6 @@ * Computes the gradient of the sigmoid of {@code x} wrt its input. * Specifically, {@code grad = dy * y * (1 - y)}, where {@code y = sigmoid(x)}, and * {@code dy} is the corresponding input gradient. - * - * @param data type for {@code z} output */ @OpMetadata( opType = SigmoidGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Sign.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Sign.java index 15f5e07b597..ee9d2d65154 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Sign.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Sign.java @@ -46,8 +46,6 @@ * * * - * - * @param data type for {@code y} output */ @OpMetadata( opType = Sign.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Sin.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Sin.java index 06269cb6278..1a13ada1838 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Sin.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Sin.java @@ -42,8 +42,6 @@ * x = tf.constant([-float("inf"), -9, -0.5, 1, 1.2, 200, 10, float("inf")]) * tf.math.sin(x) ==> [nan -0.4121185 -0.47942555 0.84147096 0.9320391 -0.87329733 -0.54402107 nan] * - * - * @param data type for {@code y} output */ @OpMetadata( opType = Sin.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Sinh.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Sinh.java index 9e1a692df76..b4af201ab99 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Sinh.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Sinh.java @@ -42,8 +42,6 @@ * x = tf.constant([-float("inf"), -9, -0.5, 1, 1.2, 2, 10, float("inf")]) * tf.math.sinh(x) ==> [-inf -4.0515420e+03 -5.2109528e-01 1.1752012e+00 1.5094614e+00 3.6268604e+00 1.1013232e+04 inf] * - * - * @param data type for {@code y} output */ @OpMetadata( opType = Sinh.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SobolSample.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SobolSample.java index 95f33401f0b..5989ca78f57 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SobolSample.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SobolSample.java @@ -40,8 +40,6 @@ * Generates points from the Sobol sequence. * Creates a Sobol sequence with {@code num_results} samples. Each sample has dimension * {@code dim}. Skips the first {@code skip} samples. - * - * @param data type for {@code samples} output */ @OpMetadata( opType = SobolSample.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Softplus.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Softplus.java index aa80f8d0840..cdb0aea4f9f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Softplus.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Softplus.java @@ -35,8 +35,6 @@ /** * The Softplus operation - * - * @param data type for {@code activations} output */ @OpMetadata( opType = Softplus.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SoftplusGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SoftplusGrad.java index 5a8445dad45..3f2901810ce 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SoftplusGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SoftplusGrad.java @@ -35,8 +35,6 @@ /** * Computes softplus gradients for a softplus operation. - * - * @param data type for {@code backprops} output */ @OpMetadata( opType = SoftplusGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Sqrt.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Sqrt.java index ac6cd68b529..8c6edfc6e89 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Sqrt.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Sqrt.java @@ -36,8 +36,6 @@ /** * Computes square root of x element-wise. * I.e., \(y = \sqrt{x} = x^{1/2}\). - * - * @param data type for {@code y} output */ @OpMetadata( opType = Sqrt.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SqrtGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SqrtGrad.java index 451143c16e4..eed0209152b 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SqrtGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SqrtGrad.java @@ -37,8 +37,6 @@ * Computes the gradient for the sqrt of {@code x} wrt its input. * Specifically, {@code grad = dy * 0.5 / y}, where {@code y = sqrt(x)}, and {@code dy} * is the corresponding input gradient. - * - * @param data type for {@code z} output */ @OpMetadata( opType = SqrtGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Square.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Square.java index d5811d17c2a..2952af307d2 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Square.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Square.java @@ -36,8 +36,6 @@ /** * Computes square of x element-wise. * I.e., \(y = x * x = x^2\). - * - * @param data type for {@code y} output */ @OpMetadata( opType = Square.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SquaredDifference.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SquaredDifference.java index 2af6fe083e3..4d880a79baa 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SquaredDifference.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/SquaredDifference.java @@ -37,8 +37,6 @@ * Returns conj(x - y)(x - y) element-wise. * NOTE: {@code math.SquaredDifference} supports broadcasting. More about broadcasting * here - * - * @param data type for {@code z} output */ @OpMetadata( opType = SquaredDifference.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Sub.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Sub.java index 6313555f9f1..b48b311d80e 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Sub.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Sub.java @@ -37,8 +37,6 @@ * Returns x - y element-wise. * NOTE: {@code math.Sub} supports broadcasting. More about broadcasting * here - * - * @param data type for {@code z} output */ @OpMetadata( opType = Sub.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Tan.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Tan.java index 566b7d2b03f..c1073f8a5bb 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Tan.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Tan.java @@ -43,8 +43,6 @@ * x = tf.constant([-float("inf"), -9, -0.5, 1, 1.2, 200, 10000, float("inf")]) * tf.math.tan(x) ==> [nan 0.45231566 -0.5463025 1.5574077 2.572152 -1.7925274 0.32097113 nan] * - * - * @param data type for {@code y} output */ @OpMetadata( opType = Tan.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Tanh.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Tanh.java index ee24b4085df..706a8d90cd0 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Tanh.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Tanh.java @@ -49,8 +49,6 @@ * * * - * - * @param data type for {@code y} output */ @OpMetadata( opType = Tanh.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/TanhGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/TanhGrad.java index c638f78b3fe..273adcf20a6 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/TanhGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/TanhGrad.java @@ -37,8 +37,6 @@ * Computes the gradient for the tanh of {@code x} wrt its input. * Specifically, {@code grad = dy * (1 - y*y)}, where {@code y = tanh(x)}, and {@code dy} * is the corresponding input gradient. - * - * @param data type for {@code z} output */ @OpMetadata( opType = TanhGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/TruncateDiv.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/TruncateDiv.java index 377eb5848d8..7857bd6221b 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/TruncateDiv.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/TruncateDiv.java @@ -41,8 +41,6 @@ * Python Semantics. *

    NOTE: {@code math.TruncateDiv} supports broadcasting. More about broadcasting * here - * - * @param data type for {@code z} output */ @OpMetadata( opType = TruncateDiv.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/TruncateMod.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/TruncateMod.java index e80c75e5709..bd7a41fafd2 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/TruncateMod.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/TruncateMod.java @@ -38,8 +38,6 @@ * the result here is consistent with a truncating divide. E.g. {@code truncate(x / y) * y + truncate_mod(x, y) = x}. *

    NOTE: {@code math.TruncateMod} supports broadcasting. More about broadcasting * here - * - * @param data type for {@code z} output */ @OpMetadata( opType = TruncateMod.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/UniformQuantizedAdd.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/UniformQuantizedAdd.java index 535d432dcca..312c712b44e 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/UniformQuantizedAdd.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/UniformQuantizedAdd.java @@ -52,8 +52,6 @@ * i.e. For both operands {@code lhs} and {@code rhs}, * if {@code operand.quantization_axis} >= 0 and {@code output.quantization_axis} >= 0, * {@code operand.dims} - {@code operand.quantization_axis} must be equal to {@code output.dims} - {@code output.quantization_axis}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = UniformQuantizedAdd.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/UnsortedSegmentMax.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/UnsortedSegmentMax.java index 50d32494e80..27888d7f1f5 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/UnsortedSegmentMax.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/UnsortedSegmentMax.java @@ -67,8 +67,6 @@ * * * - * - * @param data type for {@code output} output */ @OpMetadata( opType = UnsortedSegmentMax.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/UnsortedSegmentMin.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/UnsortedSegmentMin.java index db83daaead7..af919665a56 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/UnsortedSegmentMin.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/UnsortedSegmentMin.java @@ -64,8 +64,6 @@ * result in safe but unspecified behavior, which may include ignoring * out-of-bound indices or outputting a tensor with a 0 stored in the first * dimension of its shape if {@code num_segments} is 0. - * - * @param data type for {@code output} output */ @OpMetadata( opType = UnsortedSegmentMin.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/UnsortedSegmentProd.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/UnsortedSegmentProd.java index a36c653ef2a..fd3f76bc1e7 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/UnsortedSegmentProd.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/UnsortedSegmentProd.java @@ -64,8 +64,6 @@ * result in safe but unspecified behavior, which may include ignoring * out-of-bound indices or outputting a tensor with a 0 stored in the first * dimension of its shape if {@code num_segments} is 0. - * - * @param data type for {@code output} output */ @OpMetadata( opType = UnsortedSegmentProd.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/UnsortedSegmentSum.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/UnsortedSegmentSum.java index 14c0bef2293..af4dd57e39f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/UnsortedSegmentSum.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/UnsortedSegmentSum.java @@ -67,8 +67,6 @@ * * * - * - * @param data type for {@code output} output */ @OpMetadata( opType = UnsortedSegmentSum.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Xdivy.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Xdivy.java index 8be3546a9f0..0ba35ba8a83 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Xdivy.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Xdivy.java @@ -35,8 +35,6 @@ /** * Returns 0 if x == 0, and x / y otherwise, elementwise. - * - * @param data type for {@code z} output */ @OpMetadata( opType = Xdivy.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Xlog1py.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Xlog1py.java index b798c8ef598..c6e6184bed0 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Xlog1py.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Xlog1py.java @@ -35,8 +35,6 @@ /** * Returns 0 if x == 0, and x * log1p(y) otherwise, elementwise. - * - * @param data type for {@code z} output */ @OpMetadata( opType = Xlog1py.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Xlogy.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Xlogy.java index b4ad543093f..e27ef9a210c 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Xlogy.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Xlogy.java @@ -35,8 +35,6 @@ /** * Returns 0 if x == 0, and x * log(y) otherwise, elementwise. - * - * @param data type for {@code z} output */ @OpMetadata( opType = Xlogy.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Zeta.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Zeta.java index 887fb1af711..593507c4340 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Zeta.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/Zeta.java @@ -37,8 +37,6 @@ * Compute the Hurwitz zeta function \(\zeta(x, q)\). * The Hurwitz zeta function is defined as: *

    \(\zeta(x, q) = \sum_{n=0}^{\infty} (q + n)^{-x}\) - * - * @param data type for {@code z} output */ @OpMetadata( opType = Zeta.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/erfinv.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/erfinv.java index a4b68423646..a208c49973f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/erfinv.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/erfinv.java @@ -35,8 +35,6 @@ /** * The Erfinv operation - * - * @param data type for {@code y} output */ @OpMetadata( opType = erfinv.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/BesselJ0.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/BesselJ0.java index 6ef1d289c7d..839ca6179b3 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/BesselJ0.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/BesselJ0.java @@ -35,8 +35,6 @@ /** * The BesselJ0 operation - * - * @param data type for {@code y} output */ @OpMetadata( opType = BesselJ0.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/BesselJ1.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/BesselJ1.java index 5e7718f4144..6e125a29821 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/BesselJ1.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/BesselJ1.java @@ -35,8 +35,6 @@ /** * The BesselJ1 operation - * - * @param data type for {@code y} output */ @OpMetadata( opType = BesselJ1.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/BesselK0.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/BesselK0.java index 338b5759a10..8ec9f528212 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/BesselK0.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/BesselK0.java @@ -35,8 +35,6 @@ /** * The BesselK0 operation - * - * @param data type for {@code y} output */ @OpMetadata( opType = BesselK0.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/BesselK0e.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/BesselK0e.java index f2a01b68ba8..69d5995c59d 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/BesselK0e.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/BesselK0e.java @@ -35,8 +35,6 @@ /** * The BesselK0e operation - * - * @param data type for {@code y} output */ @OpMetadata( opType = BesselK0e.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/BesselK1.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/BesselK1.java index 8143c8107d5..f26b95a8c53 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/BesselK1.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/BesselK1.java @@ -35,8 +35,6 @@ /** * The BesselK1 operation - * - * @param data type for {@code y} output */ @OpMetadata( opType = BesselK1.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/BesselK1e.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/BesselK1e.java index 08ea2073dab..995eaccd9dd 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/BesselK1e.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/BesselK1e.java @@ -35,8 +35,6 @@ /** * The BesselK1e operation - * - * @param data type for {@code y} output */ @OpMetadata( opType = BesselK1e.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/BesselY0.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/BesselY0.java index c82e15022db..1beae63d61f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/BesselY0.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/BesselY0.java @@ -35,8 +35,6 @@ /** * The BesselY0 operation - * - * @param data type for {@code y} output */ @OpMetadata( opType = BesselY0.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/BesselY1.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/BesselY1.java index 5b86f1987e3..3985dee42d0 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/BesselY1.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/BesselY1.java @@ -35,8 +35,6 @@ /** * The BesselY1 operation - * - * @param data type for {@code y} output */ @OpMetadata( opType = BesselY1.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/Dawsn.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/Dawsn.java index 045ffc0d94c..e34e0376249 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/Dawsn.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/Dawsn.java @@ -35,8 +35,6 @@ /** * The Dawsn operation - * - * @param data type for {@code y} output */ @OpMetadata( opType = Dawsn.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/Expint.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/Expint.java index bcdff92cb07..9b61e0fcb90 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/Expint.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/Expint.java @@ -35,8 +35,6 @@ /** * The Expint operation - * - * @param data type for {@code y} output */ @OpMetadata( opType = Expint.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/FresnelCos.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/FresnelCos.java index 790daad9115..dffb6bda0f0 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/FresnelCos.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/FresnelCos.java @@ -35,8 +35,6 @@ /** * The FresnelCos operation - * - * @param data type for {@code y} output */ @OpMetadata( opType = FresnelCos.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/FresnelSin.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/FresnelSin.java index a148cb42bff..23e7e1d4bbd 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/FresnelSin.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/FresnelSin.java @@ -35,8 +35,6 @@ /** * The FresnelSin operation - * - * @param data type for {@code y} output */ @OpMetadata( opType = FresnelSin.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/Spence.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/Spence.java index 7835a2fca79..0a012a3be6c 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/Spence.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/math/special/Spence.java @@ -35,8 +35,6 @@ /** * The Spence operation - * - * @param data type for {@code y} output */ @OpMetadata( opType = Spence.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/AvgPool.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/AvgPool.java index aa583ae8174..3d6355679c8 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/AvgPool.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/AvgPool.java @@ -38,8 +38,6 @@ * Performs average pooling on the input. * Each entry in {@code output} is the mean of the corresponding size {@code ksize} * window in {@code value}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = AvgPool.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/AvgPool3d.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/AvgPool3d.java index b7b61a50351..5f5410d91d5 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/AvgPool3d.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/AvgPool3d.java @@ -38,8 +38,6 @@ * Performs 3D average pooling on the input. * Each entry in {@code output} is the mean of the corresponding size {@code ksize} window in * {@code value}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = AvgPool3d.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/AvgPool3dGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/AvgPool3dGrad.java index 6acc17b69ae..4b41a0338b3 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/AvgPool3dGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/AvgPool3dGrad.java @@ -37,8 +37,6 @@ /** * Computes gradients of average pooling function. - * - * @param data type for {@code output} output */ @OpMetadata( opType = AvgPool3dGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/AvgPoolGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/AvgPoolGrad.java index 74acc456c92..9a2c1511bba 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/AvgPoolGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/AvgPoolGrad.java @@ -37,8 +37,6 @@ /** * Computes gradients of the average pooling function. - * - * @param data type for {@code output} output */ @OpMetadata( opType = AvgPoolGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/BatchNormWithGlobalNormalization.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/BatchNormWithGlobalNormalization.java index deaec7bdd3d..ef7ead8115e 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/BatchNormWithGlobalNormalization.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/BatchNormWithGlobalNormalization.java @@ -36,8 +36,6 @@ /** * Batch normalization. * This op is deprecated. Prefer {@code tf.nn.batch_normalization}. - * - * @param data type for {@code result} output */ @OpMetadata( opType = BatchNormWithGlobalNormalization.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/BatchNormWithGlobalNormalizationGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/BatchNormWithGlobalNormalizationGrad.java index f75aebb0e4c..03e84d778c4 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/BatchNormWithGlobalNormalizationGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/BatchNormWithGlobalNormalizationGrad.java @@ -36,8 +36,6 @@ /** * Gradients for batch normalization. * This op is deprecated. See {@code tf.nn.batch_normalization}. - * - * @param data type for {@code dx} output */ @OpMetadata( opType = BatchNormWithGlobalNormalizationGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/BiasAdd.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/BiasAdd.java index c228699e9cb..5f826546b07 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/BiasAdd.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/BiasAdd.java @@ -37,8 +37,6 @@ * Adds {@code bias} to {@code value}. * This is a special case of {@code tf.add} where {@code bias} is restricted to be 1-D. * Broadcasting is supported, so {@code value} may have any number of dimensions. - * - * @param data type for {@code output} output */ @OpMetadata( opType = BiasAdd.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/BiasAddGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/BiasAddGrad.java index 01c90a2fd49..33c2829c271 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/BiasAddGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/BiasAddGrad.java @@ -38,8 +38,6 @@ * It accumulates all the values from out_backprop into the feature dimension. * For NHWC data format, the feature dimension is the last. For NCHW data format, * the feature dimension is the third-to-last. - * - * @param data type for {@code output} output */ @OpMetadata( opType = BiasAddGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/BlockLSTM.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/BlockLSTM.java index 3363a371d20..ef303c35efc 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/BlockLSTM.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/BlockLSTM.java @@ -56,8 +56,6 @@ * this op uses IFCO. So in order for the following snippet to be equivalent * all gate-related outputs should be reordered. * - * - * @param data type for {@code i} output */ @OpMetadata( opType = BlockLSTM.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/BlockLSTMGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/BlockLSTMGrad.java index 2684ae60017..85bc08f38b6 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/BlockLSTMGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/BlockLSTMGrad.java @@ -37,8 +37,6 @@ /** * Computes the LSTM cell backward propagation for the entire time sequence. * This implementation is to be used in conjunction of BlockLSTMV2. - * - * @param data type for {@code x_grad} output */ @OpMetadata( opType = BlockLSTMGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv.java index 7e352a1ff76..096c8a3719f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv.java @@ -38,8 +38,6 @@ * Computes a N-D convolution given (N+1+batch_dims)-D {@code input} and (N+2)-D {@code filter} tensors. * General function for computing a N-D convolution. It is required that * {@code 1 <= N <= 3}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Conv.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv2d.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv2d.java index 9fef633fefd..6d7eb6e004e 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv2d.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv2d.java @@ -56,8 +56,6 @@ * *

    Must have {@code strides[0] = strides[3] = 1}. For the most common case of the same * horizontal and vertices strides, {@code strides = [1, stride, stride, 1]}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Conv2d.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv2dBackpropFilter.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv2dBackpropFilter.java index 9d09ebaa1df..2d5af50d5e6 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv2dBackpropFilter.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv2dBackpropFilter.java @@ -37,8 +37,6 @@ /** * Computes the gradients of convolution with respect to the filter. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Conv2dBackpropFilter.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv2dBackpropFilterV2.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv2dBackpropFilterV2.java index 901d2a50f72..1b8a95c8728 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv2dBackpropFilterV2.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv2dBackpropFilterV2.java @@ -35,8 +35,6 @@ /** * Computes the gradients of convolution with respect to the filter. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Conv2dBackpropFilterV2.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv2dBackpropInput.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv2dBackpropInput.java index 9e44c7170cb..fc0f5f296e1 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv2dBackpropInput.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv2dBackpropInput.java @@ -37,8 +37,6 @@ /** * Computes the gradients of convolution with respect to the input. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Conv2dBackpropInput.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv2dBackpropInputV2.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv2dBackpropInputV2.java index 1fa123e14b2..04941640016 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv2dBackpropInputV2.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv2dBackpropInputV2.java @@ -35,8 +35,6 @@ /** * Computes the gradients of convolution with respect to the input. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Conv2dBackpropInputV2.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv3d.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv3d.java index 5d3d0925894..7de4f93716d 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv3d.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv3d.java @@ -40,8 +40,6 @@ * two waveforms as a function of a time-lag applied to one of them. This * is also known as a sliding dot product or sliding inner-product. *

    Our Conv3D implements a form of cross-correlation. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Conv3d.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv3dBackpropFilter.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv3dBackpropFilter.java index 2cc01b0dfe0..79970ac4d15 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv3dBackpropFilter.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv3dBackpropFilter.java @@ -37,8 +37,6 @@ /** * Computes the gradients of 3-D convolution with respect to the filter. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Conv3dBackpropFilter.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv3dBackpropInput.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv3dBackpropInput.java index 651f027ac42..d60306ab96d 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv3dBackpropInput.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Conv3dBackpropInput.java @@ -36,8 +36,6 @@ /** * Computes the gradients of 3-D convolution with respect to the input. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Conv3dBackpropInput.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/CtcBeamSearchDecoder.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/CtcBeamSearchDecoder.java index 59cde61eb54..f270607bb50 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/CtcBeamSearchDecoder.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/CtcBeamSearchDecoder.java @@ -43,8 +43,6 @@ * the first of these is emitted. That is, when the top path is "A B B B B", * "A B" is returned if merge_repeated = True but "A B B B B" is * returned if merge_repeated = False. - * - * @param data type for {@code log_probability} output */ @OpMetadata( opType = CtcBeamSearchDecoder.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/CtcGreedyDecoder.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/CtcGreedyDecoder.java index de01c874c33..688f60ab28e 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/CtcGreedyDecoder.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/CtcGreedyDecoder.java @@ -45,8 +45,6 @@ *

    Regardless of the value of merge_repeated, if the maximum index of a given * time and batch corresponds to the blank, index {@code (num_classes - 1)}, no new * element is emitted. - * - * @param data type for {@code log_probability} output */ @OpMetadata( opType = CtcGreedyDecoder.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/CtcLoss.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/CtcLoss.java index d2dd09549fa..8369dae6c75 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/CtcLoss.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/CtcLoss.java @@ -39,8 +39,6 @@ * Calculates the CTC Loss (log probability) for each batch entry. Also calculates * the gradient. This class performs the softmax operation for you, so inputs * should be e.g. linear projections of outputs by an LSTM. - * - * @param data type for {@code loss} output */ @OpMetadata( opType = CtcLoss.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/CudnnRNN.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/CudnnRNN.java index 0525df86f45..8845090aa6e 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/CudnnRNN.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/CudnnRNN.java @@ -73,8 +73,6 @@ * major. * reserve_space: An opaque tensor that can be used in backprop calculation. It * is only produced if is_training is true. - * - * @param data type for {@code output} output */ @OpMetadata( opType = CudnnRNN.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/CudnnRNNBackprop.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/CudnnRNNBackprop.java index d76dd629918..a1e09f597ac 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/CudnnRNNBackprop.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/CudnnRNNBackprop.java @@ -83,8 +83,6 @@ * shape as input_c. * params_backprop: The backprop to the params buffer in the forward pass. Has the * same shape as params. - * - * @param data type for {@code input_backprop} output */ @OpMetadata( opType = CudnnRNNBackprop.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/CudnnRNNCanonicalToParams.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/CudnnRNNCanonicalToParams.java index a513cf67d66..0c38a68a23e 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/CudnnRNNCanonicalToParams.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/CudnnRNNCanonicalToParams.java @@ -65,8 +65,6 @@ * seed2: the 2nd part of a seed to initialize dropout. * num_proj: The output dimensionality for the projection matrices. If None or 0, * no projection is performed. - * - * @param data type for {@code params} output */ @OpMetadata( opType = CudnnRNNCanonicalToParams.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/CudnnRNNParamsToCanonical.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/CudnnRNNParamsToCanonical.java index 6a1e55f34e2..b85a3568412 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/CudnnRNNParamsToCanonical.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/CudnnRNNParamsToCanonical.java @@ -65,8 +65,6 @@ * seed2: the 2nd part of a seed to initialize dropout. * num_proj: The output dimensionality for the projection matrices. If None or 0, * no projection is performed. - * - * @param data type for {@code weights} output */ @OpMetadata( opType = CudnnRNNParamsToCanonical.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/CudnnRnnParamsSize.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/CudnnRnnParamsSize.java index 051c792e878..1dbc4d48ad8 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/CudnnRnnParamsSize.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/CudnnRnnParamsSize.java @@ -57,8 +57,6 @@ * compatible across GPUs. Please use CudnnRNNParamsWeights and * CudnnRNNParamsBiases to save and restore them in a way that is compatible * across different runs. - * - * @param data type for {@code params_size} output */ @OpMetadata( opType = CudnnRnnParamsSize.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/DataFormatDimMap.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/DataFormatDimMap.java index 3376ad9ed6e..6e83cd0c867 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/DataFormatDimMap.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/DataFormatDimMap.java @@ -36,8 +36,6 @@ /** * Returns the dimension index in the destination data format given the one in * the source data format. - * - * @param data type for {@code y} output */ @OpMetadata( opType = DataFormatDimMap.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/DataFormatVecPermute.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/DataFormatVecPermute.java index e02890a40ce..f719f7cc7ce 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/DataFormatVecPermute.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/DataFormatVecPermute.java @@ -64,8 +64,6 @@ *

      * [1, 2]
      * 
    - * - * @param data type for {@code y} output */ @OpMetadata( opType = DataFormatVecPermute.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/DepthToSpace.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/DepthToSpace.java index cceb78d27d1..2f1880cda02 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/DepthToSpace.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/DepthToSpace.java @@ -109,8 +109,6 @@ * [ [11], [12], [15], [16]]]] * * - * - * @param data type for {@code output} output */ @OpMetadata( opType = DepthToSpace.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/DepthwiseConv2dNative.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/DepthwiseConv2dNative.java index e3f7f02ac33..93a0b744513 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/DepthwiseConv2dNative.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/DepthwiseConv2dNative.java @@ -52,8 +52,6 @@ * *

    Must have {@code strides[0] = strides[3] = 1}. For the most common case of the same * horizontal and vertices strides, {@code strides = [1, stride, stride, 1]}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = DepthwiseConv2dNative.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/DepthwiseConv2dNativeBackpropFilter.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/DepthwiseConv2dNativeBackpropFilter.java index 6c55468131b..66eb190debf 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/DepthwiseConv2dNativeBackpropFilter.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/DepthwiseConv2dNativeBackpropFilter.java @@ -37,8 +37,6 @@ /** * Computes the gradients of depthwise convolution with respect to the filter. - * - * @param data type for {@code output} output */ @OpMetadata( opType = DepthwiseConv2dNativeBackpropFilter.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/DepthwiseConv2dNativeBackpropInput.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/DepthwiseConv2dNativeBackpropInput.java index 0f1a70bb566..287b29abba1 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/DepthwiseConv2dNativeBackpropInput.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/DepthwiseConv2dNativeBackpropInput.java @@ -37,8 +37,6 @@ /** * Computes the gradients of depthwise convolution with respect to the input. - * - * @param data type for {@code output} output */ @OpMetadata( opType = DepthwiseConv2dNativeBackpropInput.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Dilation2d.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Dilation2d.java index f213e685ab6..019c786873c 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Dilation2d.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Dilation2d.java @@ -57,8 +57,6 @@ * kernel size and contains all zeros. *

    Note on duality: The dilation of {@code input} by the {@code filter} is equal to the * negation of the erosion of {@code -input} by the reflected {@code filter}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Dilation2d.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Dilation2dBackpropFilter.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Dilation2dBackpropFilter.java index 93381ee22cf..cae841aee0d 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Dilation2dBackpropFilter.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Dilation2dBackpropFilter.java @@ -36,8 +36,6 @@ /** * Computes the gradient of morphological 2-D dilation with respect to the filter. - * - * @param data type for {@code filter_backprop} output */ @OpMetadata( opType = Dilation2dBackpropFilter.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Dilation2dBackpropInput.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Dilation2dBackpropInput.java index 7747bc57c64..8204785ae02 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Dilation2dBackpropInput.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Dilation2dBackpropInput.java @@ -36,8 +36,6 @@ /** * Computes the gradient of morphological 2-D dilation with respect to the input. - * - * @param data type for {@code in_backprop} output */ @OpMetadata( opType = Dilation2dBackpropInput.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Elu.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Elu.java index 6119dd0dec2..253baee2601 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Elu.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Elu.java @@ -55,8 +55,6 @@ * *

    See Fast and Accurate Deep Network Learning by Exponential Linear Units (ELUs) * - * - * @param data type for {@code activations} output */ @OpMetadata( opType = Elu.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/EluGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/EluGrad.java index 2df99ce5c8f..4d32b6d365f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/EluGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/EluGrad.java @@ -35,8 +35,6 @@ /** * Computes gradients for the exponential linear (Elu) operation. - * - * @param data type for {@code backprops} output */ @OpMetadata( opType = EluGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/FractionalAvgPool.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/FractionalAvgPool.java index 04cfd0e3cd9..bb525aac295 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/FractionalAvgPool.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/FractionalAvgPool.java @@ -41,8 +41,6 @@ * region generation step. The only difference is that after pooling regions are * generated, a mean operation is performed instead of a max operation in each * pooling region. - * - * @param data type for {@code output} output */ @OpMetadata( opType = FractionalAvgPool.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/FractionalAvgPoolGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/FractionalAvgPoolGrad.java index 71b1e624c55..eee42886ab1 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/FractionalAvgPoolGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/FractionalAvgPoolGrad.java @@ -41,8 +41,6 @@ * out_backprop to those indices that form the same pooling cell. Therefore, we * just need to know the shape of original input tensor, instead of the whole * tensor. - * - * @param data type for {@code output} output */ @OpMetadata( opType = FractionalAvgPoolGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/FractionalMaxPool.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/FractionalMaxPool.java index d4c2cb5cf15..08bcbd1a63d 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/FractionalMaxPool.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/FractionalMaxPool.java @@ -63,8 +63,6 @@ * *

    For more details on fractional max pooling, see this paper: * Benjamin Graham, Fractional Max-Pooling - * - * @param data type for {@code output} output */ @OpMetadata( opType = FractionalMaxPool.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/FractionalMaxPoolGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/FractionalMaxPoolGrad.java index 432d6bbfdb7..d44e062ccf7 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/FractionalMaxPoolGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/FractionalMaxPoolGrad.java @@ -36,8 +36,6 @@ /** * Computes gradient of the FractionalMaxPool function. - * - * @param data type for {@code output} output */ @OpMetadata( opType = FractionalMaxPoolGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/FusedBatchNorm.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/FusedBatchNorm.java index 41e62263399..f5cede8855e 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/FusedBatchNorm.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/FusedBatchNorm.java @@ -37,10 +37,6 @@ * Batch normalization. * Note that the size of 4D Tensors are defined by either "NHWC" or "NCHW". * The size of 1D Tensors matches the dimension C of the 4D Tensors. - * - * @param data type for {@code y} output - * - * @param data type for {@code batch_mean} output */ @OpMetadata( opType = FusedBatchNorm.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/FusedBatchNormGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/FusedBatchNormGrad.java index efc751554d2..985249a19fe 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/FusedBatchNormGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/FusedBatchNormGrad.java @@ -38,10 +38,6 @@ * Gradient for batch normalization. * Note that the size of 4D Tensors are defined by either "NHWC" or "NCHW". * The size of 1D Tensors matches the dimension C of the 4D Tensors. - * - * @param data type for {@code x_backprop} output - * - * @param data type for {@code scale_backprop} output */ @OpMetadata( opType = FusedBatchNormGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/FusedPadConv2d.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/FusedPadConv2d.java index 1a11cf9c722..336419f92ad 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/FusedPadConv2d.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/FusedPadConv2d.java @@ -48,8 +48,6 @@ * Internally this op uses a single per-graph scratch buffer, which means that it * will block if multiple versions are being run in parallel. This is because this * operator is primarily an optimization to minimize memory usage. - * - * @param data type for {@code output} output */ @OpMetadata( opType = FusedPadConv2d.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/FusedResizeAndPadConv2d.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/FusedResizeAndPadConv2d.java index 69b33a7ffee..8491feba1d7 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/FusedResizeAndPadConv2d.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/FusedResizeAndPadConv2d.java @@ -47,8 +47,6 @@ * Internally this op uses a single per-graph scratch buffer, which means that it * will block if multiple versions are being run in parallel. This is because this * operator is primarily an optimization to minimize memory usage. - * - * @param data type for {@code output} output */ @OpMetadata( opType = FusedResizeAndPadConv2d.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/GRUBlockCell.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/GRUBlockCell.java index 413c9db45cf..0db7843bced 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/GRUBlockCell.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/GRUBlockCell.java @@ -73,8 +73,6 @@ * * h = (1-u) \circ c + u \circ h_prev * - * - * @param data type for {@code r} output */ @OpMetadata( opType = GRUBlockCell.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/GRUBlockCellGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/GRUBlockCellGrad.java index 108aa910427..7379a2790ba 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/GRUBlockCellGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/GRUBlockCellGrad.java @@ -108,8 +108,6 @@ * * d_b_c = sum of d_c_bar along axis = 0 * - * - * @param data type for {@code d_x} output */ @OpMetadata( opType = GRUBlockCellGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/InvGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/InvGrad.java index 37f66b92878..5f178f53e50 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/InvGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/InvGrad.java @@ -37,8 +37,6 @@ * Computes the gradient for the inverse of {@code x} wrt its input. * Specifically, {@code grad = -dy * y*y}, where {@code y = 1/x}, and {@code dy} * is the corresponding input gradient. - * - * @param data type for {@code z} output */ @OpMetadata( opType = InvGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/IsotonicRegression.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/IsotonicRegression.java index 8936770d8b7..ecd511253e8 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/IsotonicRegression.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/IsotonicRegression.java @@ -38,8 +38,6 @@ /** * Solves a batch of isotonic regression problems. - * - * @param data type for {@code output} output */ @OpMetadata( opType = IsotonicRegression.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/L2Loss.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/L2Loss.java index e3b179e440c..9cc952c05cb 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/L2Loss.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/L2Loss.java @@ -39,8 +39,6 @@ *

      * output = sum(t ** 2) / 2
      * 
    - * - * @param data type for {@code output} output */ @OpMetadata( opType = L2Loss.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/LSTMBlockCell.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/LSTMBlockCell.java index 12d4402e70f..5b1e38d3fbe 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/LSTMBlockCell.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/LSTMBlockCell.java @@ -57,8 +57,6 @@ * co = tanh(cs) * h = co .* o * - * - * @param data type for {@code i} output */ @OpMetadata( opType = LSTMBlockCell.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/LSTMBlockCellGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/LSTMBlockCellGrad.java index e22e2241718..931e4bf2381 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/LSTMBlockCellGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/LSTMBlockCellGrad.java @@ -36,8 +36,6 @@ /** * Computes the LSTM cell backward propagation for 1 timestep. * This implementation is to be used in conjunction of LSTMBlockCell. - * - * @param data type for {@code cs_prev_grad} output */ @OpMetadata( opType = LSTMBlockCellGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/LeakyRelu.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/LeakyRelu.java index 022b81f82da..a0f088f9a03 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/LeakyRelu.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/LeakyRelu.java @@ -35,8 +35,6 @@ /** * Computes rectified linear: {@code max(features, features * alpha)}. - * - * @param data type for {@code activations} output */ @OpMetadata( opType = LeakyRelu.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/LocalResponseNormalization.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/LocalResponseNormalization.java index f0bb2b5017b..17c1e5c0d04 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/LocalResponseNormalization.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/LocalResponseNormalization.java @@ -46,8 +46,6 @@ * *

    For details, see Krizhevsky et al., ImageNet classification with deep * convolutional neural networks (NIPS 2012) . - * - * @param data type for {@code output} output */ @OpMetadata( opType = LocalResponseNormalization.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/LocalResponseNormalizationGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/LocalResponseNormalizationGrad.java index 041837b7871..c0b795094aa 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/LocalResponseNormalizationGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/LocalResponseNormalizationGrad.java @@ -35,8 +35,6 @@ /** * Gradients for Local Response Normalization. - * - * @param data type for {@code output} output */ @OpMetadata( opType = LocalResponseNormalizationGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/LogSoftmax.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/LogSoftmax.java index 1f9ee440140..1e19b56c19f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/LogSoftmax.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/LogSoftmax.java @@ -39,8 +39,6 @@ *

      * logsoftmax[i, j] = logits[i, j] - log(sum(exp(logits[i])))
      * 
    - * - * @param data type for {@code logsoftmax} output */ @OpMetadata( opType = LogSoftmax.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPool.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPool.java index 427b3c92bb2..75b432b8ba3 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPool.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPool.java @@ -36,8 +36,6 @@ /** * Performs max pooling on the input. - * - * @param data type for {@code output} output */ @OpMetadata( opType = MaxPool.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPool3d.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPool3d.java index d9cace3d967..d701189d5e1 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPool3d.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPool3d.java @@ -36,8 +36,6 @@ /** * Performs 3D max pooling on the input. - * - * @param data type for {@code output} output */ @OpMetadata( opType = MaxPool3d.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPool3dGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPool3dGrad.java index 6ac95b8a978..932399be80b 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPool3dGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPool3dGrad.java @@ -36,8 +36,6 @@ /** * Computes gradients of 3D max pooling function. - * - * @param data type for {@code output} output */ @OpMetadata( opType = MaxPool3dGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPool3dGradGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPool3dGradGrad.java index 5efa05dec89..74dbc598b35 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPool3dGradGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPool3dGradGrad.java @@ -36,8 +36,6 @@ /** * Computes second-order gradients of the maxpooling function. - * - * @param data type for {@code output} output */ @OpMetadata( opType = MaxPool3dGradGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPoolGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPoolGrad.java index 214b0b0d31c..a329757270c 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPoolGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPoolGrad.java @@ -36,8 +36,6 @@ /** * Computes gradients of the maxpooling function. - * - * @param data type for {@code output} output */ @OpMetadata( opType = MaxPoolGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPoolGradGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPoolGradGrad.java index a33ba6642b8..0b0f0f616b7 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPoolGradGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPoolGradGrad.java @@ -36,8 +36,6 @@ /** * Computes second-order gradients of the maxpooling function. - * - * @param data type for {@code output} output */ @OpMetadata( opType = MaxPoolGradGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPoolGradGradWithArgmax.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPoolGradGradWithArgmax.java index 35f1ffeb6dd..9dedc6014b8 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPoolGradGradWithArgmax.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPoolGradGradWithArgmax.java @@ -36,8 +36,6 @@ /** * Computes second-order gradients of the maxpooling function. - * - * @param data type for {@code output} output */ @OpMetadata( opType = MaxPoolGradGradWithArgmax.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPoolGradWithArgmax.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPoolGradWithArgmax.java index 0edd2ca5adc..60d7e7de94c 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPoolGradWithArgmax.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPoolGradWithArgmax.java @@ -36,8 +36,6 @@ /** * Computes gradients of the maxpooling function. - * - * @param data type for {@code output} output */ @OpMetadata( opType = MaxPoolGradWithArgmax.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPoolWithArgmax.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPoolWithArgmax.java index bcfba861e1e..bd19af1b703 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPoolWithArgmax.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/MaxPoolWithArgmax.java @@ -46,10 +46,6 @@ * even if padding is involved and the mathematically correct answer is outside * (either negative or too large). This is a bug, but fixing it is difficult to do * in a safe backwards compatible way, especially due to flattening. - * - * @param data type for {@code output} output - * - * @param data type for {@code argmax} output */ @OpMetadata( opType = MaxPoolWithArgmax.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/NthElement.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/NthElement.java index 383dbfc3b22..57754316380 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/NthElement.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/NthElement.java @@ -43,8 +43,6 @@ *
      * values.shape = input.shape[:-1]
      * 
    - * - * @param data type for {@code values} output */ @OpMetadata( opType = NthElement.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedAvgPool.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedAvgPool.java index 2e27d649947..8987fcd7d55 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedAvgPool.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedAvgPool.java @@ -37,8 +37,6 @@ /** * Produces the average pool of the input tensor for quantized types. - * - * @param data type for {@code output} output */ @OpMetadata( opType = QuantizedAvgPool.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedBatchNormWithGlobalNormalization.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedBatchNormWithGlobalNormalization.java index 0b9e3b27b55..7f22995509c 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedBatchNormWithGlobalNormalization.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedBatchNormWithGlobalNormalization.java @@ -39,8 +39,6 @@ * Quantized Batch normalization. * This op is deprecated and will be removed in the future. Prefer * {@code tf.nn.batch_normalization}. - * - * @param data type for {@code result} output */ @OpMetadata( opType = QuantizedBatchNormWithGlobalNormalization.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedBiasAdd.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedBiasAdd.java index c95300fa493..744eb1397eb 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedBiasAdd.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedBiasAdd.java @@ -38,8 +38,6 @@ /** * Adds Tensor 'bias' to Tensor 'input' for Quantized types. * Broadcasts the values of bias on dimensions 0..N-2 of 'input'. - * - * @param data type for {@code output} output */ @OpMetadata( opType = QuantizedBiasAdd.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DAndRelu.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DAndRelu.java index 4594e0401cc..9226b7b697e 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DAndRelu.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DAndRelu.java @@ -38,8 +38,6 @@ /** * The QuantizedConv2DAndRelu operation - * - * @param data type for {@code output} output */ @OpMetadata( opType = QuantizedConv2DAndRelu.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DAndReluAndRequantize.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DAndReluAndRequantize.java index 0104cbf9908..f02eba09012 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DAndReluAndRequantize.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DAndReluAndRequantize.java @@ -38,8 +38,6 @@ /** * The QuantizedConv2DAndReluAndRequantize operation - * - * @param data type for {@code output} output */ @OpMetadata( opType = QuantizedConv2DAndReluAndRequantize.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DAndRequantize.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DAndRequantize.java index 5fe5999adab..66344508160 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DAndRequantize.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DAndRequantize.java @@ -38,8 +38,6 @@ /** * The QuantizedConv2DAndRequantize operation - * - * @param data type for {@code output} output */ @OpMetadata( opType = QuantizedConv2DAndRequantize.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DPerChannel.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DPerChannel.java index 134449aba91..bfd108c34d3 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DPerChannel.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DPerChannel.java @@ -38,8 +38,6 @@ /** * Computes QuantizedConv2D per channel. - * - * @param data type for {@code output} output */ @OpMetadata( opType = QuantizedConv2DPerChannel.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DWithBias.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DWithBias.java index 27f5343c6ff..fe5566ac7e9 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DWithBias.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DWithBias.java @@ -38,8 +38,6 @@ /** * The QuantizedConv2DWithBias operation - * - * @param data type for {@code output} output */ @OpMetadata( opType = QuantizedConv2DWithBias.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DWithBiasAndRelu.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DWithBiasAndRelu.java index 61c9bb31b45..ff7d157a846 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DWithBiasAndRelu.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DWithBiasAndRelu.java @@ -38,8 +38,6 @@ /** * The QuantizedConv2DWithBiasAndRelu operation - * - * @param data type for {@code output} output */ @OpMetadata( opType = QuantizedConv2DWithBiasAndRelu.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DWithBiasAndReluAndRequantize.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DWithBiasAndReluAndRequantize.java index 081b8ac3863..b68080cc72c 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DWithBiasAndReluAndRequantize.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DWithBiasAndReluAndRequantize.java @@ -38,8 +38,6 @@ /** * The QuantizedConv2DWithBiasAndReluAndRequantize operation - * - * @param data type for {@code output} output */ @OpMetadata( opType = QuantizedConv2DWithBiasAndReluAndRequantize.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DWithBiasAndRequantize.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DWithBiasAndRequantize.java index 21f4eef7826..5301017e666 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DWithBiasAndRequantize.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DWithBiasAndRequantize.java @@ -38,8 +38,6 @@ /** * The QuantizedConv2DWithBiasAndRequantize operation - * - * @param data type for {@code output} output */ @OpMetadata( opType = QuantizedConv2DWithBiasAndRequantize.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DWithBiasSignedSumAndReluAndRequantize.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DWithBiasSignedSumAndReluAndRequantize.java index afdd8b87219..687e41485d4 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DWithBiasSignedSumAndReluAndRequantize.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DWithBiasSignedSumAndReluAndRequantize.java @@ -38,8 +38,6 @@ /** * The QuantizedConv2DWithBiasSignedSumAndReluAndRequantize operation - * - * @param data type for {@code output} output */ @OpMetadata( opType = QuantizedConv2DWithBiasSignedSumAndReluAndRequantize.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DWithBiasSumAndRelu.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DWithBiasSumAndRelu.java index d92782f88bb..34ceb6e7898 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DWithBiasSumAndRelu.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DWithBiasSumAndRelu.java @@ -38,8 +38,6 @@ /** * The QuantizedConv2DWithBiasSumAndRelu operation - * - * @param data type for {@code output} output */ @OpMetadata( opType = QuantizedConv2DWithBiasSumAndRelu.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DWithBiasSumAndReluAndRequantize.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DWithBiasSumAndReluAndRequantize.java index 0d9c4fab0f6..021873d6885 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DWithBiasSumAndReluAndRequantize.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2DWithBiasSumAndReluAndRequantize.java @@ -38,8 +38,6 @@ /** * The QuantizedConv2DWithBiasSumAndReluAndRequantize operation - * - * @param data type for {@code output} output */ @OpMetadata( opType = QuantizedConv2DWithBiasSumAndReluAndRequantize.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2d.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2d.java index 88482fc869f..77d21ba9794 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2d.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedConv2d.java @@ -42,8 +42,6 @@ * number of the associated minimum, and the highest represents the maximum. * This means that you can only interpret the quantized output in the same way, by * taking the returned minimum and maximum values into account. - * - * @param data type for {@code output} output */ @OpMetadata( opType = QuantizedConv2d.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedDepthwiseConv2D.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedDepthwiseConv2D.java index 19c05799f1f..3281b31698b 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedDepthwiseConv2D.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedDepthwiseConv2D.java @@ -38,8 +38,6 @@ /** * Computes quantized depthwise Conv2D. - * - * @param data type for {@code output} output */ @OpMetadata( opType = QuantizedDepthwiseConv2D.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedDepthwiseConv2DWithBias.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedDepthwiseConv2DWithBias.java index 9414fd9e015..70314ace0b0 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedDepthwiseConv2DWithBias.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedDepthwiseConv2DWithBias.java @@ -38,8 +38,6 @@ /** * Computes quantized depthwise Conv2D with Bias. - * - * @param data type for {@code output} output */ @OpMetadata( opType = QuantizedDepthwiseConv2DWithBias.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedDepthwiseConv2DWithBiasAndRelu.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedDepthwiseConv2DWithBiasAndRelu.java index c8d6a30445b..76b0917f709 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedDepthwiseConv2DWithBiasAndRelu.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedDepthwiseConv2DWithBiasAndRelu.java @@ -38,8 +38,6 @@ /** * Computes quantized depthwise Conv2D with Bias and Relu. - * - * @param data type for {@code output} output */ @OpMetadata( opType = QuantizedDepthwiseConv2DWithBiasAndRelu.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedDepthwiseConv2DWithBiasAndReluAndRequantize.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedDepthwiseConv2DWithBiasAndReluAndRequantize.java index b23311716d2..55dfdecdb39 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedDepthwiseConv2DWithBiasAndReluAndRequantize.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedDepthwiseConv2DWithBiasAndReluAndRequantize.java @@ -38,8 +38,6 @@ /** * Computes quantized depthwise Conv2D with Bias, Relu and Requantize. - * - * @param data type for {@code output} output */ @OpMetadata( opType = QuantizedDepthwiseConv2DWithBiasAndReluAndRequantize.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedInstanceNorm.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedInstanceNorm.java index 54bd27c1705..48aedde6806 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedInstanceNorm.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedInstanceNorm.java @@ -36,8 +36,6 @@ /** * Quantized Instance normalization. - * - * @param data type for {@code y} output */ @OpMetadata( opType = QuantizedInstanceNorm.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedMaxPool.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedMaxPool.java index b1323bb3b42..e57d4e945b4 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedMaxPool.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedMaxPool.java @@ -37,8 +37,6 @@ /** * Produces the max pool of the input tensor for quantized types. - * - * @param data type for {@code output} output */ @OpMetadata( opType = QuantizedMaxPool.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedRelu.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedRelu.java index b80e07346d9..ad55085ab6f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedRelu.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedRelu.java @@ -37,8 +37,6 @@ /** * Computes Quantized Rectified Linear: {@code max(features, 0)} - * - * @param data type for {@code activations} output */ @OpMetadata( opType = QuantizedRelu.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedRelu6.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedRelu6.java index d820e51188a..2b2f21a6b45 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedRelu6.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedRelu6.java @@ -37,8 +37,6 @@ /** * Computes Quantized Rectified Linear 6: {@code min(max(features, 0), 6)} - * - * @param data type for {@code activations} output */ @OpMetadata( opType = QuantizedRelu6.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedReluX.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedReluX.java index 577df61b8dd..41daae389b6 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedReluX.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/QuantizedReluX.java @@ -37,8 +37,6 @@ /** * Computes Quantized Rectified Linear X: {@code min(max(features, 0), max_value)} - * - * @param data type for {@code activations} output */ @OpMetadata( opType = QuantizedReluX.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Relu.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Relu.java index 218fee4f3d2..126eb0c4c56 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Relu.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Relu.java @@ -45,8 +45,6 @@ * * * - * - * @param data type for {@code activations} output */ @OpMetadata( opType = Relu.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Relu6.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Relu6.java index 19de03d7f8e..5500229b21c 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Relu6.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Relu6.java @@ -35,8 +35,6 @@ /** * Computes rectified linear 6: {@code min(max(features, 0), 6)}. - * - * @param data type for {@code activations} output */ @OpMetadata( opType = Relu6.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Relu6Grad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Relu6Grad.java index 48ec9cb7037..9af8b816d87 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Relu6Grad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Relu6Grad.java @@ -35,8 +35,6 @@ /** * Computes rectified linear 6 gradients for a Relu6 operation. - * - * @param data type for {@code backprops} output */ @OpMetadata( opType = Relu6Grad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/ReluGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/ReluGrad.java index 5e7103853f3..b15132dd583 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/ReluGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/ReluGrad.java @@ -35,8 +35,6 @@ /** * Computes rectified linear gradients for a Relu operation. - * - * @param data type for {@code backprops} output */ @OpMetadata( opType = ReluGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Selu.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Selu.java index d382a2f5a75..33d504105ec 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Selu.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Selu.java @@ -40,8 +40,6 @@ * {@code initializer = tf.variance_scaling_initializer(factor=1.0, mode='FAN_IN')}. * For correct dropout, use {@code tf.contrib.nn.alpha_dropout}. *

    See Self-Normalizing Neural Networks - * - * @param data type for {@code activations} output */ @OpMetadata( opType = Selu.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/SeluGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/SeluGrad.java index 7a2e0656275..bd2d2203f69 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/SeluGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/SeluGrad.java @@ -35,8 +35,6 @@ /** * Computes gradients for the scaled exponential linear (Selu) operation. - * - * @param data type for {@code backprops} output */ @OpMetadata( opType = SeluGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Softmax.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Softmax.java index 36ef20f21fd..dd6b9ecb2b5 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Softmax.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Softmax.java @@ -39,8 +39,6 @@ *

      * $$softmax[i, j] = exp(logits[i, j]) / sum_j(exp(logits[i, j]))$$
      * 
    - * - * @param data type for {@code softmax} output */ @OpMetadata( opType = Softmax.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/SoftmaxCrossEntropyWithLogits.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/SoftmaxCrossEntropyWithLogits.java index 9a17188c048..a7836f24051 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/SoftmaxCrossEntropyWithLogits.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/SoftmaxCrossEntropyWithLogits.java @@ -36,8 +36,6 @@ /** * Computes softmax cross entropy cost and gradients to backpropagate. * Inputs are the logits, not probabilities. - * - * @param data type for {@code loss} output */ @OpMetadata( opType = SoftmaxCrossEntropyWithLogits.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Softsign.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Softsign.java index 1345a1ffd11..1144c4c21be 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Softsign.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/Softsign.java @@ -35,8 +35,6 @@ /** * Computes softsign: {@code features / (abs(features) + 1)}. - * - * @param data type for {@code activations} output */ @OpMetadata( opType = Softsign.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/SoftsignGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/SoftsignGrad.java index b16c933ffe0..3ebe407b08e 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/SoftsignGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/SoftsignGrad.java @@ -35,8 +35,6 @@ /** * Computes softsign gradients for a softsign operation. - * - * @param data type for {@code backprops} output */ @OpMetadata( opType = SoftsignGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/SpaceToBatch.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/SpaceToBatch.java index 050a12e7f98..e35f65ee574 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/SpaceToBatch.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/SpaceToBatch.java @@ -100,8 +100,6 @@ * *

    Among others, this operation is useful for reducing atrous convolution into * regular convolution. - * - * @param data type for {@code output} output */ @OpMetadata( opType = SpaceToBatch.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/SpaceToDepth.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/SpaceToDepth.java index 18449c4627c..aaaddf55663 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/SpaceToDepth.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/SpaceToDepth.java @@ -103,8 +103,6 @@ * [[9, 10, 11, 12], * [13, 14, 15, 16]]]] * - * - * @param data type for {@code output} output */ @OpMetadata( opType = SpaceToDepth.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/SparseSoftmaxCrossEntropyWithLogits.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/SparseSoftmaxCrossEntropyWithLogits.java index 043587de9b5..1b7c99a694e 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/SparseSoftmaxCrossEntropyWithLogits.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/SparseSoftmaxCrossEntropyWithLogits.java @@ -40,8 +40,6 @@ * of features. This label is considered to have probability 1.0 for the * given row. *

    Inputs are the logits, not probabilities. - * - * @param data type for {@code loss} output */ @OpMetadata( opType = SparseSoftmaxCrossEntropyWithLogits.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/TopK.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/TopK.java index b752c40666b..189f0434054 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/TopK.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/TopK.java @@ -46,10 +46,6 @@ * values.shape = indices.shape = input.shape[:-1] + [k] * *

    If two elements are equal, the lower-index element appears first. - * - * @param data type for {@code values} output - * - * @param data type for {@code indices} output */ @OpMetadata( opType = TopK.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/UniformQuantizedConvolution.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/UniformQuantizedConvolution.java index 9b4715c3a21..124c2b062f0 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/UniformQuantizedConvolution.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/UniformQuantizedConvolution.java @@ -55,8 +55,6 @@ * *

    {@code output} is also quantized, using the same formula. * If {@code rhs} is per-tensor quantized, {@code output} must be also per-tensor quantized. - * - * @param data type for {@code output} output */ @OpMetadata( opType = UniformQuantizedConvolution.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/UniformQuantizedConvolutionHybrid.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/UniformQuantizedConvolutionHybrid.java index 02b51c0dfe4..8510272759e 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/UniformQuantizedConvolutionHybrid.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/nn/UniformQuantizedConvolutionHybrid.java @@ -55,8 +55,6 @@ * *

    {@code rhs} must be quantized Tensor, where its data value is quantized using the formula: * quantized_data = clip(original_data / scale + zero_point, quantization_min_val, quantization_max_val). - * - * @param data type for {@code output} output */ @OpMetadata( opType = UniformQuantizedConvolutionHybrid.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/Dequantize.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/Dequantize.java index 743b6c81d93..a062ee1db29 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/Dequantize.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/Dequantize.java @@ -80,8 +80,6 @@ * : std::max(min_range / min_expected_T, * max_range / max_expected_T); * - * - * @param data type for {@code output} output */ @OpMetadata( opType = Dequantize.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/FakeQuantWithMinMaxArgsGradient.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/FakeQuantWithMinMaxArgsGradient.java index 4f3b11ce977..87007c73d6b 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/FakeQuantWithMinMaxArgsGradient.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/FakeQuantWithMinMaxArgsGradient.java @@ -136,6 +136,38 @@ public static Options narrowRange(Boolean narrowRange) { * Gets backprops. * Backpropagated gradients below the FakeQuantWithMinMaxArgs operation: * {@code gradients * (inputs >= min && inputs <= max)}. + *

    +   * import tensorflow as tf
    +   *
    +   * # Define some sample data
    +   * gradients = tf.random.uniform((2, 3), minval=-5.0, maxval=5.0, dtype=tf.float32)
    +   * inputs = tf.random.uniform((2, 3), minval=-10.0, maxval=10.0, dtype=tf.float32)
    +   *
    +   * # Define quantization parameters (adjust as needed)
    +   * min_val = -2.0
    +   * max_val = 8.0
    +   * num_bits = 4  # Number of bits for quantization
    +   *
    +   * # Calculate gradients for fake quantization with specified parameters
    +   * output_gradients = tf.quantization.fake_quant_with_min_max_args_gradient(
    +   *     gradients=gradients, inputs=inputs, min=min_val, max=max_val, num_bits=num_bits, narrow_range = False, name=None
    +   * )
    +   *
    +   * # Print the original gradients and the gradients after the fake-quant operation
    +   * print("Original Gradients:")
    +   * print(gradients)
    +   * print("\nGradients after Fake-Quantization:")
    +   * print(output_gradients)
    +   *
    +   * 
    + *

    #Original Gradients: + * #tf.Tensor( + * #[[ 1.242547 3.217492 3.568469 ] + * #[-0.55371046 0.23130894 2.608243 ]], shape=(2, 3), dtype=float32) + *

    #Gradients after Fake-Quantization: + * #tf.Tensor( + * #[[ 0. 3.217492 3.568469 ] + * [-0.55371046 0.23130894 2.608243 ]], shape=(2, 3), dtype=float32)
    * @return backprops. */ public Output backprops() { diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/FakeQuantWithMinMaxVars.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/FakeQuantWithMinMaxVars.java index faa38bb0585..e78b22ca6d5 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/FakeQuantWithMinMaxVars.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/FakeQuantWithMinMaxVars.java @@ -57,6 +57,28 @@ * *

    This operation has a gradient and thus allows for training {@code min} and {@code max} * values. + *

    + *
    + *
    + *

    constant_input = tf.constant([[1.2, -0.3, 0.7], [2.1, 0.5, -1.0]], dtype=tf.float32) + *

    min_val = -0.5 + * max_val = 0.8 + * num_bits = 8 + * narrow_range = False #False:for the quantization range [0; 2^num_bits - 1] + *

    quantized_data = tf.quantization.fake_quant_with_min_max_vars( + * ... inputs=constant_input, min=min_val, max=max_val, num_bits=num_bits, narrow_range=narrow_range + * ... ) + *

    print("Input:\n", constant_input.numpy()) + * Input: + * [[ 1.2 -0.3 0.7] + * [ 2.1 0.5 -1. ]] + * print("Output:\n", quantized_data.numpy()) + * Output: + * [[ 0.8003921 -0.3007843 0.6984313] + * [ 0.8003921 0.4996078 -0.4996078]] + *

    + *
    + *
    */ @OpMetadata( opType = FakeQuantWithMinMaxVars.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/Quantize.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/Quantize.java index a6a5df07a8a..ed34d301ec7 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/Quantize.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/Quantize.java @@ -128,8 +128,6 @@ *

    Ensures the minimum quantization range is at least this value. * The legacy default value for this is 0.01, but it is strongly suggested to * set it to 0 for new uses. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Quantize.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/QuantizeAndDequantize.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/QuantizeAndDequantize.java index b6552257828..eeb9f05536c 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/QuantizeAndDequantize.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/QuantizeAndDequantize.java @@ -38,8 +38,6 @@ * Quantizes then dequantizes a tensor. * This is almost identical to QuantizeAndDequantizeV2, except that num_bits is a * tensor, so its value can change during training. - * - * @param data type for {@code output} output */ @OpMetadata( opType = QuantizeAndDequantize.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/QuantizeAndDequantizeV3.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/QuantizeAndDequantizeV3.java index a715ecdb8e5..e1de6cd2ab7 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/QuantizeAndDequantizeV3.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/QuantizeAndDequantizeV3.java @@ -38,8 +38,6 @@ * Quantizes then dequantizes a tensor. * This is almost identical to QuantizeAndDequantizeV2, except that num_bits is a * tensor, so its value can change during training. - * - * @param data type for {@code output} output */ @OpMetadata( opType = QuantizeAndDequantizeV3.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/QuantizeAndDequantizeV4.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/QuantizeAndDequantizeV4.java index 75b47a7f0f9..7de2e59c64b 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/QuantizeAndDequantizeV4.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/QuantizeAndDequantizeV4.java @@ -37,8 +37,6 @@ * Quantizes then dequantizes a tensor. * This is almost identical to QuantizeAndDequantizeV2, except that it returns a * gradient of 1 for inputs that are within the quantization range, or 0 otherwise. - * - * @param data type for {@code output} output */ @OpMetadata( opType = QuantizeAndDequantizeV4.OP_NAME, @@ -114,7 +112,7 @@ public static QuantizeAndDequantizeV4 create(Scope scope, * Sets the signedInput option. * * @param signedInput Whether the quantization is signed or unsigned. (actually this parameter should - * have been called {@code signed_output}</b>) + * have been called {@code signed_output}) * @return this Options instance. */ public static Options signedInput(Boolean signedInput) { @@ -218,7 +216,7 @@ private Options() { * Sets the signedInput option. * * @param signedInput Whether the quantization is signed or unsigned. (actually this parameter should - * have been called {@code signed_output}</b>) + * have been called {@code signed_output}) * @return this Options instance. */ public Options signedInput(Boolean signedInput) { @@ -317,7 +315,7 @@ public static class Inputs extends RawOpInputs{@code signed_output}</b>) + * have been called {@code signed_output}) */ public final boolean signedInput; diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/QuantizeAndDequantizeV4Grad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/QuantizeAndDequantizeV4Grad.java index d2d9d9e6035..65cf77c43ca 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/QuantizeAndDequantizeV4Grad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/QuantizeAndDequantizeV4Grad.java @@ -37,8 +37,6 @@ * Returns the gradient of {@code QuantizeAndDequantizeV4}. * Returns a gradient of 1 for inputs that are within the quantization range, * or 0 otherwise. - * - * @param data type for {@code input_backprop} output */ @OpMetadata( opType = QuantizeAndDequantizeV4Grad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/QuantizeDownAndShrinkRange.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/QuantizeDownAndShrinkRange.java index d8aee82efb2..77aaa257758 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/QuantizeDownAndShrinkRange.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/QuantizeDownAndShrinkRange.java @@ -56,8 +56,6 @@ * input values that only uses a small fraction of the possible range. By feeding * that output into this operator, we can reduce it from 32 bits down to 8 with * minimal loss of accuracy. - * - * @param data type for {@code output} output */ @OpMetadata( opType = QuantizeDownAndShrinkRange.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/QuantizedConcat.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/QuantizedConcat.java index cae65990d35..a52e49b8080 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/QuantizedConcat.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/QuantizedConcat.java @@ -38,8 +38,6 @@ /** * Concatenates quantized tensors along one dimension. - * - * @param data type for {@code output} output */ @OpMetadata( opType = QuantizedConcat.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/QuantizedMatMulWithBiasAndDequantize.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/QuantizedMatMulWithBiasAndDequantize.java index 69827ccd019..c03a82caf5c 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/QuantizedMatMulWithBiasAndDequantize.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/QuantizedMatMulWithBiasAndDequantize.java @@ -37,8 +37,6 @@ /** * The QuantizedMatMulWithBiasAndDequantize operation - * - * @param data type for {@code out} output */ @OpMetadata( opType = QuantizedMatMulWithBiasAndDequantize.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/QuantizedMatMulWithBiasAndRequantize.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/QuantizedMatMulWithBiasAndRequantize.java index cd48b07ac48..b848d068a15 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/QuantizedMatMulWithBiasAndRequantize.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/QuantizedMatMulWithBiasAndRequantize.java @@ -37,8 +37,6 @@ /** * The QuantizedMatMulWithBiasAndRequantize operation - * - * @param data type for {@code out} output */ @OpMetadata( opType = QuantizedMatMulWithBiasAndRequantize.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/Requantize.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/Requantize.java index 48bfa78ab74..0ebd2ce0e3a 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/Requantize.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/Requantize.java @@ -43,8 +43,6 @@ * interpretation of the {@code input} data. For example, if {@code input_min} is -1.0f and * {@code input_max} is 1.0f, and we are dealing with {@code quint16} quantized data, then a 0 * value in the 16-bit data should be interpreted as -1.0f, and a 65535 means 1.0f. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Requantize.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/UniformDequantize.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/UniformDequantize.java index 97dad1321da..8f5d44bf663 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/UniformDequantize.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/UniformDequantize.java @@ -40,8 +40,6 @@ * Perform dequantization on the quantized Tensor {@code input}. * Given quantized {@code input} which was quantized using {@code scales} and {@code zero_points}, performs dequantization using the formula: * dequantized_data = (quantized_data - zero_point) * scale. - * - * @param data type for {@code output} output */ @OpMetadata( opType = UniformDequantize.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/UniformQuantize.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/UniformQuantize.java index 43fed90b7cc..390ceb83d8a 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/UniformQuantize.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/UniformQuantize.java @@ -40,8 +40,6 @@ * Perform quantization on Tensor {@code input}. * Given {@code input}, {@code scales} and {@code zero_points}, performs quantization using the formula: * quantized_data = floor(input_data * (1.0f / scale) + 0.5f) + zero_point - * - * @param data type for {@code output} output */ @OpMetadata( opType = UniformQuantize.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/UniformQuantizedDot.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/UniformQuantizedDot.java index 16768a99b22..eff33c22ce7 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/UniformQuantizedDot.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/UniformQuantizedDot.java @@ -44,8 +44,6 @@ * quantized_data = clip(original_data / scale + zero_point, quantization_min_val, quantization_max_val). * {@code output} is also quantized, using the same formula. * If {@code rhs} is per-tensor quantized, {@code output} must be also per-tensor quantized. - * - * @param data type for {@code output} output */ @OpMetadata( opType = UniformQuantizedDot.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/UniformQuantizedDotHybrid.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/UniformQuantizedDotHybrid.java index ed8c67f9a53..1f30f7a1a4c 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/UniformQuantizedDotHybrid.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/UniformQuantizedDotHybrid.java @@ -43,8 +43,6 @@ * {@code lhs} and {@code rhs} must be 2D Tensors and the lhs.dim_size(1) must match rhs.dim_size(0). * {@code rhs} must be quantized Tensor, where its data value is quantized using the formula: * quantized_data = clip(original_data / scale + zero_point, quantization_min_val, quantization_max_val). - * - * @param data type for {@code output} output */ @OpMetadata( opType = UniformQuantizedDotHybrid.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/UniformRequantize.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/UniformRequantize.java index 85f81e8f202..eb4c511b567 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/UniformRequantize.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/quantization/UniformRequantize.java @@ -52,8 +52,6 @@ *

  • per-axis -> per-axis where input_quantization_axis equals output_quantization_axis. * i.e. At least one among input_quantization_axis and output_quantization_axis must be -1, or two must be equal.
  • * - * - * @param data type for {@code output} output */ @OpMetadata( opType = UniformRequantize.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedBincount.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedBincount.java index 2607b8e0fcf..0aadded3990 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedBincount.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedBincount.java @@ -42,8 +42,6 @@ * the value in {@code weights} at each index where the corresponding value in {@code arr} is * {@code i}. *

    Values in {@code arr} outside of the range [0, size) are ignored. - * - * @param data type for {@code output} output */ @OpMetadata( opType = RaggedBincount.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedCountSparseOutput.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedCountSparseOutput.java index 1e654d1665b..720919e6873 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedCountSparseOutput.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedCountSparseOutput.java @@ -37,8 +37,6 @@ /** * Performs sparse-output bin counting for a ragged tensor input. * Counts the number of times each value occurs in the input. - * - * @param data type for {@code output_values} output */ @OpMetadata( opType = RaggedCountSparseOutput.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedCross.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedCross.java index 1d5cc361a5f..3b356804b4f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedCross.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedCross.java @@ -39,10 +39,6 @@ /** * Generates a feature cross from a list of tensors, and returns it as a * RaggedTensor. See {@code tf.ragged.cross} for more details. - * - * @param data type for {@code output_values} output - * - * @param data type for {@code output_row_splits} output */ @OpMetadata( opType = RaggedCross.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedFillEmptyRows.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedFillEmptyRows.java index 5f1b9cf66ec..d8414fd1ae3 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedFillEmptyRows.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedFillEmptyRows.java @@ -37,8 +37,6 @@ /** * The RaggedFillEmptyRows operation - * - * @param data type for {@code output_values} output */ @OpMetadata( opType = RaggedFillEmptyRows.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedFillEmptyRowsGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedFillEmptyRowsGrad.java index 9ea15d1320a..314e4a689af 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedFillEmptyRowsGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedFillEmptyRowsGrad.java @@ -36,8 +36,6 @@ /** * The RaggedFillEmptyRowsGrad operation - * - * @param data type for {@code d_values} output */ @OpMetadata( opType = RaggedFillEmptyRowsGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedGather.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedGather.java index 059c102f6ed..3c71b9987c4 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedGather.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedGather.java @@ -56,10 +56,6 @@ * *

    (Note: This c++ op is used to implement the higher-level python * {@code tf.ragged.gather} op, which also supports ragged indices.) - * - * @param data type for {@code output_nested_splits} output - * - * @param data type for {@code output_dense_values} output */ @OpMetadata( opType = RaggedGather.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedRange.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedRange.java index 52d8d2d66b9..39a6487398e 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedRange.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedRange.java @@ -50,10 +50,6 @@ *

    The input tensors {@code starts}, {@code limits}, and {@code deltas} may be scalars or vectors. * The vector inputs must all have the same size. Scalar inputs are broadcast * to match the size of the vector inputs. - * - * @param data type for {@code rt_nested_splits} output - * - * @param data type for {@code rt_dense_values} output */ @OpMetadata( opType = RaggedRange.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedTensorFromVariant.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedTensorFromVariant.java index 9223acdcd39..5e9e6cae9a7 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedTensorFromVariant.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedTensorFromVariant.java @@ -50,10 +50,6 @@ * values of the decoded {@code RaggedTensor}. If {@code input_ragged_rank} is -1, then it is * inferred as {@code output_ragged_rank} - {@code rank(encoded_ragged)}. See * {@code RaggedTensorToVariant} for the corresponding encoding logic. - * - * @param data type for {@code output_nested_splits} output - * - * @param data type for {@code output_dense_values} output */ @OpMetadata( opType = RaggedTensorFromVariant.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedTensorToSparse.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedTensorToSparse.java index 510cab39924..e765d995332 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedTensorToSparse.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedTensorToSparse.java @@ -41,8 +41,6 @@ * input=ragged.from_nested_row_splits(rt_dense_values, rt_nested_splits) * output=SparseTensor(indices=sparse_indices, values=sparse_values, * dense_shape=sparse_dense_shape) - * - * @param data type for {@code sparse_values} output */ @OpMetadata( opType = RaggedTensorToSparse.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedTensorToTensor.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedTensorToTensor.java index 127c85e9f72..1bbb93a9327 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedTensorToTensor.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedTensorToTensor.java @@ -54,8 +54,6 @@ *

  • "FIRST_DIM_SIZE": if value_rowids is used for the first dimension, then it * is preceded by "FIRST_DIM_SIZE".
  • * - * - * @param data type for {@code result} output */ @OpMetadata( opType = RaggedTensorToTensor.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedTensorToVariantGradient.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedTensorToVariantGradient.java index d8e57336a0e..ca254cd1cf5 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedTensorToVariantGradient.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/ragged/RaggedTensorToVariantGradient.java @@ -42,8 +42,6 @@ * op, given the variant-encoded ragged gradients of the outputs, along with * the outer row-splits and the shape of the dense-values that were provided as * inputs to the RaggedTensorToVariant op. - * - * @param data type for {@code dense_values_grad} output */ @OpMetadata( opType = RaggedTensorToVariantGradient.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/Multinomial.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/Multinomial.java index 6412651e6ac..a213609fca6 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/Multinomial.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/Multinomial.java @@ -38,8 +38,6 @@ /** * Draws samples from a multinomial distribution. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Multinomial.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/NonDeterministicInts.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/NonDeterministicInts.java index 6008cd03718..83f81ee6c51 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/NonDeterministicInts.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/NonDeterministicInts.java @@ -38,8 +38,6 @@ /** * Non-deterministically generates some integers. * This op may use some OS-provided source of non-determinism (e.g. an RNG), so each execution will give different results. - * - * @param data type for {@code output} output */ @OpMetadata( opType = NonDeterministicInts.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/ParameterizedTruncatedNormal.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/ParameterizedTruncatedNormal.java index e2a12f2a3c9..4bc87b4da51 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/ParameterizedTruncatedNormal.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/ParameterizedTruncatedNormal.java @@ -37,8 +37,6 @@ * Outputs random values from a normal distribution. The parameters may each be a * scalar which applies to the entire output, or a vector of length shape[0] which * stores the parameters for each batch. - * - * @param data type for {@code output} output */ @OpMetadata( opType = ParameterizedTruncatedNormal.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/RandomGamma.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/RandomGamma.java index 5558b534e66..cc1a0ab9ba6 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/RandomGamma.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/RandomGamma.java @@ -38,8 +38,6 @@ * This op uses the algorithm by Marsaglia et al. to acquire samples via * transformation-rejection from pairs of uniform and normal random variables. * See http://dl.acm.org/citation.cfm?id=358414 - * - * @param data type for {@code output} output */ @OpMetadata( opType = RandomGamma.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/RandomGammaGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/RandomGammaGrad.java index 7baaab08ee4..4ab62242717 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/RandomGammaGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/RandomGammaGrad.java @@ -35,8 +35,6 @@ /** * Computes the derivative of a Gamma random sample w.r.t. {@code alpha}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = RandomGammaGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/RandomPoisson.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/RandomPoisson.java index d26081bd288..3e5fc40fc2f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/RandomPoisson.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/RandomPoisson.java @@ -45,8 +45,6 @@ * random variables. * See Donald E. Knuth (1969). Seminumerical Algorithms. The Art of Computer * Programming, Volume 2. Addison Wesley - * - * @param data type for {@code output} output */ @OpMetadata( opType = RandomPoisson.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/RandomShuffle.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/RandomShuffle.java index 8c52e218fc8..517900e7df1 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/RandomShuffle.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/RandomShuffle.java @@ -43,8 +43,6 @@ * [3, 4], ==> [1, 2], * [5, 6]] [3, 4]] * - * - * @param data type for {@code output} output */ @OpMetadata( opType = RandomShuffle.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/RandomStandardNormal.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/RandomStandardNormal.java index 3addc74b9bb..322fe10883c 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/RandomStandardNormal.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/RandomStandardNormal.java @@ -37,8 +37,6 @@ /** * Outputs random values from a normal distribution. * The generated values will have mean 0 and standard deviation 1. - * - * @param data type for {@code output} output */ @OpMetadata( opType = RandomStandardNormal.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/RandomUniform.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/RandomUniform.java index 74487b121aa..5940994392c 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/RandomUniform.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/RandomUniform.java @@ -38,8 +38,6 @@ * Outputs random values from a uniform distribution. * The generated values follow a uniform distribution in the range {@code [0, 1)}. The * lower bound 0 is included in the range, while the upper bound 1 is excluded. - * - * @param data type for {@code output} output */ @OpMetadata( opType = RandomUniform.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/RandomUniformInt.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/RandomUniformInt.java index 243fd44c671..6eba6a6c8b8 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/RandomUniformInt.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/RandomUniformInt.java @@ -41,8 +41,6 @@ *

    The random integers are slightly biased unless {@code maxval - minval} is an exact * power of two. The bias is small for values of {@code maxval - minval} significantly * smaller than the range of the output (either {@code 2^32} or {@code 2^64}). - * - * @param data type for {@code output} output */ @OpMetadata( opType = RandomUniformInt.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatefulRandomBinomial.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatefulRandomBinomial.java index fc03e7feddb..67bc6bf1167 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatefulRandomBinomial.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatefulRandomBinomial.java @@ -38,8 +38,6 @@ /** * The StatefulRandomBinomial operation - * - * @param data type for {@code output} output */ @OpMetadata( opType = StatefulRandomBinomial.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatefulStandardNormal.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatefulStandardNormal.java index 8330a9f4b49..ff905308114 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatefulStandardNormal.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatefulStandardNormal.java @@ -39,8 +39,6 @@ /** * Outputs random values from a normal distribution. * The generated values will have mean 0 and standard deviation 1. - * - * @param data type for {@code output} output */ @OpMetadata( opType = StatefulStandardNormal.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatefulTruncatedNormal.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatefulTruncatedNormal.java index e623baabf5c..409dff36de6 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatefulTruncatedNormal.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatefulTruncatedNormal.java @@ -41,8 +41,6 @@ * The generated values follow a normal distribution with mean 0 and standard * deviation 1, except that values whose magnitude is more than 2 standard * deviations from the mean are dropped and re-picked. - * - * @param data type for {@code output} output */ @OpMetadata( opType = StatefulTruncatedNormal.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatefulUniform.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatefulUniform.java index a0e85b0458f..65f86463b06 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatefulUniform.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatefulUniform.java @@ -40,8 +40,6 @@ * Outputs random values from a uniform distribution. * The generated values follow a uniform distribution in the range {@code [0, 1)}. The * lower bound 0 is included in the range, while the upper bound 1 is excluded. - * - * @param data type for {@code output} output */ @OpMetadata( opType = StatefulUniform.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatefulUniformFullInt.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatefulUniformFullInt.java index a43b26418ea..80f425ff575 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatefulUniformFullInt.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatefulUniformFullInt.java @@ -38,8 +38,6 @@ /** * Outputs random integers from a uniform distribution. * The generated values are uniform integers covering the whole range of {@code dtype}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = StatefulUniformFullInt.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatefulUniformInt.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatefulUniformInt.java index 154f3bd2841..d2854aea992 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatefulUniformInt.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatefulUniformInt.java @@ -42,8 +42,6 @@ *

    The random integers are slightly biased unless {@code maxval - minval} is an exact * power of two. The bias is small for values of {@code maxval - minval} significantly * smaller than the range of the output (either {@code 2^32} or {@code 2^64}). - * - * @param data type for {@code output} output */ @OpMetadata( opType = StatefulUniformInt.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessMultinomial.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessMultinomial.java index 1c306047fd5..45a902b2da8 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessMultinomial.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessMultinomial.java @@ -38,8 +38,6 @@ /** * Draws samples from a multinomial distribution. - * - * @param data type for {@code output} output */ @OpMetadata( opType = StatelessMultinomial.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessParameterizedTruncatedNormal.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessParameterizedTruncatedNormal.java index b10e961aab2..64f85682701 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessParameterizedTruncatedNormal.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessParameterizedTruncatedNormal.java @@ -35,8 +35,6 @@ /** * The StatelessParameterizedTruncatedNormal operation - * - * @param data type for {@code output} output */ @OpMetadata( opType = StatelessParameterizedTruncatedNormal.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomBinomial.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomBinomial.java index 71a3cb24cf9..ebd295592eb 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomBinomial.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomBinomial.java @@ -39,8 +39,6 @@ * Outputs deterministic pseudorandom random numbers from a binomial distribution. * Outputs random values from a binomial distribution. *

    The outputs are a deterministic function of {@code shape}, {@code seed}, {@code counts}, and {@code probs}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = StatelessRandomBinomial.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomGamma.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomGamma.java index e57dfcf90f6..69bd0d03ddd 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomGamma.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomGamma.java @@ -39,8 +39,6 @@ * Outputs deterministic pseudorandom random numbers from a gamma distribution. * Outputs random values from a gamma distribution. *

    The outputs are a deterministic function of the inputs. - * - * @param data type for {@code output} output */ @OpMetadata( opType = StatelessRandomGamma.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomNormal.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomNormal.java index 7081e980beb..bf0fa718d0e 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomNormal.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomNormal.java @@ -39,8 +39,6 @@ * Outputs deterministic pseudorandom values from a normal distribution. * The generated values will have mean 0 and standard deviation 1. *

    The outputs are a deterministic function of {@code shape} and {@code seed}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = StatelessRandomNormal.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomNormalV2.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomNormalV2.java index b1e9dcb4439..ef4f9aafee6 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomNormalV2.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomNormalV2.java @@ -41,8 +41,6 @@ * Outputs deterministic pseudorandom values from a normal distribution. * The generated values will have mean 0 and standard deviation 1. *

    The outputs are a deterministic function of {@code shape}, {@code key}, {@code counter} and {@code alg}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = StatelessRandomNormalV2.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomPoisson.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomPoisson.java index 3a55731c32d..c617e49f652 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomPoisson.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomPoisson.java @@ -38,8 +38,6 @@ * Outputs deterministic pseudorandom random numbers from a Poisson distribution. * Outputs random values from a Poisson distribution. *

    The outputs are a deterministic function of {@code shape}, {@code seed}, and {@code lam}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = StatelessRandomPoisson.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomUniform.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomUniform.java index 6e18ceffb6f..86c24f1e171 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomUniform.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomUniform.java @@ -40,8 +40,6 @@ * The generated values follow a uniform distribution in the range {@code [0, 1)}. The * lower bound 0 is included in the range, while the upper bound 1 is excluded. *

    The outputs are a deterministic function of {@code shape} and {@code seed}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = StatelessRandomUniform.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomUniformFullInt.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomUniformFullInt.java index ef2bf5e7884..41e703d9ddf 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomUniformFullInt.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomUniformFullInt.java @@ -38,8 +38,6 @@ * Outputs deterministic pseudorandom random integers from a uniform distribution. * The generated values are uniform integers covering the whole range of {@code dtype}. *

    The outputs are a deterministic function of {@code shape} and {@code seed}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = StatelessRandomUniformFullInt.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomUniformFullIntV2.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomUniformFullIntV2.java index 50fb67d6fe1..7a910d86feb 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomUniformFullIntV2.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomUniformFullIntV2.java @@ -40,8 +40,6 @@ * Outputs deterministic pseudorandom random integers from a uniform distribution. * The generated values are uniform integers covering the whole range of {@code dtype}. *

    The outputs are a deterministic function of {@code shape}, {@code key}, {@code counter} and {@code alg}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = StatelessRandomUniformFullIntV2.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomUniformInt.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomUniformInt.java index 8bce8bc129e..5c792f75e51 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomUniformInt.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomUniformInt.java @@ -37,8 +37,6 @@ * Outputs deterministic pseudorandom random integers from a uniform distribution. * The generated values follow a uniform distribution in the range {@code [minval, maxval)}. *

    The outputs are a deterministic function of {@code shape}, {@code seed}, {@code minval}, and {@code maxval}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = StatelessRandomUniformInt.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomUniformIntV2.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomUniformIntV2.java index aa3e3d0de83..ae538d14050 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomUniformIntV2.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomUniformIntV2.java @@ -39,8 +39,6 @@ * Outputs deterministic pseudorandom random integers from a uniform distribution. * The generated values follow a uniform distribution in the range {@code [minval, maxval)}. *

    The outputs are a deterministic function of {@code shape}, {@code key}, {@code counter}, {@code alg}, {@code minval} and {@code maxval}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = StatelessRandomUniformIntV2.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomUniformV2.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomUniformV2.java index 8b0e106cb95..86bb5202639 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomUniformV2.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessRandomUniformV2.java @@ -42,8 +42,6 @@ * The generated values follow a uniform distribution in the range {@code [0, 1)}. The * lower bound 0 is included in the range, while the upper bound 1 is excluded. *

    The outputs are a deterministic function of {@code shape}, {@code key}, {@code counter} and {@code alg}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = StatelessRandomUniformV2.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessTruncatedNormal.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessTruncatedNormal.java index 2ddedee0436..83c4ebdab9c 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessTruncatedNormal.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessTruncatedNormal.java @@ -41,8 +41,6 @@ * deviation 1, except that values whose magnitude is more than 2 standard * deviations from the mean are dropped and re-picked. *

    The outputs are a deterministic function of {@code shape} and {@code seed}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = StatelessTruncatedNormal.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessTruncatedNormalV2.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessTruncatedNormalV2.java index 6505cd06561..ae8b00ae1df 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessTruncatedNormalV2.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/StatelessTruncatedNormalV2.java @@ -43,8 +43,6 @@ * deviation 1, except that values whose magnitude is more than 2 standard * deviations from the mean are dropped and re-picked. *

    The outputs are a deterministic function of {@code shape}, {@code key}, {@code counter} and {@code alg}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = StatelessTruncatedNormalV2.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/TruncatedNormal.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/TruncatedNormal.java index ee3e12c25e3..36fbe8a2a05 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/TruncatedNormal.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/TruncatedNormal.java @@ -39,8 +39,6 @@ * The generated values follow a normal distribution with mean 0 and standard * deviation 1, except that values whose magnitude is more than 2 standard * deviations from the mean are dropped and re-picked. - * - * @param data type for {@code output} output */ @OpMetadata( opType = TruncatedNormal.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/experimental/StatelessShuffle.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/experimental/StatelessShuffle.java index 5100d0ef8c6..dc17294084b 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/experimental/StatelessShuffle.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/random/experimental/StatelessShuffle.java @@ -45,8 +45,6 @@ * [5, 6]] [3, 4]] * *

    The outputs are a deterministic function of {@code value}, {@code key}, {@code counter} and {@code alg}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = StatelessShuffle.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Fft.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Fft.java index 42ef1e6bdf9..220c72d1723 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Fft.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Fft.java @@ -37,8 +37,6 @@ * Fast Fourier transform. * Computes the 1-dimensional discrete Fourier transform over the inner-most * dimension of {@code input}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Fft.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Fft2d.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Fft2d.java index 118d2db63e0..4f78086027b 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Fft2d.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Fft2d.java @@ -37,8 +37,6 @@ * 2D fast Fourier transform. * Computes the 2-dimensional discrete Fourier transform over the inner-most * 2 dimensions of {@code input}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Fft2d.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Fft3d.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Fft3d.java index 6195de0eae8..7f5478e228a 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Fft3d.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Fft3d.java @@ -37,8 +37,6 @@ * 3D fast Fourier transform. * Computes the 3-dimensional discrete Fourier transform over the inner-most 3 * dimensions of {@code input}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Fft3d.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/FftNd.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/FftNd.java index b7f4268150c..8f530229379 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/FftNd.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/FftNd.java @@ -44,8 +44,6 @@ * is not given, the default shape(input) is used. *

    Axes mean the dimensions to perform the transform on. Default is to perform on * all axes. - * - * @param data type for {@code output} output */ @OpMetadata( opType = FftNd.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Ifft.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Ifft.java index 3a313a6f23e..6b1f6fa6d8c 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Ifft.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Ifft.java @@ -37,8 +37,6 @@ * Inverse fast Fourier transform. * Computes the inverse 1-dimensional discrete Fourier transform over the * inner-most dimension of {@code input}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Ifft.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Ifft2d.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Ifft2d.java index ad0902bf3a1..2c4c19b2ead 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Ifft2d.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Ifft2d.java @@ -37,8 +37,6 @@ * Inverse 2D fast Fourier transform. * Computes the inverse 2-dimensional discrete Fourier transform over the * inner-most 2 dimensions of {@code input}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Ifft2d.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Ifft3d.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Ifft3d.java index 82251ed232c..efcb06fafcd 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Ifft3d.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Ifft3d.java @@ -37,8 +37,6 @@ * Inverse 3D fast Fourier transform. * Computes the inverse 3-dimensional discrete Fourier transform over the * inner-most 3 dimensions of {@code input}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Ifft3d.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/IfftNd.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/IfftNd.java index 82855d2bab4..181e3756015 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/IfftNd.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/IfftNd.java @@ -44,8 +44,6 @@ * is not given, the default shape(input) is used. *

    Axes mean the dimensions to perform the transform on. Default is to perform on * all axes. - * - * @param data type for {@code output} output */ @OpMetadata( opType = IfftNd.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Irfft.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Irfft.java index ecf2703b6e8..50f6daef0a0 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Irfft.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Irfft.java @@ -50,8 +50,6 @@ *

    Along the axis {@code signal.Irfft} is computed on, if {@code fft_length / 2 + 1} is smaller * than the corresponding dimension of {@code input}, the dimension is cropped. If it is * larger, the dimension is padded with zeros. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Irfft.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Irfft2d.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Irfft2d.java index 8a448fd2a52..01214bfec41 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Irfft2d.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Irfft2d.java @@ -51,8 +51,6 @@ * {@code fft_length / 2 + 1} for the inner-most dimension) is smaller than the * corresponding dimension of {@code input}, the dimension is cropped. If it is larger, * the dimension is padded with zeros. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Irfft2d.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Irfft3d.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Irfft3d.java index a336791cb83..c83389668b4 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Irfft3d.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Irfft3d.java @@ -51,8 +51,6 @@ * {@code fft_length / 2 + 1} for the inner-most dimension) is smaller than the * corresponding dimension of {@code input}, the dimension is cropped. If it is larger, * the dimension is padded with zeros. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Irfft3d.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/IrfftNd.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/IrfftNd.java index 93006aea156..5e83c9f4dc3 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/IrfftNd.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/IrfftNd.java @@ -48,8 +48,6 @@ * is not given, the default shape(input) is used. *

    Axes mean the dimensions to perform the transform on. Default is to perform on * all axes. - * - * @param data type for {@code output} output */ @OpMetadata( opType = IrfftNd.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Rfft.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Rfft.java index f5c14f6eec7..c4d7b74e39a 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Rfft.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Rfft.java @@ -46,8 +46,6 @@ *

    Along the axis {@code signal.Rfft} is computed on, if {@code fft_length} is smaller than the * corresponding dimension of {@code input}, the dimension is cropped. If it is larger, * the dimension is padded with zeros. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Rfft.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Rfft2d.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Rfft2d.java index 6587b7378c1..314d16f4eec 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Rfft2d.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Rfft2d.java @@ -47,8 +47,6 @@ *

    Along each axis {@code signal.Rfft2d} is computed on, if {@code fft_length} is smaller than the * corresponding dimension of {@code input}, the dimension is cropped. If it is larger, * the dimension is padded with zeros. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Rfft2d.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Rfft3d.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Rfft3d.java index 35746c0f93b..282c4b7386e 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Rfft3d.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/Rfft3d.java @@ -47,8 +47,6 @@ *

    Along each axis {@code signal.Rfft3d} is computed on, if {@code fft_length} is smaller than the * corresponding dimension of {@code input}, the dimension is cropped. If it is larger, * the dimension is padded with zeros. - * - * @param data type for {@code output} output */ @OpMetadata( opType = Rfft3d.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/RfftNd.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/RfftNd.java index 85e48957ee4..17bf1368600 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/RfftNd.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/signal/RfftNd.java @@ -47,8 +47,6 @@ * is not given, the default shape(input) is used. *

    Axes mean the dimensions to perform the transform on. Default is to perform on * all axes. - * - * @param data type for {@code output} output */ @OpMetadata( opType = RfftNd.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/ConvertToListOfSparseCoreCooTensors.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/ConvertToListOfSparseCoreCooTensors.java new file mode 100644 index 00000000000..7ed71c4c316 --- /dev/null +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/ConvertToListOfSparseCoreCooTensors.java @@ -0,0 +1,209 @@ +/* Copyright 2018-2023 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. +=======================================================================*/ + +// This class has been generated, DO NOT EDIT! + +package org.tensorflow.op.sparse; + +import java.util.Arrays; +import java.util.List; +import org.tensorflow.GraphOperation; +import org.tensorflow.Operand; +import org.tensorflow.Operation; +import org.tensorflow.OperationBuilder; +import org.tensorflow.Output; +import org.tensorflow.op.RawOp; +import org.tensorflow.op.RawOpInputs; +import org.tensorflow.op.Scope; +import org.tensorflow.op.annotation.Endpoint; +import org.tensorflow.op.annotation.OpInputsMetadata; +import org.tensorflow.op.annotation.OpMetadata; +import org.tensorflow.op.annotation.Operator; +import org.tensorflow.types.TFloat32; +import org.tensorflow.types.TInt32; + +/** + * The ConvertToListOfSparseCoreCooTensors operation + */ +@OpMetadata( + opType = ConvertToListOfSparseCoreCooTensors.OP_NAME, + inputsClass = ConvertToListOfSparseCoreCooTensors.Inputs.class +) +@Operator( + group = "sparse" +) +public final class ConvertToListOfSparseCoreCooTensors extends RawOp { + /** + * The name of this op, as known by TensorFlow core engine + */ + public static final String OP_NAME = "ConvertToListOfSparseCoreCooTensors"; + + private List> rowIdsList; + + private List> colIdsList; + + private List> gainsList; + + @SuppressWarnings("unchecked") + public ConvertToListOfSparseCoreCooTensors(Operation operation) { + super(operation, OP_NAME); + int outputIdx = 0; + int rowIdsListLength = operation.outputListLength("row_ids_list"); + rowIdsList = Arrays.asList((Output[]) operation.outputList(outputIdx, rowIdsListLength)); + outputIdx += rowIdsListLength; + int colIdsListLength = operation.outputListLength("col_ids_list"); + colIdsList = Arrays.asList((Output[]) operation.outputList(outputIdx, colIdsListLength)); + outputIdx += colIdsListLength; + int gainsListLength = operation.outputListLength("gains_list"); + gainsList = Arrays.asList((Output[]) operation.outputList(outputIdx, gainsListLength)); + outputIdx += gainsListLength; + } + + /** + * Factory method to create a class wrapping a new ConvertToListOfSparseCoreCooTensors operation. + * + * @param scope current scope + * @param indicesOrRowSplits The indicesOrRowSplits value + * @param values The values value + * @param weights The weights value + * @param sampleCount The value of the sampleCount attribute + * @param numScPerChip The value of the numScPerChip attribute + * @param rowOffset The value of the rowOffset attribute + * @param colOffset The value of the colOffset attribute + * @param colShift The value of the colShift attribute + * @param numScShards The value of the numScShards attribute + * @param stackedTableSampleCount The value of the stackedTableSampleCount attribute + * @param combiner The value of the combiner attribute + * @return a new instance of ConvertToListOfSparseCoreCooTensors + */ + @Endpoint( + describeByClass = true + ) + public static ConvertToListOfSparseCoreCooTensors create(Scope scope, + Operand indicesOrRowSplits, Operand values, Operand weights, + Long sampleCount, Long numScPerChip, Long rowOffset, Long colOffset, Long colShift, + Long numScShards, Long stackedTableSampleCount, String combiner) { + OperationBuilder opBuilder = scope.opBuilder(OP_NAME, "ConvertToListOfSparseCoreCooTensors"); + opBuilder.addInput(indicesOrRowSplits.asOutput()); + opBuilder.addInput(values.asOutput()); + opBuilder.addInput(weights.asOutput()); + opBuilder.setAttr("sample_count", sampleCount); + opBuilder.setAttr("num_sc_per_chip", numScPerChip); + opBuilder.setAttr("row_offset", rowOffset); + opBuilder.setAttr("col_offset", colOffset); + opBuilder.setAttr("col_shift", colShift); + opBuilder.setAttr("num_sc_shards", numScShards); + opBuilder.setAttr("stacked_table_sample_count", stackedTableSampleCount); + opBuilder.setAttr("combiner", combiner); + return new ConvertToListOfSparseCoreCooTensors(opBuilder.build()); + } + + /** + * Gets rowIdsList. + * + * @return rowIdsList. + */ + public List> rowIdsList() { + return rowIdsList; + } + + /** + * Gets colIdsList. + * + * @return colIdsList. + */ + public List> colIdsList() { + return colIdsList; + } + + /** + * Gets gainsList. + * + * @return gainsList. + */ + public List> gainsList() { + return gainsList; + } + + @OpInputsMetadata( + outputsClass = ConvertToListOfSparseCoreCooTensors.class + ) + public static class Inputs extends RawOpInputs { + /** + * The indicesOrRowSplits input + */ + public final Operand indicesOrRowSplits; + + /** + * The values input + */ + public final Operand values; + + /** + * The weights input + */ + public final Operand weights; + + /** + * The sampleCount attribute + */ + public final long sampleCount; + + /** + * The rowOffset attribute + */ + public final long rowOffset; + + /** + * The colOffset attribute + */ + public final long colOffset; + + /** + * The colShift attribute + */ + public final long colShift; + + /** + * The numScShards attribute + */ + public final long numScShards; + + /** + * The stackedTableSampleCount attribute + */ + public final long stackedTableSampleCount; + + /** + * The combiner attribute + */ + public final String combiner; + + public Inputs(GraphOperation op) { + super(new ConvertToListOfSparseCoreCooTensors(op), op, Arrays.asList("sample_count", "row_offset", "col_offset", "col_shift", "num_sc_shards", "stacked_table_sample_count", "combiner")); + int inputIndex = 0; + indicesOrRowSplits = (Operand) op.input(inputIndex++); + values = (Operand) op.input(inputIndex++); + weights = (Operand) op.input(inputIndex++); + sampleCount = op.attributes().getAttrInt("sample_count"); + rowOffset = op.attributes().getAttrInt("row_offset"); + colOffset = op.attributes().getAttrInt("col_offset"); + colShift = op.attributes().getAttrInt("col_shift"); + numScShards = op.attributes().getAttrInt("num_sc_shards"); + stackedTableSampleCount = op.attributes().getAttrInt("stacked_table_sample_count"); + combiner = op.attributes().getAttrString("combiner"); + } + } +} diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/ConvertToSparseCoreCsrWrappedCooTensor.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/ConvertToSparseCoreCsrWrappedCooTensor.java new file mode 100644 index 00000000000..6590a927699 --- /dev/null +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/ConvertToSparseCoreCsrWrappedCooTensor.java @@ -0,0 +1,283 @@ +/* Copyright 2018-2023 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. +=======================================================================*/ + +// This class has been generated, DO NOT EDIT! + +package org.tensorflow.op.sparse; + +import java.util.Arrays; +import org.tensorflow.GraphOperation; +import org.tensorflow.Operand; +import org.tensorflow.Operation; +import org.tensorflow.OperationBuilder; +import org.tensorflow.Output; +import org.tensorflow.op.Operands; +import org.tensorflow.op.RawOp; +import org.tensorflow.op.RawOpInputs; +import org.tensorflow.op.Scope; +import org.tensorflow.op.annotation.Endpoint; +import org.tensorflow.op.annotation.OpInputsMetadata; +import org.tensorflow.op.annotation.OpMetadata; +import org.tensorflow.op.annotation.Operator; +import org.tensorflow.types.TFloat32; +import org.tensorflow.types.TInt32; +import org.tensorflow.types.TInt64; + +/** + * The ConvertToSparseCoreCsrWrappedCooTensor operation + */ +@OpMetadata( + opType = ConvertToSparseCoreCsrWrappedCooTensor.OP_NAME, + inputsClass = ConvertToSparseCoreCsrWrappedCooTensor.Inputs.class +) +@Operator( + group = "sparse" +) +public final class ConvertToSparseCoreCsrWrappedCooTensor extends RawOp { + /** + * The name of this op, as known by TensorFlow core engine + */ + public static final String OP_NAME = "ConvertToSparseCoreCsrWrappedCooTensor"; + + private Output rowPointers; + + private Output sortedSampleIds; + + private Output sortedTokenIds; + + private Output sortedGains; + + private Output rowPointersUnpaddedSize; + + private Output idsUnpaddedSize; + + private Output numMinibatchesPerSc; + + public ConvertToSparseCoreCsrWrappedCooTensor(Operation operation) { + super(operation, OP_NAME); + int outputIdx = 0; + rowPointers = operation.output(outputIdx++); + sortedSampleIds = operation.output(outputIdx++); + sortedTokenIds = operation.output(outputIdx++); + sortedGains = operation.output(outputIdx++); + rowPointersUnpaddedSize = operation.output(outputIdx++); + idsUnpaddedSize = operation.output(outputIdx++); + numMinibatchesPerSc = operation.output(outputIdx++); + } + + /** + * Factory method to create a class wrapping a new ConvertToSparseCoreCsrWrappedCooTensor operation. + * + * @param scope current scope + * @param sortedRowIdsList The sortedRowIdsList value + * @param sortedColIdsList The sortedColIdsList value + * @param sortedGainsList The sortedGainsList value + * @param idCountsList The idCountsList value + * @param splits The splits value + * @param sampleCountPerSc The value of the sampleCountPerSc attribute + * @param numReplica The value of the numReplica attribute + * @param maxMinibatchesPerSc The value of the maxMinibatchesPerSc attribute + * @param maxIdsPerChipPerSample The value of the maxIdsPerChipPerSample attribute + * @param tableVocabSize The value of the tableVocabSize attribute + * @param featureWidth The value of the featureWidth attribute + * @param tableName The value of the tableName attribute + * @param allowIdDropping The value of the allowIdDropping attribute + * @return a new instance of ConvertToSparseCoreCsrWrappedCooTensor + */ + @Endpoint( + describeByClass = true + ) + public static ConvertToSparseCoreCsrWrappedCooTensor create(Scope scope, + Iterable> sortedRowIdsList, Iterable> sortedColIdsList, + Iterable> sortedGainsList, Iterable> idCountsList, + Operand splits, Long sampleCountPerSc, Long numReplica, Long maxMinibatchesPerSc, + Long maxIdsPerChipPerSample, Long tableVocabSize, Long featureWidth, String tableName, + Boolean allowIdDropping) { + OperationBuilder opBuilder = scope.opBuilder(OP_NAME, "ConvertToSparseCoreCsrWrappedCooTensor"); + opBuilder.addInputList(Operands.asOutputs(sortedRowIdsList)); + opBuilder.addInputList(Operands.asOutputs(sortedColIdsList)); + opBuilder.addInputList(Operands.asOutputs(sortedGainsList)); + opBuilder.addInputList(Operands.asOutputs(idCountsList)); + opBuilder.addInput(splits.asOutput()); + opBuilder.setAttr("sample_count_per_sc", sampleCountPerSc); + opBuilder.setAttr("num_replica", numReplica); + opBuilder.setAttr("max_minibatches_per_sc", maxMinibatchesPerSc); + opBuilder.setAttr("max_ids_per_chip_per_sample", maxIdsPerChipPerSample); + opBuilder.setAttr("table_vocab_size", tableVocabSize); + opBuilder.setAttr("feature_width", featureWidth); + opBuilder.setAttr("table_name", tableName); + opBuilder.setAttr("allow_id_dropping", allowIdDropping); + return new ConvertToSparseCoreCsrWrappedCooTensor(opBuilder.build()); + } + + /** + * Gets rowPointers. + * + * @return rowPointers. + */ + public Output rowPointers() { + return rowPointers; + } + + /** + * Gets sortedSampleIds. + * + * @return sortedSampleIds. + */ + public Output sortedSampleIds() { + return sortedSampleIds; + } + + /** + * Gets sortedTokenIds. + * + * @return sortedTokenIds. + */ + public Output sortedTokenIds() { + return sortedTokenIds; + } + + /** + * Gets sortedGains. + * + * @return sortedGains. + */ + public Output sortedGains() { + return sortedGains; + } + + /** + * Gets rowPointersUnpaddedSize. + * + * @return rowPointersUnpaddedSize. + */ + public Output rowPointersUnpaddedSize() { + return rowPointersUnpaddedSize; + } + + /** + * Gets idsUnpaddedSize. + * + * @return idsUnpaddedSize. + */ + public Output idsUnpaddedSize() { + return idsUnpaddedSize; + } + + /** + * Gets numMinibatchesPerSc. + * + * @return numMinibatchesPerSc. + */ + public Output numMinibatchesPerSc() { + return numMinibatchesPerSc; + } + + @OpInputsMetadata( + outputsClass = ConvertToSparseCoreCsrWrappedCooTensor.class + ) + public static class Inputs extends RawOpInputs { + /** + * The sortedRowIdsList input + */ + public final Iterable> sortedRowIdsList; + + /** + * The sortedColIdsList input + */ + public final Iterable> sortedColIdsList; + + /** + * The sortedGainsList input + */ + public final Iterable> sortedGainsList; + + /** + * The idCountsList input + */ + public final Iterable> idCountsList; + + /** + * The splits input + */ + public final Operand splits; + + /** + * The sampleCountPerSc attribute + */ + public final long sampleCountPerSc; + + /** + * The numReplica attribute + */ + public final long numReplica; + + /** + * The maxMinibatchesPerSc attribute + */ + public final long maxMinibatchesPerSc; + + /** + * The maxIdsPerChipPerSample attribute + */ + public final long maxIdsPerChipPerSample; + + /** + * The tableVocabSize attribute + */ + public final long tableVocabSize; + + /** + * The featureWidth attribute + */ + public final long featureWidth; + + /** + * The tableName attribute + */ + public final String tableName; + + /** + * The allowIdDropping attribute + */ + public final boolean allowIdDropping; + + public Inputs(GraphOperation op) { + super(new ConvertToSparseCoreCsrWrappedCooTensor(op), op, Arrays.asList("sample_count_per_sc", "num_replica", "max_minibatches_per_sc", "max_ids_per_chip_per_sample", "table_vocab_size", "feature_width", "table_name", "allow_id_dropping")); + int inputIndex = 0; + int sortedRowIdsListLength = op.inputListLength("sorted_row_ids_list"); + sortedRowIdsList = Arrays.asList((Operand[]) op.inputList(inputIndex, sortedRowIdsListLength)); + inputIndex += sortedRowIdsListLength; + int sortedColIdsListLength = op.inputListLength("sorted_col_ids_list"); + sortedColIdsList = Arrays.asList((Operand[]) op.inputList(inputIndex, sortedColIdsListLength)); + inputIndex += sortedColIdsListLength; + int sortedGainsListLength = op.inputListLength("sorted_gains_list"); + sortedGainsList = Arrays.asList((Operand[]) op.inputList(inputIndex, sortedGainsListLength)); + inputIndex += sortedGainsListLength; + int idCountsListLength = op.inputListLength("id_counts_list"); + idCountsList = Arrays.asList((Operand[]) op.inputList(inputIndex, idCountsListLength)); + inputIndex += idCountsListLength; + splits = (Operand) op.input(inputIndex++); + sampleCountPerSc = op.attributes().getAttrInt("sample_count_per_sc"); + numReplica = op.attributes().getAttrInt("num_replica"); + maxMinibatchesPerSc = op.attributes().getAttrInt("max_minibatches_per_sc"); + maxIdsPerChipPerSample = op.attributes().getAttrInt("max_ids_per_chip_per_sample"); + tableVocabSize = op.attributes().getAttrInt("table_vocab_size"); + featureWidth = op.attributes().getAttrInt("feature_width"); + tableName = op.attributes().getAttrString("table_name"); + allowIdDropping = op.attributes().getAttrBool("allow_id_dropping"); + } + } +} diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/DenseCountSparseOutput.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/DenseCountSparseOutput.java index 49d78c0517c..5cf78a2a0a6 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/DenseCountSparseOutput.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/DenseCountSparseOutput.java @@ -37,8 +37,6 @@ /** * Performs sparse-output bin counting for a tf.tensor input. * Counts the number of times each value occurs in the input. - * - * @param data type for {@code output_values} output */ @OpMetadata( opType = DenseCountSparseOutput.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/DenseToDenseSetOperation.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/DenseToDenseSetOperation.java index 2ea6aa671d1..546adba1a9d 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/DenseToDenseSetOperation.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/DenseToDenseSetOperation.java @@ -42,8 +42,6 @@ * has rank {@code n} and the same 1st {@code n-1} dimensions as {@code set1} and {@code set2}. The {@code nth} * dimension contains the result of {@code set_operation} applied to the corresponding * {@code [0...n-1]} dimension of {@code set}. - * - * @param data type for {@code result_values} output */ @OpMetadata( opType = DenseToDenseSetOperation.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/DenseToSparseSetOperation.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/DenseToSparseSetOperation.java index bb75893bfd4..1b8cbcaee50 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/DenseToSparseSetOperation.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/DenseToSparseSetOperation.java @@ -48,8 +48,6 @@ * has rank {@code n} and the same 1st {@code n-1} dimensions as {@code set1} and {@code set2}. The {@code nth} * dimension contains the result of {@code set_operation} applied to the corresponding * {@code [0...n-1]} dimension of {@code set}. - * - * @param data type for {@code result_values} output */ @OpMetadata( opType = DenseToSparseSetOperation.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/DeserializeSparse.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/DeserializeSparse.java index 697249eca81..ba0c51f9a1e 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/DeserializeSparse.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/DeserializeSparse.java @@ -76,8 +76,6 @@ * values = [1, 2, 3, 4, 5] * shape = [2 50] * - * - * @param data type for {@code sparse_values} output */ @OpMetadata( opType = DeserializeSparse.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/GetStatsFromListOfSparseCoreCooTensors.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/GetStatsFromListOfSparseCoreCooTensors.java new file mode 100644 index 00000000000..51f5c33d66b --- /dev/null +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/GetStatsFromListOfSparseCoreCooTensors.java @@ -0,0 +1,204 @@ +/* Copyright 2018-2023 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. +=======================================================================*/ + +// This class has been generated, DO NOT EDIT! + +package org.tensorflow.op.sparse; + +import java.util.Arrays; +import java.util.List; +import org.tensorflow.GraphOperation; +import org.tensorflow.Operand; +import org.tensorflow.Operation; +import org.tensorflow.OperationBuilder; +import org.tensorflow.Output; +import org.tensorflow.op.Operands; +import org.tensorflow.op.RawOp; +import org.tensorflow.op.RawOpInputs; +import org.tensorflow.op.Scope; +import org.tensorflow.op.annotation.Endpoint; +import org.tensorflow.op.annotation.OpInputsMetadata; +import org.tensorflow.op.annotation.OpMetadata; +import org.tensorflow.op.annotation.Operator; +import org.tensorflow.types.TFloat32; +import org.tensorflow.types.TInt32; + +/** + * The GetStatsFromListOfSparseCoreCooTensors operation + */ +@OpMetadata( + opType = GetStatsFromListOfSparseCoreCooTensors.OP_NAME, + inputsClass = GetStatsFromListOfSparseCoreCooTensors.Inputs.class +) +@Operator( + group = "sparse" +) +public final class GetStatsFromListOfSparseCoreCooTensors extends RawOp { + /** + * The name of this op, as known by TensorFlow core engine + */ + public static final String OP_NAME = "GetStatsFromListOfSparseCoreCooTensors"; + + private Output maxIdsPerSparseCore; + + private Output maxUniqueIdsPerSparseCore; + + public GetStatsFromListOfSparseCoreCooTensors(Operation operation) { + super(operation, OP_NAME); + int outputIdx = 0; + maxIdsPerSparseCore = operation.output(outputIdx++); + maxUniqueIdsPerSparseCore = operation.output(outputIdx++); + } + + /** + * Factory method to create a class wrapping a new GetStatsFromListOfSparseCoreCooTensors operation. + * + * @param scope current scope + * @param rowIdsList The rowIdsList value + * @param colIdsList The colIdsList value + * @param gainsList The gainsList value + * @param sampleCountList The value of the sampleCountList attribute + * @param colOffsetList The value of the colOffsetList attribute + * @param numReplica The value of the numReplica attribute + * @param tableVocabSize The value of the tableVocabSize attribute + * @param featureWidth The value of the featureWidth attribute + * @param numScPerChip The value of the numScPerChip attribute + * @param tableName The value of the tableName attribute + * @return a new instance of GetStatsFromListOfSparseCoreCooTensors + */ + @Endpoint( + describeByClass = true + ) + public static GetStatsFromListOfSparseCoreCooTensors create(Scope scope, + Iterable> rowIdsList, Iterable> colIdsList, + Iterable> gainsList, List sampleCountList, List colOffsetList, + Long numReplica, Long tableVocabSize, Long featureWidth, Long numScPerChip, + String tableName) { + OperationBuilder opBuilder = scope.opBuilder(OP_NAME, "GetStatsFromListOfSparseCoreCooTensors"); + opBuilder.addInputList(Operands.asOutputs(rowIdsList)); + opBuilder.addInputList(Operands.asOutputs(colIdsList)); + opBuilder.addInputList(Operands.asOutputs(gainsList)); + long[] sampleCountListArray = new long[sampleCountList.size()]; + for (int i = 0 ; i < sampleCountListArray.length ; i++) { + sampleCountListArray[i] = sampleCountList.get(i); + } + opBuilder.setAttr("sample_count_list", sampleCountListArray); + long[] colOffsetListArray = new long[colOffsetList.size()]; + for (int i = 0 ; i < colOffsetListArray.length ; i++) { + colOffsetListArray[i] = colOffsetList.get(i); + } + opBuilder.setAttr("col_offset_list", colOffsetListArray); + opBuilder.setAttr("num_replica", numReplica); + opBuilder.setAttr("table_vocab_size", tableVocabSize); + opBuilder.setAttr("feature_width", featureWidth); + opBuilder.setAttr("num_sc_per_chip", numScPerChip); + opBuilder.setAttr("table_name", tableName); + return new GetStatsFromListOfSparseCoreCooTensors(opBuilder.build()); + } + + /** + * Gets maxIdsPerSparseCore. + * + * @return maxIdsPerSparseCore. + */ + public Output maxIdsPerSparseCore() { + return maxIdsPerSparseCore; + } + + /** + * Gets maxUniqueIdsPerSparseCore. + * + * @return maxUniqueIdsPerSparseCore. + */ + public Output maxUniqueIdsPerSparseCore() { + return maxUniqueIdsPerSparseCore; + } + + @OpInputsMetadata( + outputsClass = GetStatsFromListOfSparseCoreCooTensors.class + ) + public static class Inputs extends RawOpInputs { + /** + * The rowIdsList input + */ + public final Iterable> rowIdsList; + + /** + * The colIdsList input + */ + public final Iterable> colIdsList; + + /** + * The gainsList input + */ + public final Iterable> gainsList; + + /** + * The sampleCountList attribute + */ + public final long[] sampleCountList; + + /** + * The colOffsetList attribute + */ + public final long[] colOffsetList; + + /** + * The numReplica attribute + */ + public final long numReplica; + + /** + * The tableVocabSize attribute + */ + public final long tableVocabSize; + + /** + * The featureWidth attribute + */ + public final long featureWidth; + + /** + * The numScPerChip attribute + */ + public final long numScPerChip; + + /** + * The tableName attribute + */ + public final String tableName; + + public Inputs(GraphOperation op) { + super(new GetStatsFromListOfSparseCoreCooTensors(op), op, Arrays.asList("sample_count_list", "col_offset_list", "num_replica", "table_vocab_size", "feature_width", "num_sc_per_chip", "table_name")); + int inputIndex = 0; + int rowIdsListLength = op.inputListLength("row_ids_list"); + rowIdsList = Arrays.asList((Operand[]) op.inputList(inputIndex, rowIdsListLength)); + inputIndex += rowIdsListLength; + int colIdsListLength = op.inputListLength("col_ids_list"); + colIdsList = Arrays.asList((Operand[]) op.inputList(inputIndex, colIdsListLength)); + inputIndex += colIdsListLength; + int gainsListLength = op.inputListLength("gains_list"); + gainsList = Arrays.asList((Operand[]) op.inputList(inputIndex, gainsListLength)); + inputIndex += gainsListLength; + sampleCountList = op.attributes().getAttrIntList("sample_count_list"); + colOffsetList = op.attributes().getAttrIntList("col_offset_list"); + numReplica = op.attributes().getAttrInt("num_replica"); + tableVocabSize = op.attributes().getAttrInt("table_vocab_size"); + featureWidth = op.attributes().getAttrInt("feature_width"); + numScPerChip = op.attributes().getAttrInt("num_sc_per_chip"); + tableName = op.attributes().getAttrString("table_name"); + } + } +} diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SortListOfSparseCoreCooTensors.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SortListOfSparseCoreCooTensors.java new file mode 100644 index 00000000000..fb26033cfd2 --- /dev/null +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SortListOfSparseCoreCooTensors.java @@ -0,0 +1,240 @@ +/* Copyright 2018-2023 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. +=======================================================================*/ + +// This class has been generated, DO NOT EDIT! + +package org.tensorflow.op.sparse; + +import java.util.Arrays; +import java.util.List; +import org.tensorflow.GraphOperation; +import org.tensorflow.Operand; +import org.tensorflow.Operation; +import org.tensorflow.OperationBuilder; +import org.tensorflow.Output; +import org.tensorflow.op.Operands; +import org.tensorflow.op.RawOp; +import org.tensorflow.op.RawOpInputs; +import org.tensorflow.op.Scope; +import org.tensorflow.op.annotation.Endpoint; +import org.tensorflow.op.annotation.OpInputsMetadata; +import org.tensorflow.op.annotation.OpMetadata; +import org.tensorflow.types.TFloat32; +import org.tensorflow.types.TInt32; + +/** + * The SortListOfSparseCoreCooTensors operation + */ +@OpMetadata( + opType = SortListOfSparseCoreCooTensors.OP_NAME, + inputsClass = SortListOfSparseCoreCooTensors.Inputs.class +) +public final class SortListOfSparseCoreCooTensors extends RawOp { + /** + * The name of this op, as known by TensorFlow core engine + */ + public static final String OP_NAME = "SortListOfSparseCoreCooTensors"; + + private Output sortedRowIds; + + private Output sortedColIds; + + private Output sortedGains; + + private Output idCounts; + + public SortListOfSparseCoreCooTensors(Operation operation) { + super(operation, OP_NAME); + int outputIdx = 0; + sortedRowIds = operation.output(outputIdx++); + sortedColIds = operation.output(outputIdx++); + sortedGains = operation.output(outputIdx++); + idCounts = operation.output(outputIdx++); + } + + /** + * Factory method to create a class wrapping a new SortListOfSparseCoreCooTensors operation. + * + * @param scope current scope + * @param rowIdsList The rowIdsList value + * @param colIdsList The colIdsList value + * @param gainsList The gainsList value + * @param sampleCountList The value of the sampleCountList attribute + * @param colOffsetList The value of the colOffsetList attribute + * @param numReplica The value of the numReplica attribute + * @param tableVocabSize The value of the tableVocabSize attribute + * @param featureWidth The value of the featureWidth attribute + * @param numScPerChip The value of the numScPerChip attribute + * @param maxIdsPerSparseCore The value of the maxIdsPerSparseCore attribute + * @param maxUniqueIdsPerSparseCore The value of the maxUniqueIdsPerSparseCore attribute + * @param tableName The value of the tableName attribute + * @return a new instance of SortListOfSparseCoreCooTensors + */ + @Endpoint( + describeByClass = true + ) + public static SortListOfSparseCoreCooTensors create(Scope scope, + Iterable> rowIdsList, Iterable> colIdsList, + Iterable> gainsList, List sampleCountList, List colOffsetList, + Long numReplica, Long tableVocabSize, Long featureWidth, Long numScPerChip, + Long maxIdsPerSparseCore, Long maxUniqueIdsPerSparseCore, String tableName) { + OperationBuilder opBuilder = scope.opBuilder(OP_NAME, "SortListOfSparseCoreCooTensors"); + opBuilder.addInputList(Operands.asOutputs(rowIdsList)); + opBuilder.addInputList(Operands.asOutputs(colIdsList)); + opBuilder.addInputList(Operands.asOutputs(gainsList)); + long[] sampleCountListArray = new long[sampleCountList.size()]; + for (int i = 0 ; i < sampleCountListArray.length ; i++) { + sampleCountListArray[i] = sampleCountList.get(i); + } + opBuilder.setAttr("sample_count_list", sampleCountListArray); + long[] colOffsetListArray = new long[colOffsetList.size()]; + for (int i = 0 ; i < colOffsetListArray.length ; i++) { + colOffsetListArray[i] = colOffsetList.get(i); + } + opBuilder.setAttr("col_offset_list", colOffsetListArray); + opBuilder.setAttr("num_replica", numReplica); + opBuilder.setAttr("table_vocab_size", tableVocabSize); + opBuilder.setAttr("feature_width", featureWidth); + opBuilder.setAttr("num_sc_per_chip", numScPerChip); + opBuilder.setAttr("max_ids_per_sparse_core", maxIdsPerSparseCore); + opBuilder.setAttr("max_unique_ids_per_sparse_core", maxUniqueIdsPerSparseCore); + opBuilder.setAttr("table_name", tableName); + return new SortListOfSparseCoreCooTensors(opBuilder.build()); + } + + /** + * Gets sortedRowIds. + * + * @return sortedRowIds. + */ + public Output sortedRowIds() { + return sortedRowIds; + } + + /** + * Gets sortedColIds. + * + * @return sortedColIds. + */ + public Output sortedColIds() { + return sortedColIds; + } + + /** + * Gets sortedGains. + * + * @return sortedGains. + */ + public Output sortedGains() { + return sortedGains; + } + + /** + * Gets idCounts. + * + * @return idCounts. + */ + public Output idCounts() { + return idCounts; + } + + @OpInputsMetadata( + outputsClass = SortListOfSparseCoreCooTensors.class + ) + public static class Inputs extends RawOpInputs { + /** + * The rowIdsList input + */ + public final Iterable> rowIdsList; + + /** + * The colIdsList input + */ + public final Iterable> colIdsList; + + /** + * The gainsList input + */ + public final Iterable> gainsList; + + /** + * The sampleCountList attribute + */ + public final long[] sampleCountList; + + /** + * The colOffsetList attribute + */ + public final long[] colOffsetList; + + /** + * The numReplica attribute + */ + public final long numReplica; + + /** + * The tableVocabSize attribute + */ + public final long tableVocabSize; + + /** + * The featureWidth attribute + */ + public final long featureWidth; + + /** + * The numScPerChip attribute + */ + public final long numScPerChip; + + /** + * The maxIdsPerSparseCore attribute + */ + public final long maxIdsPerSparseCore; + + /** + * The maxUniqueIdsPerSparseCore attribute + */ + public final long maxUniqueIdsPerSparseCore; + + /** + * The tableName attribute + */ + public final String tableName; + + public Inputs(GraphOperation op) { + super(new SortListOfSparseCoreCooTensors(op), op, Arrays.asList("sample_count_list", "col_offset_list", "num_replica", "table_vocab_size", "feature_width", "num_sc_per_chip", "max_ids_per_sparse_core", "max_unique_ids_per_sparse_core", "table_name")); + int inputIndex = 0; + int rowIdsListLength = op.inputListLength("row_ids_list"); + rowIdsList = Arrays.asList((Operand[]) op.inputList(inputIndex, rowIdsListLength)); + inputIndex += rowIdsListLength; + int colIdsListLength = op.inputListLength("col_ids_list"); + colIdsList = Arrays.asList((Operand[]) op.inputList(inputIndex, colIdsListLength)); + inputIndex += colIdsListLength; + int gainsListLength = op.inputListLength("gains_list"); + gainsList = Arrays.asList((Operand[]) op.inputList(inputIndex, gainsListLength)); + inputIndex += gainsListLength; + sampleCountList = op.attributes().getAttrIntList("sample_count_list"); + colOffsetList = op.attributes().getAttrIntList("col_offset_list"); + numReplica = op.attributes().getAttrInt("num_replica"); + tableVocabSize = op.attributes().getAttrInt("table_vocab_size"); + featureWidth = op.attributes().getAttrInt("feature_width"); + numScPerChip = op.attributes().getAttrInt("num_sc_per_chip"); + maxIdsPerSparseCore = op.attributes().getAttrInt("max_ids_per_sparse_core"); + maxUniqueIdsPerSparseCore = op.attributes().getAttrInt("max_unique_ids_per_sparse_core"); + tableName = op.attributes().getAttrString("table_name"); + } + } +} diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseAccumulatorTakeGradient.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseAccumulatorTakeGradient.java index aeb639d2d6e..fb8a868349d 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseAccumulatorTakeGradient.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseAccumulatorTakeGradient.java @@ -45,8 +45,6 @@ * average of the accumulated gradients. Also automatically increments * the recorded global_step in the accumulator by 1, and resets the * aggregate to 0. - * - * @param data type for {@code values} output */ @OpMetadata( opType = SparseAccumulatorTakeGradient.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseAdd.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseAdd.java index 1591773a20c..88ef61b78a1 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseAdd.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseAdd.java @@ -48,8 +48,6 @@ * {@code thresh == 0} (default) means everything is kept and actual thresholding happens * only for a positive value. *

    In the following shapes, {@code nnz} is the count after taking {@code thresh} into account. - * - * @param data type for {@code sum_values} output */ @OpMetadata( opType = SparseAdd.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseAddGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseAddGrad.java index 7d6c0923f4f..8a844c96eff 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseAddGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseAddGrad.java @@ -40,8 +40,6 @@ * as {@code SparseTensor} objects. This op takes in the upstream gradient w.r.t. * non-empty values of the sum, and outputs the gradients w.r.t. the non-empty * values of A and B. - * - * @param data type for {@code a_val_grad} output */ @OpMetadata( opType = SparseAddGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseBincount.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseBincount.java index b7414e4ab54..9eca1295d45 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseBincount.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseBincount.java @@ -42,8 +42,6 @@ * the value in {@code weights} at each index where the corresponding value in {@code arr} is * {@code i}. *

    Values in {@code arr} outside of the range [0, size) are ignored. - * - * @param data type for {@code output} output */ @OpMetadata( opType = SparseBincount.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseConcat.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseConcat.java index 6d53b3a723b..016f010647b 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseConcat.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseConcat.java @@ -74,8 +74,6 @@ * [ a] concat [ d e ] = [ a d e ] * [b c ] [ ] [b c ] * - * - * @param data type for {@code output_values} output */ @OpMetadata( opType = SparseConcat.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseCountSparseOutput.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseCountSparseOutput.java index c3983444bd3..4c59b4e2774 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseCountSparseOutput.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseCountSparseOutput.java @@ -37,8 +37,6 @@ /** * Performs sparse-output bin counting for a sparse tensor input. * Counts the number of times each value occurs in the input. - * - * @param data type for {@code output_values} output */ @OpMetadata( opType = SparseCountSparseOutput.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseDenseCwiseAdd.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseDenseCwiseAdd.java index 261d292d3b0..10ac8721d98 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseDenseCwiseAdd.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseDenseCwiseAdd.java @@ -43,8 +43,6 @@ *

    By these rules, the result is a logical SparseTensor with exactly the same * indices and shape, but possibly with different non-zero values. The output of * this Op is the resultant non-zero values. - * - * @param data type for {@code output} output */ @OpMetadata( opType = SparseDenseCwiseAdd.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseDenseCwiseDiv.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseDenseCwiseDiv.java index e0b56d6827c..724997892b1 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseDenseCwiseDiv.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseDenseCwiseDiv.java @@ -38,8 +38,6 @@ * Component-wise divides a SparseTensor by a dense Tensor. * Limitation: this Op only broadcasts the dense side to the sparse side, but not * the other direction. - * - * @param data type for {@code output} output */ @OpMetadata( opType = SparseDenseCwiseDiv.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseDenseCwiseMul.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseDenseCwiseMul.java index 3fb7a03c683..fe8386f0838 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseDenseCwiseMul.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseDenseCwiseMul.java @@ -41,8 +41,6 @@ * contents of the dense tensor (even if it's +/-INF and that INF*0 == NaN). *

    Limitation: this Op only broadcasts the dense side to the sparse side, but not * the other direction. - * - * @param data type for {@code output} output */ @OpMetadata( opType = SparseDenseCwiseMul.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseFillEmptyRows.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseFillEmptyRows.java index 989fda03492..ef0d2f85afa 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseFillEmptyRows.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseFillEmptyRows.java @@ -71,8 +71,6 @@ *

      * reverse_index_map[j] = out_j s.t. indices[j, :] == output_indices[out_j, :]
      * 
    - * - * @param data type for {@code output_values} output */ @OpMetadata( opType = SparseFillEmptyRows.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseFillEmptyRowsGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseFillEmptyRowsGrad.java index 21d4e2f099f..3b1c80bb5b1 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseFillEmptyRowsGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseFillEmptyRowsGrad.java @@ -43,8 +43,6 @@ *

    d_values[j] = grad_values[reverse_index_map[j]] * d_default_value = sum_{k : 0 .. N_full - 1} ( * grad_values[k] * 1{k not in reverse_index_map}) - * - * @param data type for {@code d_values} output */ @OpMetadata( opType = SparseFillEmptyRowsGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseReduceMax.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseReduceMax.java index 1e48a53ea82..256695f0acd 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseReduceMax.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseReduceMax.java @@ -47,8 +47,6 @@ *

    If {@code reduction_axes} has no entries, all dimensions are reduced, and a tensor * with a single element is returned. Additionally, the axes can be negative, * which are interpreted according to the indexing rules in Python. - * - * @param data type for {@code output} output */ @OpMetadata( opType = SparseReduceMax.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseReduceMaxSparse.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseReduceMaxSparse.java index 8f337f0c19e..b0a65daea67 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseReduceMaxSparse.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseReduceMaxSparse.java @@ -47,8 +47,6 @@ *

    If {@code reduction_axes} has no entries, all dimensions are reduced, and a tensor * with a single element is returned. Additionally, the axes can be negative, * which are interpreted according to the indexing rules in Python. - * - * @param data type for {@code output_values} output */ @OpMetadata( opType = SparseReduceMaxSparse.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseReduceSum.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseReduceSum.java index 26e0ecbfc45..3589487bece 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseReduceSum.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseReduceSum.java @@ -47,8 +47,6 @@ *

    If {@code reduction_axes} has no entries, all dimensions are reduced, and a tensor * with a single element is returned. Additionally, the axes can be negative, * which are interpreted according to the indexing rules in Python. - * - * @param data type for {@code output} output */ @OpMetadata( opType = SparseReduceSum.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseReduceSumSparse.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseReduceSumSparse.java index bb434694ccf..ef58eac0af1 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseReduceSumSparse.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseReduceSumSparse.java @@ -47,8 +47,6 @@ *

    If {@code reduction_axes} has no entries, all dimensions are reduced, and a tensor * with a single element is returned. Additionally, the axes can be negative, * which are interpreted according to the indexing rules in Python. - * - * @param data type for {@code output_values} output */ @OpMetadata( opType = SparseReduceSumSparse.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseReorder.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseReorder.java index 9e963285d77..4e2883435f9 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseReorder.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseReorder.java @@ -42,8 +42,6 @@ *

    Reordering does not affect the shape of the SparseTensor. *

    If the tensor has rank {@code R} and {@code N} non-empty values, {@code input_indices} has * shape {@code [N, R]}, input_values has length {@code N}, and input_shape has length {@code R}. - * - * @param data type for {@code output_values} output */ @OpMetadata( opType = SparseReorder.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentMean.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentMean.java index c1899b2fbf6..4703ba10fca 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentMean.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentMean.java @@ -38,8 +38,6 @@ * See {@code tf.sparse.segment_sum} for usage examples. *

    Like {@code SegmentMean}, but {@code segment_ids} can have rank less than {@code data}'s first * dimension, selecting a subset of dimension 0, specified by {@code indices}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = SparseSegmentMean.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentMeanGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentMeanGrad.java index 50f29512a23..9da8038eee9 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentMeanGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentMeanGrad.java @@ -39,10 +39,6 @@ * Returns tensor "output" with same shape as grad, except for dimension 0 whose * value is the number of unique indexes in "indices". Also returns vector * "sorted_unique_indices" containing the corresponding indexes from "indices". - * - * @param data type for {@code output} output - * - * @param data type for {@code sorted_unique_indices} output */ @OpMetadata( opType = SparseSegmentMeanGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentMeanWithNumSegments.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentMeanWithNumSegments.java index d1c0e07c099..99cf33231a5 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentMeanWithNumSegments.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentMeanWithNumSegments.java @@ -40,8 +40,6 @@ *

    Read * the section on segmentation * for an explanation of segments. - * - * @param data type for {@code output} output */ @OpMetadata( opType = SparseSegmentMeanWithNumSegments.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentSqrtN.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentSqrtN.java index ee0dc4238fc..5e299d7d124 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentSqrtN.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentSqrtN.java @@ -37,8 +37,6 @@ * Computes the sum along sparse segments of a tensor divided by the sqrt of N. * N is the size of the segment being reduced. *

    See {@code tf.sparse.segment_sum} for usage examples. - * - * @param data type for {@code output} output */ @OpMetadata( opType = SparseSegmentSqrtN.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentSqrtNGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentSqrtNGrad.java index 075cbacbcfb..b458c7daff9 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentSqrtNGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentSqrtNGrad.java @@ -39,10 +39,6 @@ * Returns tensor "output" with same shape as grad, except for dimension 0 whose * value is the number of unique indexes in "indices". Also returns vector * "sorted_unique_indices" containing the corresponding indexes from "indices". - * - * @param data type for {@code output} output - * - * @param data type for {@code sorted_unique_indices} output */ @OpMetadata( opType = SparseSegmentSqrtNGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentSqrtNWithNumSegments.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentSqrtNWithNumSegments.java index 84ccc501312..146dd696d6e 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentSqrtNWithNumSegments.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentSqrtNWithNumSegments.java @@ -41,8 +41,6 @@ *

    Read * the section on segmentation * for an explanation of segments. - * - * @param data type for {@code output} output */ @OpMetadata( opType = SparseSegmentSqrtNWithNumSegments.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentSum.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentSum.java index cf2ce2c9851..2f28386d05c 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentSum.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentSum.java @@ -61,8 +61,6 @@ * # Which is equivalent to: * tf.segment_sum(c, tf.constant([0, 0, 1])) * - * - * @param data type for {@code output} output */ @OpMetadata( opType = SparseSegmentSum.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentSumGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentSumGrad.java index 71b8f92448e..1372d6f7089 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentSumGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentSumGrad.java @@ -39,10 +39,6 @@ * Returns tensor "output" with same shape as grad, except for dimension 0 whose * value is the number of unique indexes in "indices". Also returns vector * "sorted_unique_indices" containing the corresponding indexes from "indices". - * - * @param data type for {@code output} output - * - * @param data type for {@code sorted_unique_indices} output */ @OpMetadata( opType = SparseSegmentSumGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentSumWithNumSegments.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentSumWithNumSegments.java index 4c44377244d..88b577afec1 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentSumWithNumSegments.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSegmentSumWithNumSegments.java @@ -59,8 +59,6 @@ * # [-1 -2 -3 -4] * # [ 0 0 0 0]] * - * - * @param data type for {@code output} output */ @OpMetadata( opType = SparseSegmentSumWithNumSegments.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSlice.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSlice.java index 58c794dfb2f..a3718f1a7e0 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSlice.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSlice.java @@ -52,8 +52,6 @@ * [ d e ] * [ ] * - * - * @param data type for {@code output_values} output */ @OpMetadata( opType = SparseSlice.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSliceGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSliceGrad.java index 4cfa41a7e45..969ef935dc7 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSliceGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSliceGrad.java @@ -39,8 +39,6 @@ * This op takes in the upstream gradient w.r.t. non-empty values of * the sliced {@code SparseTensor}, and outputs the gradients w.r.t. * the non-empty values of input {@code SparseTensor}. - * - * @param data type for {@code val_grad} output */ @OpMetadata( opType = SparseSliceGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSoftmax.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSoftmax.java index be61533da26..43cd85b5a9f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSoftmax.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSoftmax.java @@ -48,8 +48,6 @@ * (3) Renormalizes the remaining elements. *

    Hence, the {@code SparseTensor} result has exactly the same non-zero indices and * shape. - * - * @param data type for {@code output} output */ @OpMetadata( opType = SparseSoftmax.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSparseMaximum.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSparseMaximum.java index 22a1d407274..80b44623ca8 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSparseMaximum.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSparseMaximum.java @@ -37,8 +37,6 @@ /** * Returns the element-wise max of two SparseTensors. * Assumes the two SparseTensors have the same shape, i.e., no broadcasting. - * - * @param data type for {@code output_values} output */ @OpMetadata( opType = SparseSparseMaximum.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSparseMinimum.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSparseMinimum.java index 8dd8978c627..ecbc022d09d 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSparseMinimum.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSparseMinimum.java @@ -37,8 +37,6 @@ /** * Returns the element-wise min of two SparseTensors. * Assumes the two SparseTensors have the same shape, i.e., no broadcasting. - * - * @param data type for {@code output_values} output */ @OpMetadata( opType = SparseSparseMinimum.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSplit.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSplit.java index a09e9ff9d38..da66d34d134 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSplit.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseSplit.java @@ -55,8 +55,6 @@ * [ d e ] * [ ] * - * - * @param data type for {@code output_values} output */ @OpMetadata( opType = SparseSplit.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseTensorDenseAdd.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseTensorDenseAdd.java index c153cf68776..7f73769030b 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseTensorDenseAdd.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseTensorDenseAdd.java @@ -37,8 +37,6 @@ /** * Adds up a {@code SparseTensor} and a dense {@code Tensor}, producing a dense {@code Tensor}. * This Op does not require {@code a_indices} be sorted in standard lexicographic order. - * - * @param data type for {@code output} output */ @OpMetadata( opType = SparseTensorDenseAdd.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseTensorDenseMatMul.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseTensorDenseMatMul.java index 346c9297596..0425354268c 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseTensorDenseMatMul.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseTensorDenseMatMul.java @@ -45,8 +45,6 @@ * if adjoint_a == true: * A should be sorted in order of increasing dimension 1 (i.e., "column major" * order instead of "row major" order). - * - * @param data type for {@code product} output */ @OpMetadata( opType = SparseTensorDenseMatMul.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseToDense.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseToDense.java index 95c8f189d48..448a7c4ec83 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseToDense.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseToDense.java @@ -52,8 +52,6 @@ *

    Indices should be sorted in lexicographic order, and indices must not * contain any repeats. If {@code validate_indices} is true, these properties * are checked during execution. - * - * @param data type for {@code dense} output */ @OpMetadata( opType = SparseToDense.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseToSparseSetOperation.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseToSparseSetOperation.java index 8a71016a669..e658f88abb7 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseToSparseSetOperation.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/SparseToSparseSetOperation.java @@ -54,8 +54,6 @@ * has rank {@code n} and the same 1st {@code n-1} dimensions as {@code set1} and {@code set2}. The {@code nth} * dimension contains the result of {@code set_operation} applied to the corresponding * {@code [0...n-1]} dimension of {@code set}. - * - * @param data type for {@code result_values} output */ @OpMetadata( opType = SparseToSparseSetOperation.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/TakeManySparseFromTensorsMap.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/TakeManySparseFromTensorsMap.java index e72ec904466..2c6293f402d 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/TakeManySparseFromTensorsMap.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/sparse/TakeManySparseFromTensorsMap.java @@ -77,8 +77,6 @@ * values = [1, 2, 3, 4, 5] * shape = [2 50] * - * - * @param data type for {@code sparse_values} output */ @OpMetadata( opType = TakeManySparseFromTensorsMap.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/strings/StringNGrams.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/strings/StringNGrams.java index 6f5739989d0..c04fa6cd987 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/strings/StringNGrams.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/strings/StringNGrams.java @@ -40,8 +40,6 @@ * This op accepts a ragged tensor with 1 ragged dimension containing only * strings and outputs a ragged tensor with 1 ragged dimension containing ngrams * of that string, joined along the innermost axis. - * - * @param data type for {@code ngrams_splits} output */ @OpMetadata( opType = StringNGrams.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/strings/ToNumber.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/strings/ToNumber.java index e4564334bf1..74e4816ed43 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/strings/ToNumber.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/strings/ToNumber.java @@ -50,8 +50,6 @@ * * * - * - * @param data type for {@code output} output */ @OpMetadata( opType = ToNumber.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/strings/UnicodeDecode.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/strings/UnicodeDecode.java index bffb35e17e0..40624c66adf 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/strings/UnicodeDecode.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/strings/UnicodeDecode.java @@ -52,8 +52,6 @@ *

  • {@code row_splits[i+1] - row_splits[i]} is the number of characters in the {@code i}th * string (in row-major order).
  • * - * - * @param data type for {@code row_splits} output */ @OpMetadata( opType = UnicodeDecode.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/strings/UnicodeDecodeWithOffsets.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/strings/UnicodeDecodeWithOffsets.java index 690789b6843..5989e8e7106 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/strings/UnicodeDecodeWithOffsets.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/strings/UnicodeDecodeWithOffsets.java @@ -56,8 +56,6 @@ *
  • {@code row_splits[i+1] - row_splits[i]} is the number of characters in the {@code i}th * string (in row-major order).
  • * - * - * @param data type for {@code row_splits} output */ @OpMetadata( opType = UnicodeDecodeWithOffsets.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/AllToAll.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/AllToAll.java index dfe6664886c..3bd1592cbc7 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/AllToAll.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/AllToAll.java @@ -49,8 +49,6 @@ * split_count=2 *

    replica 0's output: {@code [[A], [C]]} * replica 1's output: {@code [[B], [D]]} - * - * @param data type for {@code output} output */ @OpMetadata( opType = AllToAll.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/ComputeDedupDataSize.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/ComputeDedupDataSize.java index 4305affd43e..6ff27567e92 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/ComputeDedupDataSize.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/ComputeDedupDataSize.java @@ -29,7 +29,6 @@ import org.tensorflow.op.annotation.Endpoint; import org.tensorflow.op.annotation.OpInputsMetadata; import org.tensorflow.op.annotation.OpMetadata; -import org.tensorflow.op.annotation.Operator; import org.tensorflow.types.TInt32; /** @@ -42,14 +41,11 @@ opType = ComputeDedupDataSize.OP_NAME, inputsClass = ComputeDedupDataSize.Inputs.class ) -@Operator( - group = "tpu" -) public final class ComputeDedupDataSize extends RawOp implements Operand { /** * The name of this op, as known by TensorFlow core engine */ - public static final String OP_NAME = "ComputeDedupDataSize"; + public static final String OP_NAME = "ComputeDedupDataSizeV2"; private Output numElements; @@ -60,18 +56,25 @@ public ComputeDedupDataSize(Operation operation) { } /** - * Factory method to create a class wrapping a new ComputeDedupDataSize operation. + * Factory method to create a class wrapping a new ComputeDedupDataSizeV2 operation. * * @param scope current scope * @param config Serialized TPUEmbeddingConfiguration proto. + * @param embeddingPartitions Serialized EmbeddingPartitionsProto proto. + * @param hbmBuffersConfig Serialized HbmBuffersConfig proto. + * @param tpuTopology Serialized TpuTopologyArgsProto proto. * @return a new instance of ComputeDedupDataSize */ @Endpoint( describeByClass = true ) - public static ComputeDedupDataSize create(Scope scope, String config) { + public static ComputeDedupDataSize create(Scope scope, String config, String embeddingPartitions, + String hbmBuffersConfig, String tpuTopology) { OperationBuilder opBuilder = scope.opBuilder(OP_NAME, "ComputeDedupDataSize"); opBuilder.setAttr("config", config); + opBuilder.setAttr("embedding_partitions", embeddingPartitions); + opBuilder.setAttr("hbm_buffers_config", hbmBuffersConfig); + opBuilder.setAttr("tpu_topology", tpuTopology); return new ComputeDedupDataSize(opBuilder.build()); } @@ -98,10 +101,28 @@ public static class Inputs extends RawOpInputs { */ public final String config; + /** + * Serialized EmbeddingPartitionsProto proto. + */ + public final String embeddingPartitions; + + /** + * Serialized HbmBuffersConfig proto. + */ + public final String hbmBuffersConfig; + + /** + * Serialized TpuTopologyArgsProto proto. + */ + public final String tpuTopology; + public Inputs(GraphOperation op) { - super(new ComputeDedupDataSize(op), op, Arrays.asList("config")); + super(new ComputeDedupDataSize(op), op, Arrays.asList("config", "embedding_partitions", "hbm_buffers_config", "tpu_topology")); int inputIndex = 0; config = op.attributes().getAttrString("config"); + embeddingPartitions = op.attributes().getAttrString("embedding_partitions"); + hbmBuffersConfig = op.attributes().getAttrString("hbm_buffers_config"); + tpuTopology = op.attributes().getAttrString("tpu_topology"); } } } diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/ComputeDedupDataTupleMask.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/ComputeDedupDataTupleMask.java index 95078aebabc..1160a8536a2 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/ComputeDedupDataTupleMask.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/ComputeDedupDataTupleMask.java @@ -29,7 +29,6 @@ import org.tensorflow.op.annotation.Endpoint; import org.tensorflow.op.annotation.OpInputsMetadata; import org.tensorflow.op.annotation.OpMetadata; -import org.tensorflow.op.annotation.Operator; import org.tensorflow.types.TInt32; /** @@ -42,14 +41,11 @@ opType = ComputeDedupDataTupleMask.OP_NAME, inputsClass = ComputeDedupDataTupleMask.Inputs.class ) -@Operator( - group = "tpu" -) public final class ComputeDedupDataTupleMask extends RawOp implements Operand { /** * The name of this op, as known by TensorFlow core engine */ - public static final String OP_NAME = "ComputeDedupDataTupleMask"; + public static final String OP_NAME = "ComputeDedupDataTupleMaskV2"; private Output outputShape; @@ -60,18 +56,25 @@ public ComputeDedupDataTupleMask(Operation operation) { } /** - * Factory method to create a class wrapping a new ComputeDedupDataTupleMask operation. + * Factory method to create a class wrapping a new ComputeDedupDataTupleMaskV2 operation. * * @param scope current scope * @param config Serialized TPUEmbeddingConfiguration proto. + * @param embeddingPartitions Serialized EmbeddingPartitionsProto proto. + * @param hbmBuffersConfig Serialized HbmBuffersConfig proto. + * @param tpuTopology Serialized TpuTopologyArgsProto proto. * @return a new instance of ComputeDedupDataTupleMask */ @Endpoint( describeByClass = true ) - public static ComputeDedupDataTupleMask create(Scope scope, String config) { + public static ComputeDedupDataTupleMask create(Scope scope, String config, + String embeddingPartitions, String hbmBuffersConfig, String tpuTopology) { OperationBuilder opBuilder = scope.opBuilder(OP_NAME, "ComputeDedupDataTupleMask"); opBuilder.setAttr("config", config); + opBuilder.setAttr("embedding_partitions", embeddingPartitions); + opBuilder.setAttr("hbm_buffers_config", hbmBuffersConfig); + opBuilder.setAttr("tpu_topology", tpuTopology); return new ComputeDedupDataTupleMask(opBuilder.build()); } @@ -103,10 +106,28 @@ public static class Inputs extends RawOpInputs { */ public final String config; + /** + * Serialized EmbeddingPartitionsProto proto. + */ + public final String embeddingPartitions; + + /** + * Serialized HbmBuffersConfig proto. + */ + public final String hbmBuffersConfig; + + /** + * Serialized TpuTopologyArgsProto proto. + */ + public final String tpuTopology; + public Inputs(GraphOperation op) { - super(new ComputeDedupDataTupleMask(op), op, Arrays.asList("config")); + super(new ComputeDedupDataTupleMask(op), op, Arrays.asList("config", "embedding_partitions", "hbm_buffers_config", "tpu_topology")); int inputIndex = 0; config = op.attributes().getAttrString("config"); + embeddingPartitions = op.attributes().getAttrString("embedding_partitions"); + hbmBuffersConfig = op.attributes().getAttrString("hbm_buffers_config"); + tpuTopology = op.attributes().getAttrString("tpu_topology"); } } } diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/CrossReplicaSum.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/CrossReplicaSum.java index c56e985eafb..15e942cac31 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/CrossReplicaSum.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/CrossReplicaSum.java @@ -41,8 +41,6 @@ * Passing group_assignment={@code [[0,2,4,6],[1,3,5,7]]} sets {@code A, C, E, G} as group 0, * and {@code B, D, F, H} as group 1. Thus we get the outputs: * {@code [A+C+E+G, B+D+F+H, A+C+E+G, B+D+F+H, A+C+E+G, B+D+F+H, A+C+E+G, B+D+F+H]}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = CrossReplicaSum.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/FinalizeTPUEmbedding.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/FinalizeTPUEmbedding.java index 6ce405ea522..db44a52d05b 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/FinalizeTPUEmbedding.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/FinalizeTPUEmbedding.java @@ -22,6 +22,7 @@ import org.tensorflow.Operand; import org.tensorflow.Operation; import org.tensorflow.OperationBuilder; +import org.tensorflow.Output; import org.tensorflow.op.RawOp; import org.tensorflow.op.RawOpInputs; import org.tensorflow.op.Scope; @@ -45,14 +46,21 @@ public final class FinalizeTPUEmbedding extends RawOp { /** * The name of this op, as known by TensorFlow core engine */ - public static final String OP_NAME = "FinalizeTPUEmbedding"; + public static final String OP_NAME = "FinalizeTPUEmbeddingV2"; + + private Output embeddingPartitions; + + private Output hbmBuffersConfig; public FinalizeTPUEmbedding(Operation operation) { super(operation, OP_NAME); + int outputIdx = 0; + embeddingPartitions = operation.output(outputIdx++); + hbmBuffersConfig = operation.output(outputIdx++); } /** - * Factory method to create a class wrapping a new FinalizeTPUEmbedding operation. + * Factory method to create a class wrapping a new FinalizeTPUEmbeddingV2 operation. * * @param scope current scope * @param commonConfig A string-encoded common configuration proto containing metadata @@ -73,6 +81,26 @@ public static FinalizeTPUEmbedding create(Scope scope, Operand commonCo return new FinalizeTPUEmbedding(opBuilder.build()); } + /** + * Gets embeddingPartitions. + * A string-encoded embedding partitions proto describing how embedding tables are + * partitioned along their feature and ID. + * @return embeddingPartitions. + */ + public Output embeddingPartitions() { + return embeddingPartitions; + } + + /** + * Gets hbmBuffersConfig. + * A string-encoded HBM buffers config proto specifies where HBM buffers are + * located. + * @return hbmBuffersConfig. + */ + public Output hbmBuffersConfig() { + return hbmBuffersConfig; + } + @OpInputsMetadata( outputsClass = FinalizeTPUEmbedding.class ) diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/GetTpuTaskId.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/GetTpuTaskId.java new file mode 100644 index 00000000000..c4eb00be8dd --- /dev/null +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/GetTpuTaskId.java @@ -0,0 +1,97 @@ +/* Copyright 2018-2023 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. +=======================================================================*/ + +// This class has been generated, DO NOT EDIT! + +package org.tensorflow.op.tpu; + +import java.util.Arrays; +import org.tensorflow.GraphOperation; +import org.tensorflow.Operand; +import org.tensorflow.Operation; +import org.tensorflow.OperationBuilder; +import org.tensorflow.Output; +import org.tensorflow.op.RawOp; +import org.tensorflow.op.RawOpInputs; +import org.tensorflow.op.Scope; +import org.tensorflow.op.annotation.Endpoint; +import org.tensorflow.op.annotation.OpInputsMetadata; +import org.tensorflow.op.annotation.OpMetadata; +import org.tensorflow.op.annotation.Operator; +import org.tensorflow.types.TInt32; + +/** + * An op returns the TPU task ID from TPU topology. + * This op is to return the TPU task ID from TPU topology. + */ +@OpMetadata( + opType = GetTpuTaskId.OP_NAME, + inputsClass = GetTpuTaskId.Inputs.class +) +@Operator( + group = "tpu" +) +public final class GetTpuTaskId extends RawOp implements Operand { + /** + * The name of this op, as known by TensorFlow core engine + */ + public static final String OP_NAME = "GetTpuTaskId"; + + private Output tpuTaskId; + + public GetTpuTaskId(Operation operation) { + super(operation, OP_NAME); + int outputIdx = 0; + tpuTaskId = operation.output(outputIdx++); + } + + /** + * Factory method to create a class wrapping a new GetTpuTaskId operation. + * + * @param scope current scope + * @return a new instance of GetTpuTaskId + */ + @Endpoint( + describeByClass = true + ) + public static GetTpuTaskId create(Scope scope) { + OperationBuilder opBuilder = scope.opBuilder(OP_NAME, "GetTpuTaskId"); + return new GetTpuTaskId(opBuilder.build()); + } + + /** + * Gets tpuTaskId. + * The TPU task ID from TPU topology. + * @return tpuTaskId. + */ + public Output tpuTaskId() { + return tpuTaskId; + } + + @Override + public Output asOutput() { + return tpuTaskId; + } + + @OpInputsMetadata( + outputsClass = GetTpuTaskId.class + ) + public static class Inputs extends RawOpInputs { + public Inputs(GraphOperation op) { + super(new GetTpuTaskId(op), op, Arrays.asList()); + int inputIndex = 0; + } + } +} diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/InfeedDequeue.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/InfeedDequeue.java index 20e200e26af..2f2d689a23a 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/InfeedDequeue.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/InfeedDequeue.java @@ -37,8 +37,6 @@ /** * A placeholder op for a value that will be fed into the computation. - * - * @param data type for {@code output} output */ @OpMetadata( opType = InfeedDequeue.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/OutfeedDequeue.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/OutfeedDequeue.java index 27a9edc8214..f2043c5047c 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/OutfeedDequeue.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/OutfeedDequeue.java @@ -38,8 +38,6 @@ /** * Retrieves a single tensor from the computation outfeed. * This operation will block indefinitely until data is available. - * - * @param data type for {@code output} output */ @OpMetadata( opType = OutfeedDequeue.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/OutfeedDequeueV2.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/OutfeedDequeueV2.java index 481f916e86a..dc0d6a3649a 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/OutfeedDequeueV2.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/OutfeedDequeueV2.java @@ -40,8 +40,6 @@ * Retrieves a single tensor from the computation outfeed. Device ordinal is a * tensor allowing dynamic outfeed. * This operation will block indefinitely until data is available. - * - * @param data type for {@code output} output */ @OpMetadata( opType = OutfeedDequeueV2.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/PartitionedInput.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/PartitionedInput.java index be69029e573..89d11541c1b 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/PartitionedInput.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/PartitionedInput.java @@ -37,8 +37,6 @@ /** * An op that groups a list of partitioned inputs together. Supports ND sharding. - * - * @param data type for {@code output} output */ @OpMetadata( opType = PartitionedInput.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/PartitionedOutput.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/PartitionedOutput.java index a49b96f066d..b69bdea9a7b 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/PartitionedOutput.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/PartitionedOutput.java @@ -38,8 +38,6 @@ /** * An op that demultiplexes a tensor to be sharded by XLA to a list of partitioned * outputs outside the XLA computation. Supports ND sharding. - * - * @param data type for {@code output} output */ @OpMetadata( opType = PartitionedOutput.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/ReplicatedInput.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/ReplicatedInput.java index 37c057fc375..5f5ae14be0e 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/ReplicatedInput.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/ReplicatedInput.java @@ -46,8 +46,6 @@ * %computation = "tf.Computation"(%replicated_input) * *

    The above computation has a replicated input of two replicas. - * - * @param data type for {@code output} output */ @OpMetadata( opType = ReplicatedInput.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/ReplicatedOutput.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/ReplicatedOutput.java index fcc447fb932..6daab9ae1a2 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/ReplicatedOutput.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/ReplicatedOutput.java @@ -45,8 +45,6 @@ * %replicated_output:2 = "tf.TPUReplicatedOutput"(%computation) * *

    The above computation has a replicated output of two replicas. - * - * @param data type for {@code outputs} output */ @OpMetadata( opType = ReplicatedOutput.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/SplitDedupData.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/SplitDedupData.java index ad72b480077..8e8d4537dff 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/SplitDedupData.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/SplitDedupData.java @@ -41,10 +41,6 @@ * Deduplication data is an XLA tuple, which consists of integer and floating point * values. This op is to split these values into two groups for two types, and * construct each group as one tensor to return. - * - * @param data type for {@code integer_tensor} output - * - * @param data type for {@code float_tensor} output */ @OpMetadata( opType = SplitDedupData.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/TPUReplicatedInput.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/TPUReplicatedInput.java index 1816bb842df..80ac7e3ea03 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/TPUReplicatedInput.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/TPUReplicatedInput.java @@ -47,8 +47,6 @@ * *

    The above computation has a replicated input of two replicas. * - * @param data type for {@code output} output - * * @deprecated use {@link org.tensorflow.op.tpu.ReplicatedInput} instead */ @OpMetadata( diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/TPUReplicatedOutput.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/TPUReplicatedOutput.java index ea53c36f109..dcc1b12b2b8 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/TPUReplicatedOutput.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/TPUReplicatedOutput.java @@ -46,8 +46,6 @@ * *

    The above computation has a replicated output of two replicas. * - * @param data type for {@code outputs} output - * * @deprecated use {@link org.tensorflow.op.tpu.ReplicatedOutput} instead */ @OpMetadata( diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/UpdateTaskIdAndGlobalCoreArray.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/UpdateTaskIdAndGlobalCoreArray.java new file mode 100644 index 00000000000..1a0fb866178 --- /dev/null +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/tpu/UpdateTaskIdAndGlobalCoreArray.java @@ -0,0 +1,86 @@ +/* Copyright 2018-2023 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. +=======================================================================*/ + +// This class has been generated, DO NOT EDIT! + +package org.tensorflow.op.tpu; + +import java.util.Arrays; +import org.tensorflow.GraphOperation; +import org.tensorflow.Operand; +import org.tensorflow.Operation; +import org.tensorflow.OperationBuilder; +import org.tensorflow.op.Operands; +import org.tensorflow.op.RawOp; +import org.tensorflow.op.RawOpInputs; +import org.tensorflow.op.Scope; +import org.tensorflow.op.annotation.Endpoint; +import org.tensorflow.op.annotation.OpInputsMetadata; +import org.tensorflow.op.annotation.OpMetadata; +import org.tensorflow.types.TInt32; + +/** + * An op to update the task ID and global core array. + * This op is to update the task ID and global core array. + */ +@OpMetadata( + opType = UpdateTaskIdAndGlobalCoreArray.OP_NAME, + inputsClass = UpdateTaskIdAndGlobalCoreArray.Inputs.class +) +public final class UpdateTaskIdAndGlobalCoreArray extends RawOp { + /** + * The name of this op, as known by TensorFlow core engine + */ + public static final String OP_NAME = "UpdateTaskIdAndGlobalCoreArray"; + + public UpdateTaskIdAndGlobalCoreArray(Operation operation) { + super(operation, OP_NAME); + } + + /** + * Factory method to create a class wrapping a new UpdateTaskIdAndGlobalCoreArray operation. + * + * @param scope current scope + * @param tpuTaskIdToShardId An array of int32 that maps TPU task ID to shard ID. + * @return a new instance of UpdateTaskIdAndGlobalCoreArray + */ + @Endpoint( + describeByClass = true + ) + public static UpdateTaskIdAndGlobalCoreArray create(Scope scope, + Iterable> tpuTaskIdToShardId) { + OperationBuilder opBuilder = scope.opBuilder(OP_NAME, "UpdateTaskIdAndGlobalCoreArray"); + opBuilder.addInputList(Operands.asOutputs(tpuTaskIdToShardId)); + return new UpdateTaskIdAndGlobalCoreArray(opBuilder.build()); + } + + @OpInputsMetadata( + outputsClass = UpdateTaskIdAndGlobalCoreArray.class + ) + public static class Inputs extends RawOpInputs { + /** + * An array of int32 that maps TPU task ID to shard ID. + */ + public final Iterable> tpuTaskIdToShardId; + + public Inputs(GraphOperation op) { + super(new UpdateTaskIdAndGlobalCoreArray(op), op, Arrays.asList()); + int inputIndex = 0; + int tpuTaskIdToShardIdLength = op.inputListLength("tpu_task_id_to_shard_id"); + tpuTaskIdToShardId = Arrays.asList((Operand[]) op.inputList(inputIndex, tpuTaskIdToShardIdLength)); + inputIndex += tpuTaskIdToShardIdLength; + } + } +} diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/AccumulatorTakeGradient.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/AccumulatorTakeGradient.java index a2d152ab93e..e7c94866732 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/AccumulatorTakeGradient.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/AccumulatorTakeGradient.java @@ -43,8 +43,6 @@ * aggregated more than num_required gradients, it returns the average of * the accumulated gradients. Also automatically increments the recorded * global_step in the accumulator by 1, and resets the aggregate to 0. - * - * @param data type for {@code average} output */ @OpMetadata( opType = AccumulatorTakeGradient.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyAdaMax.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyAdaMax.java index 5a6b4fa2871..0bdb47444ad 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyAdaMax.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyAdaMax.java @@ -38,8 +38,6 @@ * m_t <- beta1 * m_{t-1} + (1 - beta1) * g * v_t <- max(beta2 * v_{t-1}, abs(g)) * variable <- variable - learning_rate / (1 - beta1^t) * m_t / (v_t + epsilon) - * - * @param data type for {@code out} output */ @OpMetadata( opType = ApplyAdaMax.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyAdadelta.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyAdadelta.java index be5bdc297ea..7d53245fe2a 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyAdadelta.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyAdadelta.java @@ -39,8 +39,6 @@ * update = (update_accum + epsilon).sqrt() * (accum + epsilon()).rsqrt() * grad; * update_accum = rho() * update_accum + (1 - rho()) * update.square(); * var -= update; - * - * @param data type for {@code out} output */ @OpMetadata( opType = ApplyAdadelta.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyAdagrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyAdagrad.java index 9a717cb0daf..0d243bfce4b 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyAdagrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyAdagrad.java @@ -37,8 +37,6 @@ * Update '*var' according to the adagrad scheme. * accum += grad * grad * var -= lr * grad * (1 / sqrt(accum)) - * - * @param data type for {@code out} output */ @OpMetadata( opType = ApplyAdagrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyAdagradDa.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyAdagradDa.java index b1577260bf8..a2769eae2e7 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyAdagradDa.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyAdagradDa.java @@ -36,8 +36,6 @@ /** * Update '*var' according to the proximal adagrad scheme. - * - * @param data type for {@code out} output */ @OpMetadata( opType = ApplyAdagradDa.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyAdagradV2.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyAdagradV2.java index 6766d80538e..22d0edd340e 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyAdagradV2.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyAdagradV2.java @@ -37,8 +37,6 @@ * Update '*var' according to the adagrad scheme. * accum += grad * grad * var -= lr * grad * (1 / sqrt(accum)) - * - * @param data type for {@code out} output */ @OpMetadata( opType = ApplyAdagradV2.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyAdam.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyAdam.java index 91dbb1d72f6..8dbd525dc98 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyAdam.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyAdam.java @@ -39,8 +39,6 @@ * $$m_t := \beta_1 \cdot m{t-1} + (1 - \beta_1) \cdot g$$ * $$v_t := \beta_2 \cdot v_{t-1} + (1 - \beta_2) \cdot g^2$$ * $$\text{var} := \begin{cases} \text{var} - (m_t \beta_1 + g \cdot (1 - \beta_1))\cdot\text{lr}_t/(\sqrt{v_t} + \epsilon), &\text{if use_nesterov}\\ \text{var} - m_t \cdot \text{lr}_t /(\sqrt{v_t} + \epsilon), &\text{otherwise} \end{cases}$$ - * - * @param data type for {@code out} output */ @OpMetadata( opType = ApplyAdam.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyAddSign.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyAddSign.java index 434802b1590..69127231eb1 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyAddSign.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyAddSign.java @@ -38,8 +38,6 @@ * m_t <- beta1 * m_{t-1} + (1 - beta1) * g * update <- (alpha + sign_decay * sign(g) *sign(m)) * g * variable <- variable - lr_t * update - * - * @param data type for {@code out} output */ @OpMetadata( opType = ApplyAddSign.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyCenteredRmsProp.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyCenteredRmsProp.java index 46f9975e74a..f7801bf277e 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyCenteredRmsProp.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyCenteredRmsProp.java @@ -49,8 +49,6 @@ * ms <- rho * ms_{t-1} + (1-rho) * grad * grad * mom <- momentum * mom_{t-1} + lr * grad / sqrt(ms - mg * mg + epsilon) * var <- var - mom - * - * @param data type for {@code out} output */ @OpMetadata( opType = ApplyCenteredRmsProp.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyFtrl.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyFtrl.java index c14505600ef..cd010677d47 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyFtrl.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyFtrl.java @@ -42,8 +42,6 @@ * quadratic = 1.0 / (accum_new^(lr_power) * lr) + 2 * l2 * var = (sign(linear) * l1 - linear) / quadratic if |linear| > l1 else 0.0 * accum = accum_new - * - * @param data type for {@code out} output */ @OpMetadata( opType = ApplyFtrl.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyGradientDescent.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyGradientDescent.java index f7c93955d6b..5ebb7b31330 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyGradientDescent.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyGradientDescent.java @@ -35,8 +35,6 @@ /** * Update '*var' by subtracting 'alpha' * 'delta' from it. - * - * @param data type for {@code out} output */ @OpMetadata( opType = ApplyGradientDescent.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyMomentum.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyMomentum.java index fc82fa94853..1aa402b6783 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyMomentum.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyMomentum.java @@ -38,8 +38,6 @@ * Set use_nesterov = True if you want to use Nesterov momentum. *

    accum = accum * momentum + grad * var -= lr * accum - * - * @param data type for {@code out} output */ @OpMetadata( opType = ApplyMomentum.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyPowerSign.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyPowerSign.java index dad41ae5e50..f298f853be2 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyPowerSign.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyPowerSign.java @@ -38,8 +38,6 @@ * m_t <- beta1 * m_{t-1} + (1 - beta1) * g * update <- exp(logbase * sign_decay * sign(g) * sign(m_t)) * g * variable <- variable - lr_t * update - * - * @param data type for {@code out} output */ @OpMetadata( opType = ApplyPowerSign.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyProximalAdagrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyProximalAdagrad.java index 8f2c0b1d0b2..a095146963b 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyProximalAdagrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyProximalAdagrad.java @@ -38,8 +38,6 @@ * accum += grad * grad * prox_v = var - lr * grad * (1 / sqrt(accum)) * var = sign(prox_v)/(1+lrl2) * max{|prox_v|-lrl1,0} - * - * @param data type for {@code out} output */ @OpMetadata( opType = ApplyProximalAdagrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyProximalGradientDescent.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyProximalGradientDescent.java index 488faf4d559..ffd6ee70e68 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyProximalGradientDescent.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyProximalGradientDescent.java @@ -37,8 +37,6 @@ * Update '*var' as FOBOS algorithm with fixed learning rate. * prox_v = var - alpha * delta * var = sign(prox_v)/(1+alphal2) * max{|prox_v|-alphal1,0} - * - * @param data type for {@code out} output */ @OpMetadata( opType = ApplyProximalGradientDescent.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyRmsProp.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyRmsProp.java index 539fa33e176..fcfeb5b895a 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyRmsProp.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ApplyRmsProp.java @@ -43,8 +43,6 @@ *

    ms <- rho * ms_{t-1} + (1-rho) * grad * grad * mom <- momentum * mom_{t-1} + lr * grad / sqrt(ms + epsilon) * var <- var - mom - * - * @param data type for {@code out} output */ @OpMetadata( opType = ApplyRmsProp.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/BatchMatMul.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/BatchMatMul.java index 14fdcd8d781..17560573705 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/BatchMatMul.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/BatchMatMul.java @@ -56,8 +56,6 @@ *

    NOTE: {@code train.BatchMatMul} supports broadcasting in the batch dimensions. More * about broadcasting * here . - * - * @param data type for {@code output} output */ @OpMetadata( opType = BatchMatMul.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/PreventGradient.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/PreventGradient.java index a7181e6cb0b..c98b11d0050 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/PreventGradient.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/PreventGradient.java @@ -41,8 +41,6 @@ * because no gradient must ever be registered for this function. This * op exists to prevent subtle bugs from silently returning unimplemented * gradients in some corner cases. - * - * @param data type for {@code output} output */ @OpMetadata( opType = PreventGradient.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ResourceAccumulatorTakeGradient.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ResourceAccumulatorTakeGradient.java index 4b7a918f597..843ecae89f1 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ResourceAccumulatorTakeGradient.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/ResourceAccumulatorTakeGradient.java @@ -42,8 +42,6 @@ * aggregated more than num_required gradients, it returns the average of * the accumulated gradients. Also automatically increments the recorded * global_step in the accumulator by 1, and resets the aggregate to 0. - * - * @param data type for {@code average} output */ @OpMetadata( opType = ResourceAccumulatorTakeGradient.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/RestoreSlice.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/RestoreSlice.java index b0faba2454c..a33a34b3179 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/RestoreSlice.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/RestoreSlice.java @@ -42,8 +42,6 @@ * larger tensor and the slice that the restored tensor covers. *

    The {@code shape_and_slice} input has the same format as the * elements of the {@code shapes_and_slices} input of the {@code SaveSlices} op. - * - * @param data type for {@code tensor} output */ @OpMetadata( opType = RestoreSlice.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyAdadelta.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyAdadelta.java index c68618fecc1..8b12e83f51f 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyAdadelta.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyAdadelta.java @@ -36,8 +36,6 @@ /** * var: Should be from a Variable(). - * - * @param data type for {@code out} output */ @OpMetadata( opType = SparseApplyAdadelta.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyAdagrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyAdagrad.java index a75507dde54..fbda4c582a0 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyAdagrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyAdagrad.java @@ -39,8 +39,6 @@ * That is for rows we have grad for, we update var and accum as follows: * $$accum += grad * grad$$ * $$var -= lr * grad * (1 / sqrt(accum))$$ - * - * @param data type for {@code out} output */ @OpMetadata( opType = SparseApplyAdagrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyAdagradDa.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyAdagradDa.java index cdd24328bb6..33cdae176f0 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyAdagradDa.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyAdagradDa.java @@ -37,8 +37,6 @@ /** * Update entries in '*var' and '*accum' according to the proximal adagrad scheme. - * - * @param data type for {@code out} output */ @OpMetadata( opType = SparseApplyAdagradDa.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyCenteredRmsProp.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyCenteredRmsProp.java index 731ecdd88a7..cfbf01b8044 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyCenteredRmsProp.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyCenteredRmsProp.java @@ -49,8 +49,6 @@ *

    $$ms <- rho * ms_{t-1} + (1-rho) * grad * grad$$ * $$mom <- momentum * mom_{t-1} + lr * grad / sqrt(ms + epsilon)$$ * $$var <- var - mom$$ - * - * @param data type for {@code out} output */ @OpMetadata( opType = SparseApplyCenteredRmsProp.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyFtrl.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyFtrl.java index 8c609b198bd..72cce364480 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyFtrl.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyFtrl.java @@ -44,8 +44,6 @@ * quadratic = 1.0 / (accum_new^(lr_power) * lr) + 2 * l2 * var = (sign(linear) * l1 - linear) / quadratic if |linear| > l1 else 0.0 * accum = accum_new - * - * @param data type for {@code out} output */ @OpMetadata( opType = SparseApplyFtrl.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyMomentum.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyMomentum.java index 2e22789fd23..d2ae83d8c17 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyMomentum.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyMomentum.java @@ -40,8 +40,6 @@ *

    That is for rows we have grad for, we update var and accum as follows: *

    $$accum = accum * momentum + grad$$ * $$var -= lr * accum$$ - * - * @param data type for {@code out} output */ @OpMetadata( opType = SparseApplyMomentum.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyProximalAdagrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyProximalAdagrad.java index 68ca59089e1..70b28897f24 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyProximalAdagrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyProximalAdagrad.java @@ -41,8 +41,6 @@ * $$prox_v = var$$ * $$prox_v -= lr * grad * (1 / sqrt(accum))$$ * $$var = sign(prox_v)/(1+lrl2) * max{|prox_v|-lrl1,0}$$ - * - * @param data type for {@code out} output */ @OpMetadata( opType = SparseApplyProximalAdagrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyProximalGradientDescent.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyProximalGradientDescent.java index 08b098f80ca..3da972089e7 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyProximalGradientDescent.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyProximalGradientDescent.java @@ -39,8 +39,6 @@ * That is for rows we have grad for, we update var as follows: * $$prox_v = var - alpha * grad$$ * $$var = sign(prox_v)/(1+alphal2) * max{|prox_v|-alphal1,0}$$ - * - * @param data type for {@code out} output */ @OpMetadata( opType = SparseApplyProximalGradientDescent.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyRmsProp.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyRmsProp.java index a648dc04b08..3c642ebcf81 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyRmsProp.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/SparseApplyRmsProp.java @@ -44,8 +44,6 @@ *

    $$ms <- rho * ms_{t-1} + (1-rho) * grad * grad$$ * $$mom <- momentum * mom_{t-1} + lr * grad / sqrt(ms + epsilon)$$ * $$var <- var - mom$$ - * - * @param data type for {@code out} output */ @OpMetadata( opType = SparseApplyRmsProp.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/TileGrad.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/TileGrad.java index bdc5c23fc46..9e1b7e0fbb4 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/TileGrad.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/train/TileGrad.java @@ -39,8 +39,6 @@ * Since {@code Tile} takes an input and repeats the input {@code multiples} times * along each dimension, {@code train.TileGrad} takes in {@code multiples} and aggregates * each repeated tile of {@code input} into {@code output}. - * - * @param data type for {@code output} output */ @OpMetadata( opType = TileGrad.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/AssignVariableConcatND.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/AssignVariableConcatND.java index 51f000b2687..c58943ff50d 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/AssignVariableConcatND.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/AssignVariableConcatND.java @@ -88,18 +88,8 @@ public AssignVariableConcatND(Operation operation) { * * @param scope current scope * @param resource Resource variable for concatenated input tensors across all dimensions. - * } - * in_arg { - * name: "inputs" - * description: <<END - * Input tensor slices in row-major order to merge across all dimensions. All + * @param inputs Input tensor slices in row-major order to merge across all dimensions. All * inputs must have the same shape. - * } - * out_arg { - * name: "output" - * description: <<END - * Output tensor formed from merging input slices based on num_concats defined. - * @param inputs The inputs value * @param numConcats Number of ways to merge per dimension. * @param options carries optional attribute values * @return a new instance of AssignVariableConcatND @@ -197,22 +187,12 @@ public Options paddings(Long... paddings) { public static class Inputs extends RawOpInputs { /** * Resource variable for concatenated input tensors across all dimensions. - * } - * in_arg { - * name: "inputs" - * description: <<END - * Input tensor slices in row-major order to merge across all dimensions. All - * inputs must have the same shape. - * } - * out_arg { - * name: "output" - * description: <<END - * Output tensor formed from merging input slices based on num_concats defined. */ public final Operand resource; /** - * The inputs input + * Input tensor slices in row-major order to merge across all dimensions. All + * inputs must have the same shape. */ public final Iterable> inputs; diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/ConcatND.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/ConcatND.java index 7e55c95e679..5749305af89 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/ConcatND.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/ConcatND.java @@ -66,8 +66,6 @@ * [4, 5, 6], * [8, 9, 10]] * - * - * @param data type for {@code output} output */ @OpMetadata( opType = ConcatND.OP_NAME, @@ -96,11 +94,6 @@ public ConcatND(Operation operation) { * @param scope current scope * @param inputs Input tensor slices in row-major order to merge across all dimensions. All * inputs must have the same shape. - * } - * out_arg { - * name: "output" - * description: <<END - * Output tensor formed from merging input slices based on num_concats defined. * @param numConcats Number of ways to merge per dimension. * @param options carries optional attribute values * @param data type for {@code XlaConcatND} output and operands @@ -158,7 +151,7 @@ public static Options paddings(Long... paddings) { /** * Gets output. - * + * Output tensor formed from merging input slices based on num_concats defined. * @return output. */ public Output output() { @@ -213,11 +206,6 @@ public static class Inputs extends RawOpInputs> { /** * Input tensor slices in row-major order to merge across all dimensions. All * inputs must have the same shape. - * } - * out_arg { - * name: "output" - * description: <<END - * Output tensor formed from merging input slices based on num_concats defined. */ public final Iterable> inputs; diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/ReadVariableSplitND.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/ReadVariableSplitND.java index 666103dd273..9788f2927f0 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/ReadVariableSplitND.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/ReadVariableSplitND.java @@ -67,8 +67,6 @@ * [[8, 0], * [0, 0]] * - * - * @param data type for {@code outputs} output */ @OpMetadata( opType = ReadVariableSplitND.OP_NAME, @@ -99,11 +97,6 @@ public ReadVariableSplitND(Operation operation) { * * @param scope current scope * @param resource Resource variable of input tensor to split across all dimensions. - * } - * out_arg { - * name: "outputs" - * description: <<END - * Output slices based on input and num_splits defined, in row-major order. * @param T The value of the T attribute * @param N The value of the N attribute * @param numSplits Number of ways to split per dimension. Shape dimensions must be evenly @@ -165,7 +158,7 @@ public static Options paddings(Long... paddings) { /** * Gets outputs. - * + * Output slices based on input and num_splits defined, in row-major order. * @return outputs. */ public List> outputs() { @@ -218,11 +211,6 @@ public Options paddings(Long... paddings) { public static class Inputs extends RawOpInputs> { /** * Resource variable of input tensor to split across all dimensions. - * } - * out_arg { - * name: "outputs" - * description: <<END - * Output slices based on input and num_splits defined, in row-major order. */ public final Operand resource; diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/SplitND.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/SplitND.java index 6bf5656f68c..299b2f95437 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/SplitND.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/SplitND.java @@ -66,8 +66,6 @@ * [[8, 0], * [0, 0]] * - * - * @param data type for {@code outputs} output */ @OpMetadata( opType = SplitND.OP_NAME, @@ -98,11 +96,6 @@ public SplitND(Operation operation) { * * @param scope current scope * @param input Input tensor to split across all dimensions. - * } - * out_arg { - * name: "outputs" - * description: <<END - * Output slices based on input and num_splits defined, in row-major order. * @param N The value of the N attribute * @param numSplits Number of ways to split per dimension. Shape dimensions must be evenly * divisible. @@ -161,7 +154,7 @@ public static Options paddings(Long... paddings) { /** * Gets outputs. - * + * Output slices based on input and num_splits defined, in row-major order. * @return outputs. */ public List> outputs() { @@ -214,11 +207,6 @@ public Options paddings(Long... paddings) { public static class Inputs extends RawOpInputs> { /** * Input tensor to split across all dimensions. - * } - * out_arg { - * name: "outputs" - * description: <<END - * Output slices based on input and num_splits defined, in row-major order. */ public final Operand input; diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/XlaRecvFromHost.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/XlaRecvFromHost.java index c8d5507a673..b05f7199f7a 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/XlaRecvFromHost.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/XlaRecvFromHost.java @@ -41,8 +41,6 @@ * Toutput: element type for output. * shape: shape for output. * key: A unique identifier for this region used to match up host transfers. - * - * @param data type for {@code output} output */ @OpMetadata( opType = XlaRecvFromHost.OP_NAME, diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/XlaRecvTPUEmbeddingActivations.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/XlaRecvTPUEmbeddingActivations.java index 1af06a9de56..b3499a237f0 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/XlaRecvTPUEmbeddingActivations.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/XlaRecvTPUEmbeddingActivations.java @@ -31,7 +31,6 @@ import org.tensorflow.op.annotation.Endpoint; import org.tensorflow.op.annotation.OpInputsMetadata; import org.tensorflow.op.annotation.OpMetadata; -import org.tensorflow.op.annotation.Operator; import org.tensorflow.types.TFloat32; import org.tensorflow.types.family.TType; @@ -46,14 +45,11 @@ opType = XlaRecvTPUEmbeddingActivations.OP_NAME, inputsClass = XlaRecvTPUEmbeddingActivations.Inputs.class ) -@Operator( - group = "xla" -) public final class XlaRecvTPUEmbeddingActivations extends RawOp implements Iterable> { /** * The name of this op, as known by TensorFlow core engine */ - public static final String OP_NAME = "XlaRecvTPUEmbeddingActivations"; + public static final String OP_NAME = "XlaRecvTPUEmbeddingActivationsV2"; private List> outputs; @@ -67,7 +63,7 @@ public XlaRecvTPUEmbeddingActivations(Operation operation) { } /** - * Factory method to create a class wrapping a new XlaRecvTPUEmbeddingActivations operation. + * Factory method to create a class wrapping a new XlaRecvTPUEmbeddingActivationsV2 operation. * * @param scope current scope * @param deduplicationData A Tensor with type=DT_VARIANT containing the deduplication @@ -80,17 +76,24 @@ public XlaRecvTPUEmbeddingActivations(Operation operation) { * present in the tpu embedding config, it is equal to the number of features * otherwise equal to number of embedding tables in the model. * @param config Serialized TPUEmbeddingConfiguration proto. + * @param embeddingPartitions Serialized EmbeddingPartitionsProto proto. + * @param hbmBuffersConfig Serialized HbmBuffersConfig proto. + * @param tpuTopology Serialized TpuTopologyArgsProto proto. * @return a new instance of XlaRecvTPUEmbeddingActivations */ @Endpoint( describeByClass = true ) public static XlaRecvTPUEmbeddingActivations create(Scope scope, - Operand deduplicationData, Long numTables, String config) { + Operand deduplicationData, Long numTables, String config, + String embeddingPartitions, String hbmBuffersConfig, String tpuTopology) { OperationBuilder opBuilder = scope.opBuilder(OP_NAME, "XlaRecvTPUEmbeddingActivations"); opBuilder.addInput(deduplicationData.asOutput()); opBuilder.setAttr("num_tables", numTables); opBuilder.setAttr("config", config); + opBuilder.setAttr("embedding_partitions", embeddingPartitions); + opBuilder.setAttr("hbm_buffers_config", hbmBuffersConfig); + opBuilder.setAttr("tpu_topology", tpuTopology); return new XlaRecvTPUEmbeddingActivations(opBuilder.build()); } @@ -129,11 +132,29 @@ public static class Inputs extends RawOpInputs { */ public final String config; + /** + * Serialized EmbeddingPartitionsProto proto. + */ + public final String embeddingPartitions; + + /** + * Serialized HbmBuffersConfig proto. + */ + public final String hbmBuffersConfig; + + /** + * Serialized TpuTopologyArgsProto proto. + */ + public final String tpuTopology; + public Inputs(GraphOperation op) { - super(new XlaRecvTPUEmbeddingActivations(op), op, Arrays.asList("config")); + super(new XlaRecvTPUEmbeddingActivations(op), op, Arrays.asList("config", "embedding_partitions", "hbm_buffers_config", "tpu_topology")); int inputIndex = 0; deduplicationData = (Operand) op.input(inputIndex++); config = op.attributes().getAttrString("config"); + embeddingPartitions = op.attributes().getAttrString("embedding_partitions"); + hbmBuffersConfig = op.attributes().getAttrString("hbm_buffers_config"); + tpuTopology = op.attributes().getAttrString("tpu_topology"); } } } diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/XlaRecvTPUEmbeddingDeduplicationData.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/XlaRecvTPUEmbeddingDeduplicationData.java index abf76b9a0ad..a0c18fb338c 100644 --- a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/XlaRecvTPUEmbeddingDeduplicationData.java +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/XlaRecvTPUEmbeddingDeduplicationData.java @@ -29,7 +29,6 @@ import org.tensorflow.op.annotation.Endpoint; import org.tensorflow.op.annotation.OpInputsMetadata; import org.tensorflow.op.annotation.OpMetadata; -import org.tensorflow.op.annotation.Operator; import org.tensorflow.types.family.TType; /** @@ -45,14 +44,11 @@ opType = XlaRecvTPUEmbeddingDeduplicationData.OP_NAME, inputsClass = XlaRecvTPUEmbeddingDeduplicationData.Inputs.class ) -@Operator( - group = "xla" -) public final class XlaRecvTPUEmbeddingDeduplicationData extends RawOp implements Operand { /** * The name of this op, as known by TensorFlow core engine */ - public static final String OP_NAME = "XlaRecvTPUEmbeddingDeduplicationData"; + public static final String OP_NAME = "XlaRecvTPUEmbeddingDeduplicationDataV2"; private Output output; @@ -64,18 +60,25 @@ public XlaRecvTPUEmbeddingDeduplicationData(Operation operation) { } /** - * Factory method to create a class wrapping a new XlaRecvTPUEmbeddingDeduplicationData operation. + * Factory method to create a class wrapping a new XlaRecvTPUEmbeddingDeduplicationDataV2 operation. * * @param scope current scope * @param config Serialized TPUEmbeddingConfiguration proto. + * @param embeddingPartitions Serialized EmbeddingPartitionsProto proto. + * @param hbmBuffersConfig Serialized HbmBuffersConfig proto. + * @param tpuTopology Serialized TpuTopologyArgsProto proto. * @return a new instance of XlaRecvTPUEmbeddingDeduplicationData */ @Endpoint( describeByClass = true ) - public static XlaRecvTPUEmbeddingDeduplicationData create(Scope scope, String config) { + public static XlaRecvTPUEmbeddingDeduplicationData create(Scope scope, String config, + String embeddingPartitions, String hbmBuffersConfig, String tpuTopology) { OperationBuilder opBuilder = scope.opBuilder(OP_NAME, "XlaRecvTPUEmbeddingDeduplicationData"); opBuilder.setAttr("config", config); + opBuilder.setAttr("embedding_partitions", embeddingPartitions); + opBuilder.setAttr("hbm_buffers_config", hbmBuffersConfig); + opBuilder.setAttr("tpu_topology", tpuTopology); return new XlaRecvTPUEmbeddingDeduplicationData(opBuilder.build()); } @@ -103,10 +106,28 @@ public static class Inputs extends RawOpInputs> gradients, Iterable> learningRates, - Operand deduplicationData, String config, Options... options) { + Operand deduplicationData, String config, String embeddingPartitions, + String hbmBuffersConfig, String tpuTopology, Options... options) { OperationBuilder opBuilder = scope.opBuilder(OP_NAME, "XlaSendTPUEmbeddingGradients"); opBuilder.addInputList(Operands.asOutputs(gradients)); opBuilder.addInputList(Operands.asOutputs(learningRates)); opBuilder.addInput(deduplicationData.asOutput()); opBuilder.setAttr("config", config); + opBuilder.setAttr("embedding_partitions", embeddingPartitions); + opBuilder.setAttr("hbm_buffers_config", hbmBuffersConfig); + opBuilder.setAttr("tpu_topology", tpuTopology); if (options != null) { for (Options opts : options) { if (opts.NumLearningRateTags != null) { @@ -161,8 +164,23 @@ public static class Inputs extends RawOpInputs { */ public final String config; + /** + * Serialized EmbeddingPartitionsProto proto. + */ + public final String embeddingPartitions; + + /** + * Serialized HbmBuffersConfig proto. + */ + public final String hbmBuffersConfig; + + /** + * Serialized TpuTopologyArgsProto proto. + */ + public final String tpuTopology; + public Inputs(GraphOperation op) { - super(new XlaSendTPUEmbeddingGradients(op), op, Arrays.asList("config")); + super(new XlaSendTPUEmbeddingGradients(op), op, Arrays.asList("config", "embedding_partitions", "hbm_buffers_config", "tpu_topology")); int inputIndex = 0; int gradientsLength = op.inputListLength("gradients"); gradients = Arrays.asList((Operand[]) op.inputList(inputIndex, gradientsLength)); @@ -172,6 +190,9 @@ public Inputs(GraphOperation op) { inputIndex += learningRatesLength; deduplicationData = (Operand) op.input(inputIndex++); config = op.attributes().getAttrString("config"); + embeddingPartitions = op.attributes().getAttrString("embedding_partitions"); + hbmBuffersConfig = op.attributes().getAttrString("hbm_buffers_config"); + tpuTopology = op.attributes().getAttrString("tpu_topology"); } } } diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/XlaSparseDenseMatmulGradWithAdagradAndStaticBufferSize.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/XlaSparseDenseMatmulGradWithAdagradAndStaticBufferSize.java new file mode 100644 index 00000000000..f8ab65a6ee1 --- /dev/null +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/XlaSparseDenseMatmulGradWithAdagradAndStaticBufferSize.java @@ -0,0 +1,279 @@ +/* Copyright 2018-2023 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. +=======================================================================*/ + +// This class has been generated, DO NOT EDIT! + +package org.tensorflow.op.xla; + +import java.util.Arrays; +import org.tensorflow.GraphOperation; +import org.tensorflow.Operand; +import org.tensorflow.Operation; +import org.tensorflow.OperationBuilder; +import org.tensorflow.Output; +import org.tensorflow.op.RawOp; +import org.tensorflow.op.RawOpInputs; +import org.tensorflow.op.Scope; +import org.tensorflow.op.annotation.Endpoint; +import org.tensorflow.op.annotation.OpInputsMetadata; +import org.tensorflow.op.annotation.OpMetadata; +import org.tensorflow.types.TFloat32; +import org.tensorflow.types.TInt32; + +/** + * The XlaSparseDenseMatmulGradWithAdagradAndStaticBufferSize operation + */ +@OpMetadata( + opType = XlaSparseDenseMatmulGradWithAdagradAndStaticBufferSize.OP_NAME, + inputsClass = XlaSparseDenseMatmulGradWithAdagradAndStaticBufferSize.Inputs.class +) +public final class XlaSparseDenseMatmulGradWithAdagradAndStaticBufferSize extends RawOp { + /** + * The name of this op, as known by TensorFlow core engine + */ + public static final String OP_NAME = "XlaSparseDenseMatmulGradWithAdagradAndStaticBufferSize"; + + private Output updatedEmbeddingTable; + + private Output updatedAccumulator; + + public XlaSparseDenseMatmulGradWithAdagradAndStaticBufferSize(Operation operation) { + super(operation, OP_NAME); + int outputIdx = 0; + updatedEmbeddingTable = operation.output(outputIdx++); + updatedAccumulator = operation.output(outputIdx++); + } + + /** + * Factory method to create a class wrapping a new XlaSparseDenseMatmulGradWithAdagradAndStaticBufferSize operation. + * + * @param scope current scope + * @param rowPointers The rowPointers value + * @param sortedSampleIds The sortedSampleIds value + * @param sortedTokenIds The sortedTokenIds value + * @param sortedGains The sortedGains value + * @param activationGradients The activationGradients value + * @param learningRate The learningRate value + * @param embeddingTable The embeddingTable value + * @param accumulator The accumulator value + * @param numMinibatchesPerPhysicalSparseCore The numMinibatchesPerPhysicalSparseCore value + * @param maxIdsPerSparseCore The value of the maxIdsPerSparseCore attribute + * @param maxUniqueIdsPerSparseCore The value of the maxUniqueIdsPerSparseCore attribute + * @param tableName The value of the tableName attribute + * @param options carries optional attribute values + * @return a new instance of XlaSparseDenseMatmulGradWithAdagradAndStaticBufferSize + */ + @Endpoint( + describeByClass = true + ) + public static XlaSparseDenseMatmulGradWithAdagradAndStaticBufferSize create(Scope scope, + Operand rowPointers, Operand sortedSampleIds, Operand sortedTokenIds, + Operand sortedGains, Operand activationGradients, + Operand learningRate, Operand embeddingTable, + Operand accumulator, Operand numMinibatchesPerPhysicalSparseCore, + Long maxIdsPerSparseCore, Long maxUniqueIdsPerSparseCore, String tableName, + Options... options) { + OperationBuilder opBuilder = scope.opBuilder(OP_NAME, "XlaSparseDenseMatmulGradWithAdagradAndStaticBufferSize"); + opBuilder.addInput(rowPointers.asOutput()); + opBuilder.addInput(sortedSampleIds.asOutput()); + opBuilder.addInput(sortedTokenIds.asOutput()); + opBuilder.addInput(sortedGains.asOutput()); + opBuilder.addInput(activationGradients.asOutput()); + opBuilder.addInput(learningRate.asOutput()); + opBuilder.addInput(embeddingTable.asOutput()); + opBuilder.addInput(accumulator.asOutput()); + opBuilder.addInput(numMinibatchesPerPhysicalSparseCore.asOutput()); + opBuilder.setAttr("max_ids_per_sparse_core", maxIdsPerSparseCore); + opBuilder.setAttr("max_unique_ids_per_sparse_core", maxUniqueIdsPerSparseCore); + opBuilder.setAttr("table_name", tableName); + if (options != null) { + for (Options opts : options) { + if (opts.clipWeightMin != null) { + opBuilder.setAttr("clip_weight_min", opts.clipWeightMin); + } + if (opts.clipWeightMax != null) { + opBuilder.setAttr("clip_weight_max", opts.clipWeightMax); + } + } + } + return new XlaSparseDenseMatmulGradWithAdagradAndStaticBufferSize(opBuilder.build()); + } + + /** + * Sets the clipWeightMin option. + * + * @param clipWeightMin the clipWeightMin option + * @return this Options instance. + */ + public static Options clipWeightMin(Float clipWeightMin) { + return new Options().clipWeightMin(clipWeightMin); + } + + /** + * Sets the clipWeightMax option. + * + * @param clipWeightMax the clipWeightMax option + * @return this Options instance. + */ + public static Options clipWeightMax(Float clipWeightMax) { + return new Options().clipWeightMax(clipWeightMax); + } + + /** + * Gets updatedEmbeddingTable. + * + * @return updatedEmbeddingTable. + */ + public Output updatedEmbeddingTable() { + return updatedEmbeddingTable; + } + + /** + * Gets updatedAccumulator. + * + * @return updatedAccumulator. + */ + public Output updatedAccumulator() { + return updatedAccumulator; + } + + /** + * Optional attributes for {@link org.tensorflow.op.xla.XlaSparseDenseMatmulGradWithAdagradAndStaticBufferSize} + */ + public static class Options { + private Float clipWeightMin; + + private Float clipWeightMax; + + private Options() { + } + + /** + * Sets the clipWeightMin option. + * + * @param clipWeightMin the clipWeightMin option + * @return this Options instance. + */ + public Options clipWeightMin(Float clipWeightMin) { + this.clipWeightMin = clipWeightMin; + return this; + } + + /** + * Sets the clipWeightMax option. + * + * @param clipWeightMax the clipWeightMax option + * @return this Options instance. + */ + public Options clipWeightMax(Float clipWeightMax) { + this.clipWeightMax = clipWeightMax; + return this; + } + } + + @OpInputsMetadata( + outputsClass = XlaSparseDenseMatmulGradWithAdagradAndStaticBufferSize.class + ) + public static class Inputs extends RawOpInputs { + /** + * The rowPointers input + */ + public final Operand rowPointers; + + /** + * The sortedSampleIds input + */ + public final Operand sortedSampleIds; + + /** + * The sortedTokenIds input + */ + public final Operand sortedTokenIds; + + /** + * The sortedGains input + */ + public final Operand sortedGains; + + /** + * The activationGradients input + */ + public final Operand activationGradients; + + /** + * The learningRate input + */ + public final Operand learningRate; + + /** + * The embeddingTable input + */ + public final Operand embeddingTable; + + /** + * The accumulator input + */ + public final Operand accumulator; + + /** + * The numMinibatchesPerPhysicalSparseCore input + */ + public final Operand numMinibatchesPerPhysicalSparseCore; + + /** + * The clipWeightMin attribute + */ + public final float clipWeightMin; + + /** + * The clipWeightMax attribute + */ + public final float clipWeightMax; + + /** + * The maxIdsPerSparseCore attribute + */ + public final long maxIdsPerSparseCore; + + /** + * The maxUniqueIdsPerSparseCore attribute + */ + public final long maxUniqueIdsPerSparseCore; + + /** + * The tableName attribute + */ + public final String tableName; + + public Inputs(GraphOperation op) { + super(new XlaSparseDenseMatmulGradWithAdagradAndStaticBufferSize(op), op, Arrays.asList("clip_weight_min", "clip_weight_max", "max_ids_per_sparse_core", "max_unique_ids_per_sparse_core", "table_name")); + int inputIndex = 0; + rowPointers = (Operand) op.input(inputIndex++); + sortedSampleIds = (Operand) op.input(inputIndex++); + sortedTokenIds = (Operand) op.input(inputIndex++); + sortedGains = (Operand) op.input(inputIndex++); + activationGradients = (Operand) op.input(inputIndex++); + learningRate = (Operand) op.input(inputIndex++); + embeddingTable = (Operand) op.input(inputIndex++); + accumulator = (Operand) op.input(inputIndex++); + numMinibatchesPerPhysicalSparseCore = (Operand) op.input(inputIndex++); + clipWeightMin = op.attributes().getAttrFloat("clip_weight_min"); + clipWeightMax = op.attributes().getAttrFloat("clip_weight_max"); + maxIdsPerSparseCore = op.attributes().getAttrInt("max_ids_per_sparse_core"); + maxUniqueIdsPerSparseCore = op.attributes().getAttrInt("max_unique_ids_per_sparse_core"); + tableName = op.attributes().getAttrString("table_name"); + } + } +} diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/XlaSparseDenseMatmulGradWithAdagradMomentumAndStaticBufferSize.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/XlaSparseDenseMatmulGradWithAdagradMomentumAndStaticBufferSize.java new file mode 100644 index 00000000000..e007641d72a --- /dev/null +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/XlaSparseDenseMatmulGradWithAdagradMomentumAndStaticBufferSize.java @@ -0,0 +1,340 @@ +/* Copyright 2018-2023 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. +=======================================================================*/ + +// This class has been generated, DO NOT EDIT! + +package org.tensorflow.op.xla; + +import java.util.Arrays; +import org.tensorflow.GraphOperation; +import org.tensorflow.Operand; +import org.tensorflow.Operation; +import org.tensorflow.OperationBuilder; +import org.tensorflow.Output; +import org.tensorflow.op.RawOp; +import org.tensorflow.op.RawOpInputs; +import org.tensorflow.op.Scope; +import org.tensorflow.op.annotation.Endpoint; +import org.tensorflow.op.annotation.OpInputsMetadata; +import org.tensorflow.op.annotation.OpMetadata; +import org.tensorflow.types.TFloat32; +import org.tensorflow.types.TInt32; + +/** + * The XlaSparseDenseMatmulGradWithAdagradMomentumAndStaticBufferSize operation + */ +@OpMetadata( + opType = XlaSparseDenseMatmulGradWithAdagradMomentumAndStaticBufferSize.OP_NAME, + inputsClass = XlaSparseDenseMatmulGradWithAdagradMomentumAndStaticBufferSize.Inputs.class +) +public final class XlaSparseDenseMatmulGradWithAdagradMomentumAndStaticBufferSize extends RawOp { + /** + * The name of this op, as known by TensorFlow core engine + */ + public static final String OP_NAME = "XlaSparseDenseMatmulGradWithAdagradMomentumAndStaticBufferSize"; + + private Output updatedEmbeddingTable; + + private Output updatedAccumulator; + + private Output updatedMomenta; + + public XlaSparseDenseMatmulGradWithAdagradMomentumAndStaticBufferSize(Operation operation) { + super(operation, OP_NAME); + int outputIdx = 0; + updatedEmbeddingTable = operation.output(outputIdx++); + updatedAccumulator = operation.output(outputIdx++); + updatedMomenta = operation.output(outputIdx++); + } + + /** + * Factory method to create a class wrapping a new XlaSparseDenseMatmulGradWithAdagradMomentumAndStaticBufferSize operation. + * + * @param scope current scope + * @param rowPointers The rowPointers value + * @param sortedSampleIds The sortedSampleIds value + * @param sortedTokenIds The sortedTokenIds value + * @param sortedGains The sortedGains value + * @param activationGradients The activationGradients value + * @param learningRate The learningRate value + * @param embeddingTable The embeddingTable value + * @param accumulator The accumulator value + * @param momenta The momenta value + * @param numMinibatchesPerPhysicalSparseCore The numMinibatchesPerPhysicalSparseCore value + * @param useNesterov The value of the useNesterov attribute + * @param exponent The value of the exponent attribute + * @param beta1 The value of the beta1 attribute + * @param beta2 The value of the beta2 attribute + * @param epsilon The value of the epsilon attribute + * @param maxIdsPerSparseCore The value of the maxIdsPerSparseCore attribute + * @param maxUniqueIdsPerSparseCore The value of the maxUniqueIdsPerSparseCore attribute + * @param tableName The value of the tableName attribute + * @param options carries optional attribute values + * @return a new instance of XlaSparseDenseMatmulGradWithAdagradMomentumAndStaticBufferSize + */ + @Endpoint( + describeByClass = true + ) + public static XlaSparseDenseMatmulGradWithAdagradMomentumAndStaticBufferSize create(Scope scope, + Operand rowPointers, Operand sortedSampleIds, Operand sortedTokenIds, + Operand sortedGains, Operand activationGradients, + Operand learningRate, Operand embeddingTable, + Operand accumulator, Operand momenta, + Operand numMinibatchesPerPhysicalSparseCore, Boolean useNesterov, Float exponent, + Float beta1, Float beta2, Float epsilon, Long maxIdsPerSparseCore, + Long maxUniqueIdsPerSparseCore, String tableName, Options... options) { + OperationBuilder opBuilder = scope.opBuilder(OP_NAME, "XlaSparseDenseMatmulGradWithAdagradMomentumAndStaticBufferSize"); + opBuilder.addInput(rowPointers.asOutput()); + opBuilder.addInput(sortedSampleIds.asOutput()); + opBuilder.addInput(sortedTokenIds.asOutput()); + opBuilder.addInput(sortedGains.asOutput()); + opBuilder.addInput(activationGradients.asOutput()); + opBuilder.addInput(learningRate.asOutput()); + opBuilder.addInput(embeddingTable.asOutput()); + opBuilder.addInput(accumulator.asOutput()); + opBuilder.addInput(momenta.asOutput()); + opBuilder.addInput(numMinibatchesPerPhysicalSparseCore.asOutput()); + opBuilder.setAttr("use_nesterov", useNesterov); + opBuilder.setAttr("exponent", exponent); + opBuilder.setAttr("beta1", beta1); + opBuilder.setAttr("beta2", beta2); + opBuilder.setAttr("epsilon", epsilon); + opBuilder.setAttr("max_ids_per_sparse_core", maxIdsPerSparseCore); + opBuilder.setAttr("max_unique_ids_per_sparse_core", maxUniqueIdsPerSparseCore); + opBuilder.setAttr("table_name", tableName); + if (options != null) { + for (Options opts : options) { + if (opts.clipWeightMin != null) { + opBuilder.setAttr("clip_weight_min", opts.clipWeightMin); + } + if (opts.clipWeightMax != null) { + opBuilder.setAttr("clip_weight_max", opts.clipWeightMax); + } + } + } + return new XlaSparseDenseMatmulGradWithAdagradMomentumAndStaticBufferSize(opBuilder.build()); + } + + /** + * Sets the clipWeightMin option. + * + * @param clipWeightMin the clipWeightMin option + * @return this Options instance. + */ + public static Options clipWeightMin(Float clipWeightMin) { + return new Options().clipWeightMin(clipWeightMin); + } + + /** + * Sets the clipWeightMax option. + * + * @param clipWeightMax the clipWeightMax option + * @return this Options instance. + */ + public static Options clipWeightMax(Float clipWeightMax) { + return new Options().clipWeightMax(clipWeightMax); + } + + /** + * Gets updatedEmbeddingTable. + * + * @return updatedEmbeddingTable. + */ + public Output updatedEmbeddingTable() { + return updatedEmbeddingTable; + } + + /** + * Gets updatedAccumulator. + * + * @return updatedAccumulator. + */ + public Output updatedAccumulator() { + return updatedAccumulator; + } + + /** + * Gets updatedMomenta. + * + * @return updatedMomenta. + */ + public Output updatedMomenta() { + return updatedMomenta; + } + + /** + * Optional attributes for {@link org.tensorflow.op.xla.XlaSparseDenseMatmulGradWithAdagradMomentumAndStaticBufferSize} + */ + public static class Options { + private Float clipWeightMin; + + private Float clipWeightMax; + + private Options() { + } + + /** + * Sets the clipWeightMin option. + * + * @param clipWeightMin the clipWeightMin option + * @return this Options instance. + */ + public Options clipWeightMin(Float clipWeightMin) { + this.clipWeightMin = clipWeightMin; + return this; + } + + /** + * Sets the clipWeightMax option. + * + * @param clipWeightMax the clipWeightMax option + * @return this Options instance. + */ + public Options clipWeightMax(Float clipWeightMax) { + this.clipWeightMax = clipWeightMax; + return this; + } + } + + @OpInputsMetadata( + outputsClass = XlaSparseDenseMatmulGradWithAdagradMomentumAndStaticBufferSize.class + ) + public static class Inputs extends RawOpInputs { + /** + * The rowPointers input + */ + public final Operand rowPointers; + + /** + * The sortedSampleIds input + */ + public final Operand sortedSampleIds; + + /** + * The sortedTokenIds input + */ + public final Operand sortedTokenIds; + + /** + * The sortedGains input + */ + public final Operand sortedGains; + + /** + * The activationGradients input + */ + public final Operand activationGradients; + + /** + * The learningRate input + */ + public final Operand learningRate; + + /** + * The embeddingTable input + */ + public final Operand embeddingTable; + + /** + * The accumulator input + */ + public final Operand accumulator; + + /** + * The momenta input + */ + public final Operand momenta; + + /** + * The numMinibatchesPerPhysicalSparseCore input + */ + public final Operand numMinibatchesPerPhysicalSparseCore; + + /** + * The useNesterov attribute + */ + public final boolean useNesterov; + + /** + * The exponent attribute + */ + public final float exponent; + + /** + * The beta1 attribute + */ + public final float beta1; + + /** + * The beta2 attribute + */ + public final float beta2; + + /** + * The epsilon attribute + */ + public final float epsilon; + + /** + * The clipWeightMin attribute + */ + public final float clipWeightMin; + + /** + * The clipWeightMax attribute + */ + public final float clipWeightMax; + + /** + * The maxIdsPerSparseCore attribute + */ + public final long maxIdsPerSparseCore; + + /** + * The maxUniqueIdsPerSparseCore attribute + */ + public final long maxUniqueIdsPerSparseCore; + + /** + * The tableName attribute + */ + public final String tableName; + + public Inputs(GraphOperation op) { + super(new XlaSparseDenseMatmulGradWithAdagradMomentumAndStaticBufferSize(op), op, Arrays.asList("use_nesterov", "exponent", "beta1", "beta2", "epsilon", "clip_weight_min", "clip_weight_max", "max_ids_per_sparse_core", "max_unique_ids_per_sparse_core", "table_name")); + int inputIndex = 0; + rowPointers = (Operand) op.input(inputIndex++); + sortedSampleIds = (Operand) op.input(inputIndex++); + sortedTokenIds = (Operand) op.input(inputIndex++); + sortedGains = (Operand) op.input(inputIndex++); + activationGradients = (Operand) op.input(inputIndex++); + learningRate = (Operand) op.input(inputIndex++); + embeddingTable = (Operand) op.input(inputIndex++); + accumulator = (Operand) op.input(inputIndex++); + momenta = (Operand) op.input(inputIndex++); + numMinibatchesPerPhysicalSparseCore = (Operand) op.input(inputIndex++); + useNesterov = op.attributes().getAttrBool("use_nesterov"); + exponent = op.attributes().getAttrFloat("exponent"); + beta1 = op.attributes().getAttrFloat("beta1"); + beta2 = op.attributes().getAttrFloat("beta2"); + epsilon = op.attributes().getAttrFloat("epsilon"); + clipWeightMin = op.attributes().getAttrFloat("clip_weight_min"); + clipWeightMax = op.attributes().getAttrFloat("clip_weight_max"); + maxIdsPerSparseCore = op.attributes().getAttrInt("max_ids_per_sparse_core"); + maxUniqueIdsPerSparseCore = op.attributes().getAttrInt("max_unique_ids_per_sparse_core"); + tableName = op.attributes().getAttrString("table_name"); + } + } +} diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/XlaSparseDenseMatmulGradWithAdamAndStaticBufferSize.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/XlaSparseDenseMatmulGradWithAdamAndStaticBufferSize.java new file mode 100644 index 00000000000..fe875c67f69 --- /dev/null +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/XlaSparseDenseMatmulGradWithAdamAndStaticBufferSize.java @@ -0,0 +1,331 @@ +/* Copyright 2018-2023 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. +=======================================================================*/ + +// This class has been generated, DO NOT EDIT! + +package org.tensorflow.op.xla; + +import java.util.Arrays; +import org.tensorflow.GraphOperation; +import org.tensorflow.Operand; +import org.tensorflow.Operation; +import org.tensorflow.OperationBuilder; +import org.tensorflow.Output; +import org.tensorflow.op.RawOp; +import org.tensorflow.op.RawOpInputs; +import org.tensorflow.op.Scope; +import org.tensorflow.op.annotation.Endpoint; +import org.tensorflow.op.annotation.OpInputsMetadata; +import org.tensorflow.op.annotation.OpMetadata; +import org.tensorflow.types.TFloat32; +import org.tensorflow.types.TInt32; + +/** + * The XlaSparseDenseMatmulGradWithAdamAndStaticBufferSize operation + */ +@OpMetadata( + opType = XlaSparseDenseMatmulGradWithAdamAndStaticBufferSize.OP_NAME, + inputsClass = XlaSparseDenseMatmulGradWithAdamAndStaticBufferSize.Inputs.class +) +public final class XlaSparseDenseMatmulGradWithAdamAndStaticBufferSize extends RawOp { + /** + * The name of this op, as known by TensorFlow core engine + */ + public static final String OP_NAME = "XlaSparseDenseMatmulGradWithAdamAndStaticBufferSize"; + + private Output updatedEmbeddingTable; + + private Output updatedMomenta; + + private Output updatedVelocity; + + public XlaSparseDenseMatmulGradWithAdamAndStaticBufferSize(Operation operation) { + super(operation, OP_NAME); + int outputIdx = 0; + updatedEmbeddingTable = operation.output(outputIdx++); + updatedMomenta = operation.output(outputIdx++); + updatedVelocity = operation.output(outputIdx++); + } + + /** + * Factory method to create a class wrapping a new XlaSparseDenseMatmulGradWithAdamAndStaticBufferSize operation. + * + * @param scope current scope + * @param rowPointers The rowPointers value + * @param sortedSampleIds The sortedSampleIds value + * @param sortedTokenIds The sortedTokenIds value + * @param sortedGains The sortedGains value + * @param activationGradients The activationGradients value + * @param learningRate The learningRate value + * @param embeddingTable The embeddingTable value + * @param momenta The momenta value + * @param velocity The velocity value + * @param numMinibatchesPerPhysicalSparseCore The numMinibatchesPerPhysicalSparseCore value + * @param useSumInsideSqrt The value of the useSumInsideSqrt attribute + * @param beta1 The value of the beta1 attribute + * @param beta2 The value of the beta2 attribute + * @param epsilon The value of the epsilon attribute + * @param maxIdsPerSparseCore The value of the maxIdsPerSparseCore attribute + * @param maxUniqueIdsPerSparseCore The value of the maxUniqueIdsPerSparseCore attribute + * @param tableName The value of the tableName attribute + * @param options carries optional attribute values + * @return a new instance of XlaSparseDenseMatmulGradWithAdamAndStaticBufferSize + */ + @Endpoint( + describeByClass = true + ) + public static XlaSparseDenseMatmulGradWithAdamAndStaticBufferSize create(Scope scope, + Operand rowPointers, Operand sortedSampleIds, Operand sortedTokenIds, + Operand sortedGains, Operand activationGradients, + Operand learningRate, Operand embeddingTable, Operand momenta, + Operand velocity, Operand numMinibatchesPerPhysicalSparseCore, + Boolean useSumInsideSqrt, Float beta1, Float beta2, Float epsilon, Long maxIdsPerSparseCore, + Long maxUniqueIdsPerSparseCore, String tableName, Options... options) { + OperationBuilder opBuilder = scope.opBuilder(OP_NAME, "XlaSparseDenseMatmulGradWithAdamAndStaticBufferSize"); + opBuilder.addInput(rowPointers.asOutput()); + opBuilder.addInput(sortedSampleIds.asOutput()); + opBuilder.addInput(sortedTokenIds.asOutput()); + opBuilder.addInput(sortedGains.asOutput()); + opBuilder.addInput(activationGradients.asOutput()); + opBuilder.addInput(learningRate.asOutput()); + opBuilder.addInput(embeddingTable.asOutput()); + opBuilder.addInput(momenta.asOutput()); + opBuilder.addInput(velocity.asOutput()); + opBuilder.addInput(numMinibatchesPerPhysicalSparseCore.asOutput()); + opBuilder.setAttr("use_sum_inside_sqrt", useSumInsideSqrt); + opBuilder.setAttr("beta1", beta1); + opBuilder.setAttr("beta2", beta2); + opBuilder.setAttr("epsilon", epsilon); + opBuilder.setAttr("max_ids_per_sparse_core", maxIdsPerSparseCore); + opBuilder.setAttr("max_unique_ids_per_sparse_core", maxUniqueIdsPerSparseCore); + opBuilder.setAttr("table_name", tableName); + if (options != null) { + for (Options opts : options) { + if (opts.clipWeightMin != null) { + opBuilder.setAttr("clip_weight_min", opts.clipWeightMin); + } + if (opts.clipWeightMax != null) { + opBuilder.setAttr("clip_weight_max", opts.clipWeightMax); + } + } + } + return new XlaSparseDenseMatmulGradWithAdamAndStaticBufferSize(opBuilder.build()); + } + + /** + * Sets the clipWeightMin option. + * + * @param clipWeightMin the clipWeightMin option + * @return this Options instance. + */ + public static Options clipWeightMin(Float clipWeightMin) { + return new Options().clipWeightMin(clipWeightMin); + } + + /** + * Sets the clipWeightMax option. + * + * @param clipWeightMax the clipWeightMax option + * @return this Options instance. + */ + public static Options clipWeightMax(Float clipWeightMax) { + return new Options().clipWeightMax(clipWeightMax); + } + + /** + * Gets updatedEmbeddingTable. + * + * @return updatedEmbeddingTable. + */ + public Output updatedEmbeddingTable() { + return updatedEmbeddingTable; + } + + /** + * Gets updatedMomenta. + * + * @return updatedMomenta. + */ + public Output updatedMomenta() { + return updatedMomenta; + } + + /** + * Gets updatedVelocity. + * + * @return updatedVelocity. + */ + public Output updatedVelocity() { + return updatedVelocity; + } + + /** + * Optional attributes for {@link org.tensorflow.op.xla.XlaSparseDenseMatmulGradWithAdamAndStaticBufferSize} + */ + public static class Options { + private Float clipWeightMin; + + private Float clipWeightMax; + + private Options() { + } + + /** + * Sets the clipWeightMin option. + * + * @param clipWeightMin the clipWeightMin option + * @return this Options instance. + */ + public Options clipWeightMin(Float clipWeightMin) { + this.clipWeightMin = clipWeightMin; + return this; + } + + /** + * Sets the clipWeightMax option. + * + * @param clipWeightMax the clipWeightMax option + * @return this Options instance. + */ + public Options clipWeightMax(Float clipWeightMax) { + this.clipWeightMax = clipWeightMax; + return this; + } + } + + @OpInputsMetadata( + outputsClass = XlaSparseDenseMatmulGradWithAdamAndStaticBufferSize.class + ) + public static class Inputs extends RawOpInputs { + /** + * The rowPointers input + */ + public final Operand rowPointers; + + /** + * The sortedSampleIds input + */ + public final Operand sortedSampleIds; + + /** + * The sortedTokenIds input + */ + public final Operand sortedTokenIds; + + /** + * The sortedGains input + */ + public final Operand sortedGains; + + /** + * The activationGradients input + */ + public final Operand activationGradients; + + /** + * The learningRate input + */ + public final Operand learningRate; + + /** + * The embeddingTable input + */ + public final Operand embeddingTable; + + /** + * The momenta input + */ + public final Operand momenta; + + /** + * The velocity input + */ + public final Operand velocity; + + /** + * The numMinibatchesPerPhysicalSparseCore input + */ + public final Operand numMinibatchesPerPhysicalSparseCore; + + /** + * The useSumInsideSqrt attribute + */ + public final boolean useSumInsideSqrt; + + /** + * The beta1 attribute + */ + public final float beta1; + + /** + * The beta2 attribute + */ + public final float beta2; + + /** + * The epsilon attribute + */ + public final float epsilon; + + /** + * The clipWeightMin attribute + */ + public final float clipWeightMin; + + /** + * The clipWeightMax attribute + */ + public final float clipWeightMax; + + /** + * The maxIdsPerSparseCore attribute + */ + public final long maxIdsPerSparseCore; + + /** + * The maxUniqueIdsPerSparseCore attribute + */ + public final long maxUniqueIdsPerSparseCore; + + /** + * The tableName attribute + */ + public final String tableName; + + public Inputs(GraphOperation op) { + super(new XlaSparseDenseMatmulGradWithAdamAndStaticBufferSize(op), op, Arrays.asList("use_sum_inside_sqrt", "beta1", "beta2", "epsilon", "clip_weight_min", "clip_weight_max", "max_ids_per_sparse_core", "max_unique_ids_per_sparse_core", "table_name")); + int inputIndex = 0; + rowPointers = (Operand) op.input(inputIndex++); + sortedSampleIds = (Operand) op.input(inputIndex++); + sortedTokenIds = (Operand) op.input(inputIndex++); + sortedGains = (Operand) op.input(inputIndex++); + activationGradients = (Operand) op.input(inputIndex++); + learningRate = (Operand) op.input(inputIndex++); + embeddingTable = (Operand) op.input(inputIndex++); + momenta = (Operand) op.input(inputIndex++); + velocity = (Operand) op.input(inputIndex++); + numMinibatchesPerPhysicalSparseCore = (Operand) op.input(inputIndex++); + useSumInsideSqrt = op.attributes().getAttrBool("use_sum_inside_sqrt"); + beta1 = op.attributes().getAttrFloat("beta1"); + beta2 = op.attributes().getAttrFloat("beta2"); + epsilon = op.attributes().getAttrFloat("epsilon"); + clipWeightMin = op.attributes().getAttrFloat("clip_weight_min"); + clipWeightMax = op.attributes().getAttrFloat("clip_weight_max"); + maxIdsPerSparseCore = op.attributes().getAttrInt("max_ids_per_sparse_core"); + maxUniqueIdsPerSparseCore = op.attributes().getAttrInt("max_unique_ids_per_sparse_core"); + tableName = op.attributes().getAttrString("table_name"); + } + } +} diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/XlaSparseDenseMatmulGradWithCsrInput.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/XlaSparseDenseMatmulGradWithCsrInput.java new file mode 100644 index 00000000000..7ac92263e93 --- /dev/null +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/XlaSparseDenseMatmulGradWithCsrInput.java @@ -0,0 +1,184 @@ +/* Copyright 2018-2023 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. +=======================================================================*/ + +// This class has been generated, DO NOT EDIT! + +package org.tensorflow.op.xla; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import org.tensorflow.ConcreteFunction; +import org.tensorflow.GraphOperation; +import org.tensorflow.Operand; +import org.tensorflow.Operation; +import org.tensorflow.OperationBuilder; +import org.tensorflow.Output; +import org.tensorflow.op.Operands; +import org.tensorflow.op.RawOp; +import org.tensorflow.op.RawOpInputs; +import org.tensorflow.op.Scope; +import org.tensorflow.op.annotation.Endpoint; +import org.tensorflow.op.annotation.OpInputsMetadata; +import org.tensorflow.op.annotation.OpMetadata; +import org.tensorflow.types.TFloat32; +import org.tensorflow.types.TInt32; + +/** + * The XlaSparseDenseMatmulGradWithCsrInput operation + */ +@OpMetadata( + opType = XlaSparseDenseMatmulGradWithCsrInput.OP_NAME, + inputsClass = XlaSparseDenseMatmulGradWithCsrInput.Inputs.class +) +public final class XlaSparseDenseMatmulGradWithCsrInput extends RawOp implements Iterable> { + /** + * The name of this op, as known by TensorFlow core engine + */ + public static final String OP_NAME = "XlaSparseDenseMatmulGradWithCsrInput"; + + private List> updatedTables; + + @SuppressWarnings("unchecked") + public XlaSparseDenseMatmulGradWithCsrInput(Operation operation) { + super(operation, OP_NAME); + int outputIdx = 0; + int updatedTablesLength = operation.outputListLength("updated_tables"); + updatedTables = Arrays.asList((Output[]) operation.outputList(outputIdx, updatedTablesLength)); + outputIdx += updatedTablesLength; + } + + /** + * Factory method to create a class wrapping a new XlaSparseDenseMatmulGradWithCsrInput operation. + * + * @param scope current scope + * @param rowPointers The rowPointers value + * @param sortedSampleIds The sortedSampleIds value + * @param sortedTokenIds The sortedTokenIds value + * @param sortedGains The sortedGains value + * @param activationGradients The activationGradients value + * @param tables The tables value + * @param hyperparameters The hyperparameters value + * @param numMinibatchesPerPhysicalSparseCore The numMinibatchesPerPhysicalSparseCore value + * @param customComputation The value of the customComputation attribute + * @param tableName The value of the tableName attribute + * @return a new instance of XlaSparseDenseMatmulGradWithCsrInput + */ + @Endpoint( + describeByClass = true + ) + public static XlaSparseDenseMatmulGradWithCsrInput create(Scope scope, + Operand rowPointers, Operand sortedSampleIds, Operand sortedTokenIds, + Operand sortedGains, Operand activationGradients, + Iterable> tables, Iterable> hyperparameters, + Operand numMinibatchesPerPhysicalSparseCore, ConcreteFunction customComputation, + String tableName) { + OperationBuilder opBuilder = scope.opBuilder(OP_NAME, "XlaSparseDenseMatmulGradWithCsrInput"); + opBuilder.addInput(rowPointers.asOutput()); + opBuilder.addInput(sortedSampleIds.asOutput()); + opBuilder.addInput(sortedTokenIds.asOutput()); + opBuilder.addInput(sortedGains.asOutput()); + opBuilder.addInput(activationGradients.asOutput()); + opBuilder.addInputList(Operands.asOutputs(tables)); + opBuilder.addInputList(Operands.asOutputs(hyperparameters)); + opBuilder.addInput(numMinibatchesPerPhysicalSparseCore.asOutput()); + opBuilder.setAttr("custom_computation", customComputation); + opBuilder.setAttr("table_name", tableName); + return new XlaSparseDenseMatmulGradWithCsrInput(opBuilder.build()); + } + + /** + * Gets updatedTables. + * + * @return updatedTables. + */ + public List> updatedTables() { + return updatedTables; + } + + @Override + @SuppressWarnings({"rawtypes", "unchecked"}) + public Iterator> iterator() { + return (Iterator) updatedTables.iterator(); + } + + @OpInputsMetadata( + outputsClass = XlaSparseDenseMatmulGradWithCsrInput.class + ) + public static class Inputs extends RawOpInputs { + /** + * The rowPointers input + */ + public final Operand rowPointers; + + /** + * The sortedSampleIds input + */ + public final Operand sortedSampleIds; + + /** + * The sortedTokenIds input + */ + public final Operand sortedTokenIds; + + /** + * The sortedGains input + */ + public final Operand sortedGains; + + /** + * The activationGradients input + */ + public final Operand activationGradients; + + /** + * The tables input + */ + public final Iterable> tables; + + /** + * The hyperparameters input + */ + public final Iterable> hyperparameters; + + /** + * The numMinibatchesPerPhysicalSparseCore input + */ + public final Operand numMinibatchesPerPhysicalSparseCore; + + /** + * The tableName attribute + */ + public final String tableName; + + public Inputs(GraphOperation op) { + super(new XlaSparseDenseMatmulGradWithCsrInput(op), op, Arrays.asList("table_name")); + int inputIndex = 0; + rowPointers = (Operand) op.input(inputIndex++); + sortedSampleIds = (Operand) op.input(inputIndex++); + sortedTokenIds = (Operand) op.input(inputIndex++); + sortedGains = (Operand) op.input(inputIndex++); + activationGradients = (Operand) op.input(inputIndex++); + int tablesLength = op.inputListLength("tables"); + tables = Arrays.asList((Operand[]) op.inputList(inputIndex, tablesLength)); + inputIndex += tablesLength; + int hyperparametersLength = op.inputListLength("hyperparameters"); + hyperparameters = Arrays.asList((Operand[]) op.inputList(inputIndex, hyperparametersLength)); + inputIndex += hyperparametersLength; + numMinibatchesPerPhysicalSparseCore = (Operand) op.input(inputIndex++); + tableName = op.attributes().getAttrString("table_name"); + } + } +} diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/XlaSparseDenseMatmulGradWithFtrlAndStaticBufferSize.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/XlaSparseDenseMatmulGradWithFtrlAndStaticBufferSize.java new file mode 100644 index 00000000000..7bfa0c2cc45 --- /dev/null +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/XlaSparseDenseMatmulGradWithFtrlAndStaticBufferSize.java @@ -0,0 +1,341 @@ +/* Copyright 2018-2023 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. +=======================================================================*/ + +// This class has been generated, DO NOT EDIT! + +package org.tensorflow.op.xla; + +import java.util.Arrays; +import org.tensorflow.GraphOperation; +import org.tensorflow.Operand; +import org.tensorflow.Operation; +import org.tensorflow.OperationBuilder; +import org.tensorflow.Output; +import org.tensorflow.op.RawOp; +import org.tensorflow.op.RawOpInputs; +import org.tensorflow.op.Scope; +import org.tensorflow.op.annotation.Endpoint; +import org.tensorflow.op.annotation.OpInputsMetadata; +import org.tensorflow.op.annotation.OpMetadata; +import org.tensorflow.types.TFloat32; +import org.tensorflow.types.TInt32; + +/** + * The XlaSparseDenseMatmulGradWithFtrlAndStaticBufferSize operation + */ +@OpMetadata( + opType = XlaSparseDenseMatmulGradWithFtrlAndStaticBufferSize.OP_NAME, + inputsClass = XlaSparseDenseMatmulGradWithFtrlAndStaticBufferSize.Inputs.class +) +public final class XlaSparseDenseMatmulGradWithFtrlAndStaticBufferSize extends RawOp { + /** + * The name of this op, as known by TensorFlow core engine + */ + public static final String OP_NAME = "XlaSparseDenseMatmulGradWithFtrlAndStaticBufferSize"; + + private Output updatedEmbeddingTable; + + private Output updatedAccumulator; + + private Output updatedLinear; + + public XlaSparseDenseMatmulGradWithFtrlAndStaticBufferSize(Operation operation) { + super(operation, OP_NAME); + int outputIdx = 0; + updatedEmbeddingTable = operation.output(outputIdx++); + updatedAccumulator = operation.output(outputIdx++); + updatedLinear = operation.output(outputIdx++); + } + + /** + * Factory method to create a class wrapping a new XlaSparseDenseMatmulGradWithFtrlAndStaticBufferSize operation. + * + * @param scope current scope + * @param rowPointers The rowPointers value + * @param sortedSampleIds The sortedSampleIds value + * @param sortedTokenIds The sortedTokenIds value + * @param sortedGains The sortedGains value + * @param activationGradients The activationGradients value + * @param learningRate The learningRate value + * @param embeddingTable The embeddingTable value + * @param accumulator The accumulator value + * @param linear The linear value + * @param numMinibatchesPerPhysicalSparseCore The numMinibatchesPerPhysicalSparseCore value + * @param multiplyLinearByLearningRate The value of the multiplyLinearByLearningRate attribute + * @param beta The value of the beta attribute + * @param learningRatePower The value of the learningRatePower attribute + * @param l1RegularizationStrength The value of the l1RegularizationStrength attribute + * @param l2RegularizationStrength The value of the l2RegularizationStrength attribute + * @param maxIdsPerSparseCore The value of the maxIdsPerSparseCore attribute + * @param maxUniqueIdsPerSparseCore The value of the maxUniqueIdsPerSparseCore attribute + * @param tableName The value of the tableName attribute + * @param options carries optional attribute values + * @return a new instance of XlaSparseDenseMatmulGradWithFtrlAndStaticBufferSize + */ + @Endpoint( + describeByClass = true + ) + public static XlaSparseDenseMatmulGradWithFtrlAndStaticBufferSize create(Scope scope, + Operand rowPointers, Operand sortedSampleIds, Operand sortedTokenIds, + Operand sortedGains, Operand activationGradients, + Operand learningRate, Operand embeddingTable, + Operand accumulator, Operand linear, + Operand numMinibatchesPerPhysicalSparseCore, Boolean multiplyLinearByLearningRate, + Float beta, Float learningRatePower, Float l1RegularizationStrength, + Float l2RegularizationStrength, Long maxIdsPerSparseCore, Long maxUniqueIdsPerSparseCore, + String tableName, Options... options) { + OperationBuilder opBuilder = scope.opBuilder(OP_NAME, "XlaSparseDenseMatmulGradWithFtrlAndStaticBufferSize"); + opBuilder.addInput(rowPointers.asOutput()); + opBuilder.addInput(sortedSampleIds.asOutput()); + opBuilder.addInput(sortedTokenIds.asOutput()); + opBuilder.addInput(sortedGains.asOutput()); + opBuilder.addInput(activationGradients.asOutput()); + opBuilder.addInput(learningRate.asOutput()); + opBuilder.addInput(embeddingTable.asOutput()); + opBuilder.addInput(accumulator.asOutput()); + opBuilder.addInput(linear.asOutput()); + opBuilder.addInput(numMinibatchesPerPhysicalSparseCore.asOutput()); + opBuilder.setAttr("multiply_linear_by_learning_rate", multiplyLinearByLearningRate); + opBuilder.setAttr("beta", beta); + opBuilder.setAttr("learning_rate_power", learningRatePower); + opBuilder.setAttr("l1_regularization_strength", l1RegularizationStrength); + opBuilder.setAttr("l2_regularization_strength", l2RegularizationStrength); + opBuilder.setAttr("max_ids_per_sparse_core", maxIdsPerSparseCore); + opBuilder.setAttr("max_unique_ids_per_sparse_core", maxUniqueIdsPerSparseCore); + opBuilder.setAttr("table_name", tableName); + if (options != null) { + for (Options opts : options) { + if (opts.clipWeightMin != null) { + opBuilder.setAttr("clip_weight_min", opts.clipWeightMin); + } + if (opts.clipWeightMax != null) { + opBuilder.setAttr("clip_weight_max", opts.clipWeightMax); + } + } + } + return new XlaSparseDenseMatmulGradWithFtrlAndStaticBufferSize(opBuilder.build()); + } + + /** + * Sets the clipWeightMin option. + * + * @param clipWeightMin the clipWeightMin option + * @return this Options instance. + */ + public static Options clipWeightMin(Float clipWeightMin) { + return new Options().clipWeightMin(clipWeightMin); + } + + /** + * Sets the clipWeightMax option. + * + * @param clipWeightMax the clipWeightMax option + * @return this Options instance. + */ + public static Options clipWeightMax(Float clipWeightMax) { + return new Options().clipWeightMax(clipWeightMax); + } + + /** + * Gets updatedEmbeddingTable. + * + * @return updatedEmbeddingTable. + */ + public Output updatedEmbeddingTable() { + return updatedEmbeddingTable; + } + + /** + * Gets updatedAccumulator. + * + * @return updatedAccumulator. + */ + public Output updatedAccumulator() { + return updatedAccumulator; + } + + /** + * Gets updatedLinear. + * + * @return updatedLinear. + */ + public Output updatedLinear() { + return updatedLinear; + } + + /** + * Optional attributes for {@link org.tensorflow.op.xla.XlaSparseDenseMatmulGradWithFtrlAndStaticBufferSize} + */ + public static class Options { + private Float clipWeightMin; + + private Float clipWeightMax; + + private Options() { + } + + /** + * Sets the clipWeightMin option. + * + * @param clipWeightMin the clipWeightMin option + * @return this Options instance. + */ + public Options clipWeightMin(Float clipWeightMin) { + this.clipWeightMin = clipWeightMin; + return this; + } + + /** + * Sets the clipWeightMax option. + * + * @param clipWeightMax the clipWeightMax option + * @return this Options instance. + */ + public Options clipWeightMax(Float clipWeightMax) { + this.clipWeightMax = clipWeightMax; + return this; + } + } + + @OpInputsMetadata( + outputsClass = XlaSparseDenseMatmulGradWithFtrlAndStaticBufferSize.class + ) + public static class Inputs extends RawOpInputs { + /** + * The rowPointers input + */ + public final Operand rowPointers; + + /** + * The sortedSampleIds input + */ + public final Operand sortedSampleIds; + + /** + * The sortedTokenIds input + */ + public final Operand sortedTokenIds; + + /** + * The sortedGains input + */ + public final Operand sortedGains; + + /** + * The activationGradients input + */ + public final Operand activationGradients; + + /** + * The learningRate input + */ + public final Operand learningRate; + + /** + * The embeddingTable input + */ + public final Operand embeddingTable; + + /** + * The accumulator input + */ + public final Operand accumulator; + + /** + * The linear input + */ + public final Operand linear; + + /** + * The numMinibatchesPerPhysicalSparseCore input + */ + public final Operand numMinibatchesPerPhysicalSparseCore; + + /** + * The multiplyLinearByLearningRate attribute + */ + public final boolean multiplyLinearByLearningRate; + + /** + * The beta attribute + */ + public final float beta; + + /** + * The learningRatePower attribute + */ + public final float learningRatePower; + + /** + * The l1RegularizationStrength attribute + */ + public final float l1RegularizationStrength; + + /** + * The l2RegularizationStrength attribute + */ + public final float l2RegularizationStrength; + + /** + * The clipWeightMin attribute + */ + public final float clipWeightMin; + + /** + * The clipWeightMax attribute + */ + public final float clipWeightMax; + + /** + * The maxIdsPerSparseCore attribute + */ + public final long maxIdsPerSparseCore; + + /** + * The maxUniqueIdsPerSparseCore attribute + */ + public final long maxUniqueIdsPerSparseCore; + + /** + * The tableName attribute + */ + public final String tableName; + + public Inputs(GraphOperation op) { + super(new XlaSparseDenseMatmulGradWithFtrlAndStaticBufferSize(op), op, Arrays.asList("multiply_linear_by_learning_rate", "beta", "learning_rate_power", "l1_regularization_strength", "l2_regularization_strength", "clip_weight_min", "clip_weight_max", "max_ids_per_sparse_core", "max_unique_ids_per_sparse_core", "table_name")); + int inputIndex = 0; + rowPointers = (Operand) op.input(inputIndex++); + sortedSampleIds = (Operand) op.input(inputIndex++); + sortedTokenIds = (Operand) op.input(inputIndex++); + sortedGains = (Operand) op.input(inputIndex++); + activationGradients = (Operand) op.input(inputIndex++); + learningRate = (Operand) op.input(inputIndex++); + embeddingTable = (Operand) op.input(inputIndex++); + accumulator = (Operand) op.input(inputIndex++); + linear = (Operand) op.input(inputIndex++); + numMinibatchesPerPhysicalSparseCore = (Operand) op.input(inputIndex++); + multiplyLinearByLearningRate = op.attributes().getAttrBool("multiply_linear_by_learning_rate"); + beta = op.attributes().getAttrFloat("beta"); + learningRatePower = op.attributes().getAttrFloat("learning_rate_power"); + l1RegularizationStrength = op.attributes().getAttrFloat("l1_regularization_strength"); + l2RegularizationStrength = op.attributes().getAttrFloat("l2_regularization_strength"); + clipWeightMin = op.attributes().getAttrFloat("clip_weight_min"); + clipWeightMax = op.attributes().getAttrFloat("clip_weight_max"); + maxIdsPerSparseCore = op.attributes().getAttrInt("max_ids_per_sparse_core"); + maxUniqueIdsPerSparseCore = op.attributes().getAttrInt("max_unique_ids_per_sparse_core"); + tableName = op.attributes().getAttrString("table_name"); + } + } +} diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/XlaSparseDenseMatmulGradWithSgdAndStaticBufferSize.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/XlaSparseDenseMatmulGradWithSgdAndStaticBufferSize.java new file mode 100644 index 00000000000..65c059d2821 --- /dev/null +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/XlaSparseDenseMatmulGradWithSgdAndStaticBufferSize.java @@ -0,0 +1,263 @@ +/* Copyright 2018-2023 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. +=======================================================================*/ + +// This class has been generated, DO NOT EDIT! + +package org.tensorflow.op.xla; + +import java.util.Arrays; +import org.tensorflow.GraphOperation; +import org.tensorflow.Operand; +import org.tensorflow.Operation; +import org.tensorflow.OperationBuilder; +import org.tensorflow.Output; +import org.tensorflow.op.RawOp; +import org.tensorflow.op.RawOpInputs; +import org.tensorflow.op.Scope; +import org.tensorflow.op.annotation.Endpoint; +import org.tensorflow.op.annotation.OpInputsMetadata; +import org.tensorflow.op.annotation.OpMetadata; +import org.tensorflow.types.TFloat32; +import org.tensorflow.types.TInt32; + +/** + * The XlaSparseDenseMatmulGradWithSgdAndStaticBufferSize operation + */ +@OpMetadata( + opType = XlaSparseDenseMatmulGradWithSgdAndStaticBufferSize.OP_NAME, + inputsClass = XlaSparseDenseMatmulGradWithSgdAndStaticBufferSize.Inputs.class +) +public final class XlaSparseDenseMatmulGradWithSgdAndStaticBufferSize extends RawOp implements Operand { + /** + * The name of this op, as known by TensorFlow core engine + */ + public static final String OP_NAME = "XlaSparseDenseMatmulGradWithSgdAndStaticBufferSize"; + + private Output updatedEmbeddingTable; + + public XlaSparseDenseMatmulGradWithSgdAndStaticBufferSize(Operation operation) { + super(operation, OP_NAME); + int outputIdx = 0; + updatedEmbeddingTable = operation.output(outputIdx++); + } + + /** + * Factory method to create a class wrapping a new XlaSparseDenseMatmulGradWithSgdAndStaticBufferSize operation. + * + * @param scope current scope + * @param rowPointers The rowPointers value + * @param sortedSampleIds The sortedSampleIds value + * @param sortedTokenIds The sortedTokenIds value + * @param sortedGains The sortedGains value + * @param activationGradients The activationGradients value + * @param learningRate The learningRate value + * @param embeddingTable The embeddingTable value + * @param numMinibatchesPerPhysicalSparseCore The numMinibatchesPerPhysicalSparseCore value + * @param maxIdsPerSparseCore The value of the maxIdsPerSparseCore attribute + * @param maxUniqueIdsPerSparseCore The value of the maxUniqueIdsPerSparseCore attribute + * @param tableName The value of the tableName attribute + * @param options carries optional attribute values + * @return a new instance of XlaSparseDenseMatmulGradWithSgdAndStaticBufferSize + */ + @Endpoint( + describeByClass = true + ) + public static XlaSparseDenseMatmulGradWithSgdAndStaticBufferSize create(Scope scope, + Operand rowPointers, Operand sortedSampleIds, Operand sortedTokenIds, + Operand sortedGains, Operand activationGradients, + Operand learningRate, Operand embeddingTable, + Operand numMinibatchesPerPhysicalSparseCore, Long maxIdsPerSparseCore, + Long maxUniqueIdsPerSparseCore, String tableName, Options... options) { + OperationBuilder opBuilder = scope.opBuilder(OP_NAME, "XlaSparseDenseMatmulGradWithSgdAndStaticBufferSize"); + opBuilder.addInput(rowPointers.asOutput()); + opBuilder.addInput(sortedSampleIds.asOutput()); + opBuilder.addInput(sortedTokenIds.asOutput()); + opBuilder.addInput(sortedGains.asOutput()); + opBuilder.addInput(activationGradients.asOutput()); + opBuilder.addInput(learningRate.asOutput()); + opBuilder.addInput(embeddingTable.asOutput()); + opBuilder.addInput(numMinibatchesPerPhysicalSparseCore.asOutput()); + opBuilder.setAttr("max_ids_per_sparse_core", maxIdsPerSparseCore); + opBuilder.setAttr("max_unique_ids_per_sparse_core", maxUniqueIdsPerSparseCore); + opBuilder.setAttr("table_name", tableName); + if (options != null) { + for (Options opts : options) { + if (opts.clipWeightMin != null) { + opBuilder.setAttr("clip_weight_min", opts.clipWeightMin); + } + if (opts.clipWeightMax != null) { + opBuilder.setAttr("clip_weight_max", opts.clipWeightMax); + } + } + } + return new XlaSparseDenseMatmulGradWithSgdAndStaticBufferSize(opBuilder.build()); + } + + /** + * Sets the clipWeightMin option. + * + * @param clipWeightMin the clipWeightMin option + * @return this Options instance. + */ + public static Options clipWeightMin(Float clipWeightMin) { + return new Options().clipWeightMin(clipWeightMin); + } + + /** + * Sets the clipWeightMax option. + * + * @param clipWeightMax the clipWeightMax option + * @return this Options instance. + */ + public static Options clipWeightMax(Float clipWeightMax) { + return new Options().clipWeightMax(clipWeightMax); + } + + /** + * Gets updatedEmbeddingTable. + * + * @return updatedEmbeddingTable. + */ + public Output updatedEmbeddingTable() { + return updatedEmbeddingTable; + } + + @Override + public Output asOutput() { + return updatedEmbeddingTable; + } + + /** + * Optional attributes for {@link org.tensorflow.op.xla.XlaSparseDenseMatmulGradWithSgdAndStaticBufferSize} + */ + public static class Options { + private Float clipWeightMin; + + private Float clipWeightMax; + + private Options() { + } + + /** + * Sets the clipWeightMin option. + * + * @param clipWeightMin the clipWeightMin option + * @return this Options instance. + */ + public Options clipWeightMin(Float clipWeightMin) { + this.clipWeightMin = clipWeightMin; + return this; + } + + /** + * Sets the clipWeightMax option. + * + * @param clipWeightMax the clipWeightMax option + * @return this Options instance. + */ + public Options clipWeightMax(Float clipWeightMax) { + this.clipWeightMax = clipWeightMax; + return this; + } + } + + @OpInputsMetadata( + outputsClass = XlaSparseDenseMatmulGradWithSgdAndStaticBufferSize.class + ) + public static class Inputs extends RawOpInputs { + /** + * The rowPointers input + */ + public final Operand rowPointers; + + /** + * The sortedSampleIds input + */ + public final Operand sortedSampleIds; + + /** + * The sortedTokenIds input + */ + public final Operand sortedTokenIds; + + /** + * The sortedGains input + */ + public final Operand sortedGains; + + /** + * The activationGradients input + */ + public final Operand activationGradients; + + /** + * The learningRate input + */ + public final Operand learningRate; + + /** + * The embeddingTable input + */ + public final Operand embeddingTable; + + /** + * The numMinibatchesPerPhysicalSparseCore input + */ + public final Operand numMinibatchesPerPhysicalSparseCore; + + /** + * The clipWeightMin attribute + */ + public final float clipWeightMin; + + /** + * The clipWeightMax attribute + */ + public final float clipWeightMax; + + /** + * The maxIdsPerSparseCore attribute + */ + public final long maxIdsPerSparseCore; + + /** + * The maxUniqueIdsPerSparseCore attribute + */ + public final long maxUniqueIdsPerSparseCore; + + /** + * The tableName attribute + */ + public final String tableName; + + public Inputs(GraphOperation op) { + super(new XlaSparseDenseMatmulGradWithSgdAndStaticBufferSize(op), op, Arrays.asList("clip_weight_min", "clip_weight_max", "max_ids_per_sparse_core", "max_unique_ids_per_sparse_core", "table_name")); + int inputIndex = 0; + rowPointers = (Operand) op.input(inputIndex++); + sortedSampleIds = (Operand) op.input(inputIndex++); + sortedTokenIds = (Operand) op.input(inputIndex++); + sortedGains = (Operand) op.input(inputIndex++); + activationGradients = (Operand) op.input(inputIndex++); + learningRate = (Operand) op.input(inputIndex++); + embeddingTable = (Operand) op.input(inputIndex++); + numMinibatchesPerPhysicalSparseCore = (Operand) op.input(inputIndex++); + clipWeightMin = op.attributes().getAttrFloat("clip_weight_min"); + clipWeightMax = op.attributes().getAttrFloat("clip_weight_max"); + maxIdsPerSparseCore = op.attributes().getAttrInt("max_ids_per_sparse_core"); + maxUniqueIdsPerSparseCore = op.attributes().getAttrInt("max_unique_ids_per_sparse_core"); + tableName = op.attributes().getAttrString("table_name"); + } + } +} diff --git a/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/XlaSparseDenseMatmulWithStaticBufferSize.java b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/XlaSparseDenseMatmulWithStaticBufferSize.java new file mode 100644 index 00000000000..268a9b0fc4b --- /dev/null +++ b/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/op/xla/XlaSparseDenseMatmulWithStaticBufferSize.java @@ -0,0 +1,202 @@ +/* Copyright 2018-2023 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. +=======================================================================*/ + +// This class has been generated, DO NOT EDIT! + +package org.tensorflow.op.xla; + +import java.util.Arrays; +import org.tensorflow.GraphOperation; +import org.tensorflow.Operand; +import org.tensorflow.Operation; +import org.tensorflow.OperationBuilder; +import org.tensorflow.Output; +import org.tensorflow.op.RawOp; +import org.tensorflow.op.RawOpInputs; +import org.tensorflow.op.Scope; +import org.tensorflow.op.annotation.Endpoint; +import org.tensorflow.op.annotation.OpInputsMetadata; +import org.tensorflow.op.annotation.OpMetadata; +import org.tensorflow.types.TFloat32; +import org.tensorflow.types.TInt32; + +/** + * The XlaSparseDenseMatmulWithStaticBufferSize operation + */ +@OpMetadata( + opType = XlaSparseDenseMatmulWithStaticBufferSize.OP_NAME, + inputsClass = XlaSparseDenseMatmulWithStaticBufferSize.Inputs.class +) +public final class XlaSparseDenseMatmulWithStaticBufferSize extends RawOp implements Operand { + /** + * The name of this op, as known by TensorFlow core engine + */ + public static final String OP_NAME = "XlaSparseDenseMatmulWithStaticBufferSize"; + + private Output activations; + + public XlaSparseDenseMatmulWithStaticBufferSize(Operation operation) { + super(operation, OP_NAME); + int outputIdx = 0; + activations = operation.output(outputIdx++); + } + + /** + * Factory method to create a class wrapping a new XlaSparseDenseMatmulWithStaticBufferSize operation. + * + * @param scope current scope + * @param rowPointers The rowPointers value + * @param sortedSampleIds The sortedSampleIds value + * @param sortedTokenIds The sortedTokenIds value + * @param sortedGains The sortedGains value + * @param embeddingTable The embeddingTable value + * @param numMinibatchesPerPhysicalSparseCore The numMinibatchesPerPhysicalSparseCore value + * @param inputSize The value of the inputSize attribute + * @param quantizationConfigLow The value of the quantizationConfigLow attribute + * @param quantizationConfigHigh The value of the quantizationConfigHigh attribute + * @param quantizationConfigNumBuckets The value of the quantizationConfigNumBuckets attribute + * @param maxIdsPerSparseCore The value of the maxIdsPerSparseCore attribute + * @param maxUniqueIdsPerSparseCore The value of the maxUniqueIdsPerSparseCore attribute + * @param tableName The value of the tableName attribute + * @return a new instance of XlaSparseDenseMatmulWithStaticBufferSize + */ + @Endpoint( + describeByClass = true + ) + public static XlaSparseDenseMatmulWithStaticBufferSize create(Scope scope, + Operand rowPointers, Operand sortedSampleIds, Operand sortedTokenIds, + Operand sortedGains, Operand embeddingTable, + Operand numMinibatchesPerPhysicalSparseCore, Long inputSize, + Float quantizationConfigLow, Float quantizationConfigHigh, Long quantizationConfigNumBuckets, + Long maxIdsPerSparseCore, Long maxUniqueIdsPerSparseCore, String tableName) { + OperationBuilder opBuilder = scope.opBuilder(OP_NAME, "XlaSparseDenseMatmulWithStaticBufferSize"); + opBuilder.addInput(rowPointers.asOutput()); + opBuilder.addInput(sortedSampleIds.asOutput()); + opBuilder.addInput(sortedTokenIds.asOutput()); + opBuilder.addInput(sortedGains.asOutput()); + opBuilder.addInput(embeddingTable.asOutput()); + opBuilder.addInput(numMinibatchesPerPhysicalSparseCore.asOutput()); + opBuilder.setAttr("input_size", inputSize); + opBuilder.setAttr("quantization_config_low", quantizationConfigLow); + opBuilder.setAttr("quantization_config_high", quantizationConfigHigh); + opBuilder.setAttr("quantization_config_num_buckets", quantizationConfigNumBuckets); + opBuilder.setAttr("max_ids_per_sparse_core", maxIdsPerSparseCore); + opBuilder.setAttr("max_unique_ids_per_sparse_core", maxUniqueIdsPerSparseCore); + opBuilder.setAttr("table_name", tableName); + return new XlaSparseDenseMatmulWithStaticBufferSize(opBuilder.build()); + } + + /** + * Gets activations. + * + * @return activations. + */ + public Output activations() { + return activations; + } + + @Override + public Output asOutput() { + return activations; + } + + @OpInputsMetadata( + outputsClass = XlaSparseDenseMatmulWithStaticBufferSize.class + ) + public static class Inputs extends RawOpInputs { + /** + * The rowPointers input + */ + public final Operand rowPointers; + + /** + * The sortedSampleIds input + */ + public final Operand sortedSampleIds; + + /** + * The sortedTokenIds input + */ + public final Operand sortedTokenIds; + + /** + * The sortedGains input + */ + public final Operand sortedGains; + + /** + * The embeddingTable input + */ + public final Operand embeddingTable; + + /** + * The numMinibatchesPerPhysicalSparseCore input + */ + public final Operand numMinibatchesPerPhysicalSparseCore; + + /** + * The inputSize attribute + */ + public final long inputSize; + + /** + * The quantizationConfigLow attribute + */ + public final float quantizationConfigLow; + + /** + * The quantizationConfigHigh attribute + */ + public final float quantizationConfigHigh; + + /** + * The quantizationConfigNumBuckets attribute + */ + public final long quantizationConfigNumBuckets; + + /** + * The maxIdsPerSparseCore attribute + */ + public final long maxIdsPerSparseCore; + + /** + * The maxUniqueIdsPerSparseCore attribute + */ + public final long maxUniqueIdsPerSparseCore; + + /** + * The tableName attribute + */ + public final String tableName; + + public Inputs(GraphOperation op) { + super(new XlaSparseDenseMatmulWithStaticBufferSize(op), op, Arrays.asList("input_size", "quantization_config_low", "quantization_config_high", "quantization_config_num_buckets", "max_ids_per_sparse_core", "max_unique_ids_per_sparse_core", "table_name")); + int inputIndex = 0; + rowPointers = (Operand) op.input(inputIndex++); + sortedSampleIds = (Operand) op.input(inputIndex++); + sortedTokenIds = (Operand) op.input(inputIndex++); + sortedGains = (Operand) op.input(inputIndex++); + embeddingTable = (Operand) op.input(inputIndex++); + numMinibatchesPerPhysicalSparseCore = (Operand) op.input(inputIndex++); + inputSize = op.attributes().getAttrInt("input_size"); + quantizationConfigLow = op.attributes().getAttrFloat("quantization_config_low"); + quantizationConfigHigh = op.attributes().getAttrFloat("quantization_config_high"); + quantizationConfigNumBuckets = op.attributes().getAttrInt("quantization_config_num_buckets"); + maxIdsPerSparseCore = op.attributes().getAttrInt("max_ids_per_sparse_core"); + maxUniqueIdsPerSparseCore = op.attributes().getAttrInt("max_unique_ids_per_sparse_core"); + tableName = op.attributes().getAttrString("table_name"); + } + } +} diff --git a/tensorflow-core/tensorflow-core-generator/pom.xml b/tensorflow-core/tensorflow-core-generator/pom.xml index a90d85a1d4b..923bd52b4e6 100644 --- a/tensorflow-core/tensorflow-core-generator/pom.xml +++ b/tensorflow-core/tensorflow-core-generator/pom.xml @@ -5,7 +5,7 @@ org.tensorflow tensorflow-core - 1.0.0-SNAPSHOT + 1.1.0-SNAPSHOT tensorflow-core-generator jar diff --git a/tensorflow-core/tensorflow-core-native/BUILD b/tensorflow-core/tensorflow-core-native/BUILD index e8d01ef0a72..b3b1a2cfcd7 100644 --- a/tensorflow-core/tensorflow-core-native/BUILD +++ b/tensorflow-core/tensorflow-core-native/BUILD @@ -4,6 +4,8 @@ java_proto_library( name = "java_proto_gen_sources", deps = [ "@org_tensorflow//tensorflow/core:protos_all", + "@local_xla//xla/tsl/protobuf:bfc_memory_map_proto", + "@local_xla//xla/tsl/protobuf:test_log_proto", "@local_tsl//tsl/protobuf:protos_all" ] ) diff --git a/tensorflow-core/tensorflow-core-native/WORKSPACE b/tensorflow-core/tensorflow-core-native/WORKSPACE index 1a745b13613..ad2c74508ad 100644 --- a/tensorflow-core/tensorflow-core-native/WORKSPACE +++ b/tensorflow-core/tensorflow-core-native/WORKSPACE @@ -14,96 +14,74 @@ http_archive( patch_tool = "patch", patch_args = ["-p1"], patch_cmds = [ - "find tensorflow third_party/xla/third_party/tsl -name \\*.proto | xargs sed -i.bak '/^option java_package/d'", - "find tensorflow third_party/xla/third_party/tsl -name \\*.proto | xargs sed -i.bak 's/^package tensorflow\\([^;]*\\).*$/package tensorflow\\1;\\noption java_package = \"org.tensorflow.proto\\1\";/'", + "find tensorflow third_party/xla/third_party/tsl third_party/xla/xla/tsl -name \\*.proto | xargs sed -i.bak '/^option java_package/d'", + "find tensorflow third_party/xla/third_party/tsl third_party/xla/xla/tsl -name \\*.proto | xargs sed -i.bak 's/^package tensorflow\\([^;]*\\).*$/package tensorflow\\1;\\noption java_package = \"org.tensorflow.proto\\1\";/'", ], urls = [ - "https://github.com/tensorflow/tensorflow/archive/refs/tags/v2.16.2.tar.gz", + "https://github.com/tensorflow/tensorflow/archive/refs/tags/v2.18.0.tar.gz", ], - sha256 = "023849bf253080cb1e4f09386f5eb900492da2288274086ed6cfecd6d99da9eb", - strip_prefix = "tensorflow-2.16.2" + sha256 = "d7876f4bb0235cac60eb6316392a7c48676729860da1ab659fb440379ad5186d", + strip_prefix = "tensorflow-2.18.0" ) ##### Copy content of tensorflow/WORKSPACE here (make sure to change references of default package "//" to "@org_tensorflow//") +# buildifier: disable=load-on-top + # We must initialize hermetic python first. load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( - name = "bazel_skylib", - sha256 = "74d544d96f4a5bb630d465ca8bbcfe231e3594e5aae57e1edbf17a6eb3ca2506", - urls = [ - "https://storage.googleapis.com/mirror.tensorflow.org/github.com/bazelbuild/bazel-skylib/releases/download/1.3.0/bazel-skylib-1.3.0.tar.gz", - "https://github.com/bazelbuild/bazel-skylib/releases/download/1.3.0/bazel-skylib-1.3.0.tar.gz", - ], + name = "rules_java", + sha256 = "c73336802d0b4882e40770666ad055212df4ea62cfa6edf9cb0f9d29828a0934", + url = "https://github.com/bazelbuild/rules_java/releases/download/5.3.5/rules_java-5.3.5.tar.gz", ) -http_archive( - name = "rules_python", - sha256 = "9d04041ac92a0985e344235f5d946f71ac543f1b1565f2cdbc9a2aaee8adf55b", - strip_prefix = "rules_python-0.26.0", - url = "https://github.com/bazelbuild/rules_python/releases/download/0.26.0/rules_python-0.26.0.tar.gz", -) +# Initialize the TensorFlow repository and all dependencies. +# +# The cascade of load() statements and tf_workspace?() calls works around the +# restriction that load() statements need to be at the top of .bzl files. +# E.g. we can not retrieve a new repository with http_archive and then load() +# a macro from that repository in the same file. +load("@org_tensorflow//tensorflow:workspace3.bzl", "tf_workspace3") -load("@rules_python//python:repositories.bzl", "py_repositories") +tf_workspace3() -py_repositories() +# Initialize hermetic Python +load("@local_xla//third_party/py:python_init_rules.bzl", "python_init_rules") -load("@rules_python//python:repositories.bzl", "python_register_toolchains") -load( - "@org_tensorflow//tensorflow/tools/toolchains/python:python_repo.bzl", - "python_repository", -) - -python_repository(name = "python_version_repo") +python_init_rules() -load("@python_version_repo//:py_version.bzl", "TF_PYTHON_VERSION") +load("@local_xla//third_party/py:python_init_repositories.bzl", "python_init_repositories") -python_register_toolchains( - name = "python", - ignore_root_user_error = True, - python_version = TF_PYTHON_VERSION, +python_init_repositories( + default_python_version = "system", + local_wheel_dist_folder = "dist", + local_wheel_inclusion_list = [ + "tensorflow*", + "tf_nightly*", + ], + local_wheel_workspaces = ["//:WORKSPACE"], + requirements = { + "3.9": "@org_tensorflow//:requirements_lock_3_9.txt", + "3.10": "@org_tensorflow//:requirements_lock_3_10.txt", + "3.11": "@org_tensorflow//:requirements_lock_3_11.txt", + "3.12": "@org_tensorflow//:requirements_lock_3_12.txt", + }, ) -load("@python//:defs.bzl", "interpreter") -load("@rules_python//python:pip.bzl", "package_annotation", "pip_parse") +load("@local_xla//third_party/py:python_init_toolchains.bzl", "python_init_toolchains") -NUMPY_ANNOTATIONS = { - "numpy": package_annotation( - additive_build_content = """\ -filegroup( - name = "includes", - srcs = glob(["site-packages/numpy/core/include/**/*.h"]), -) -cc_library( - name = "numpy_headers", - hdrs = [":includes"], - strip_include_prefix="site-packages/numpy/core/include/", -) -""", - ), -} +python_init_toolchains() -#pip_parse( -# name = "pypi", -# annotations = NUMPY_ANNOTATIONS, -# python_interpreter_target = interpreter, -# requirements = "//:requirements_lock_" + HERMETIC_PYTHON_VERSION.replace(".", "_") + ".txt", -#) +load("@local_xla//third_party/py:python_init_pip.bzl", "python_init_pip") -#load("@pypi//:requirements.bzl", "install_deps") +python_init_pip() -#install_deps() +load("@pypi//:requirements.bzl", "install_deps") -# Initialize the TensorFlow repository and all dependencies. -# -# The cascade of load() statements and tf_workspace?() calls works around the -# restriction that load() statements need to be at the top of .bzl files. -# E.g. we can not retrieve a new repository with http_archive and then load() -# a macro from that repository in the same file. -load("@org_tensorflow//tensorflow:workspace3.bzl", "tf_workspace3") - -tf_workspace3() +install_deps() +# End hermetic Python initialization load("@org_tensorflow//tensorflow:workspace2.bzl", "tf_workspace2") @@ -115,4 +93,51 @@ tf_workspace1() load("@org_tensorflow//tensorflow:workspace0.bzl", "tf_workspace0") -tf_workspace0() \ No newline at end of file +tf_workspace0() + +load( + "@local_tsl//third_party/gpus/cuda/hermetic:cuda_json_init_repository.bzl", + "cuda_json_init_repository", +) + +cuda_json_init_repository() + +load( + "@cuda_redist_json//:distributions.bzl", + "CUDA_REDISTRIBUTIONS", + "CUDNN_REDISTRIBUTIONS", +) +load( + "@local_tsl//third_party/gpus/cuda/hermetic:cuda_redist_init_repositories.bzl", + "cuda_redist_init_repositories", + "cudnn_redist_init_repository", +) + +cuda_redist_init_repositories( + cuda_redistributions = CUDA_REDISTRIBUTIONS, +) + +cudnn_redist_init_repository( + cudnn_redistributions = CUDNN_REDISTRIBUTIONS, +) + +load( + "@local_tsl//third_party/gpus/cuda/hermetic:cuda_configure.bzl", + "cuda_configure", +) + +cuda_configure(name = "local_config_cuda") + +load( + "@local_tsl//third_party/nccl/hermetic:nccl_redist_init_repository.bzl", + "nccl_redist_init_repository", +) + +nccl_redist_init_repository() + +load( + "@local_tsl//third_party/nccl/hermetic:nccl_configure.bzl", + "nccl_configure", +) + +nccl_configure(name = "local_config_nccl") \ No newline at end of file diff --git a/tensorflow-core/tensorflow-core-native/pom.xml b/tensorflow-core/tensorflow-core-native/pom.xml index 23682984a4a..3814864439a 100644 --- a/tensorflow-core/tensorflow-core-native/pom.xml +++ b/tensorflow-core/tensorflow-core-native/pom.xml @@ -6,7 +6,7 @@ org.tensorflow tensorflow-core - 1.0.0-SNAPSHOT + 1.1.0-SNAPSHOT tensorflow-core-native jar @@ -113,12 +113,6 @@ ${project.version} ${javacpp.platform.linux-x86_64}-gpu - - ${project.groupId} - ${project.artifactId} - ${project.version} - ${javacpp.platform.macosx-x86_64} - ${project.groupId} ${project.artifactId} @@ -167,10 +161,6 @@ ${project.build.directory}/${project.artifactId}-${project.version}-${javacpp.platform.macosx-arm64}.jar ${javacpp.platform.macosx-arm64} - - ${project.build.directory}/${project.artifactId}-${project.version}-${javacpp.platform.macosx-x86_64}.jar - ${javacpp.platform.macosx-x86_64} - ${project.build.directory}/${project.artifactId}-${project.version}-${javacpp.platform.windows-x86_64}.jar ${javacpp.platform.windows-x86_64} @@ -329,6 +319,7 @@ ${project.basedir}/bazel-${project.artifactId}/external/org_tensorflow/ ${project.basedir}/bazel-${project.artifactId}/external/local_tsl/ + ${project.basedir}/bazel-${project.artifactId}/external/local_xla/ ${project.basedir}/bazel-bin/external/org_tensorflow/ ${project.basedir}/bazel-${project.artifactId}/external/com_google_absl/ ${project.basedir}/bazel-${project.artifactId}/external/eigen_archive/ diff --git a/tensorflow-core/tensorflow-core-native/scripts/bazel_generate.sh b/tensorflow-core/tensorflow-core-native/scripts/bazel_generate.sh index 9d9941d1cf8..ab0fd0ec6c1 100755 --- a/tensorflow-core/tensorflow-core-native/scripts/bazel_generate.sh +++ b/tensorflow-core/tensorflow-core-native/scripts/bazel_generate.sh @@ -24,7 +24,7 @@ cp -f $TENSORFLOW_SRCS/core/ops/ops.pbtxt $GEN_RESOURCE_DIR/org/tensorflow cp -rf $TENSORFLOW_SRCS/core/api_def/base_api $GEN_RESOURCE_DIR/org/tensorflow/ # Copy generated Java protos from source jars -echo "Extracting TF/TSL proto Java sources" +echo "Extracting TF/TSL/XLA proto Java sources" cd $GEN_SRCS_DIR -find $TENSORFLOW_BIN $BAZEL_BIN/external/local_tsl/tsl -name \*-speed-src.jar -exec jar xf {} \; +find $TENSORFLOW_BIN $BAZEL_BIN/external/local_tsl/tsl $BAZEL_BIN/external/local_xla/xla -name \*-speed-src.jar -exec jar xf {} \; rm -rf META-INF diff --git a/tensorflow-core/tensorflow-core-native/scripts/dist_download.sh b/tensorflow-core/tensorflow-core-native/scripts/dist_download.sh index 7727faefaed..acf28b9391d 100755 --- a/tensorflow-core/tensorflow-core-native/scripts/dist_download.sh +++ b/tensorflow-core/tensorflow-core-native/scripts/dist_download.sh @@ -5,23 +5,20 @@ DOWNLOAD_FOLDER="$1" case ${PLATFORM:-} in 'linux-x86_64') - WHEEL_URL='https://files.pythonhosted.org/packages/c6/d9/f2ff325194b8e8acb6b69f303c838b0486f41b8028ec42261f2eb037a031/tensorflow_cpu-2.16.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl' + WHEEL_URL='https://files.pythonhosted.org/packages/aa/1d/032a9d40762895e51cad06f382135c14d16487a0ad9dcc65aae5bd89c968/tensorflow_cpu-2.18.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl' ;; 'linux-x86_64-gpu') - WHEEL_URL='https://files.pythonhosted.org/packages/43/dd/8f03331107b76e63313d2089ddfbd13f15e51fb8ed73517cdd0ab3341928/tensorflow-2.16.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl' + WHEEL_URL='https://files.pythonhosted.org/packages/84/76/c55967ac9968ddaede25a4dce37aba37e9030656f02c12676151ce1b6f22/tensorflow-2.18.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl' ;; - 'macosx-x86_64') - WHEEL_URL='https://files.pythonhosted.org/packages/6d/69/9999c2d9e8a3b08dfcfc7e9259a05fb1da5f700936091d2eb4a7985c2776/tensorflow-2.16.2-cp311-cp311-macosx_10_15_x86_64.whl' + 'linux-arm64') + WHEEL_URL='https://files.pythonhosted.org/packages/56/e4/55aaac2b15af4dad079e5af329a79d961e5206589d0e02b1e8da221472ed/tensorflow-2.18.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl' ;; 'macosx-arm64') - WHEEL_URL='https://files.pythonhosted.org/packages/9d/72/6f09443493b9df2fd8a9585c9af4d9453762906a8e5735a8a5efa6e3d1e3/tensorflow-2.16.2-cp311-cp311-macosx_12_0_arm64.whl' + WHEEL_URL='https://files.pythonhosted.org/packages/26/08/556c4159675c1a30e077ec2a942eeeb81b457cc35c247a5b4a59a1274f05/tensorflow-2.18.0-cp311-cp311-macosx_12_0_arm64.whl' ;; 'windows-x86_64') - WHEEL_URL='https://files.pythonhosted.org/packages/46/87/c3e4e9fe7c630f38a6984afdd1d4ed531ef9c74dc66b86f46f6bdd89d608/tensorflow_intel-2.16.2-cp311-cp311-win_amd64.whl' - CLIB_URL='https://storage.googleapis.com/tensorflow/versions/2.16.2/libtensorflow-cpu-windows-x86_64.zip' - ;; - 'linux-arm64') - WHEEL_URL='https://files.pythonhosted.org/packages/b5/01/c03e98c8e97d151d9ce075fae210f838832eb53d8aa55669d384cb72925b/tensorflow-2.16.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl' + WHEEL_URL='https://files.pythonhosted.org/packages/76/ad/fa6c508a15ff79cb5409294c293388e0999b7d480f84b65e4287277434fe/tensorflow_intel-2.18.0-cp311-cp311-win_amd64.whl' + CLIB_URL='https://storage.googleapis.com/tensorflow/versions/2.18.0/libtensorflow-cpu-windows-x86_64.zip' ;; *) echo "TensorFlow distribution for ${PLATFORM} is not supported for download" @@ -55,7 +52,8 @@ if [[ "$PLATFORM" =~ "linux" ]]; then ln -fs libtensorflow_cc.so.2 libtensorflow_cc.so ln -fs libtensorflow_framework.so.2 libtensorflow_framework.so if [[ "$PLATFORM" == "linux-arm64" ]]; then - ln -fs libomp-e9212f90.so.5 libomp-e9212f90.so + cp ../tensorflow.libs/libomp-6196b3b5.so.5 libomp-6196b3b5.so.5 + ln -fs libomp-6196b3b5.so.5 libomp-6196b3b5.so fi elif [[ "$PLATFORM" =~ "macosx" ]]; then ln -fs libtensorflow_cc.2.dylib libtensorflow_cc.dylib diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/internal/c_api/global/tensorflow.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/internal/c_api/global/tensorflow.java index 2a80e6bb86d..8a6ef604683 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/internal/c_api/global/tensorflow.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/internal/c_api/global/tensorflow.java @@ -1,4 +1,4 @@ -// Targeted by JavaCPP version 1.5.10: DO NOT EDIT THIS FILE +// Targeted by JavaCPP version 1.5.12-SNAPSHOT: DO NOT EDIT THIS FILE package org.tensorflow.internal.c_api.global; @@ -274,7 +274,7 @@ public static native void TF_TString_Copy(TF_TString dst, String src, // #endif // TENSORFLOW_TSL_PLATFORM_CTSTRING_H_ -// Parsed from tsl/c/tsl_status.h +// Parsed from xla/tsl/c/tsl_status.h /* Copyright 2019 The TensorFlow Authors. All Rights Reserved. @@ -291,8 +291,8 @@ public static native void TF_TString_Copy(TF_TString dst, String src, limitations under the License. ==============================================================================*/ -// #ifndef TENSORFLOW_TSL_C_TSL_STATUS_H_ -// #define TENSORFLOW_TSL_C_TSL_STATUS_H_ +// #ifndef XLA_TSL_C_TSL_STATUS_H_ +// #define XLA_TSL_C_TSL_STATUS_H_ // #ifdef __cplusplus // #endif @@ -351,7 +351,7 @@ public static native void TF_TString_Copy(TF_TString dst, String src, // #ifdef __cplusplus /* end extern "C" */ // #endif -// #endif // TENSORFLOW_TSL_C_TSL_STATUS_H_ +// #endif // XLA_TSL_C_TSL_STATUS_H_ // Parsed from tensorflow/c/c_api_macros.h @@ -507,7 +507,7 @@ public static native void TF_TString_Copy(TF_TString dst, String src, // #define TENSORFLOW_C_TF_STATUS_H_ // #include "tensorflow/c/c_api_macros.h" -// #include "tsl/c/tsl_status.h" +// #include "xla/tsl/c/tsl_status.h" // #ifdef __cplusplus // Targeting ../TF_Status.java @@ -689,6 +689,13 @@ public static native TF_Tensor TF_NewTensor( Deallocator_Pointer_long_Pointer deallocator, Pointer deallocator_arg); +// Returns the alignment, in bytes, required for allocating aligned tensors. +// +// This can be used in combination with TF_NewTensor to manually manage +// memory while ensuring the resulting tensors satisfy TensorFlow's +// memory alignment preferences. +public static native @Cast("size_t") long TF_TensorDefaultAlignment(); + // Allocate and return a new Tensor. // // This function is an alternative to TF_NewTensor and should be used when @@ -4367,7 +4374,8 @@ public static native void TFE_ContextUpdateServerDefWithTimeout( // This API is for experimental usage and may be subject to change. public static native void TFE_ContextSetServerDefWithTimeout( TFE_Context ctx, int keep_alive_secs, @Const Pointer proto, @Cast("size_t") long proto_len, - @Cast("int64_t") long init_timeout_in_ms, TF_Status status); + @Cast("int64_t") long init_timeout_in_ms, TF_Status status, + @Cast("bool") boolean clear_existing_contexts); // Set server def with retries and timeout. This is helpful for fault-tolerant // initial connection in high-preemption environments, such as @@ -4375,7 +4383,8 @@ public static native void TFE_ContextSetServerDefWithTimeout( // This API is for experimental usage and may be subject to change. public static native void TFE_ContextSetServerDefWithTimeoutAndRetries( TFE_Context ctx, int keep_alive_secs, @Const Pointer proto, @Cast("size_t") long proto_len, - @Cast("int64_t") long init_timeout_in_ms, int retries, TF_Status status); + @Cast("int64_t") long init_timeout_in_ms, int retries, TF_Status status, + @Cast("bool") boolean clear_existing_contexts); // Checks whether a remote worker is alive or not. This will return true even if // the context doesn't exist on the remote worker. diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/AvailableDeviceInfo.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/AvailableDeviceInfo.java index e71192c47b2..50aa7d93009 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/AvailableDeviceInfo.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/AvailableDeviceInfo.java @@ -1,5 +1,5 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! -// source: tsl/protobuf/test_log.proto +// source: xla/tsl/protobuf/test_log.proto package org.tensorflow.proto; diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/AvailableDeviceInfoOrBuilder.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/AvailableDeviceInfoOrBuilder.java index ef9f13504d3..c35a7c6a745 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/AvailableDeviceInfoOrBuilder.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/AvailableDeviceInfoOrBuilder.java @@ -1,5 +1,5 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! -// source: tsl/protobuf/test_log.proto +// source: xla/tsl/protobuf/test_log.proto package org.tensorflow.proto; diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/BenchmarkEntries.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/BenchmarkEntries.java index b3ed52d11c0..73be037bfe8 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/BenchmarkEntries.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/BenchmarkEntries.java @@ -1,5 +1,5 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! -// source: tsl/protobuf/test_log.proto +// source: xla/tsl/protobuf/test_log.proto package org.tensorflow.proto; diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/BenchmarkEntriesOrBuilder.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/BenchmarkEntriesOrBuilder.java index b99b30bf045..de029d1d399 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/BenchmarkEntriesOrBuilder.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/BenchmarkEntriesOrBuilder.java @@ -1,5 +1,5 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! -// source: tsl/protobuf/test_log.proto +// source: xla/tsl/protobuf/test_log.proto package org.tensorflow.proto; diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/BenchmarkEntry.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/BenchmarkEntry.java index 0c470285827..efe111640d5 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/BenchmarkEntry.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/BenchmarkEntry.java @@ -1,5 +1,5 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! -// source: tsl/protobuf/test_log.proto +// source: xla/tsl/protobuf/test_log.proto package org.tensorflow.proto; diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/BenchmarkEntryOrBuilder.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/BenchmarkEntryOrBuilder.java index 476aae9ca10..fba00ccb7f1 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/BenchmarkEntryOrBuilder.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/BenchmarkEntryOrBuilder.java @@ -1,5 +1,5 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! -// source: tsl/protobuf/test_log.proto +// source: xla/tsl/protobuf/test_log.proto package org.tensorflow.proto; diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/BfcMemoryMap.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/BfcMemoryMap.java index fad0c98b837..e894298881d 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/BfcMemoryMap.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/BfcMemoryMap.java @@ -1,5 +1,5 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! -// source: tsl/protobuf/bfc_memory_map.proto +// source: xla/tsl/protobuf/bfc_memory_map.proto package org.tensorflow.proto; @@ -5091,28 +5091,28 @@ public org.tensorflow.proto.BfcMemoryMap.MemoryDump getDefaultInstanceForType() descriptor; static { java.lang.String[] descriptorData = { - "\n!tsl/protobuf/bfc_memory_map.proto\022\nten" + - "sorflow\"\222\001\n\021MemAllocatorStats\022\022\n\nnum_all" + - "ocs\030\001 \001(\003\022\024\n\014bytes_in_use\030\002 \001(\003\022\031\n\021peak_" + - "bytes_in_use\030\003 \001(\003\022\032\n\022largest_alloc_size" + - "\030\004 \001(\003\022\034\n\024fragmentation_metric\030\005 \001(\002\"\256\001\n" + - "\010MemChunk\022\017\n\007address\030\001 \001(\004\022\014\n\004size\030\002 \001(\003" + - "\022\026\n\016requested_size\030\003 \001(\003\022\013\n\003bin\030\004 \001(\005\022\017\n" + - "\007op_name\030\005 \001(\t\022\026\n\016freed_at_count\030\006 \001(\004\022\024" + - "\n\014action_count\030\007 \001(\004\022\016\n\006in_use\030\010 \001(\010\022\017\n\007" + - "step_id\030\t \001(\004\"\213\001\n\nBinSummary\022\013\n\003bin\030\001 \001(" + - "\005\022\032\n\022total_bytes_in_use\030\002 \001(\003\022\032\n\022total_b" + - "ytes_in_bin\030\003 \001(\003\022\033\n\023total_chunks_in_use" + - "\030\004 \001(\003\022\033\n\023total_chunks_in_bin\030\005 \001(\003\".\n\010S" + - "napShot\022\024\n\014action_count\030\001 \001(\004\022\014\n\004size\030\002 " + - "\001(\003\"\315\001\n\nMemoryDump\022\026\n\016allocator_name\030\001 \001" + - "(\t\022+\n\013bin_summary\030\002 \003(\0132\026.tensorflow.Bin" + - "Summary\022#\n\005chunk\030\003 \003(\0132\024.tensorflow.MemC" + - "hunk\022\'\n\tsnap_shot\030\004 \003(\0132\024.tensorflow.Sna" + - "pShot\022,\n\005stats\030\005 \001(\0132\035.tensorflow.MemAll" + - "ocatorStatsBV\n\024org.tensorflow.protoZ>git" + - "hub.com/google/tsl/tsl/go/protobuf/for_c" + - "ore_protos_go_protob\006proto3" + "\n%xla/tsl/protobuf/bfc_memory_map.proto\022" + + "\ntensorflow\"\222\001\n\021MemAllocatorStats\022\022\n\nnum" + + "_allocs\030\001 \001(\003\022\024\n\014bytes_in_use\030\002 \001(\003\022\031\n\021p" + + "eak_bytes_in_use\030\003 \001(\003\022\032\n\022largest_alloc_" + + "size\030\004 \001(\003\022\034\n\024fragmentation_metric\030\005 \001(\002" + + "\"\256\001\n\010MemChunk\022\017\n\007address\030\001 \001(\004\022\014\n\004size\030\002" + + " \001(\003\022\026\n\016requested_size\030\003 \001(\003\022\013\n\003bin\030\004 \001(" + + "\005\022\017\n\007op_name\030\005 \001(\t\022\026\n\016freed_at_count\030\006 \001" + + "(\004\022\024\n\014action_count\030\007 \001(\004\022\016\n\006in_use\030\010 \001(\010" + + "\022\017\n\007step_id\030\t \001(\004\"\213\001\n\nBinSummary\022\013\n\003bin\030" + + "\001 \001(\005\022\032\n\022total_bytes_in_use\030\002 \001(\003\022\032\n\022tot" + + "al_bytes_in_bin\030\003 \001(\003\022\033\n\023total_chunks_in" + + "_use\030\004 \001(\003\022\033\n\023total_chunks_in_bin\030\005 \001(\003\"" + + ".\n\010SnapShot\022\024\n\014action_count\030\001 \001(\004\022\014\n\004siz" + + "e\030\002 \001(\003\"\315\001\n\nMemoryDump\022\026\n\016allocator_name" + + "\030\001 \001(\t\022+\n\013bin_summary\030\002 \003(\0132\026.tensorflow" + + ".BinSummary\022#\n\005chunk\030\003 \003(\0132\024.tensorflow." + + "MemChunk\022\'\n\tsnap_shot\030\004 \003(\0132\024.tensorflow" + + ".SnapShot\022,\n\005stats\030\005 \001(\0132\035.tensorflow.Me" + + "mAllocatorStatsBV\n\024org.tensorflow.protoZ" + + ">github.com/google/tsl/tsl/go/protobuf/f" + + "or_core_protos_go_protob\006proto3" }; descriptor = com.google.protobuf.Descriptors.FileDescriptor .internalBuildGeneratedFileFrom(descriptorData, diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/BuildConfiguration.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/BuildConfiguration.java index 8e3f0c9e7b5..19b464ffb52 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/BuildConfiguration.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/BuildConfiguration.java @@ -1,5 +1,5 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! -// source: tsl/protobuf/test_log.proto +// source: xla/tsl/protobuf/test_log.proto package org.tensorflow.proto; diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/BuildConfigurationOrBuilder.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/BuildConfigurationOrBuilder.java index 0f4bc0c0740..112534dc95a 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/BuildConfigurationOrBuilder.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/BuildConfigurationOrBuilder.java @@ -1,5 +1,5 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! -// source: tsl/protobuf/test_log.proto +// source: xla/tsl/protobuf/test_log.proto package org.tensorflow.proto; diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/CPUInfo.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/CPUInfo.java index 906c5e01a83..3816e55e459 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/CPUInfo.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/CPUInfo.java @@ -1,5 +1,5 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! -// source: tsl/protobuf/test_log.proto +// source: xla/tsl/protobuf/test_log.proto package org.tensorflow.proto; diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/CPUInfoOrBuilder.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/CPUInfoOrBuilder.java index de66bb23d57..9ede760853d 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/CPUInfoOrBuilder.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/CPUInfoOrBuilder.java @@ -1,5 +1,5 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! -// source: tsl/protobuf/test_log.proto +// source: xla/tsl/protobuf/test_log.proto package org.tensorflow.proto; diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/CommitId.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/CommitId.java index 3fdd1c804b6..9f6ad5f08bc 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/CommitId.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/CommitId.java @@ -1,5 +1,5 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! -// source: tsl/protobuf/test_log.proto +// source: xla/tsl/protobuf/test_log.proto package org.tensorflow.proto; diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/CommitIdOrBuilder.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/CommitIdOrBuilder.java index 1b124825e66..cb78f3bd9d2 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/CommitIdOrBuilder.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/CommitIdOrBuilder.java @@ -1,5 +1,5 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! -// source: tsl/protobuf/test_log.proto +// source: xla/tsl/protobuf/test_log.proto package org.tensorflow.proto; diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/ConfigProto.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/ConfigProto.java index 04d15e4a308..5dcca1ed5f7 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/ConfigProto.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/ConfigProto.java @@ -354,6 +354,17 @@ public interface ExperimentalOrBuilder extends */ boolean getEnableMultiHost(); + /** + *

    +     * If true, use ifrt as the backend for TFRT. This is only used when
    +     * `use_tfrt` is true.
    +     * 
    + * + * bool tfrt_use_ifrt = 32; + * @return The tfrtUseIfrt. + */ + boolean getTfrtUseIfrt(); + /** *
          * Port for the Pathways server. Ignored if enable_multi_host=false.
    @@ -1101,6 +1112,22 @@ public boolean getEnableMultiHost() {
           return enableMultiHost_;
         }
     
    +    public static final int TFRT_USE_IFRT_FIELD_NUMBER = 32;
    +    private boolean tfrtUseIfrt_;
    +    /**
    +     * 
    +     * If true, use ifrt as the backend for TFRT. This is only used when
    +     * `use_tfrt` is true.
    +     * 
    + * + * bool tfrt_use_ifrt = 32; + * @return The tfrtUseIfrt. + */ + @java.lang.Override + public boolean getTfrtUseIfrt() { + return tfrtUseIfrt_; + } + public static final int BACKEND_SERVER_PORT_FIELD_NUMBER = 28; private int backendServerPort_; /** @@ -1369,6 +1396,9 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) if (streamMergeThreshold_ != 0) { output.writeInt32(31, streamMergeThreshold_); } + if (tfrtUseIfrt_ != false) { + output.writeBool(32, tfrtUseIfrt_); + } getUnknownFields().writeTo(output); } @@ -1484,6 +1514,10 @@ public int getSerializedSize() { size += com.google.protobuf.CodedOutputStream .computeInt32Size(31, streamMergeThreshold_); } + if (tfrtUseIfrt_ != false) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(32, tfrtUseIfrt_); + } size += getUnknownFields().getSerializedSize(); memoizedSize = size; return size; @@ -1537,6 +1571,8 @@ public boolean equals(final java.lang.Object obj) { != other.getUseTfrt()) return false; if (getEnableMultiHost() != other.getEnableMultiHost()) return false; + if (getTfrtUseIfrt() + != other.getTfrtUseIfrt()) return false; if (getBackendServerPort() != other.getBackendServerPort()) return false; if (getTargetTpu() @@ -1620,6 +1656,9 @@ public int hashCode() { hash = (37 * hash) + ENABLE_MULTI_HOST_FIELD_NUMBER; hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean( getEnableMultiHost()); + hash = (37 * hash) + TFRT_USE_IFRT_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean( + getTfrtUseIfrt()); hash = (37 * hash) + BACKEND_SERVER_PORT_FIELD_NUMBER; hash = (53 * hash) + getBackendServerPort(); hash = (37 * hash) + TARGET_TPU_FIELD_NUMBER; @@ -1820,6 +1859,8 @@ public Builder clear() { enableMultiHost_ = false; + tfrtUseIfrt_ = false; + backendServerPort_ = 0; targetTpu_ = false; @@ -1890,6 +1931,7 @@ public org.tensorflow.proto.ConfigProto.Experimental buildPartial() { result.xlaFusionAutotunerThresh_ = xlaFusionAutotunerThresh_; result.useTfrt_ = useTfrt_; result.enableMultiHost_ = enableMultiHost_; + result.tfrtUseIfrt_ = tfrtUseIfrt_; result.backendServerPort_ = backendServerPort_; result.targetTpu_ = targetTpu_; result.targetGpu_ = targetGpu_; @@ -2007,6 +2049,9 @@ public Builder mergeFrom(org.tensorflow.proto.ConfigProto.Experimental other) { if (other.getEnableMultiHost() != false) { setEnableMultiHost(other.getEnableMultiHost()); } + if (other.getTfrtUseIfrt() != false) { + setTfrtUseIfrt(other.getTfrtUseIfrt()); + } if (other.getBackendServerPort() != 0) { setBackendServerPort(other.getBackendServerPort()); } @@ -2199,6 +2244,11 @@ public Builder mergeFrom( break; } // case 248 + case 256: { + tfrtUseIfrt_ = input.readBool(); + + break; + } // case 256 default: { if (!super.parseUnknownField(input, extensionRegistry, tag)) { done = true; // was an endgroup tag @@ -3423,6 +3473,52 @@ public Builder clearEnableMultiHost() { return this; } + private boolean tfrtUseIfrt_ ; + /** + *
    +       * If true, use ifrt as the backend for TFRT. This is only used when
    +       * `use_tfrt` is true.
    +       * 
    + * + * bool tfrt_use_ifrt = 32; + * @return The tfrtUseIfrt. + */ + @java.lang.Override + public boolean getTfrtUseIfrt() { + return tfrtUseIfrt_; + } + /** + *
    +       * If true, use ifrt as the backend for TFRT. This is only used when
    +       * `use_tfrt` is true.
    +       * 
    + * + * bool tfrt_use_ifrt = 32; + * @param value The tfrtUseIfrt to set. + * @return This builder for chaining. + */ + public Builder setTfrtUseIfrt(boolean value) { + + tfrtUseIfrt_ = value; + onChanged(); + return this; + } + /** + *
    +       * If true, use ifrt as the backend for TFRT. This is only used when
    +       * `use_tfrt` is true.
    +       * 
    + * + * bool tfrt_use_ifrt = 32; + * @return This builder for chaining. + */ + public Builder clearTfrtUseIfrt() { + + tfrtUseIfrt_ = false; + onChanged(); + return this; + } + private int backendServerPort_ ; /** *
    @@ -4461,6 +4557,44 @@ public org.tensorflow.proto.GPUOptionsOrBuilder getGpuOptionsOrBuilder() {
         return getGpuOptions();
       }
     
    +  public static final int PLUGGABLE_DEVICE_OPTIONS_FIELD_NUMBER = 18;
    +  private org.tensorflow.proto.GPUOptions pluggableDeviceOptions_;
    +  /**
    +   * 
    +   * Options that apply to pluggable devices.
    +   * 
    + * + * .tensorflow.GPUOptions pluggable_device_options = 18; + * @return Whether the pluggableDeviceOptions field is set. + */ + @java.lang.Override + public boolean hasPluggableDeviceOptions() { + return pluggableDeviceOptions_ != null; + } + /** + *
    +   * Options that apply to pluggable devices.
    +   * 
    + * + * .tensorflow.GPUOptions pluggable_device_options = 18; + * @return The pluggableDeviceOptions. + */ + @java.lang.Override + public org.tensorflow.proto.GPUOptions getPluggableDeviceOptions() { + return pluggableDeviceOptions_ == null ? org.tensorflow.proto.GPUOptions.getDefaultInstance() : pluggableDeviceOptions_; + } + /** + *
    +   * Options that apply to pluggable devices.
    +   * 
    + * + * .tensorflow.GPUOptions pluggable_device_options = 18; + */ + @java.lang.Override + public org.tensorflow.proto.GPUOptionsOrBuilder getPluggableDeviceOptionsOrBuilder() { + return getPluggableDeviceOptions(); + } + public static final int ALLOW_SOFT_PLACEMENT_FIELD_NUMBER = 7; private boolean allowSoftPlacement_; /** @@ -4757,6 +4891,9 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) if (shareClusterDevicesInSession_ != false) { output.writeBool(17, shareClusterDevicesInSession_); } + if (pluggableDeviceOptions_ != null) { + output.writeMessage(18, getPluggableDeviceOptions()); + } getUnknownFields().writeTo(output); } @@ -4844,6 +4981,10 @@ public int getSerializedSize() { size += com.google.protobuf.CodedOutputStream .computeBoolSize(17, shareClusterDevicesInSession_); } + if (pluggableDeviceOptions_ != null) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(18, getPluggableDeviceOptions()); + } size += getUnknownFields().getSerializedSize(); memoizedSize = size; return size; @@ -4878,6 +5019,11 @@ public boolean equals(final java.lang.Object obj) { if (!getGpuOptions() .equals(other.getGpuOptions())) return false; } + if (hasPluggableDeviceOptions() != other.hasPluggableDeviceOptions()) return false; + if (hasPluggableDeviceOptions()) { + if (!getPluggableDeviceOptions() + .equals(other.getPluggableDeviceOptions())) return false; + } if (getAllowSoftPlacement() != other.getAllowSoftPlacement()) return false; if (getLogDevicePlacement() @@ -4944,6 +5090,10 @@ public int hashCode() { hash = (37 * hash) + GPU_OPTIONS_FIELD_NUMBER; hash = (53 * hash) + getGpuOptions().hashCode(); } + if (hasPluggableDeviceOptions()) { + hash = (37 * hash) + PLUGGABLE_DEVICE_OPTIONS_FIELD_NUMBER; + hash = (53 * hash) + getPluggableDeviceOptions().hashCode(); + } hash = (37 * hash) + ALLOW_SOFT_PLACEMENT_FIELD_NUMBER; hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean( getAllowSoftPlacement()); @@ -5154,6 +5304,12 @@ public Builder clear() { gpuOptions_ = null; gpuOptionsBuilder_ = null; } + if (pluggableDeviceOptionsBuilder_ == null) { + pluggableDeviceOptions_ = null; + } else { + pluggableDeviceOptions_ = null; + pluggableDeviceOptionsBuilder_ = null; + } allowSoftPlacement_ = false; logDevicePlacement_ = false; @@ -5240,6 +5396,11 @@ public org.tensorflow.proto.ConfigProto buildPartial() { } else { result.gpuOptions_ = gpuOptionsBuilder_.build(); } + if (pluggableDeviceOptionsBuilder_ == null) { + result.pluggableDeviceOptions_ = pluggableDeviceOptions_; + } else { + result.pluggableDeviceOptions_ = pluggableDeviceOptionsBuilder_.build(); + } result.allowSoftPlacement_ = allowSoftPlacement_; result.logDevicePlacement_ = logDevicePlacement_; if (graphOptionsBuilder_ == null) { @@ -5366,6 +5527,9 @@ public Builder mergeFrom(org.tensorflow.proto.ConfigProto other) { if (other.hasGpuOptions()) { mergeGpuOptions(other.getGpuOptions()); } + if (other.hasPluggableDeviceOptions()) { + mergePluggableDeviceOptions(other.getPluggableDeviceOptions()); + } if (other.getAllowSoftPlacement() != false) { setAllowSoftPlacement(other.getAllowSoftPlacement()); } @@ -5526,6 +5690,13 @@ public Builder mergeFrom( break; } // case 136 + case 146: { + input.readMessage( + getPluggableDeviceOptionsFieldBuilder().getBuilder(), + extensionRegistry); + + break; + } // case 146 default: { if (!super.parseUnknownField(input, extensionRegistry, tag)) { done = true; // was an endgroup tag @@ -6886,6 +7057,161 @@ public org.tensorflow.proto.GPUOptionsOrBuilder getGpuOptionsOrBuilder() { return gpuOptionsBuilder_; } + private org.tensorflow.proto.GPUOptions pluggableDeviceOptions_; + private com.google.protobuf.SingleFieldBuilderV3< + org.tensorflow.proto.GPUOptions, org.tensorflow.proto.GPUOptions.Builder, org.tensorflow.proto.GPUOptionsOrBuilder> pluggableDeviceOptionsBuilder_; + /** + *
    +     * Options that apply to pluggable devices.
    +     * 
    + * + * .tensorflow.GPUOptions pluggable_device_options = 18; + * @return Whether the pluggableDeviceOptions field is set. + */ + public boolean hasPluggableDeviceOptions() { + return pluggableDeviceOptionsBuilder_ != null || pluggableDeviceOptions_ != null; + } + /** + *
    +     * Options that apply to pluggable devices.
    +     * 
    + * + * .tensorflow.GPUOptions pluggable_device_options = 18; + * @return The pluggableDeviceOptions. + */ + public org.tensorflow.proto.GPUOptions getPluggableDeviceOptions() { + if (pluggableDeviceOptionsBuilder_ == null) { + return pluggableDeviceOptions_ == null ? org.tensorflow.proto.GPUOptions.getDefaultInstance() : pluggableDeviceOptions_; + } else { + return pluggableDeviceOptionsBuilder_.getMessage(); + } + } + /** + *
    +     * Options that apply to pluggable devices.
    +     * 
    + * + * .tensorflow.GPUOptions pluggable_device_options = 18; + */ + public Builder setPluggableDeviceOptions(org.tensorflow.proto.GPUOptions value) { + if (pluggableDeviceOptionsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + pluggableDeviceOptions_ = value; + onChanged(); + } else { + pluggableDeviceOptionsBuilder_.setMessage(value); + } + + return this; + } + /** + *
    +     * Options that apply to pluggable devices.
    +     * 
    + * + * .tensorflow.GPUOptions pluggable_device_options = 18; + */ + public Builder setPluggableDeviceOptions( + org.tensorflow.proto.GPUOptions.Builder builderForValue) { + if (pluggableDeviceOptionsBuilder_ == null) { + pluggableDeviceOptions_ = builderForValue.build(); + onChanged(); + } else { + pluggableDeviceOptionsBuilder_.setMessage(builderForValue.build()); + } + + return this; + } + /** + *
    +     * Options that apply to pluggable devices.
    +     * 
    + * + * .tensorflow.GPUOptions pluggable_device_options = 18; + */ + public Builder mergePluggableDeviceOptions(org.tensorflow.proto.GPUOptions value) { + if (pluggableDeviceOptionsBuilder_ == null) { + if (pluggableDeviceOptions_ != null) { + pluggableDeviceOptions_ = + org.tensorflow.proto.GPUOptions.newBuilder(pluggableDeviceOptions_).mergeFrom(value).buildPartial(); + } else { + pluggableDeviceOptions_ = value; + } + onChanged(); + } else { + pluggableDeviceOptionsBuilder_.mergeFrom(value); + } + + return this; + } + /** + *
    +     * Options that apply to pluggable devices.
    +     * 
    + * + * .tensorflow.GPUOptions pluggable_device_options = 18; + */ + public Builder clearPluggableDeviceOptions() { + if (pluggableDeviceOptionsBuilder_ == null) { + pluggableDeviceOptions_ = null; + onChanged(); + } else { + pluggableDeviceOptions_ = null; + pluggableDeviceOptionsBuilder_ = null; + } + + return this; + } + /** + *
    +     * Options that apply to pluggable devices.
    +     * 
    + * + * .tensorflow.GPUOptions pluggable_device_options = 18; + */ + public org.tensorflow.proto.GPUOptions.Builder getPluggableDeviceOptionsBuilder() { + + onChanged(); + return getPluggableDeviceOptionsFieldBuilder().getBuilder(); + } + /** + *
    +     * Options that apply to pluggable devices.
    +     * 
    + * + * .tensorflow.GPUOptions pluggable_device_options = 18; + */ + public org.tensorflow.proto.GPUOptionsOrBuilder getPluggableDeviceOptionsOrBuilder() { + if (pluggableDeviceOptionsBuilder_ != null) { + return pluggableDeviceOptionsBuilder_.getMessageOrBuilder(); + } else { + return pluggableDeviceOptions_ == null ? + org.tensorflow.proto.GPUOptions.getDefaultInstance() : pluggableDeviceOptions_; + } + } + /** + *
    +     * Options that apply to pluggable devices.
    +     * 
    + * + * .tensorflow.GPUOptions pluggable_device_options = 18; + */ + private com.google.protobuf.SingleFieldBuilderV3< + org.tensorflow.proto.GPUOptions, org.tensorflow.proto.GPUOptions.Builder, org.tensorflow.proto.GPUOptionsOrBuilder> + getPluggableDeviceOptionsFieldBuilder() { + if (pluggableDeviceOptionsBuilder_ == null) { + pluggableDeviceOptionsBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + org.tensorflow.proto.GPUOptions, org.tensorflow.proto.GPUOptions.Builder, org.tensorflow.proto.GPUOptionsOrBuilder>( + getPluggableDeviceOptions(), + getParentForChildren(), + isClean()); + pluggableDeviceOptions_ = null; + } + return pluggableDeviceOptionsBuilder_; + } + private boolean allowSoftPlacement_ ; /** *
    diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/ConfigProtoOrBuilder.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/ConfigProtoOrBuilder.java
    index d158b44e08f..29a052555c6 100644
    --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/ConfigProtoOrBuilder.java
    +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/ConfigProtoOrBuilder.java
    @@ -341,6 +341,33 @@ org.tensorflow.proto.ThreadPoolOptionProtoOrBuilder getSessionInterOpThreadPoolO
        */
       org.tensorflow.proto.GPUOptionsOrBuilder getGpuOptionsOrBuilder();
     
    +  /**
    +   * 
    +   * Options that apply to pluggable devices.
    +   * 
    + * + * .tensorflow.GPUOptions pluggable_device_options = 18; + * @return Whether the pluggableDeviceOptions field is set. + */ + boolean hasPluggableDeviceOptions(); + /** + *
    +   * Options that apply to pluggable devices.
    +   * 
    + * + * .tensorflow.GPUOptions pluggable_device_options = 18; + * @return The pluggableDeviceOptions. + */ + org.tensorflow.proto.GPUOptions getPluggableDeviceOptions(); + /** + *
    +   * Options that apply to pluggable devices.
    +   * 
    + * + * .tensorflow.GPUOptions pluggable_device_options = 18; + */ + org.tensorflow.proto.GPUOptionsOrBuilder getPluggableDeviceOptionsOrBuilder(); + /** *
        * Whether soft placement is allowed. If allow_soft_placement is true,
    diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/ConfigProtos.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/ConfigProtos.java
    index bca6f96f8b0..ee8eb70f710 100644
    --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/ConfigProtos.java
    +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/ConfigProtos.java
    @@ -29,6 +29,11 @@ public static void registerAllExtensions(
       static final 
         com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internal_static_tensorflow_GPUOptions_Experimental_VirtualDevices_fieldAccessorTable;
    +  static final com.google.protobuf.Descriptors.Descriptor
    +    internal_static_tensorflow_GPUOptions_Experimental_StreamMergeOptions_descriptor;
    +  static final 
    +    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
    +      internal_static_tensorflow_GPUOptions_Experimental_StreamMergeOptions_fieldAccessorTable;
       static final com.google.protobuf.Descriptors.Descriptor
         internal_static_tensorflow_OptimizerOptions_descriptor;
       static final 
    @@ -127,7 +132,7 @@ public static void registerAllExtensions(
           "obuf/debug.proto\032.tensorflow/core/protob" +
           "uf/rewriter_config.proto\032*tensorflow/cor" +
           "e/protobuf/rpc_options.proto\032&tsl/protob" +
    -      "uf/coordination_config.proto\"\352\007\n\nGPUOpti" +
    +      "uf/coordination_config.proto\"\211\n\n\nGPUOpti" +
           "ons\022\'\n\037per_process_gpu_memory_fraction\030\001" +
           " \001(\001\022\024\n\014allow_growth\030\004 \001(\010\022\026\n\016allocator_" +
           "type\030\002 \001(\t\022\037\n\027deferred_deletion_bytes\030\003 " +
    @@ -135,7 +140,7 @@ public static void registerAllExtensions(
           "ing_active_delay_usecs\030\006 \001(\005\022$\n\034polling_" +
           "inactive_delay_msecs\030\007 \001(\005\022\034\n\024force_gpu_" +
           "compatible\030\010 \001(\010\0229\n\014experimental\030\t \001(\0132#" +
    -      ".tensorflow.GPUOptions.Experimental\032\243\005\n\014" +
    +      ".tensorflow.GPUOptions.Experimental\032\302\007\n\014" +
           "Experimental\022K\n\017virtual_devices\030\001 \003(\01322." +
           "tensorflow.GPUOptions.Experimental.Virtu" +
           "alDevices\022#\n\033num_virtual_devices_per_gpu" +
    @@ -150,126 +155,135 @@ public static void registerAllExtensions(
           "llow_retry_on_allocation_failure\030\014 \001(\010\022 " +
           "\n\030gpu_host_mem_limit_in_mb\030\r \001(\002\022$\n\034gpu_" +
           "host_mem_disallow_growth\030\016 \001(\010\022$\n\034gpu_sy" +
    -      "stem_memory_size_in_mb\030\020 \001(\005\032S\n\016VirtualD" +
    -      "evices\022\027\n\017memory_limit_mb\030\001 \003(\002\022\020\n\010prior" +
    -      "ity\030\002 \003(\005\022\026\n\016device_ordinal\030\003 \003(\005\"\235\003\n\020Op" +
    -      "timizerOptions\022+\n#do_common_subexpressio" +
    -      "n_elimination\030\001 \001(\010\022\033\n\023do_constant_foldi" +
    -      "ng\030\002 \001(\010\022$\n\034max_folded_constant_in_bytes" +
    -      "\030\006 \001(\003\022\034\n\024do_function_inlining\030\004 \001(\010\0225\n\t" +
    -      "opt_level\030\003 \001(\0162\".tensorflow.OptimizerOp" +
    -      "tions.Level\022E\n\020global_jit_level\030\005 \001(\0162+." +
    -      "tensorflow.OptimizerOptions.GlobalJitLev" +
    -      "el\022\026\n\016cpu_global_jit\030\007 \001(\010\" \n\005Level\022\006\n\002L" +
    -      "1\020\000\022\017\n\002L0\020\377\377\377\377\377\377\377\377\377\001\"C\n\016GlobalJitLevel\022\013" +
    -      "\n\007DEFAULT\020\000\022\020\n\003OFF\020\377\377\377\377\377\377\377\377\377\001\022\010\n\004ON_1\020\001\022" +
    -      "\010\n\004ON_2\020\002\"\356\002\n\014GraphOptions\022\036\n\026enable_rec" +
    -      "v_scheduling\030\002 \001(\010\0227\n\021optimizer_options\030" +
    -      "\003 \001(\0132\034.tensorflow.OptimizerOptions\022\030\n\020b" +
    -      "uild_cost_model\030\004 \001(\003\022\036\n\026build_cost_mode" +
    -      "l_after\030\t \001(\003\022\024\n\014infer_shapes\030\005 \001(\010\022\032\n\022p" +
    -      "lace_pruned_graph\030\006 \001(\010\022 \n\030enable_bfloat" +
    -      "16_sendrecv\030\007 \001(\010\022\025\n\rtimeline_step\030\010 \001(\005" +
    -      "\0223\n\017rewrite_options\030\n \001(\0132\032.tensorflow.R" +
    -      "ewriterConfigJ\004\010\001\020\002R%skip_common_subexpr" +
    -      "ession_elimination\"A\n\025ThreadPoolOptionPr" +
    -      "oto\022\023\n\013num_threads\030\001 \001(\005\022\023\n\013global_name\030" +
    -      "\002 \001(\t\"0\n\017SessionMetadata\022\014\n\004name\030\001 \001(\t\022\017" +
    -      "\n\007version\030\002 \001(\003\"\225\020\n\013ConfigProto\022>\n\014devic" +
    -      "e_count\030\001 \003(\0132(.tensorflow.ConfigProto.D" +
    -      "eviceCountEntry\022$\n\034intra_op_parallelism_" +
    -      "threads\030\002 \001(\005\022$\n\034inter_op_parallelism_th" +
    -      "reads\030\005 \001(\005\022\037\n\027use_per_session_threads\030\t" +
    -      " \001(\010\022G\n\034session_inter_op_thread_pool\030\014 \003" +
    -      "(\0132!.tensorflow.ThreadPoolOptionProto\022\030\n" +
    -      "\020placement_period\030\003 \001(\005\022\026\n\016device_filter" +
    -      "s\030\004 \003(\t\022+\n\013gpu_options\030\006 \001(\0132\026.tensorflo" +
    -      "w.GPUOptions\022\034\n\024allow_soft_placement\030\007 \001" +
    -      "(\010\022\034\n\024log_device_placement\030\010 \001(\010\022/\n\rgrap" +
    -      "h_options\030\n \001(\0132\030.tensorflow.GraphOption" +
    -      "s\022\037\n\027operation_timeout_in_ms\030\013 \001(\003\022+\n\013rp" +
    -      "c_options\030\r \001(\0132\026.tensorflow.RPCOptions\022" +
    -      "+\n\013cluster_def\030\016 \001(\0132\026.tensorflow.Cluste" +
    -      "rDef\022\035\n\025isolate_session_state\030\017 \001(\010\022(\n s" +
    -      "hare_cluster_devices_in_session\030\021 \001(\010\022:\n" +
    -      "\014experimental\030\020 \001(\0132$.tensorflow.ConfigP" +
    -      "roto.Experimental\0322\n\020DeviceCountEntry\022\013\n" +
    -      "\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\005:\0028\001\032\217\n\n\014Experi" +
    -      "mental\022\037\n\027collective_group_leader\030\001 \001(\t\022" +
    -      "\025\n\rexecutor_type\030\003 \001(\t\022\032\n\022recv_buf_max_c" +
    -      "hunk\030\004 \001(\005\022\031\n\021use_numa_affinity\030\005 \001(\010\0225\n" +
    -      "-collective_deterministic_sequential_exe" +
    -      "cution\030\006 \001(\010\022\027\n\017collective_nccl\030\007 \001(\010\0226\n" +
    -      ".share_session_state_in_clusterspec_prop" +
    -      "agation\030\010 \001(\010\022\037\n\027disable_thread_spinning" +
    -      "\030\t \001(\010\022(\n share_cluster_devices_in_sessi" +
    -      "on\030\n \001(\010\0225\n\020session_metadata\030\013 \001(\0132\033.ten" +
    -      "sorflow.SessionMetadata\022!\n\031optimize_for_" +
    -      "static_graph\030\014 \001(\010\022\032\n\022enable_mlir_bridge" +
    -      "\030\r \001(\010\022S\n\023mlir_bridge_rollout\030\021 \001(\01626.te" +
    -      "nsorflow.ConfigProto.Experimental.MlirBr" +
    -      "idgeRollout\022&\n\036enable_mlir_graph_optimiz" +
    -      "ation\030\020 \001(\010\022\'\n\037disable_output_partition_" +
    -      "graphs\030\016 \001(\010\022#\n\033xla_fusion_autotuner_thr" +
    -      "esh\030\017 \001(\003\022\020\n\010use_tfrt\030\022 \001(\010\022\031\n\021enable_mu" +
    -      "lti_host\030\033 \001(\010\022\033\n\023backend_server_port\030\034 " +
    -      "\001(\005\022\022\n\ntarget_tpu\030\035 \001(\010\022\022\n\ntarget_gpu\030\036 " +
    -      "\001(\010\022\036\n\026stream_merge_threshold\030\037 \001(\005\022\'\n\037d" +
    -      "isable_functional_ops_lowering\030\025 \001(\010\022\'\n\037" +
    -      "xla_prefer_single_graph_cluster\030\026 \001(\010\022B\n" +
    -      "\023coordination_config\030\027 \001(\0132%.tensorflow." +
    -      "CoordinationServiceConfig\022)\n!disable_opt" +
    -      "imize_for_static_graph\030\030 \001(\010\0220\n(disable_" +
    -      "eager_executor_streaming_enqueue\030\032 \001(\010\"\336" +
    -      "\001\n\021MlirBridgeRollout\022#\n\037MLIR_BRIDGE_ROLL" +
    -      "OUT_UNSPECIFIED\020\000\022\037\n\033MLIR_BRIDGE_ROLLOUT" +
    -      "_ENABLED\020\001\022 \n\034MLIR_BRIDGE_ROLLOUT_DISABL" +
    -      "ED\020\002\"\004\010\003\020\003\"\004\010\004\020\004*%MLIR_BRIDGE_ROLLOUT_SA" +
    -      "FE_MODE_ENABLED*.MLIR_BRIDGE_ROLLOUT_SAF" +
    -      "E_MODE_FALLBACK_ENABLEDJ\004\010\002\020\003J\004\010\023\020\024J\004\010\024\020" +
    -      "\025J\004\010\031\020\032\"\341\004\n\nRunOptions\0226\n\013trace_level\030\001 " +
    -      "\001(\0162!.tensorflow.RunOptions.TraceLevel\022\025" +
    -      "\n\rtimeout_in_ms\030\002 \001(\003\022\034\n\024inter_op_thread" +
    -      "_pool\030\003 \001(\005\022\037\n\027output_partition_graphs\030\005" +
    -      " \001(\010\022/\n\rdebug_options\030\006 \001(\0132\030.tensorflow" +
    -      ".DebugOptions\022*\n\"report_tensor_allocatio" +
    -      "ns_upon_oom\030\007 \001(\010\0229\n\014experimental\030\010 \001(\0132" +
    -      "#.tensorflow.RunOptions.Experimental\032\322\001\n" +
    -      "\014Experimental\022\034\n\024collective_graph_key\030\001 " +
    -      "\001(\003\022\034\n\024use_run_handler_pool\030\002 \001(\010\022[\n\030run" +
    -      "_handler_pool_options\030\003 \001(\01329.tensorflow" +
    -      ".RunOptions.Experimental.RunHandlerPoolO" +
    -      "ptions\032)\n\025RunHandlerPoolOptions\022\020\n\010prior" +
    -      "ity\030\001 \001(\003\"R\n\nTraceLevel\022\014\n\010NO_TRACE\020\000\022\022\n" +
    -      "\016SOFTWARE_TRACE\020\001\022\022\n\016HARDWARE_TRACE\020\002\022\016\n" +
    -      "\nFULL_TRACE\020\003J\004\010\004\020\005\"\276\003\n\013RunMetadata\022)\n\ns" +
    -      "tep_stats\030\001 \001(\0132\025.tensorflow.StepStats\022," +
    -      "\n\ncost_graph\030\002 \001(\0132\030.tensorflow.CostGrap" +
    -      "hDef\022.\n\020partition_graphs\030\003 \003(\0132\024.tensorf" +
    -      "low.GraphDef\022?\n\017function_graphs\030\004 \003(\0132&." +
    -      "tensorflow.RunMetadata.FunctionGraphs\0225\n" +
    -      "\020session_metadata\030\005 \001(\0132\033.tensorflow.Ses" +
    -      "sionMetadata\032\255\001\n\016FunctionGraphs\022.\n\020parti" +
    -      "tion_graphs\030\001 \003(\0132\024.tensorflow.GraphDef\022" +
    -      "4\n\026pre_optimization_graph\030\002 \001(\0132\024.tensor" +
    -      "flow.GraphDef\0225\n\027post_optimization_graph" +
    -      "\030\003 \001(\0132\024.tensorflow.GraphDef\":\n\020TensorCo" +
    -      "nnection\022\023\n\013from_tensor\030\001 \001(\t\022\021\n\tto_tens" +
    -      "or\030\002 \001(\t\"\260\003\n\017CallableOptions\022\014\n\004feed\030\001 \003" +
    -      "(\t\022\r\n\005fetch\030\002 \003(\t\022\016\n\006target\030\003 \003(\t\022+\n\013run" +
    -      "_options\030\004 \001(\0132\026.tensorflow.RunOptions\0227" +
    -      "\n\021tensor_connection\030\005 \003(\0132\034.tensorflow.T" +
    -      "ensorConnection\022B\n\014feed_devices\030\006 \003(\0132,." +
    -      "tensorflow.CallableOptions.FeedDevicesEn" +
    -      "try\022D\n\rfetch_devices\030\007 \003(\0132-.tensorflow." +
    -      "CallableOptions.FetchDevicesEntry\022\027\n\017fet" +
    -      "ch_skip_sync\030\010 \001(\010\0322\n\020FeedDevicesEntry\022\013" +
    -      "\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\0323\n\021FetchD" +
    -      "evicesEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:" +
    -      "\0028\001B\200\001\n\024org.tensorflow.protoB\014ConfigProt" +
    -      "osP\001ZUgithub.com/tensorflow/tensorflow/t" +
    -      "ensorflow/go/core/protobuf/for_core_prot" +
    -      "os_go_proto\370\001\001b\006proto3"
    +      "stem_memory_size_in_mb\030\020 \001(\005\022.\n&populate" +
    +      "_pjrt_gpu_client_creation_info\030\021 \001(\010\022\017\n\007" +
    +      "node_id\030\022 \001(\005\022T\n\024stream_merge_options\030\023 " +
    +      "\001(\01326.tensorflow.GPUOptions.Experimental" +
    +      ".StreamMergeOptions\032S\n\016VirtualDevices\022\027\n" +
    +      "\017memory_limit_mb\030\001 \003(\002\022\020\n\010priority\030\002 \003(\005" +
    +      "\022\026\n\016device_ordinal\030\003 \003(\005\032\205\001\n\022StreamMerge" +
    +      "Options\022#\n\033merge_host_to_device_stream\030\001" +
    +      " \001(\010\022#\n\033merge_device_to_host_stream\030\002 \001(" +
    +      "\010\022%\n\035merge_device_to_device_stream\030\003 \001(\010" +
    +      "\"\235\003\n\020OptimizerOptions\022+\n#do_common_subex" +
    +      "pression_elimination\030\001 \001(\010\022\033\n\023do_constan" +
    +      "t_folding\030\002 \001(\010\022$\n\034max_folded_constant_i" +
    +      "n_bytes\030\006 \001(\003\022\034\n\024do_function_inlining\030\004 " +
    +      "\001(\010\0225\n\topt_level\030\003 \001(\0162\".tensorflow.Opti" +
    +      "mizerOptions.Level\022E\n\020global_jit_level\030\005" +
    +      " \001(\0162+.tensorflow.OptimizerOptions.Globa" +
    +      "lJitLevel\022\026\n\016cpu_global_jit\030\007 \001(\010\" \n\005Lev" +
    +      "el\022\006\n\002L1\020\000\022\017\n\002L0\020\377\377\377\377\377\377\377\377\377\001\"C\n\016GlobalJit" +
    +      "Level\022\013\n\007DEFAULT\020\000\022\020\n\003OFF\020\377\377\377\377\377\377\377\377\377\001\022\010\n\004" +
    +      "ON_1\020\001\022\010\n\004ON_2\020\002\"\356\002\n\014GraphOptions\022\036\n\026ena" +
    +      "ble_recv_scheduling\030\002 \001(\010\0227\n\021optimizer_o" +
    +      "ptions\030\003 \001(\0132\034.tensorflow.OptimizerOptio" +
    +      "ns\022\030\n\020build_cost_model\030\004 \001(\003\022\036\n\026build_co" +
    +      "st_model_after\030\t \001(\003\022\024\n\014infer_shapes\030\005 \001" +
    +      "(\010\022\032\n\022place_pruned_graph\030\006 \001(\010\022 \n\030enable" +
    +      "_bfloat16_sendrecv\030\007 \001(\010\022\025\n\rtimeline_ste" +
    +      "p\030\010 \001(\005\0223\n\017rewrite_options\030\n \001(\0132\032.tenso" +
    +      "rflow.RewriterConfigJ\004\010\001\020\002R%skip_common_" +
    +      "subexpression_elimination\"A\n\025ThreadPoolO" +
    +      "ptionProto\022\023\n\013num_threads\030\001 \001(\005\022\023\n\013globa" +
    +      "l_name\030\002 \001(\t\"0\n\017SessionMetadata\022\014\n\004name\030" +
    +      "\001 \001(\t\022\017\n\007version\030\002 \001(\003\"\346\020\n\013ConfigProto\022>" +
    +      "\n\014device_count\030\001 \003(\0132(.tensorflow.Config" +
    +      "Proto.DeviceCountEntry\022$\n\034intra_op_paral" +
    +      "lelism_threads\030\002 \001(\005\022$\n\034inter_op_paralle" +
    +      "lism_threads\030\005 \001(\005\022\037\n\027use_per_session_th" +
    +      "reads\030\t \001(\010\022G\n\034session_inter_op_thread_p" +
    +      "ool\030\014 \003(\0132!.tensorflow.ThreadPoolOptionP" +
    +      "roto\022\030\n\020placement_period\030\003 \001(\005\022\026\n\016device" +
    +      "_filters\030\004 \003(\t\022+\n\013gpu_options\030\006 \001(\0132\026.te" +
    +      "nsorflow.GPUOptions\0228\n\030pluggable_device_" +
    +      "options\030\022 \001(\0132\026.tensorflow.GPUOptions\022\034\n" +
    +      "\024allow_soft_placement\030\007 \001(\010\022\034\n\024log_devic" +
    +      "e_placement\030\010 \001(\010\022/\n\rgraph_options\030\n \001(\013" +
    +      "2\030.tensorflow.GraphOptions\022\037\n\027operation_" +
    +      "timeout_in_ms\030\013 \001(\003\022+\n\013rpc_options\030\r \001(\013" +
    +      "2\026.tensorflow.RPCOptions\022+\n\013cluster_def\030" +
    +      "\016 \001(\0132\026.tensorflow.ClusterDef\022\035\n\025isolate" +
    +      "_session_state\030\017 \001(\010\022(\n share_cluster_de" +
    +      "vices_in_session\030\021 \001(\010\022:\n\014experimental\030\020" +
    +      " \001(\0132$.tensorflow.ConfigProto.Experiment" +
    +      "al\0322\n\020DeviceCountEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005v" +
    +      "alue\030\002 \001(\005:\0028\001\032\246\n\n\014Experimental\022\037\n\027colle" +
    +      "ctive_group_leader\030\001 \001(\t\022\025\n\rexecutor_typ" +
    +      "e\030\003 \001(\t\022\032\n\022recv_buf_max_chunk\030\004 \001(\005\022\031\n\021u" +
    +      "se_numa_affinity\030\005 \001(\010\0225\n-collective_det" +
    +      "erministic_sequential_execution\030\006 \001(\010\022\027\n" +
    +      "\017collective_nccl\030\007 \001(\010\0226\n.share_session_" +
    +      "state_in_clusterspec_propagation\030\010 \001(\010\022\037" +
    +      "\n\027disable_thread_spinning\030\t \001(\010\022(\n share" +
    +      "_cluster_devices_in_session\030\n \001(\010\0225\n\020ses" +
    +      "sion_metadata\030\013 \001(\0132\033.tensorflow.Session" +
    +      "Metadata\022!\n\031optimize_for_static_graph\030\014 " +
    +      "\001(\010\022\032\n\022enable_mlir_bridge\030\r \001(\010\022S\n\023mlir_" +
    +      "bridge_rollout\030\021 \001(\01626.tensorflow.Config" +
    +      "Proto.Experimental.MlirBridgeRollout\022&\n\036" +
    +      "enable_mlir_graph_optimization\030\020 \001(\010\022\'\n\037" +
    +      "disable_output_partition_graphs\030\016 \001(\010\022#\n" +
    +      "\033xla_fusion_autotuner_thresh\030\017 \001(\003\022\020\n\010us" +
    +      "e_tfrt\030\022 \001(\010\022\031\n\021enable_multi_host\030\033 \001(\010\022" +
    +      "\025\n\rtfrt_use_ifrt\030  \001(\010\022\033\n\023backend_server" +
    +      "_port\030\034 \001(\005\022\022\n\ntarget_tpu\030\035 \001(\010\022\022\n\ntarge" +
    +      "t_gpu\030\036 \001(\010\022\036\n\026stream_merge_threshold\030\037 " +
    +      "\001(\005\022\'\n\037disable_functional_ops_lowering\030\025" +
    +      " \001(\010\022\'\n\037xla_prefer_single_graph_cluster\030" +
    +      "\026 \001(\010\022B\n\023coordination_config\030\027 \001(\0132%.ten" +
    +      "sorflow.CoordinationServiceConfig\022)\n!dis" +
    +      "able_optimize_for_static_graph\030\030 \001(\010\0220\n(" +
    +      "disable_eager_executor_streaming_enqueue" +
    +      "\030\032 \001(\010\"\336\001\n\021MlirBridgeRollout\022#\n\037MLIR_BRI" +
    +      "DGE_ROLLOUT_UNSPECIFIED\020\000\022\037\n\033MLIR_BRIDGE" +
    +      "_ROLLOUT_ENABLED\020\001\022 \n\034MLIR_BRIDGE_ROLLOU" +
    +      "T_DISABLED\020\002\"\004\010\003\020\003\"\004\010\004\020\004*%MLIR_BRIDGE_RO" +
    +      "LLOUT_SAFE_MODE_ENABLED*.MLIR_BRIDGE_ROL" +
    +      "LOUT_SAFE_MODE_FALLBACK_ENABLEDJ\004\010\002\020\003J\004\010" +
    +      "\023\020\024J\004\010\024\020\025J\004\010\031\020\032\"\341\004\n\nRunOptions\0226\n\013trace_" +
    +      "level\030\001 \001(\0162!.tensorflow.RunOptions.Trac" +
    +      "eLevel\022\025\n\rtimeout_in_ms\030\002 \001(\003\022\034\n\024inter_o" +
    +      "p_thread_pool\030\003 \001(\005\022\037\n\027output_partition_" +
    +      "graphs\030\005 \001(\010\022/\n\rdebug_options\030\006 \001(\0132\030.te" +
    +      "nsorflow.DebugOptions\022*\n\"report_tensor_a" +
    +      "llocations_upon_oom\030\007 \001(\010\0229\n\014experimenta" +
    +      "l\030\010 \001(\0132#.tensorflow.RunOptions.Experime" +
    +      "ntal\032\322\001\n\014Experimental\022\034\n\024collective_grap" +
    +      "h_key\030\001 \001(\003\022\034\n\024use_run_handler_pool\030\002 \001(" +
    +      "\010\022[\n\030run_handler_pool_options\030\003 \001(\01329.te" +
    +      "nsorflow.RunOptions.Experimental.RunHand" +
    +      "lerPoolOptions\032)\n\025RunHandlerPoolOptions\022" +
    +      "\020\n\010priority\030\001 \001(\003\"R\n\nTraceLevel\022\014\n\010NO_TR" +
    +      "ACE\020\000\022\022\n\016SOFTWARE_TRACE\020\001\022\022\n\016HARDWARE_TR" +
    +      "ACE\020\002\022\016\n\nFULL_TRACE\020\003J\004\010\004\020\005\"\276\003\n\013RunMetad" +
    +      "ata\022)\n\nstep_stats\030\001 \001(\0132\025.tensorflow.Ste" +
    +      "pStats\022,\n\ncost_graph\030\002 \001(\0132\030.tensorflow." +
    +      "CostGraphDef\022.\n\020partition_graphs\030\003 \003(\0132\024" +
    +      ".tensorflow.GraphDef\022?\n\017function_graphs\030" +
    +      "\004 \003(\0132&.tensorflow.RunMetadata.FunctionG" +
    +      "raphs\0225\n\020session_metadata\030\005 \001(\0132\033.tensor" +
    +      "flow.SessionMetadata\032\255\001\n\016FunctionGraphs\022" +
    +      ".\n\020partition_graphs\030\001 \003(\0132\024.tensorflow.G" +
    +      "raphDef\0224\n\026pre_optimization_graph\030\002 \001(\0132" +
    +      "\024.tensorflow.GraphDef\0225\n\027post_optimizati" +
    +      "on_graph\030\003 \001(\0132\024.tensorflow.GraphDef\":\n\020" +
    +      "TensorConnection\022\023\n\013from_tensor\030\001 \001(\t\022\021\n" +
    +      "\tto_tensor\030\002 \001(\t\"\260\003\n\017CallableOptions\022\014\n\004" +
    +      "feed\030\001 \003(\t\022\r\n\005fetch\030\002 \003(\t\022\016\n\006target\030\003 \003(" +
    +      "\t\022+\n\013run_options\030\004 \001(\0132\026.tensorflow.RunO" +
    +      "ptions\0227\n\021tensor_connection\030\005 \003(\0132\034.tens" +
    +      "orflow.TensorConnection\022B\n\014feed_devices\030" +
    +      "\006 \003(\0132,.tensorflow.CallableOptions.FeedD" +
    +      "evicesEntry\022D\n\rfetch_devices\030\007 \003(\0132-.ten" +
    +      "sorflow.CallableOptions.FetchDevicesEntr" +
    +      "y\022\027\n\017fetch_skip_sync\030\010 \001(\010\0322\n\020FeedDevice" +
    +      "sEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\0323" +
    +      "\n\021FetchDevicesEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005valu" +
    +      "e\030\002 \001(\t:\0028\001B\200\001\n\024org.tensorflow.protoB\014Co" +
    +      "nfigProtosP\001ZUgithub.com/tensorflow/tens" +
    +      "orflow/tensorflow/go/core/protobuf/for_c" +
    +      "ore_protos_go_proto\370\001\001b\006proto3"
         };
         descriptor = com.google.protobuf.Descriptors.FileDescriptor
           .internalBuildGeneratedFileFrom(descriptorData,
    @@ -294,13 +308,19 @@ public static void registerAllExtensions(
         internal_static_tensorflow_GPUOptions_Experimental_fieldAccessorTable = new
           com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
             internal_static_tensorflow_GPUOptions_Experimental_descriptor,
    -        new java.lang.String[] { "VirtualDevices", "NumVirtualDevicesPerGpu", "UseUnifiedMemory", "NumDevToDevCopyStreams", "CollectiveRingOrder", "TimestampedAllocator", "KernelTrackerMaxInterval", "KernelTrackerMaxBytes", "KernelTrackerMaxPending", "InternalFragmentationFraction", "UseCudaMallocAsync", "DisallowRetryOnAllocationFailure", "GpuHostMemLimitInMb", "GpuHostMemDisallowGrowth", "GpuSystemMemorySizeInMb", });
    +        new java.lang.String[] { "VirtualDevices", "NumVirtualDevicesPerGpu", "UseUnifiedMemory", "NumDevToDevCopyStreams", "CollectiveRingOrder", "TimestampedAllocator", "KernelTrackerMaxInterval", "KernelTrackerMaxBytes", "KernelTrackerMaxPending", "InternalFragmentationFraction", "UseCudaMallocAsync", "DisallowRetryOnAllocationFailure", "GpuHostMemLimitInMb", "GpuHostMemDisallowGrowth", "GpuSystemMemorySizeInMb", "PopulatePjrtGpuClientCreationInfo", "NodeId", "StreamMergeOptions", });
         internal_static_tensorflow_GPUOptions_Experimental_VirtualDevices_descriptor =
           internal_static_tensorflow_GPUOptions_Experimental_descriptor.getNestedTypes().get(0);
         internal_static_tensorflow_GPUOptions_Experimental_VirtualDevices_fieldAccessorTable = new
           com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
             internal_static_tensorflow_GPUOptions_Experimental_VirtualDevices_descriptor,
             new java.lang.String[] { "MemoryLimitMb", "Priority", "DeviceOrdinal", });
    +    internal_static_tensorflow_GPUOptions_Experimental_StreamMergeOptions_descriptor =
    +      internal_static_tensorflow_GPUOptions_Experimental_descriptor.getNestedTypes().get(1);
    +    internal_static_tensorflow_GPUOptions_Experimental_StreamMergeOptions_fieldAccessorTable = new
    +      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
    +        internal_static_tensorflow_GPUOptions_Experimental_StreamMergeOptions_descriptor,
    +        new java.lang.String[] { "MergeHostToDeviceStream", "MergeDeviceToHostStream", "MergeDeviceToDeviceStream", });
         internal_static_tensorflow_OptimizerOptions_descriptor =
           getDescriptor().getMessageTypes().get(1);
         internal_static_tensorflow_OptimizerOptions_fieldAccessorTable = new
    @@ -330,7 +350,7 @@ public static void registerAllExtensions(
         internal_static_tensorflow_ConfigProto_fieldAccessorTable = new
           com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
             internal_static_tensorflow_ConfigProto_descriptor,
    -        new java.lang.String[] { "DeviceCount", "IntraOpParallelismThreads", "InterOpParallelismThreads", "UsePerSessionThreads", "SessionInterOpThreadPool", "PlacementPeriod", "DeviceFilters", "GpuOptions", "AllowSoftPlacement", "LogDevicePlacement", "GraphOptions", "OperationTimeoutInMs", "RpcOptions", "ClusterDef", "IsolateSessionState", "ShareClusterDevicesInSession", "Experimental", });
    +        new java.lang.String[] { "DeviceCount", "IntraOpParallelismThreads", "InterOpParallelismThreads", "UsePerSessionThreads", "SessionInterOpThreadPool", "PlacementPeriod", "DeviceFilters", "GpuOptions", "PluggableDeviceOptions", "AllowSoftPlacement", "LogDevicePlacement", "GraphOptions", "OperationTimeoutInMs", "RpcOptions", "ClusterDef", "IsolateSessionState", "ShareClusterDevicesInSession", "Experimental", });
         internal_static_tensorflow_ConfigProto_DeviceCountEntry_descriptor =
           internal_static_tensorflow_ConfigProto_descriptor.getNestedTypes().get(0);
         internal_static_tensorflow_ConfigProto_DeviceCountEntry_fieldAccessorTable = new
    @@ -342,7 +362,7 @@ public static void registerAllExtensions(
         internal_static_tensorflow_ConfigProto_Experimental_fieldAccessorTable = new
           com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
             internal_static_tensorflow_ConfigProto_Experimental_descriptor,
    -        new java.lang.String[] { "CollectiveGroupLeader", "ExecutorType", "RecvBufMaxChunk", "UseNumaAffinity", "CollectiveDeterministicSequentialExecution", "CollectiveNccl", "ShareSessionStateInClusterspecPropagation", "DisableThreadSpinning", "ShareClusterDevicesInSession", "SessionMetadata", "OptimizeForStaticGraph", "EnableMlirBridge", "MlirBridgeRollout", "EnableMlirGraphOptimization", "DisableOutputPartitionGraphs", "XlaFusionAutotunerThresh", "UseTfrt", "EnableMultiHost", "BackendServerPort", "TargetTpu", "TargetGpu", "StreamMergeThreshold", "DisableFunctionalOpsLowering", "XlaPreferSingleGraphCluster", "CoordinationConfig", "DisableOptimizeForStaticGraph", "DisableEagerExecutorStreamingEnqueue", });
    +        new java.lang.String[] { "CollectiveGroupLeader", "ExecutorType", "RecvBufMaxChunk", "UseNumaAffinity", "CollectiveDeterministicSequentialExecution", "CollectiveNccl", "ShareSessionStateInClusterspecPropagation", "DisableThreadSpinning", "ShareClusterDevicesInSession", "SessionMetadata", "OptimizeForStaticGraph", "EnableMlirBridge", "MlirBridgeRollout", "EnableMlirGraphOptimization", "DisableOutputPartitionGraphs", "XlaFusionAutotunerThresh", "UseTfrt", "EnableMultiHost", "TfrtUseIfrt", "BackendServerPort", "TargetTpu", "TargetGpu", "StreamMergeThreshold", "DisableFunctionalOpsLowering", "XlaPreferSingleGraphCluster", "CoordinationConfig", "DisableOptimizeForStaticGraph", "DisableEagerExecutorStreamingEnqueue", });
         internal_static_tensorflow_RunOptions_descriptor =
           getDescriptor().getMessageTypes().get(6);
         internal_static_tensorflow_RunOptions_fieldAccessorTable = new
    diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/CoordinationConfig.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/CoordinationConfig.java
    index 6c1f875d2f6..5dfed710211 100644
    --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/CoordinationConfig.java
    +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/CoordinationConfig.java
    @@ -853,6 +853,17 @@ org.tensorflow.proto.CoordinationConfig.CoordinatedJobOrBuilder getCoordinatedJo
          * @return The forceDisable.
          */
         boolean getForceDisable();
    +
    +    /**
    +     * 
    +     * Use long polling to get error from coordination service as the error
    +     * propagation mechanism.
    +     * 
    + * + * bool poll_for_error_from_service_at_startup = 13; + * @return The pollForErrorFromServiceAtStartup. + */ + boolean getPollForErrorFromServiceAtStartup(); } /** *
    @@ -1223,6 +1234,22 @@ public boolean getForceDisable() {
           return forceDisable_;
         }
     
    +    public static final int POLL_FOR_ERROR_FROM_SERVICE_AT_STARTUP_FIELD_NUMBER = 13;
    +    private boolean pollForErrorFromServiceAtStartup_;
    +    /**
    +     * 
    +     * Use long polling to get error from coordination service as the error
    +     * propagation mechanism.
    +     * 
    + * + * bool poll_for_error_from_service_at_startup = 13; + * @return The pollForErrorFromServiceAtStartup. + */ + @java.lang.Override + public boolean getPollForErrorFromServiceAtStartup() { + return pollForErrorFromServiceAtStartup_; + } + private byte memoizedIsInitialized = -1; @java.lang.Override public final boolean isInitialized() { @@ -1270,6 +1297,9 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) if (forceDisable_ != false) { output.writeBool(12, forceDisable_); } + if (pollForErrorFromServiceAtStartup_ != false) { + output.writeBool(13, pollForErrorFromServiceAtStartup_); + } getUnknownFields().writeTo(output); } @@ -1325,6 +1355,10 @@ public int getSerializedSize() { size += com.google.protobuf.CodedOutputStream .computeBoolSize(12, forceDisable_); } + if (pollForErrorFromServiceAtStartup_ != false) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(13, pollForErrorFromServiceAtStartup_); + } size += getUnknownFields().getSerializedSize(); memoizedSize = size; return size; @@ -1362,6 +1396,8 @@ public boolean equals(final java.lang.Object obj) { != other.getAllowNewIncarnationToReconnect()) return false; if (getForceDisable() != other.getForceDisable()) return false; + if (getPollForErrorFromServiceAtStartup() + != other.getPollForErrorFromServiceAtStartup()) return false; if (!getUnknownFields().equals(other.getUnknownFields())) return false; return true; } @@ -1406,6 +1442,9 @@ public int hashCode() { hash = (37 * hash) + FORCE_DISABLE_FIELD_NUMBER; hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean( getForceDisable()); + hash = (37 * hash) + POLL_FOR_ERROR_FROM_SERVICE_AT_STARTUP_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean( + getPollForErrorFromServiceAtStartup()); hash = (29 * hash) + getUnknownFields().hashCode(); memoizedHashCode = hash; return hash; @@ -1566,6 +1605,8 @@ public Builder clear() { forceDisable_ = false; + pollForErrorFromServiceAtStartup_ = false; + return this; } @@ -1616,6 +1657,7 @@ public org.tensorflow.proto.CoordinationConfig.CoordinationServiceConfig buildPa result.recoverableJobs_ = recoverableJobs_; result.allowNewIncarnationToReconnect_ = allowNewIncarnationToReconnect_; result.forceDisable_ = forceDisable_; + result.pollForErrorFromServiceAtStartup_ = pollForErrorFromServiceAtStartup_; onBuilt(); return result; } @@ -1729,6 +1771,9 @@ public Builder mergeFrom(org.tensorflow.proto.CoordinationConfig.CoordinationSer if (other.getForceDisable() != false) { setForceDisable(other.getForceDisable()); } + if (other.getPollForErrorFromServiceAtStartup() != false) { + setPollForErrorFromServiceAtStartup(other.getPollForErrorFromServiceAtStartup()); + } this.mergeUnknownFields(other.getUnknownFields()); onChanged(); return this; @@ -1819,6 +1864,11 @@ public Builder mergeFrom( break; } // case 96 + case 104: { + pollForErrorFromServiceAtStartup_ = input.readBool(); + + break; + } // case 104 default: { if (!super.parseUnknownField(input, extensionRegistry, tag)) { done = true; // was an endgroup tag @@ -2798,6 +2848,52 @@ public Builder clearForceDisable() { onChanged(); return this; } + + private boolean pollForErrorFromServiceAtStartup_ ; + /** + *
    +       * Use long polling to get error from coordination service as the error
    +       * propagation mechanism.
    +       * 
    + * + * bool poll_for_error_from_service_at_startup = 13; + * @return The pollForErrorFromServiceAtStartup. + */ + @java.lang.Override + public boolean getPollForErrorFromServiceAtStartup() { + return pollForErrorFromServiceAtStartup_; + } + /** + *
    +       * Use long polling to get error from coordination service as the error
    +       * propagation mechanism.
    +       * 
    + * + * bool poll_for_error_from_service_at_startup = 13; + * @param value The pollForErrorFromServiceAtStartup to set. + * @return This builder for chaining. + */ + public Builder setPollForErrorFromServiceAtStartup(boolean value) { + + pollForErrorFromServiceAtStartup_ = value; + onChanged(); + return this; + } + /** + *
    +       * Use long polling to get error from coordination service as the error
    +       * propagation mechanism.
    +       * 
    + * + * bool poll_for_error_from_service_at_startup = 13; + * @return This builder for chaining. + */ + public Builder clearPollForErrorFromServiceAtStartup() { + + pollForErrorFromServiceAtStartup_ = false; + onChanged(); + return this; + } @java.lang.Override public final Builder setUnknownFields( final com.google.protobuf.UnknownFieldSet unknownFields) { @@ -2883,7 +2979,7 @@ public org.tensorflow.proto.CoordinationConfig.CoordinationServiceConfig getDefa java.lang.String[] descriptorData = { "\n&tsl/protobuf/coordination_config.proto" + "\022\ntensorflow\"1\n\016CoordinatedJob\022\014\n\004name\030\001" + - " \001(\t\022\021\n\tnum_tasks\030\002 \001(\005\"\240\003\n\031Coordination" + + " \001(\t\022\021\n\tnum_tasks\030\002 \001(\005\"\320\003\n\031Coordination" + "ServiceConfig\022\024\n\014service_type\030\001 \001(\t\022\026\n\016s" + "ervice_leader\030\002 \001(\t\022\033\n\023enable_health_che" + "ck\030\003 \001(\010\022&\n\036cluster_register_timeout_in_" + @@ -2893,11 +2989,12 @@ public org.tensorflow.proto.CoordinationConfig.CoordinationServiceConfig getDefa "timeout_in_ms\030\007 \001(\003\022*\n\"agent_destruction" + "_without_shutdown\030\010 \001(\010\022\030\n\020recoverable_j" + "obs\030\t \003(\t\022*\n\"allow_new_incarnation_to_re" + - "connect\030\013 \001(\010\022\025\n\rforce_disable\030\014 \001(\010J\004\010\006" + - "\020\007Bm\n\024org.tensorflow.protoZUgithub.com/t" + - "ensorflow/tensorflow/tensorflow/go/core/" + - "protobuf/for_core_protos_go_protob\006proto" + - "3" + "connect\030\013 \001(\010\022\025\n\rforce_disable\030\014 \001(\010\022.\n&" + + "poll_for_error_from_service_at_startup\030\r" + + " \001(\010J\004\010\006\020\007Bm\n\024org.tensorflow.protoZUgith" + + "ub.com/tensorflow/tensorflow/tensorflow/" + + "go/core/protobuf/for_core_protos_go_prot" + + "ob\006proto3" }; descriptor = com.google.protobuf.Descriptors.FileDescriptor .internalBuildGeneratedFileFrom(descriptorData, @@ -2914,7 +3011,7 @@ public org.tensorflow.proto.CoordinationConfig.CoordinationServiceConfig getDefa internal_static_tensorflow_CoordinationServiceConfig_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_tensorflow_CoordinationServiceConfig_descriptor, - new java.lang.String[] { "ServiceType", "ServiceLeader", "EnableHealthCheck", "ClusterRegisterTimeoutInMs", "HeartbeatTimeoutInMs", "CoordinatedJobList", "ShutdownBarrierTimeoutInMs", "AgentDestructionWithoutShutdown", "RecoverableJobs", "AllowNewIncarnationToReconnect", "ForceDisable", }); + new java.lang.String[] { "ServiceType", "ServiceLeader", "EnableHealthCheck", "ClusterRegisterTimeoutInMs", "HeartbeatTimeoutInMs", "CoordinatedJobList", "ShutdownBarrierTimeoutInMs", "AgentDestructionWithoutShutdown", "RecoverableJobs", "AllowNewIncarnationToReconnect", "ForceDisable", "PollForErrorFromServiceAtStartup", }); } // @@protoc_insertion_point(outer_class_scope) diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/EntryValue.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/EntryValue.java index 44deff4cb4d..0b6ce2fef52 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/EntryValue.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/EntryValue.java @@ -1,5 +1,5 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! -// source: tsl/protobuf/test_log.proto +// source: xla/tsl/protobuf/test_log.proto package org.tensorflow.proto; diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/EntryValueOrBuilder.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/EntryValueOrBuilder.java index 525dfd70275..6338554d477 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/EntryValueOrBuilder.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/EntryValueOrBuilder.java @@ -1,5 +1,5 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! -// source: tsl/protobuf/test_log.proto +// source: xla/tsl/protobuf/test_log.proto package org.tensorflow.proto; diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/GPUInfo.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/GPUInfo.java index f07305dc1aa..858f216fb45 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/GPUInfo.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/GPUInfo.java @@ -1,5 +1,5 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! -// source: tsl/protobuf/test_log.proto +// source: xla/tsl/protobuf/test_log.proto package org.tensorflow.proto; diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/GPUInfoOrBuilder.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/GPUInfoOrBuilder.java index 6aefc92ee8c..02d2cc61740 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/GPUInfoOrBuilder.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/GPUInfoOrBuilder.java @@ -1,5 +1,5 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! -// source: tsl/protobuf/test_log.proto +// source: xla/tsl/protobuf/test_log.proto package org.tensorflow.proto; diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/GPUOptions.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/GPUOptions.java index 8eac8bc4ef1..d9db2330adb 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/GPUOptions.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/GPUOptions.java @@ -467,6 +467,43 @@ org.tensorflow.proto.GPUOptions.Experimental.VirtualDevicesOrBuilder getVirtualD * @return The gpuSystemMemorySizeInMb. */ int getGpuSystemMemorySizeInMb(); + + /** + *
    +     * If true, save information needed for created a PjRt GPU client for
    +     * creating a client with remote devices.
    +     * 
    + * + * bool populate_pjrt_gpu_client_creation_info = 17; + * @return The populatePjrtGpuClientCreationInfo. + */ + boolean getPopulatePjrtGpuClientCreationInfo(); + + /** + *
    +     * node_id for use when creating a PjRt GPU client with remote devices,
    +     * which enumerates jobs*tasks from a ServerDef.
    +     * 
    + * + * int32 node_id = 18; + * @return The nodeId. + */ + int getNodeId(); + + /** + * .tensorflow.GPUOptions.Experimental.StreamMergeOptions stream_merge_options = 19; + * @return Whether the streamMergeOptions field is set. + */ + boolean hasStreamMergeOptions(); + /** + * .tensorflow.GPUOptions.Experimental.StreamMergeOptions stream_merge_options = 19; + * @return The streamMergeOptions. + */ + org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions getStreamMergeOptions(); + /** + * .tensorflow.GPUOptions.Experimental.StreamMergeOptions stream_merge_options = 19; + */ + org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptionsOrBuilder getStreamMergeOptionsOrBuilder(); } /** * Protobuf type {@code tensorflow.GPUOptions.Experimental} @@ -1673,105 +1710,846 @@ private void ensureDeviceOrdinalIsMutable() { } /** *
    -         * Virtual Device ordinal number determines the device ID of the device.
    -         * A Virtual device with a lower ordinal number always receives the a
    -         * smaller device id. The phyiscal device id and location in the
    -         * virtual device list is used to break ties.
    +         * Virtual Device ordinal number determines the device ID of the device.
    +         * A Virtual device with a lower ordinal number always receives the a
    +         * smaller device id. The phyiscal device id and location in the
    +         * virtual device list is used to break ties.
    +         * 
    + * + * repeated int32 device_ordinal = 3; + * @return The count of deviceOrdinal. + */ + public int getDeviceOrdinalCount() { + return deviceOrdinal_.size(); + } + /** + *
    +         * Virtual Device ordinal number determines the device ID of the device.
    +         * A Virtual device with a lower ordinal number always receives the a
    +         * smaller device id. The phyiscal device id and location in the
    +         * virtual device list is used to break ties.
    +         * 
    + * + * repeated int32 device_ordinal = 3; + * @param index The index of the element to return. + * @return The deviceOrdinal at the given index. + */ + public int getDeviceOrdinal(int index) { + return deviceOrdinal_.getInt(index); + } + /** + *
    +         * Virtual Device ordinal number determines the device ID of the device.
    +         * A Virtual device with a lower ordinal number always receives the a
    +         * smaller device id. The phyiscal device id and location in the
    +         * virtual device list is used to break ties.
    +         * 
    + * + * repeated int32 device_ordinal = 3; + * @param index The index to set the value at. + * @param value The deviceOrdinal to set. + * @return This builder for chaining. + */ + public Builder setDeviceOrdinal( + int index, int value) { + ensureDeviceOrdinalIsMutable(); + deviceOrdinal_.setInt(index, value); + onChanged(); + return this; + } + /** + *
    +         * Virtual Device ordinal number determines the device ID of the device.
    +         * A Virtual device with a lower ordinal number always receives the a
    +         * smaller device id. The phyiscal device id and location in the
    +         * virtual device list is used to break ties.
    +         * 
    + * + * repeated int32 device_ordinal = 3; + * @param value The deviceOrdinal to add. + * @return This builder for chaining. + */ + public Builder addDeviceOrdinal(int value) { + ensureDeviceOrdinalIsMutable(); + deviceOrdinal_.addInt(value); + onChanged(); + return this; + } + /** + *
    +         * Virtual Device ordinal number determines the device ID of the device.
    +         * A Virtual device with a lower ordinal number always receives the a
    +         * smaller device id. The phyiscal device id and location in the
    +         * virtual device list is used to break ties.
    +         * 
    + * + * repeated int32 device_ordinal = 3; + * @param values The deviceOrdinal to add. + * @return This builder for chaining. + */ + public Builder addAllDeviceOrdinal( + java.lang.Iterable values) { + ensureDeviceOrdinalIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, deviceOrdinal_); + onChanged(); + return this; + } + /** + *
    +         * Virtual Device ordinal number determines the device ID of the device.
    +         * A Virtual device with a lower ordinal number always receives the a
    +         * smaller device id. The phyiscal device id and location in the
    +         * virtual device list is used to break ties.
    +         * 
    + * + * repeated int32 device_ordinal = 3; + * @return This builder for chaining. + */ + public Builder clearDeviceOrdinal() { + deviceOrdinal_ = emptyIntList(); + bitField0_ = (bitField0_ & ~0x00000004); + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:tensorflow.GPUOptions.Experimental.VirtualDevices) + } + + // @@protoc_insertion_point(class_scope:tensorflow.GPUOptions.Experimental.VirtualDevices) + private static final org.tensorflow.proto.GPUOptions.Experimental.VirtualDevices DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new org.tensorflow.proto.GPUOptions.Experimental.VirtualDevices(); + } + + public static org.tensorflow.proto.GPUOptions.Experimental.VirtualDevices getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public VirtualDevices parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public org.tensorflow.proto.GPUOptions.Experimental.VirtualDevices getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface StreamMergeOptionsOrBuilder extends + // @@protoc_insertion_point(interface_extends:tensorflow.GPUOptions.Experimental.StreamMergeOptions) + com.google.protobuf.MessageOrBuilder { + + /** + *
    +       * If true, the compute stream will be used for host_to_device copy as
    +       * well. It's no longer necessary to record an event before the copy to
    +       * let the copy stream wait for the compute stream to finish. There is
    +       * also no need to wait for the copy to complete before executing the
    +       * callback function.
    +       * 
    + * + * bool merge_host_to_device_stream = 1; + * @return The mergeHostToDeviceStream. + */ + boolean getMergeHostToDeviceStream(); + + /** + *
    +       * If true, the compute stream will be used for device_to_host copy as
    +       * well. It's no longer necessary to record an event before the copy to
    +       * let the copy stream wait for the compute stream to finish.
    +       * 
    + * + * bool merge_device_to_host_stream = 2; + * @return The mergeDeviceToHostStream. + */ + boolean getMergeDeviceToHostStream(); + + /** + *
    +       * If true, the compute stream will be used for device_to_device copy as
    +       * well. It's no longer necessary to record an event before the copy to
    +       * let the copy stream wait for the compute stream of the sending device
    +       * to finish. There is also no need to wait for the compute stream of the
    +       * receiving device to finish if the copy is within the same device.
    +       * 
    + * + * bool merge_device_to_device_stream = 3; + * @return The mergeDeviceToDeviceStream. + */ + boolean getMergeDeviceToDeviceStream(); + } + /** + *
    +     * Whether to merge data transfer streams into the compute stream in the
    +     * same stream group. Stream merging helps reduce the overhead caused by
    +     * stream synchronization, especially when data transfers are frequent. For
    +     * example, setting "merge_host_to_device_stream = true" will make the
    +     * compute stream responsible for both computation and host to device memory
    +     * copy.
    +     * 
    + * + * Protobuf type {@code tensorflow.GPUOptions.Experimental.StreamMergeOptions} + */ + public static final class StreamMergeOptions extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:tensorflow.GPUOptions.Experimental.StreamMergeOptions) + StreamMergeOptionsOrBuilder { + private static final long serialVersionUID = 0L; + // Use StreamMergeOptions.newBuilder() to construct. + private StreamMergeOptions(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private StreamMergeOptions() { + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new StreamMergeOptions(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.tensorflow.proto.ConfigProtos.internal_static_tensorflow_GPUOptions_Experimental_StreamMergeOptions_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.tensorflow.proto.ConfigProtos.internal_static_tensorflow_GPUOptions_Experimental_StreamMergeOptions_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions.class, org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions.Builder.class); + } + + public static final int MERGE_HOST_TO_DEVICE_STREAM_FIELD_NUMBER = 1; + private boolean mergeHostToDeviceStream_; + /** + *
    +       * If true, the compute stream will be used for host_to_device copy as
    +       * well. It's no longer necessary to record an event before the copy to
    +       * let the copy stream wait for the compute stream to finish. There is
    +       * also no need to wait for the copy to complete before executing the
    +       * callback function.
    +       * 
    + * + * bool merge_host_to_device_stream = 1; + * @return The mergeHostToDeviceStream. + */ + @java.lang.Override + public boolean getMergeHostToDeviceStream() { + return mergeHostToDeviceStream_; + } + + public static final int MERGE_DEVICE_TO_HOST_STREAM_FIELD_NUMBER = 2; + private boolean mergeDeviceToHostStream_; + /** + *
    +       * If true, the compute stream will be used for device_to_host copy as
    +       * well. It's no longer necessary to record an event before the copy to
    +       * let the copy stream wait for the compute stream to finish.
    +       * 
    + * + * bool merge_device_to_host_stream = 2; + * @return The mergeDeviceToHostStream. + */ + @java.lang.Override + public boolean getMergeDeviceToHostStream() { + return mergeDeviceToHostStream_; + } + + public static final int MERGE_DEVICE_TO_DEVICE_STREAM_FIELD_NUMBER = 3; + private boolean mergeDeviceToDeviceStream_; + /** + *
    +       * If true, the compute stream will be used for device_to_device copy as
    +       * well. It's no longer necessary to record an event before the copy to
    +       * let the copy stream wait for the compute stream of the sending device
    +       * to finish. There is also no need to wait for the compute stream of the
    +       * receiving device to finish if the copy is within the same device.
    +       * 
    + * + * bool merge_device_to_device_stream = 3; + * @return The mergeDeviceToDeviceStream. + */ + @java.lang.Override + public boolean getMergeDeviceToDeviceStream() { + return mergeDeviceToDeviceStream_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (mergeHostToDeviceStream_ != false) { + output.writeBool(1, mergeHostToDeviceStream_); + } + if (mergeDeviceToHostStream_ != false) { + output.writeBool(2, mergeDeviceToHostStream_); + } + if (mergeDeviceToDeviceStream_ != false) { + output.writeBool(3, mergeDeviceToDeviceStream_); + } + getUnknownFields().writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (mergeHostToDeviceStream_ != false) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(1, mergeHostToDeviceStream_); + } + if (mergeDeviceToHostStream_ != false) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(2, mergeDeviceToHostStream_); + } + if (mergeDeviceToDeviceStream_ != false) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(3, mergeDeviceToDeviceStream_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions)) { + return super.equals(obj); + } + org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions other = (org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions) obj; + + if (getMergeHostToDeviceStream() + != other.getMergeHostToDeviceStream()) return false; + if (getMergeDeviceToHostStream() + != other.getMergeDeviceToHostStream()) return false; + if (getMergeDeviceToDeviceStream() + != other.getMergeDeviceToDeviceStream()) return false; + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + MERGE_HOST_TO_DEVICE_STREAM_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean( + getMergeHostToDeviceStream()); + hash = (37 * hash) + MERGE_DEVICE_TO_HOST_STREAM_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean( + getMergeDeviceToHostStream()); + hash = (37 * hash) + MERGE_DEVICE_TO_DEVICE_STREAM_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean( + getMergeDeviceToDeviceStream()); + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
    +       * Whether to merge data transfer streams into the compute stream in the
    +       * same stream group. Stream merging helps reduce the overhead caused by
    +       * stream synchronization, especially when data transfers are frequent. For
    +       * example, setting "merge_host_to_device_stream = true" will make the
    +       * compute stream responsible for both computation and host to device memory
    +       * copy.
    +       * 
    + * + * Protobuf type {@code tensorflow.GPUOptions.Experimental.StreamMergeOptions} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:tensorflow.GPUOptions.Experimental.StreamMergeOptions) + org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptionsOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.tensorflow.proto.ConfigProtos.internal_static_tensorflow_GPUOptions_Experimental_StreamMergeOptions_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.tensorflow.proto.ConfigProtos.internal_static_tensorflow_GPUOptions_Experimental_StreamMergeOptions_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions.class, org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions.Builder.class); + } + + // Construct using org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions.newBuilder() + private Builder() { + + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + + } + @java.lang.Override + public Builder clear() { + super.clear(); + mergeHostToDeviceStream_ = false; + + mergeDeviceToHostStream_ = false; + + mergeDeviceToDeviceStream_ = false; + + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.tensorflow.proto.ConfigProtos.internal_static_tensorflow_GPUOptions_Experimental_StreamMergeOptions_descriptor; + } + + @java.lang.Override + public org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions getDefaultInstanceForType() { + return org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions.getDefaultInstance(); + } + + @java.lang.Override + public org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions build() { + org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions buildPartial() { + org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions result = new org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions(this); + result.mergeHostToDeviceStream_ = mergeHostToDeviceStream_; + result.mergeDeviceToHostStream_ = mergeDeviceToHostStream_; + result.mergeDeviceToDeviceStream_ = mergeDeviceToDeviceStream_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions) { + return mergeFrom((org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions other) { + if (other == org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions.getDefaultInstance()) return this; + if (other.getMergeHostToDeviceStream() != false) { + setMergeHostToDeviceStream(other.getMergeHostToDeviceStream()); + } + if (other.getMergeDeviceToHostStream() != false) { + setMergeDeviceToHostStream(other.getMergeDeviceToHostStream()); + } + if (other.getMergeDeviceToDeviceStream() != false) { + setMergeDeviceToDeviceStream(other.getMergeDeviceToDeviceStream()); + } + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 8: { + mergeHostToDeviceStream_ = input.readBool(); + + break; + } // case 8 + case 16: { + mergeDeviceToHostStream_ = input.readBool(); + + break; + } // case 16 + case 24: { + mergeDeviceToDeviceStream_ = input.readBool(); + + break; + } // case 24 + default: { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + + private boolean mergeHostToDeviceStream_ ; + /** + *
    +         * If true, the compute stream will be used for host_to_device copy as
    +         * well. It's no longer necessary to record an event before the copy to
    +         * let the copy stream wait for the compute stream to finish. There is
    +         * also no need to wait for the copy to complete before executing the
    +         * callback function.
    +         * 
    + * + * bool merge_host_to_device_stream = 1; + * @return The mergeHostToDeviceStream. + */ + @java.lang.Override + public boolean getMergeHostToDeviceStream() { + return mergeHostToDeviceStream_; + } + /** + *
    +         * If true, the compute stream will be used for host_to_device copy as
    +         * well. It's no longer necessary to record an event before the copy to
    +         * let the copy stream wait for the compute stream to finish. There is
    +         * also no need to wait for the copy to complete before executing the
    +         * callback function.
    +         * 
    + * + * bool merge_host_to_device_stream = 1; + * @param value The mergeHostToDeviceStream to set. + * @return This builder for chaining. + */ + public Builder setMergeHostToDeviceStream(boolean value) { + + mergeHostToDeviceStream_ = value; + onChanged(); + return this; + } + /** + *
    +         * If true, the compute stream will be used for host_to_device copy as
    +         * well. It's no longer necessary to record an event before the copy to
    +         * let the copy stream wait for the compute stream to finish. There is
    +         * also no need to wait for the copy to complete before executing the
    +         * callback function.
              * 
    * - * repeated int32 device_ordinal = 3; - * @return The count of deviceOrdinal. + * bool merge_host_to_device_stream = 1; + * @return This builder for chaining. */ - public int getDeviceOrdinalCount() { - return deviceOrdinal_.size(); + public Builder clearMergeHostToDeviceStream() { + + mergeHostToDeviceStream_ = false; + onChanged(); + return this; } + + private boolean mergeDeviceToHostStream_ ; /** *
    -         * Virtual Device ordinal number determines the device ID of the device.
    -         * A Virtual device with a lower ordinal number always receives the a
    -         * smaller device id. The phyiscal device id and location in the
    -         * virtual device list is used to break ties.
    +         * If true, the compute stream will be used for device_to_host copy as
    +         * well. It's no longer necessary to record an event before the copy to
    +         * let the copy stream wait for the compute stream to finish.
              * 
    * - * repeated int32 device_ordinal = 3; - * @param index The index of the element to return. - * @return The deviceOrdinal at the given index. + * bool merge_device_to_host_stream = 2; + * @return The mergeDeviceToHostStream. */ - public int getDeviceOrdinal(int index) { - return deviceOrdinal_.getInt(index); + @java.lang.Override + public boolean getMergeDeviceToHostStream() { + return mergeDeviceToHostStream_; } /** *
    -         * Virtual Device ordinal number determines the device ID of the device.
    -         * A Virtual device with a lower ordinal number always receives the a
    -         * smaller device id. The phyiscal device id and location in the
    -         * virtual device list is used to break ties.
    +         * If true, the compute stream will be used for device_to_host copy as
    +         * well. It's no longer necessary to record an event before the copy to
    +         * let the copy stream wait for the compute stream to finish.
              * 
    * - * repeated int32 device_ordinal = 3; - * @param index The index to set the value at. - * @param value The deviceOrdinal to set. + * bool merge_device_to_host_stream = 2; + * @param value The mergeDeviceToHostStream to set. * @return This builder for chaining. */ - public Builder setDeviceOrdinal( - int index, int value) { - ensureDeviceOrdinalIsMutable(); - deviceOrdinal_.setInt(index, value); + public Builder setMergeDeviceToHostStream(boolean value) { + + mergeDeviceToHostStream_ = value; onChanged(); return this; } /** *
    -         * Virtual Device ordinal number determines the device ID of the device.
    -         * A Virtual device with a lower ordinal number always receives the a
    -         * smaller device id. The phyiscal device id and location in the
    -         * virtual device list is used to break ties.
    +         * If true, the compute stream will be used for device_to_host copy as
    +         * well. It's no longer necessary to record an event before the copy to
    +         * let the copy stream wait for the compute stream to finish.
              * 
    * - * repeated int32 device_ordinal = 3; - * @param value The deviceOrdinal to add. + * bool merge_device_to_host_stream = 2; * @return This builder for chaining. */ - public Builder addDeviceOrdinal(int value) { - ensureDeviceOrdinalIsMutable(); - deviceOrdinal_.addInt(value); + public Builder clearMergeDeviceToHostStream() { + + mergeDeviceToHostStream_ = false; onChanged(); return this; } + + private boolean mergeDeviceToDeviceStream_ ; /** *
    -         * Virtual Device ordinal number determines the device ID of the device.
    -         * A Virtual device with a lower ordinal number always receives the a
    -         * smaller device id. The phyiscal device id and location in the
    -         * virtual device list is used to break ties.
    +         * If true, the compute stream will be used for device_to_device copy as
    +         * well. It's no longer necessary to record an event before the copy to
    +         * let the copy stream wait for the compute stream of the sending device
    +         * to finish. There is also no need to wait for the compute stream of the
    +         * receiving device to finish if the copy is within the same device.
              * 
    * - * repeated int32 device_ordinal = 3; - * @param values The deviceOrdinal to add. + * bool merge_device_to_device_stream = 3; + * @return The mergeDeviceToDeviceStream. + */ + @java.lang.Override + public boolean getMergeDeviceToDeviceStream() { + return mergeDeviceToDeviceStream_; + } + /** + *
    +         * If true, the compute stream will be used for device_to_device copy as
    +         * well. It's no longer necessary to record an event before the copy to
    +         * let the copy stream wait for the compute stream of the sending device
    +         * to finish. There is also no need to wait for the compute stream of the
    +         * receiving device to finish if the copy is within the same device.
    +         * 
    + * + * bool merge_device_to_device_stream = 3; + * @param value The mergeDeviceToDeviceStream to set. * @return This builder for chaining. */ - public Builder addAllDeviceOrdinal( - java.lang.Iterable values) { - ensureDeviceOrdinalIsMutable(); - com.google.protobuf.AbstractMessageLite.Builder.addAll( - values, deviceOrdinal_); + public Builder setMergeDeviceToDeviceStream(boolean value) { + + mergeDeviceToDeviceStream_ = value; onChanged(); return this; } /** *
    -         * Virtual Device ordinal number determines the device ID of the device.
    -         * A Virtual device with a lower ordinal number always receives the a
    -         * smaller device id. The phyiscal device id and location in the
    -         * virtual device list is used to break ties.
    +         * If true, the compute stream will be used for device_to_device copy as
    +         * well. It's no longer necessary to record an event before the copy to
    +         * let the copy stream wait for the compute stream of the sending device
    +         * to finish. There is also no need to wait for the compute stream of the
    +         * receiving device to finish if the copy is within the same device.
              * 
    * - * repeated int32 device_ordinal = 3; + * bool merge_device_to_device_stream = 3; * @return This builder for chaining. */ - public Builder clearDeviceOrdinal() { - deviceOrdinal_ = emptyIntList(); - bitField0_ = (bitField0_ & ~0x00000004); + public Builder clearMergeDeviceToDeviceStream() { + + mergeDeviceToDeviceStream_ = false; onChanged(); return this; } @@ -1788,23 +2566,23 @@ public final Builder mergeUnknownFields( } - // @@protoc_insertion_point(builder_scope:tensorflow.GPUOptions.Experimental.VirtualDevices) + // @@protoc_insertion_point(builder_scope:tensorflow.GPUOptions.Experimental.StreamMergeOptions) } - // @@protoc_insertion_point(class_scope:tensorflow.GPUOptions.Experimental.VirtualDevices) - private static final org.tensorflow.proto.GPUOptions.Experimental.VirtualDevices DEFAULT_INSTANCE; + // @@protoc_insertion_point(class_scope:tensorflow.GPUOptions.Experimental.StreamMergeOptions) + private static final org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new org.tensorflow.proto.GPUOptions.Experimental.VirtualDevices(); + DEFAULT_INSTANCE = new org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions(); } - public static org.tensorflow.proto.GPUOptions.Experimental.VirtualDevices getDefaultInstance() { + public static org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions getDefaultInstance() { return DEFAULT_INSTANCE; } - private static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { @java.lang.Override - public VirtualDevices parsePartialFrom( + public StreamMergeOptions parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { @@ -1823,17 +2601,17 @@ public VirtualDevices parsePartialFrom( } }; - public static com.google.protobuf.Parser parser() { + public static com.google.protobuf.Parser parser() { return PARSER; } @java.lang.Override - public com.google.protobuf.Parser getParserForType() { + public com.google.protobuf.Parser getParserForType() { return PARSER; } @java.lang.Override - public org.tensorflow.proto.GPUOptions.Experimental.VirtualDevices getDefaultInstanceForType() { + public org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions getDefaultInstanceForType() { return DEFAULT_INSTANCE; } @@ -2365,6 +3143,64 @@ public int getGpuSystemMemorySizeInMb() { return gpuSystemMemorySizeInMb_; } + public static final int POPULATE_PJRT_GPU_CLIENT_CREATION_INFO_FIELD_NUMBER = 17; + private boolean populatePjrtGpuClientCreationInfo_; + /** + *
    +     * If true, save information needed for created a PjRt GPU client for
    +     * creating a client with remote devices.
    +     * 
    + * + * bool populate_pjrt_gpu_client_creation_info = 17; + * @return The populatePjrtGpuClientCreationInfo. + */ + @java.lang.Override + public boolean getPopulatePjrtGpuClientCreationInfo() { + return populatePjrtGpuClientCreationInfo_; + } + + public static final int NODE_ID_FIELD_NUMBER = 18; + private int nodeId_; + /** + *
    +     * node_id for use when creating a PjRt GPU client with remote devices,
    +     * which enumerates jobs*tasks from a ServerDef.
    +     * 
    + * + * int32 node_id = 18; + * @return The nodeId. + */ + @java.lang.Override + public int getNodeId() { + return nodeId_; + } + + public static final int STREAM_MERGE_OPTIONS_FIELD_NUMBER = 19; + private org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions streamMergeOptions_; + /** + * .tensorflow.GPUOptions.Experimental.StreamMergeOptions stream_merge_options = 19; + * @return Whether the streamMergeOptions field is set. + */ + @java.lang.Override + public boolean hasStreamMergeOptions() { + return streamMergeOptions_ != null; + } + /** + * .tensorflow.GPUOptions.Experimental.StreamMergeOptions stream_merge_options = 19; + * @return The streamMergeOptions. + */ + @java.lang.Override + public org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions getStreamMergeOptions() { + return streamMergeOptions_ == null ? org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions.getDefaultInstance() : streamMergeOptions_; + } + /** + * .tensorflow.GPUOptions.Experimental.StreamMergeOptions stream_merge_options = 19; + */ + @java.lang.Override + public org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptionsOrBuilder getStreamMergeOptionsOrBuilder() { + return getStreamMergeOptions(); + } + private byte memoizedIsInitialized = -1; @java.lang.Override public final boolean isInitialized() { @@ -2424,6 +3260,15 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) if (gpuSystemMemorySizeInMb_ != 0) { output.writeInt32(16, gpuSystemMemorySizeInMb_); } + if (populatePjrtGpuClientCreationInfo_ != false) { + output.writeBool(17, populatePjrtGpuClientCreationInfo_); + } + if (nodeId_ != 0) { + output.writeInt32(18, nodeId_); + } + if (streamMergeOptions_ != null) { + output.writeMessage(19, getStreamMergeOptions()); + } getUnknownFields().writeTo(output); } @@ -2492,6 +3337,18 @@ public int getSerializedSize() { size += com.google.protobuf.CodedOutputStream .computeInt32Size(16, gpuSystemMemorySizeInMb_); } + if (populatePjrtGpuClientCreationInfo_ != false) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(17, populatePjrtGpuClientCreationInfo_); + } + if (nodeId_ != 0) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size(18, nodeId_); + } + if (streamMergeOptions_ != null) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(19, getStreamMergeOptions()); + } size += getUnknownFields().getSerializedSize(); memoizedSize = size; return size; @@ -2539,6 +3396,15 @@ public boolean equals(final java.lang.Object obj) { != other.getGpuHostMemDisallowGrowth()) return false; if (getGpuSystemMemorySizeInMb() != other.getGpuSystemMemorySizeInMb()) return false; + if (getPopulatePjrtGpuClientCreationInfo() + != other.getPopulatePjrtGpuClientCreationInfo()) return false; + if (getNodeId() + != other.getNodeId()) return false; + if (hasStreamMergeOptions() != other.hasStreamMergeOptions()) return false; + if (hasStreamMergeOptions()) { + if (!getStreamMergeOptions() + .equals(other.getStreamMergeOptions())) return false; + } if (!getUnknownFields().equals(other.getUnknownFields())) return false; return true; } @@ -2589,6 +3455,15 @@ public int hashCode() { getGpuHostMemDisallowGrowth()); hash = (37 * hash) + GPU_SYSTEM_MEMORY_SIZE_IN_MB_FIELD_NUMBER; hash = (53 * hash) + getGpuSystemMemorySizeInMb(); + hash = (37 * hash) + POPULATE_PJRT_GPU_CLIENT_CREATION_INFO_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean( + getPopulatePjrtGpuClientCreationInfo()); + hash = (37 * hash) + NODE_ID_FIELD_NUMBER; + hash = (53 * hash) + getNodeId(); + if (hasStreamMergeOptions()) { + hash = (37 * hash) + STREAM_MERGE_OPTIONS_FIELD_NUMBER; + hash = (53 * hash) + getStreamMergeOptions().hashCode(); + } hash = (29 * hash) + getUnknownFields().hashCode(); memoizedHashCode = hash; return hash; @@ -2752,6 +3627,16 @@ public Builder clear() { gpuSystemMemorySizeInMb_ = 0; + populatePjrtGpuClientCreationInfo_ = false; + + nodeId_ = 0; + + if (streamMergeOptionsBuilder_ == null) { + streamMergeOptions_ = null; + } else { + streamMergeOptions_ = null; + streamMergeOptionsBuilder_ = null; + } return this; } @@ -2802,6 +3687,13 @@ public org.tensorflow.proto.GPUOptions.Experimental buildPartial() { result.gpuHostMemLimitInMb_ = gpuHostMemLimitInMb_; result.gpuHostMemDisallowGrowth_ = gpuHostMemDisallowGrowth_; result.gpuSystemMemorySizeInMb_ = gpuSystemMemorySizeInMb_; + result.populatePjrtGpuClientCreationInfo_ = populatePjrtGpuClientCreationInfo_; + result.nodeId_ = nodeId_; + if (streamMergeOptionsBuilder_ == null) { + result.streamMergeOptions_ = streamMergeOptions_; + } else { + result.streamMergeOptions_ = streamMergeOptionsBuilder_.build(); + } onBuilt(); return result; } @@ -2919,6 +3811,15 @@ public Builder mergeFrom(org.tensorflow.proto.GPUOptions.Experimental other) { if (other.getGpuSystemMemorySizeInMb() != 0) { setGpuSystemMemorySizeInMb(other.getGpuSystemMemorySizeInMb()); } + if (other.getPopulatePjrtGpuClientCreationInfo() != false) { + setPopulatePjrtGpuClientCreationInfo(other.getPopulatePjrtGpuClientCreationInfo()); + } + if (other.getNodeId() != 0) { + setNodeId(other.getNodeId()); + } + if (other.hasStreamMergeOptions()) { + mergeStreamMergeOptions(other.getStreamMergeOptions()); + } this.mergeUnknownFields(other.getUnknownFields()); onChanged(); return this; @@ -3028,6 +3929,23 @@ public Builder mergeFrom( break; } // case 128 + case 136: { + populatePjrtGpuClientCreationInfo_ = input.readBool(); + + break; + } // case 136 + case 144: { + nodeId_ = input.readInt32(); + + break; + } // case 144 + case 154: { + input.readMessage( + getStreamMergeOptionsFieldBuilder().getBuilder(), + extensionRegistry); + + break; + } // case 154 default: { if (!super.parseUnknownField(input, extensionRegistry, tag)) { done = true; // was an endgroup tag @@ -4783,6 +5701,217 @@ public Builder clearGpuSystemMemorySizeInMb() { onChanged(); return this; } + + private boolean populatePjrtGpuClientCreationInfo_ ; + /** + *
    +       * If true, save information needed for created a PjRt GPU client for
    +       * creating a client with remote devices.
    +       * 
    + * + * bool populate_pjrt_gpu_client_creation_info = 17; + * @return The populatePjrtGpuClientCreationInfo. + */ + @java.lang.Override + public boolean getPopulatePjrtGpuClientCreationInfo() { + return populatePjrtGpuClientCreationInfo_; + } + /** + *
    +       * If true, save information needed for created a PjRt GPU client for
    +       * creating a client with remote devices.
    +       * 
    + * + * bool populate_pjrt_gpu_client_creation_info = 17; + * @param value The populatePjrtGpuClientCreationInfo to set. + * @return This builder for chaining. + */ + public Builder setPopulatePjrtGpuClientCreationInfo(boolean value) { + + populatePjrtGpuClientCreationInfo_ = value; + onChanged(); + return this; + } + /** + *
    +       * If true, save information needed for created a PjRt GPU client for
    +       * creating a client with remote devices.
    +       * 
    + * + * bool populate_pjrt_gpu_client_creation_info = 17; + * @return This builder for chaining. + */ + public Builder clearPopulatePjrtGpuClientCreationInfo() { + + populatePjrtGpuClientCreationInfo_ = false; + onChanged(); + return this; + } + + private int nodeId_ ; + /** + *
    +       * node_id for use when creating a PjRt GPU client with remote devices,
    +       * which enumerates jobs*tasks from a ServerDef.
    +       * 
    + * + * int32 node_id = 18; + * @return The nodeId. + */ + @java.lang.Override + public int getNodeId() { + return nodeId_; + } + /** + *
    +       * node_id for use when creating a PjRt GPU client with remote devices,
    +       * which enumerates jobs*tasks from a ServerDef.
    +       * 
    + * + * int32 node_id = 18; + * @param value The nodeId to set. + * @return This builder for chaining. + */ + public Builder setNodeId(int value) { + + nodeId_ = value; + onChanged(); + return this; + } + /** + *
    +       * node_id for use when creating a PjRt GPU client with remote devices,
    +       * which enumerates jobs*tasks from a ServerDef.
    +       * 
    + * + * int32 node_id = 18; + * @return This builder for chaining. + */ + public Builder clearNodeId() { + + nodeId_ = 0; + onChanged(); + return this; + } + + private org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions streamMergeOptions_; + private com.google.protobuf.SingleFieldBuilderV3< + org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions, org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions.Builder, org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptionsOrBuilder> streamMergeOptionsBuilder_; + /** + * .tensorflow.GPUOptions.Experimental.StreamMergeOptions stream_merge_options = 19; + * @return Whether the streamMergeOptions field is set. + */ + public boolean hasStreamMergeOptions() { + return streamMergeOptionsBuilder_ != null || streamMergeOptions_ != null; + } + /** + * .tensorflow.GPUOptions.Experimental.StreamMergeOptions stream_merge_options = 19; + * @return The streamMergeOptions. + */ + public org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions getStreamMergeOptions() { + if (streamMergeOptionsBuilder_ == null) { + return streamMergeOptions_ == null ? org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions.getDefaultInstance() : streamMergeOptions_; + } else { + return streamMergeOptionsBuilder_.getMessage(); + } + } + /** + * .tensorflow.GPUOptions.Experimental.StreamMergeOptions stream_merge_options = 19; + */ + public Builder setStreamMergeOptions(org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions value) { + if (streamMergeOptionsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + streamMergeOptions_ = value; + onChanged(); + } else { + streamMergeOptionsBuilder_.setMessage(value); + } + + return this; + } + /** + * .tensorflow.GPUOptions.Experimental.StreamMergeOptions stream_merge_options = 19; + */ + public Builder setStreamMergeOptions( + org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions.Builder builderForValue) { + if (streamMergeOptionsBuilder_ == null) { + streamMergeOptions_ = builderForValue.build(); + onChanged(); + } else { + streamMergeOptionsBuilder_.setMessage(builderForValue.build()); + } + + return this; + } + /** + * .tensorflow.GPUOptions.Experimental.StreamMergeOptions stream_merge_options = 19; + */ + public Builder mergeStreamMergeOptions(org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions value) { + if (streamMergeOptionsBuilder_ == null) { + if (streamMergeOptions_ != null) { + streamMergeOptions_ = + org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions.newBuilder(streamMergeOptions_).mergeFrom(value).buildPartial(); + } else { + streamMergeOptions_ = value; + } + onChanged(); + } else { + streamMergeOptionsBuilder_.mergeFrom(value); + } + + return this; + } + /** + * .tensorflow.GPUOptions.Experimental.StreamMergeOptions stream_merge_options = 19; + */ + public Builder clearStreamMergeOptions() { + if (streamMergeOptionsBuilder_ == null) { + streamMergeOptions_ = null; + onChanged(); + } else { + streamMergeOptions_ = null; + streamMergeOptionsBuilder_ = null; + } + + return this; + } + /** + * .tensorflow.GPUOptions.Experimental.StreamMergeOptions stream_merge_options = 19; + */ + public org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions.Builder getStreamMergeOptionsBuilder() { + + onChanged(); + return getStreamMergeOptionsFieldBuilder().getBuilder(); + } + /** + * .tensorflow.GPUOptions.Experimental.StreamMergeOptions stream_merge_options = 19; + */ + public org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptionsOrBuilder getStreamMergeOptionsOrBuilder() { + if (streamMergeOptionsBuilder_ != null) { + return streamMergeOptionsBuilder_.getMessageOrBuilder(); + } else { + return streamMergeOptions_ == null ? + org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions.getDefaultInstance() : streamMergeOptions_; + } + } + /** + * .tensorflow.GPUOptions.Experimental.StreamMergeOptions stream_merge_options = 19; + */ + private com.google.protobuf.SingleFieldBuilderV3< + org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions, org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions.Builder, org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptionsOrBuilder> + getStreamMergeOptionsFieldBuilder() { + if (streamMergeOptionsBuilder_ == null) { + streamMergeOptionsBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions, org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptions.Builder, org.tensorflow.proto.GPUOptions.Experimental.StreamMergeOptionsOrBuilder>( + getStreamMergeOptions(), + getParentForChildren(), + isClean()); + streamMergeOptions_ = null; + } + return streamMergeOptionsBuilder_; + } @java.lang.Override public final Builder setUnknownFields( final com.google.protobuf.UnknownFieldSet unknownFields) { diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/MachineConfiguration.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/MachineConfiguration.java index 56ab6b425d1..6dbc6ce6f3b 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/MachineConfiguration.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/MachineConfiguration.java @@ -1,5 +1,5 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! -// source: tsl/protobuf/test_log.proto +// source: xla/tsl/protobuf/test_log.proto package org.tensorflow.proto; diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/MachineConfigurationOrBuilder.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/MachineConfigurationOrBuilder.java index 5821218bf8f..e3c944d06be 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/MachineConfigurationOrBuilder.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/MachineConfigurationOrBuilder.java @@ -1,5 +1,5 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! -// source: tsl/protobuf/test_log.proto +// source: xla/tsl/protobuf/test_log.proto package org.tensorflow.proto; diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/MemoryInfo.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/MemoryInfo.java index 8c4b5b692a6..d351a728e2a 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/MemoryInfo.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/MemoryInfo.java @@ -1,5 +1,5 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! -// source: tsl/protobuf/test_log.proto +// source: xla/tsl/protobuf/test_log.proto package org.tensorflow.proto; diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/MemoryInfoOrBuilder.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/MemoryInfoOrBuilder.java index 265206a7c19..6a2f7e6c9e8 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/MemoryInfoOrBuilder.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/MemoryInfoOrBuilder.java @@ -1,5 +1,5 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! -// source: tsl/protobuf/test_log.proto +// source: xla/tsl/protobuf/test_log.proto package org.tensorflow.proto; diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/MetricEntry.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/MetricEntry.java index 70a5e1ba8bc..d9454e9bc70 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/MetricEntry.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/MetricEntry.java @@ -1,5 +1,5 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! -// source: tsl/protobuf/test_log.proto +// source: xla/tsl/protobuf/test_log.proto package org.tensorflow.proto; diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/MetricEntryOrBuilder.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/MetricEntryOrBuilder.java index 9898de2810f..e8f2867a14a 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/MetricEntryOrBuilder.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/MetricEntryOrBuilder.java @@ -1,5 +1,5 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! -// source: tsl/protobuf/test_log.proto +// source: xla/tsl/protobuf/test_log.proto package org.tensorflow.proto; diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/PlatformInfo.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/PlatformInfo.java index 782524cf4d4..d2875cf5041 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/PlatformInfo.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/PlatformInfo.java @@ -1,5 +1,5 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! -// source: tsl/protobuf/test_log.proto +// source: xla/tsl/protobuf/test_log.proto package org.tensorflow.proto; diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/PlatformInfoOrBuilder.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/PlatformInfoOrBuilder.java index fd9455571a2..caade7d2f32 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/PlatformInfoOrBuilder.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/PlatformInfoOrBuilder.java @@ -1,5 +1,5 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! -// source: tsl/protobuf/test_log.proto +// source: xla/tsl/protobuf/test_log.proto package org.tensorflow.proto; diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/ResourceHandleProto.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/ResourceHandleProto.java index 159c9574b47..df26d1e77cd 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/ResourceHandleProto.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/ResourceHandleProto.java @@ -59,27 +59,47 @@ public interface DtypeAndShapeOrBuilder extends com.google.protobuf.MessageOrBuilder { /** + *
    +     * Data type of the tensor.
    +     * 
    + * * .tensorflow.DataType dtype = 1; * @return The enum numeric value on the wire for dtype. */ int getDtypeValue(); /** + *
    +     * Data type of the tensor.
    +     * 
    + * * .tensorflow.DataType dtype = 1; * @return The dtype. */ org.tensorflow.proto.DataType getDtype(); /** + *
    +     * Shape of the tensor.
    +     * 
    + * * .tensorflow.TensorShapeProto shape = 2; * @return Whether the shape field is set. */ boolean hasShape(); /** + *
    +     * Shape of the tensor.
    +     * 
    + * * .tensorflow.TensorShapeProto shape = 2; * @return The shape. */ org.tensorflow.proto.TensorShapeProto getShape(); /** + *
    +     * Shape of the tensor.
    +     * 
    + * * .tensorflow.TensorShapeProto shape = 2; */ org.tensorflow.proto.TensorShapeProtoOrBuilder getShapeOrBuilder(); @@ -132,6 +152,10 @@ protected java.lang.Object newInstance( public static final int DTYPE_FIELD_NUMBER = 1; private int dtype_; /** + *
    +     * Data type of the tensor.
    +     * 
    + * * .tensorflow.DataType dtype = 1; * @return The enum numeric value on the wire for dtype. */ @@ -139,6 +163,10 @@ protected java.lang.Object newInstance( return dtype_; } /** + *
    +     * Data type of the tensor.
    +     * 
    + * * .tensorflow.DataType dtype = 1; * @return The dtype. */ @@ -151,6 +179,10 @@ protected java.lang.Object newInstance( public static final int SHAPE_FIELD_NUMBER = 2; private org.tensorflow.proto.TensorShapeProto shape_; /** + *
    +     * Shape of the tensor.
    +     * 
    + * * .tensorflow.TensorShapeProto shape = 2; * @return Whether the shape field is set. */ @@ -159,6 +191,10 @@ public boolean hasShape() { return shape_ != null; } /** + *
    +     * Shape of the tensor.
    +     * 
    + * * .tensorflow.TensorShapeProto shape = 2; * @return The shape. */ @@ -167,6 +203,10 @@ public org.tensorflow.proto.TensorShapeProto getShape() { return shape_ == null ? org.tensorflow.proto.TensorShapeProto.getDefaultInstance() : shape_; } /** + *
    +     * Shape of the tensor.
    +     * 
    + * * .tensorflow.TensorShapeProto shape = 2; */ @java.lang.Override @@ -531,6 +571,10 @@ public Builder mergeFrom( private int dtype_ = 0; /** + *
    +       * Data type of the tensor.
    +       * 
    + * * .tensorflow.DataType dtype = 1; * @return The enum numeric value on the wire for dtype. */ @@ -538,6 +582,10 @@ public Builder mergeFrom( return dtype_; } /** + *
    +       * Data type of the tensor.
    +       * 
    + * * .tensorflow.DataType dtype = 1; * @param value The enum numeric value on the wire for dtype to set. * @return This builder for chaining. @@ -549,6 +597,10 @@ public Builder setDtypeValue(int value) { return this; } /** + *
    +       * Data type of the tensor.
    +       * 
    + * * .tensorflow.DataType dtype = 1; * @return The dtype. */ @@ -559,6 +611,10 @@ public org.tensorflow.proto.DataType getDtype() { return result == null ? org.tensorflow.proto.DataType.UNRECOGNIZED : result; } /** + *
    +       * Data type of the tensor.
    +       * 
    + * * .tensorflow.DataType dtype = 1; * @param value The dtype to set. * @return This builder for chaining. @@ -573,6 +629,10 @@ public Builder setDtype(org.tensorflow.proto.DataType value) { return this; } /** + *
    +       * Data type of the tensor.
    +       * 
    + * * .tensorflow.DataType dtype = 1; * @return This builder for chaining. */ @@ -587,6 +647,10 @@ public Builder clearDtype() { private com.google.protobuf.SingleFieldBuilderV3< org.tensorflow.proto.TensorShapeProto, org.tensorflow.proto.TensorShapeProto.Builder, org.tensorflow.proto.TensorShapeProtoOrBuilder> shapeBuilder_; /** + *
    +       * Shape of the tensor.
    +       * 
    + * * .tensorflow.TensorShapeProto shape = 2; * @return Whether the shape field is set. */ @@ -594,6 +658,10 @@ public boolean hasShape() { return shapeBuilder_ != null || shape_ != null; } /** + *
    +       * Shape of the tensor.
    +       * 
    + * * .tensorflow.TensorShapeProto shape = 2; * @return The shape. */ @@ -605,6 +673,10 @@ public org.tensorflow.proto.TensorShapeProto getShape() { } } /** + *
    +       * Shape of the tensor.
    +       * 
    + * * .tensorflow.TensorShapeProto shape = 2; */ public Builder setShape(org.tensorflow.proto.TensorShapeProto value) { @@ -621,6 +693,10 @@ public Builder setShape(org.tensorflow.proto.TensorShapeProto value) { return this; } /** + *
    +       * Shape of the tensor.
    +       * 
    + * * .tensorflow.TensorShapeProto shape = 2; */ public Builder setShape( @@ -635,6 +711,10 @@ public Builder setShape( return this; } /** + *
    +       * Shape of the tensor.
    +       * 
    + * * .tensorflow.TensorShapeProto shape = 2; */ public Builder mergeShape(org.tensorflow.proto.TensorShapeProto value) { @@ -653,6 +733,10 @@ public Builder mergeShape(org.tensorflow.proto.TensorShapeProto value) { return this; } /** + *
    +       * Shape of the tensor.
    +       * 
    + * * .tensorflow.TensorShapeProto shape = 2; */ public Builder clearShape() { @@ -667,6 +751,10 @@ public Builder clearShape() { return this; } /** + *
    +       * Shape of the tensor.
    +       * 
    + * * .tensorflow.TensorShapeProto shape = 2; */ public org.tensorflow.proto.TensorShapeProto.Builder getShapeBuilder() { @@ -675,6 +763,10 @@ public org.tensorflow.proto.TensorShapeProto.Builder getShapeBuilder() { return getShapeFieldBuilder().getBuilder(); } /** + *
    +       * Shape of the tensor.
    +       * 
    + * * .tensorflow.TensorShapeProto shape = 2; */ public org.tensorflow.proto.TensorShapeProtoOrBuilder getShapeOrBuilder() { @@ -686,6 +778,10 @@ public org.tensorflow.proto.TensorShapeProtoOrBuilder getShapeOrBuilder() { } } /** + *
    +       * Shape of the tensor.
    +       * 
    + * * .tensorflow.TensorShapeProto shape = 2; */ private com.google.protobuf.SingleFieldBuilderV3< diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/RewriterConfig.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/RewriterConfig.java index ae97c9cc75f..c235fb30634 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/RewriterConfig.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/RewriterConfig.java @@ -2002,8 +2002,8 @@ public boolean getDisableModelPruning() { private int autoMixedPrecision_; /** *
    -   * Optimize data types for CUDA (default is OFF).
    -   * This will try to use float16 on GPU which is faster.
    +   * Optimize data types for CUDA/oneDNN (default is OFF).
    +   * This will try to use float16 on GPU/CPU which is faster.
        * Note that this can change the numerical stability of the graph and may
        * require the use of loss scaling to maintain model convergence.
        * 
    @@ -2016,8 +2016,8 @@ public boolean getDisableModelPruning() { } /** *
    -   * Optimize data types for CUDA (default is OFF).
    -   * This will try to use float16 on GPU which is faster.
    +   * Optimize data types for CUDA/oneDNN (default is OFF).
    +   * This will try to use float16 on GPU/CPU which is faster.
        * Note that this can change the numerical stability of the graph and may
        * require the use of loss scaling to maintain model convergence.
        * 
    @@ -5074,8 +5074,8 @@ public Builder clearImplementationSelector() { private int autoMixedPrecision_ = 0; /** *
    -     * Optimize data types for CUDA (default is OFF).
    -     * This will try to use float16 on GPU which is faster.
    +     * Optimize data types for CUDA/oneDNN (default is OFF).
    +     * This will try to use float16 on GPU/CPU which is faster.
          * Note that this can change the numerical stability of the graph and may
          * require the use of loss scaling to maintain model convergence.
          * 
    @@ -5088,8 +5088,8 @@ public Builder clearImplementationSelector() { } /** *
    -     * Optimize data types for CUDA (default is OFF).
    -     * This will try to use float16 on GPU which is faster.
    +     * Optimize data types for CUDA/oneDNN (default is OFF).
    +     * This will try to use float16 on GPU/CPU which is faster.
          * Note that this can change the numerical stability of the graph and may
          * require the use of loss scaling to maintain model convergence.
          * 
    @@ -5106,8 +5106,8 @@ public Builder setAutoMixedPrecisionValue(int value) { } /** *
    -     * Optimize data types for CUDA (default is OFF).
    -     * This will try to use float16 on GPU which is faster.
    +     * Optimize data types for CUDA/oneDNN (default is OFF).
    +     * This will try to use float16 on GPU/CPU which is faster.
          * Note that this can change the numerical stability of the graph and may
          * require the use of loss scaling to maintain model convergence.
          * 
    @@ -5123,8 +5123,8 @@ public org.tensorflow.proto.RewriterConfig.Toggle getAutoMixedPrecision() { } /** *
    -     * Optimize data types for CUDA (default is OFF).
    -     * This will try to use float16 on GPU which is faster.
    +     * Optimize data types for CUDA/oneDNN (default is OFF).
    +     * This will try to use float16 on GPU/CPU which is faster.
          * Note that this can change the numerical stability of the graph and may
          * require the use of loss scaling to maintain model convergence.
          * 
    @@ -5144,8 +5144,8 @@ public Builder setAutoMixedPrecision(org.tensorflow.proto.RewriterConfig.Toggle } /** *
    -     * Optimize data types for CUDA (default is OFF).
    -     * This will try to use float16 on GPU which is faster.
    +     * Optimize data types for CUDA/oneDNN (default is OFF).
    +     * This will try to use float16 on GPU/CPU which is faster.
          * Note that this can change the numerical stability of the graph and may
          * require the use of loss scaling to maintain model convergence.
          * 
    diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/RewriterConfigOrBuilder.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/RewriterConfigOrBuilder.java index 9ad4b3cf401..2676ca54911 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/RewriterConfigOrBuilder.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/RewriterConfigOrBuilder.java @@ -305,8 +305,8 @@ public interface RewriterConfigOrBuilder extends /** *
    -   * Optimize data types for CUDA (default is OFF).
    -   * This will try to use float16 on GPU which is faster.
    +   * Optimize data types for CUDA/oneDNN (default is OFF).
    +   * This will try to use float16 on GPU/CPU which is faster.
        * Note that this can change the numerical stability of the graph and may
        * require the use of loss scaling to maintain model convergence.
        * 
    @@ -317,8 +317,8 @@ public interface RewriterConfigOrBuilder extends int getAutoMixedPrecisionValue(); /** *
    -   * Optimize data types for CUDA (default is OFF).
    -   * This will try to use float16 on GPU which is faster.
    +   * Optimize data types for CUDA/oneDNN (default is OFF).
    +   * This will try to use float16 on GPU/CPU which is faster.
        * Note that this can change the numerical stability of the graph and may
        * require the use of loss scaling to maintain model convergence.
        * 
    diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/RunConfiguration.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/RunConfiguration.java index 2a17bdafaf1..f8f244b522c 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/RunConfiguration.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/RunConfiguration.java @@ -1,5 +1,5 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! -// source: tsl/protobuf/test_log.proto +// source: xla/tsl/protobuf/test_log.proto package org.tensorflow.proto; diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/RunConfigurationOrBuilder.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/RunConfigurationOrBuilder.java index a3b3ca982e8..4f2ef9a6b2c 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/RunConfigurationOrBuilder.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/RunConfigurationOrBuilder.java @@ -1,5 +1,5 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! -// source: tsl/protobuf/test_log.proto +// source: xla/tsl/protobuf/test_log.proto package org.tensorflow.proto; diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/SignatureDef.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/SignatureDef.java index ecb73cc96e7..b701daabd03 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/SignatureDef.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/SignatureDef.java @@ -7,58 +7,6 @@ *
      * SignatureDef defines the signature of a computation supported by a TensorFlow
      * graph.
    - * For example, a model with two loss computations, sharing a single input,
    - * might have the following signature_def map, in a MetaGraphDef message.
    - * Note that across the two SignatureDefs "loss_A" and "loss_B", the input key,
    - * output key, and method_name are identical, and will be used by system(s) that
    - * implement or rely upon this particular loss method. The output tensor names
    - * differ, demonstrating how different outputs can exist for the same method.
    - * signature_def {
    - *   key: "loss_A"
    - *   value {
    - *     inputs {
    - *       key: "input"
    - *       value {
    - *         name: "input:0"
    - *         dtype: DT_STRING
    - *         tensor_shape: ...
    - *       }
    - *     }
    - *     outputs {
    - *       key: "loss_output"
    - *       value {
    - *         name: "loss_output_A:0"
    - *         dtype: DT_FLOAT
    - *         tensor_shape: ...
    - *       }
    - *     }
    - *     method_name: "some/package/compute_loss"
    - *   }
    - *   ...
    - * }
    - * signature_def {
    - *   key: "loss_B"
    - *   value {
    - *     inputs {
    - *       key: "input"
    - *       value {
    - *         name: "input:0"
    - *         dtype: DT_STRING
    - *         tensor_shape: ...
    - *       }
    - *     }
    - *     outputs {
    - *       key: "loss_output"
    - *       value {
    - *         name: "loss_output_B:0"
    - *         dtype: DT_FLOAT
    - *         tensor_shape: ...
    - *       }
    - *     }
    - *     method_name: "some/package/compute_loss"
    - *   }
    - *   ...
    - * }
      * 
    * * Protobuf type {@code tensorflow.SignatureDef} @@ -315,13 +263,12 @@ public org.tensorflow.proto.TensorInfo getOutputsOrThrow( private volatile java.lang.Object methodName_; /** *
    -   * Extensible method_name information enabling third-party users to mark a
    -   * SignatureDef as supporting a particular method. This enables producers and
    -   * consumers of SignatureDefs, e.g. a model definition library and a serving
    -   * library to have a clear hand-off regarding the semantics of a computation.
    -   * Note that multiple SignatureDefs in a single MetaGraphDef may have the same
    -   * method_name. This is commonly used to support multi-headed computation,
    -   * where a single graph computation may return multiple results.
    +   * Deprecated: TensorFlow 2 always sets this to a fixed value;
    +   * open-source TF Serving stopped checking by default since release 2.4.
    +   * In TensorFlow 1, the method_name enabled users to mark a SignatureDef as
    +   * supporting a particular method. Multiple SignatureDefs in a single
    +   * MetaGraphDef could have the same method_name (e.g., to support multi-headed
    +   * computation).
        * 
    * * string method_name = 3; @@ -342,13 +289,12 @@ public java.lang.String getMethodName() { } /** *
    -   * Extensible method_name information enabling third-party users to mark a
    -   * SignatureDef as supporting a particular method. This enables producers and
    -   * consumers of SignatureDefs, e.g. a model definition library and a serving
    -   * library to have a clear hand-off regarding the semantics of a computation.
    -   * Note that multiple SignatureDefs in a single MetaGraphDef may have the same
    -   * method_name. This is commonly used to support multi-headed computation,
    -   * where a single graph computation may return multiple results.
    +   * Deprecated: TensorFlow 2 always sets this to a fixed value;
    +   * open-source TF Serving stopped checking by default since release 2.4.
    +   * In TensorFlow 1, the method_name enabled users to mark a SignatureDef as
    +   * supporting a particular method. Multiple SignatureDefs in a single
    +   * MetaGraphDef could have the same method_name (e.g., to support multi-headed
    +   * computation).
        * 
    * * string method_name = 3; @@ -690,58 +636,6 @@ protected Builder newBuilderForType( *
        * SignatureDef defines the signature of a computation supported by a TensorFlow
        * graph.
    -   * For example, a model with two loss computations, sharing a single input,
    -   * might have the following signature_def map, in a MetaGraphDef message.
    -   * Note that across the two SignatureDefs "loss_A" and "loss_B", the input key,
    -   * output key, and method_name are identical, and will be used by system(s) that
    -   * implement or rely upon this particular loss method. The output tensor names
    -   * differ, demonstrating how different outputs can exist for the same method.
    -   * signature_def {
    -   *   key: "loss_A"
    -   *   value {
    -   *     inputs {
    -   *       key: "input"
    -   *       value {
    -   *         name: "input:0"
    -   *         dtype: DT_STRING
    -   *         tensor_shape: ...
    -   *       }
    -   *     }
    -   *     outputs {
    -   *       key: "loss_output"
    -   *       value {
    -   *         name: "loss_output_A:0"
    -   *         dtype: DT_FLOAT
    -   *         tensor_shape: ...
    -   *       }
    -   *     }
    -   *     method_name: "some/package/compute_loss"
    -   *   }
    -   *   ...
    -   * }
    -   * signature_def {
    -   *   key: "loss_B"
    -   *   value {
    -   *     inputs {
    -   *       key: "input"
    -   *       value {
    -   *         name: "input:0"
    -   *         dtype: DT_STRING
    -   *         tensor_shape: ...
    -   *       }
    -   *     }
    -   *     outputs {
    -   *       key: "loss_output"
    -   *       value {
    -   *         name: "loss_output_B:0"
    -   *         dtype: DT_FLOAT
    -   *         tensor_shape: ...
    -   *       }
    -   *     }
    -   *     method_name: "some/package/compute_loss"
    -   *   }
    -   *   ...
    -   * }
        * 
    * * Protobuf type {@code tensorflow.SignatureDef} @@ -1296,13 +1190,12 @@ public Builder putAllOutputs( private java.lang.Object methodName_ = ""; /** *
    -     * Extensible method_name information enabling third-party users to mark a
    -     * SignatureDef as supporting a particular method. This enables producers and
    -     * consumers of SignatureDefs, e.g. a model definition library and a serving
    -     * library to have a clear hand-off regarding the semantics of a computation.
    -     * Note that multiple SignatureDefs in a single MetaGraphDef may have the same
    -     * method_name. This is commonly used to support multi-headed computation,
    -     * where a single graph computation may return multiple results.
    +     * Deprecated: TensorFlow 2 always sets this to a fixed value;
    +     * open-source TF Serving stopped checking by default since release 2.4.
    +     * In TensorFlow 1, the method_name enabled users to mark a SignatureDef as
    +     * supporting a particular method. Multiple SignatureDefs in a single
    +     * MetaGraphDef could have the same method_name (e.g., to support multi-headed
    +     * computation).
          * 
    * * string method_name = 3; @@ -1322,13 +1215,12 @@ public java.lang.String getMethodName() { } /** *
    -     * Extensible method_name information enabling third-party users to mark a
    -     * SignatureDef as supporting a particular method. This enables producers and
    -     * consumers of SignatureDefs, e.g. a model definition library and a serving
    -     * library to have a clear hand-off regarding the semantics of a computation.
    -     * Note that multiple SignatureDefs in a single MetaGraphDef may have the same
    -     * method_name. This is commonly used to support multi-headed computation,
    -     * where a single graph computation may return multiple results.
    +     * Deprecated: TensorFlow 2 always sets this to a fixed value;
    +     * open-source TF Serving stopped checking by default since release 2.4.
    +     * In TensorFlow 1, the method_name enabled users to mark a SignatureDef as
    +     * supporting a particular method. Multiple SignatureDefs in a single
    +     * MetaGraphDef could have the same method_name (e.g., to support multi-headed
    +     * computation).
          * 
    * * string method_name = 3; @@ -1349,13 +1241,12 @@ public java.lang.String getMethodName() { } /** *
    -     * Extensible method_name information enabling third-party users to mark a
    -     * SignatureDef as supporting a particular method. This enables producers and
    -     * consumers of SignatureDefs, e.g. a model definition library and a serving
    -     * library to have a clear hand-off regarding the semantics of a computation.
    -     * Note that multiple SignatureDefs in a single MetaGraphDef may have the same
    -     * method_name. This is commonly used to support multi-headed computation,
    -     * where a single graph computation may return multiple results.
    +     * Deprecated: TensorFlow 2 always sets this to a fixed value;
    +     * open-source TF Serving stopped checking by default since release 2.4.
    +     * In TensorFlow 1, the method_name enabled users to mark a SignatureDef as
    +     * supporting a particular method. Multiple SignatureDefs in a single
    +     * MetaGraphDef could have the same method_name (e.g., to support multi-headed
    +     * computation).
          * 
    * * string method_name = 3; @@ -1374,13 +1265,12 @@ public Builder setMethodName( } /** *
    -     * Extensible method_name information enabling third-party users to mark a
    -     * SignatureDef as supporting a particular method. This enables producers and
    -     * consumers of SignatureDefs, e.g. a model definition library and a serving
    -     * library to have a clear hand-off regarding the semantics of a computation.
    -     * Note that multiple SignatureDefs in a single MetaGraphDef may have the same
    -     * method_name. This is commonly used to support multi-headed computation,
    -     * where a single graph computation may return multiple results.
    +     * Deprecated: TensorFlow 2 always sets this to a fixed value;
    +     * open-source TF Serving stopped checking by default since release 2.4.
    +     * In TensorFlow 1, the method_name enabled users to mark a SignatureDef as
    +     * supporting a particular method. Multiple SignatureDefs in a single
    +     * MetaGraphDef could have the same method_name (e.g., to support multi-headed
    +     * computation).
          * 
    * * string method_name = 3; @@ -1394,13 +1284,12 @@ public Builder clearMethodName() { } /** *
    -     * Extensible method_name information enabling third-party users to mark a
    -     * SignatureDef as supporting a particular method. This enables producers and
    -     * consumers of SignatureDefs, e.g. a model definition library and a serving
    -     * library to have a clear hand-off regarding the semantics of a computation.
    -     * Note that multiple SignatureDefs in a single MetaGraphDef may have the same
    -     * method_name. This is commonly used to support multi-headed computation,
    -     * where a single graph computation may return multiple results.
    +     * Deprecated: TensorFlow 2 always sets this to a fixed value;
    +     * open-source TF Serving stopped checking by default since release 2.4.
    +     * In TensorFlow 1, the method_name enabled users to mark a SignatureDef as
    +     * supporting a particular method. Multiple SignatureDefs in a single
    +     * MetaGraphDef could have the same method_name (e.g., to support multi-headed
    +     * computation).
          * 
    * * string method_name = 3; diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/SignatureDefOrBuilder.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/SignatureDefOrBuilder.java index 86ae1bcf3d1..28bd86c8f8a 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/SignatureDefOrBuilder.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/SignatureDefOrBuilder.java @@ -121,13 +121,12 @@ org.tensorflow.proto.TensorInfo getOutputsOrThrow( /** *
    -   * Extensible method_name information enabling third-party users to mark a
    -   * SignatureDef as supporting a particular method. This enables producers and
    -   * consumers of SignatureDefs, e.g. a model definition library and a serving
    -   * library to have a clear hand-off regarding the semantics of a computation.
    -   * Note that multiple SignatureDefs in a single MetaGraphDef may have the same
    -   * method_name. This is commonly used to support multi-headed computation,
    -   * where a single graph computation may return multiple results.
    +   * Deprecated: TensorFlow 2 always sets this to a fixed value;
    +   * open-source TF Serving stopped checking by default since release 2.4.
    +   * In TensorFlow 1, the method_name enabled users to mark a SignatureDef as
    +   * supporting a particular method. Multiple SignatureDefs in a single
    +   * MetaGraphDef could have the same method_name (e.g., to support multi-headed
    +   * computation).
        * 
    * * string method_name = 3; @@ -136,13 +135,12 @@ org.tensorflow.proto.TensorInfo getOutputsOrThrow( java.lang.String getMethodName(); /** *
    -   * Extensible method_name information enabling third-party users to mark a
    -   * SignatureDef as supporting a particular method. This enables producers and
    -   * consumers of SignatureDefs, e.g. a model definition library and a serving
    -   * library to have a clear hand-off regarding the semantics of a computation.
    -   * Note that multiple SignatureDefs in a single MetaGraphDef may have the same
    -   * method_name. This is commonly used to support multi-headed computation,
    -   * where a single graph computation may return multiple results.
    +   * Deprecated: TensorFlow 2 always sets this to a fixed value;
    +   * open-source TF Serving stopped checking by default since release 2.4.
    +   * In TensorFlow 1, the method_name enabled users to mark a SignatureDef as
    +   * supporting a particular method. Multiple SignatureDefs in a single
    +   * MetaGraphDef could have the same method_name (e.g., to support multi-headed
    +   * computation).
        * 
    * * string method_name = 3; diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/TensorProto.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/TensorProto.java index 0440777955e..ef4157a3352 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/TensorProto.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/TensorProto.java @@ -66,6 +66,10 @@ protected java.lang.Object newInstance( public static final int DTYPE_FIELD_NUMBER = 1; private int dtype_; /** + *
    +   * Data type of the tensor.
    +   * 
    + * * .tensorflow.DataType dtype = 1; * @return The enum numeric value on the wire for dtype. */ @@ -73,6 +77,10 @@ protected java.lang.Object newInstance( return dtype_; } /** + *
    +   * Data type of the tensor.
    +   * 
    + * * .tensorflow.DataType dtype = 1; * @return The dtype. */ @@ -1929,6 +1937,10 @@ public Builder mergeFrom( private int dtype_ = 0; /** + *
    +     * Data type of the tensor.
    +     * 
    + * * .tensorflow.DataType dtype = 1; * @return The enum numeric value on the wire for dtype. */ @@ -1936,6 +1948,10 @@ public Builder mergeFrom( return dtype_; } /** + *
    +     * Data type of the tensor.
    +     * 
    + * * .tensorflow.DataType dtype = 1; * @param value The enum numeric value on the wire for dtype to set. * @return This builder for chaining. @@ -1947,6 +1963,10 @@ public Builder setDtypeValue(int value) { return this; } /** + *
    +     * Data type of the tensor.
    +     * 
    + * * .tensorflow.DataType dtype = 1; * @return The dtype. */ @@ -1957,6 +1977,10 @@ public org.tensorflow.proto.DataType getDtype() { return result == null ? org.tensorflow.proto.DataType.UNRECOGNIZED : result; } /** + *
    +     * Data type of the tensor.
    +     * 
    + * * .tensorflow.DataType dtype = 1; * @param value The dtype to set. * @return This builder for chaining. @@ -1971,6 +1995,10 @@ public Builder setDtype(org.tensorflow.proto.DataType value) { return this; } /** + *
    +     * Data type of the tensor.
    +     * 
    + * * .tensorflow.DataType dtype = 1; * @return This builder for chaining. */ diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/TensorProtoOrBuilder.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/TensorProtoOrBuilder.java index fe901586e8c..9eafe8177e2 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/TensorProtoOrBuilder.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/TensorProtoOrBuilder.java @@ -8,11 +8,19 @@ public interface TensorProtoOrBuilder extends com.google.protobuf.MessageOrBuilder { /** + *
    +   * Data type of the tensor.
    +   * 
    + * * .tensorflow.DataType dtype = 1; * @return The enum numeric value on the wire for dtype. */ int getDtypeValue(); /** + *
    +   * Data type of the tensor.
    +   * 
    + * * .tensorflow.DataType dtype = 1; * @return The dtype. */ diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/TestLogProtos.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/TestLogProtos.java index fb587acc9e8..f56cbf6b82b 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/TestLogProtos.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/TestLogProtos.java @@ -1,5 +1,5 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! -// source: tsl/protobuf/test_log.proto +// source: xla/tsl/protobuf/test_log.proto package org.tensorflow.proto; @@ -108,68 +108,68 @@ public static void registerAllExtensions( descriptor; static { java.lang.String[] descriptorData = { - "\n\033tsl/protobuf/test_log.proto\022\ntensorflo" + - "w\032\031google/protobuf/any.proto\032\036google/pro" + - "tobuf/wrappers.proto\"D\n\nEntryValue\022\026\n\014do" + - "uble_value\030\001 \001(\001H\000\022\026\n\014string_value\030\002 \001(\t" + - "H\000B\006\n\004kind\"\214\001\n\013MetricEntry\022\014\n\004name\030\001 \001(\t" + - "\022\r\n\005value\030\002 \001(\001\022/\n\tmin_value\030\003 \001(\0132\034.goo" + - "gle.protobuf.DoubleValue\022/\n\tmax_value\030\004 " + - "\001(\0132\034.google.protobuf.DoubleValue\"\217\002\n\016Be" + - "nchmarkEntry\022\014\n\004name\030\001 \001(\t\022\r\n\005iters\030\002 \001(" + - "\003\022\020\n\010cpu_time\030\003 \001(\001\022\021\n\twall_time\030\004 \001(\001\022\022" + - "\n\nthroughput\030\005 \001(\001\0226\n\006extras\030\006 \003(\0132&.ten" + - "sorflow.BenchmarkEntry.ExtrasEntry\022(\n\007me" + - "trics\030\007 \003(\0132\027.tensorflow.MetricEntry\032E\n\013" + - "ExtrasEntry\022\013\n\003key\030\001 \001(\t\022%\n\005value\030\002 \001(\0132" + - "\026.tensorflow.EntryValue:\0028\001\"=\n\020Benchmark" + - "Entries\022)\n\005entry\030\001 \003(\0132\032.tensorflow.Benc" + - "hmarkEntry\"B\n\022BuildConfiguration\022\014\n\004mode" + - "\030\001 \001(\t\022\020\n\010cc_flags\030\002 \003(\t\022\014\n\004opts\030\003 \003(\t\"f" + - "\n\010CommitId\022\024\n\nchangelist\030\001 \001(\003H\000\022\016\n\004hash" + - "\030\002 \001(\tH\000\022\020\n\010snapshot\030\003 \001(\t\022\032\n\022pending_ch" + - "angelist\030\004 \001(\003B\006\n\004kind\"\336\001\n\007CPUInfo\022\021\n\tnu" + - "m_cores\030\001 \001(\003\022\031\n\021num_cores_allowed\030\002 \001(\003" + - "\022\023\n\013mhz_per_cpu\030\003 \001(\001\022\020\n\010cpu_info\030\004 \001(\t\022" + - "\024\n\014cpu_governor\030\005 \001(\t\0226\n\ncache_size\030\006 \003(" + - "\0132\".tensorflow.CPUInfo.CacheSizeEntry\0320\n" + - "\016CacheSizeEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 " + - "\001(\003:\0028\001\".\n\nMemoryInfo\022\r\n\005total\030\001 \001(\003\022\021\n\t" + - "available\030\002 \001(\003\"6\n\007GPUInfo\022\r\n\005model\030\001 \001(" + - "\t\022\014\n\004uuid\030\002 \001(\t\022\016\n\006bus_id\030\003 \001(\t\"p\n\014Platf" + - "ormInfo\022\014\n\004bits\030\001 \001(\t\022\017\n\007linkage\030\002 \001(\t\022\017" + - "\n\007machine\030\003 \001(\t\022\017\n\007release\030\004 \001(\t\022\016\n\006syst" + - "em\030\005 \001(\t\022\017\n\007version\030\006 \001(\t\"e\n\023AvailableDe" + - "viceInfo\022\014\n\004name\030\001 \001(\t\022\014\n\004type\030\002 \001(\t\022\024\n\014" + - "memory_limit\030\003 \001(\003\022\034\n\024physical_descripti" + - "on\030\004 \001(\t\"\263\002\n\024MachineConfiguration\022\020\n\010hos" + - "tname\030\001 \001(\t\022\031\n\021serial_identifier\030\007 \001(\t\022/" + - "\n\rplatform_info\030\002 \001(\0132\030.tensorflow.Platf" + - "ormInfo\022%\n\010cpu_info\030\003 \001(\0132\023.tensorflow.C" + - "PUInfo\022)\n\013device_info\030\004 \003(\0132\024.google.pro" + - "tobuf.Any\022>\n\025available_device_info\030\005 \003(\013" + - "2\037.tensorflow.AvailableDeviceInfo\022+\n\013mem" + - "ory_info\030\006 \001(\0132\026.tensorflow.MemoryInfo\"\221" + - "\001\n\020RunConfiguration\022\020\n\010argument\030\001 \003(\t\022;\n" + - "\010env_vars\030\002 \003(\0132).tensorflow.RunConfigur" + - "ation.EnvVarsEntry\032.\n\014EnvVarsEntry\022\013\n\003ke" + - "y\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\"\320\004\n\013TestResul" + - "ts\022\016\n\006target\030\001 \001(\t\022-\n\007entries\030\002 \001(\0132\034.te" + - "nsorflow.BenchmarkEntries\022;\n\023build_confi" + - "guration\030\003 \001(\0132\036.tensorflow.BuildConfigu" + - "ration\022\'\n\tcommit_id\030\004 \001(\0132\024.tensorflow.C" + - "ommitId\022\022\n\nstart_time\030\005 \001(\003\022\020\n\010run_time\030" + - "\006 \001(\001\022?\n\025machine_configuration\030\007 \001(\0132 .t" + - "ensorflow.MachineConfiguration\0227\n\021run_co" + - "nfiguration\030\010 \001(\0132\034.tensorflow.RunConfig" + - "uration\022\014\n\004name\030\t \001(\t\022=\n\016benchmark_type\030" + - "\n \001(\0162%.tensorflow.TestResults.Benchmark" + - "Type\022\020\n\010run_mode\030\013 \001(\t\022\022\n\ntf_version\030\014 \001" + - "(\t\"\210\001\n\rBenchmarkType\022\013\n\007UNKNOWN\020\000\022\026\n\022CPP" + - "_MICROBENCHMARK\020\001\022\024\n\020PYTHON_BENCHMARK\020\002\022" + - "\025\n\021ANDROID_BENCHMARK\020\003\022\022\n\016EDGE_BENCHMARK" + - "\020\004\022\021\n\rIOS_BENCHMARK\020\005B*\n\024org.tensorflow." + - "protoB\rTestLogProtosP\001\370\001\001b\006proto3" + "\n\037xla/tsl/protobuf/test_log.proto\022\ntenso" + + "rflow\032\031google/protobuf/any.proto\032\036google" + + "/protobuf/wrappers.proto\"D\n\nEntryValue\022\026" + + "\n\014double_value\030\001 \001(\001H\000\022\026\n\014string_value\030\002" + + " \001(\tH\000B\006\n\004kind\"\214\001\n\013MetricEntry\022\014\n\004name\030\001" + + " \001(\t\022\r\n\005value\030\002 \001(\001\022/\n\tmin_value\030\003 \001(\0132\034" + + ".google.protobuf.DoubleValue\022/\n\tmax_valu" + + "e\030\004 \001(\0132\034.google.protobuf.DoubleValue\"\217\002" + + "\n\016BenchmarkEntry\022\014\n\004name\030\001 \001(\t\022\r\n\005iters\030" + + "\002 \001(\003\022\020\n\010cpu_time\030\003 \001(\001\022\021\n\twall_time\030\004 \001" + + "(\001\022\022\n\nthroughput\030\005 \001(\001\0226\n\006extras\030\006 \003(\0132&" + + ".tensorflow.BenchmarkEntry.ExtrasEntry\022(" + + "\n\007metrics\030\007 \003(\0132\027.tensorflow.MetricEntry" + + "\032E\n\013ExtrasEntry\022\013\n\003key\030\001 \001(\t\022%\n\005value\030\002 " + + "\001(\0132\026.tensorflow.EntryValue:\0028\001\"=\n\020Bench" + + "markEntries\022)\n\005entry\030\001 \003(\0132\032.tensorflow." + + "BenchmarkEntry\"B\n\022BuildConfiguration\022\014\n\004" + + "mode\030\001 \001(\t\022\020\n\010cc_flags\030\002 \003(\t\022\014\n\004opts\030\003 \003" + + "(\t\"f\n\010CommitId\022\024\n\nchangelist\030\001 \001(\003H\000\022\016\n\004" + + "hash\030\002 \001(\tH\000\022\020\n\010snapshot\030\003 \001(\t\022\032\n\022pendin" + + "g_changelist\030\004 \001(\003B\006\n\004kind\"\336\001\n\007CPUInfo\022\021" + + "\n\tnum_cores\030\001 \001(\003\022\031\n\021num_cores_allowed\030\002" + + " \001(\003\022\023\n\013mhz_per_cpu\030\003 \001(\001\022\020\n\010cpu_info\030\004 " + + "\001(\t\022\024\n\014cpu_governor\030\005 \001(\t\0226\n\ncache_size\030" + + "\006 \003(\0132\".tensorflow.CPUInfo.CacheSizeEntr" + + "y\0320\n\016CacheSizeEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005valu" + + "e\030\002 \001(\003:\0028\001\".\n\nMemoryInfo\022\r\n\005total\030\001 \001(\003" + + "\022\021\n\tavailable\030\002 \001(\003\"6\n\007GPUInfo\022\r\n\005model\030" + + "\001 \001(\t\022\014\n\004uuid\030\002 \001(\t\022\016\n\006bus_id\030\003 \001(\t\"p\n\014P" + + "latformInfo\022\014\n\004bits\030\001 \001(\t\022\017\n\007linkage\030\002 \001" + + "(\t\022\017\n\007machine\030\003 \001(\t\022\017\n\007release\030\004 \001(\t\022\016\n\006" + + "system\030\005 \001(\t\022\017\n\007version\030\006 \001(\t\"e\n\023Availab" + + "leDeviceInfo\022\014\n\004name\030\001 \001(\t\022\014\n\004type\030\002 \001(\t" + + "\022\024\n\014memory_limit\030\003 \001(\003\022\034\n\024physical_descr" + + "iption\030\004 \001(\t\"\263\002\n\024MachineConfiguration\022\020\n" + + "\010hostname\030\001 \001(\t\022\031\n\021serial_identifier\030\007 \001" + + "(\t\022/\n\rplatform_info\030\002 \001(\0132\030.tensorflow.P" + + "latformInfo\022%\n\010cpu_info\030\003 \001(\0132\023.tensorfl" + + "ow.CPUInfo\022)\n\013device_info\030\004 \003(\0132\024.google" + + ".protobuf.Any\022>\n\025available_device_info\030\005" + + " \003(\0132\037.tensorflow.AvailableDeviceInfo\022+\n" + + "\013memory_info\030\006 \001(\0132\026.tensorflow.MemoryIn" + + "fo\"\221\001\n\020RunConfiguration\022\020\n\010argument\030\001 \003(" + + "\t\022;\n\010env_vars\030\002 \003(\0132).tensorflow.RunConf" + + "iguration.EnvVarsEntry\032.\n\014EnvVarsEntry\022\013" + + "\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\"\320\004\n\013TestR" + + "esults\022\016\n\006target\030\001 \001(\t\022-\n\007entries\030\002 \001(\0132" + + "\034.tensorflow.BenchmarkEntries\022;\n\023build_c" + + "onfiguration\030\003 \001(\0132\036.tensorflow.BuildCon" + + "figuration\022\'\n\tcommit_id\030\004 \001(\0132\024.tensorfl" + + "ow.CommitId\022\022\n\nstart_time\030\005 \001(\003\022\020\n\010run_t" + + "ime\030\006 \001(\001\022?\n\025machine_configuration\030\007 \001(\013" + + "2 .tensorflow.MachineConfiguration\0227\n\021ru" + + "n_configuration\030\010 \001(\0132\034.tensorflow.RunCo" + + "nfiguration\022\014\n\004name\030\t \001(\t\022=\n\016benchmark_t" + + "ype\030\n \001(\0162%.tensorflow.TestResults.Bench" + + "markType\022\020\n\010run_mode\030\013 \001(\t\022\022\n\ntf_version" + + "\030\014 \001(\t\"\210\001\n\rBenchmarkType\022\013\n\007UNKNOWN\020\000\022\026\n" + + "\022CPP_MICROBENCHMARK\020\001\022\024\n\020PYTHON_BENCHMAR" + + "K\020\002\022\025\n\021ANDROID_BENCHMARK\020\003\022\022\n\016EDGE_BENCH" + + "MARK\020\004\022\021\n\rIOS_BENCHMARK\020\005B*\n\024org.tensorf" + + "low.protoB\rTestLogProtosP\001\370\001\001b\006proto3" }; descriptor = com.google.protobuf.Descriptors.FileDescriptor .internalBuildGeneratedFileFrom(descriptorData, diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/TestResults.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/TestResults.java index 09ed588ef20..4bc27cbdde7 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/TestResults.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/TestResults.java @@ -1,5 +1,5 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! -// source: tsl/protobuf/test_log.proto +// source: xla/tsl/protobuf/test_log.proto package org.tensorflow.proto; diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/TestResultsOrBuilder.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/TestResultsOrBuilder.java index 3afd736b478..1d6f1545988 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/TestResultsOrBuilder.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/TestResultsOrBuilder.java @@ -1,5 +1,5 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! -// source: tsl/protobuf/test_log.proto +// source: xla/tsl/protobuf/test_log.proto package org.tensorflow.proto; diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/data/DatasetOptions.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/data/DatasetOptions.java index c7d43294b14..424adecedbd 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/data/DatasetOptions.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/data/DatasetOptions.java @@ -381,6 +381,17 @@ public interface AutotuneOptionsOrBuilder extends */ org.tensorflow.proto.data.model.Model.AutotuneAlgorithm getAutotuneAlgorithm(); + /** + * int64 initial_parallelism = 5; + * @return Whether the initialParallelism field is set. + */ + boolean hasInitialParallelism(); + /** + * int64 initial_parallelism = 5; + * @return The initialParallelism. + */ + long getInitialParallelism(); + public org.tensorflow.proto.data.DatasetOptions.AutotuneOptions.OptionalEnabledCase getOptionalEnabledCase(); public org.tensorflow.proto.data.DatasetOptions.AutotuneOptions.OptionalCpuBudgetCase getOptionalCpuBudgetCase(); @@ -388,10 +399,12 @@ public interface AutotuneOptionsOrBuilder extends public org.tensorflow.proto.data.DatasetOptions.AutotuneOptions.OptionalRamBudgetCase getOptionalRamBudgetCase(); public org.tensorflow.proto.data.DatasetOptions.AutotuneOptions.OptionalAutotuneAlgorithmCase getOptionalAutotuneAlgorithmCase(); + + public org.tensorflow.proto.data.DatasetOptions.AutotuneOptions.OptionalInitialParallelismCase getOptionalInitialParallelismCase(); } /** *
    -   * next: 5
    +   * next: 6
        * 
    * * Protobuf type {@code tensorflow.data.AutotuneOptions} @@ -589,6 +602,45 @@ public int getNumber() { optionalAutotuneAlgorithmCase_); } + private int optionalInitialParallelismCase_ = 0; + private java.lang.Object optionalInitialParallelism_; + public enum OptionalInitialParallelismCase + implements com.google.protobuf.Internal.EnumLite, + com.google.protobuf.AbstractMessage.InternalOneOfEnum { + INITIAL_PARALLELISM(5), + OPTIONALINITIALPARALLELISM_NOT_SET(0); + private final int value; + private OptionalInitialParallelismCase(int value) { + this.value = value; + } + /** + * @param value The number of the enum to look for. + * @return The enum associated with the given number. + * @deprecated Use {@link #forNumber(int)} instead. + */ + @java.lang.Deprecated + public static OptionalInitialParallelismCase valueOf(int value) { + return forNumber(value); + } + + public static OptionalInitialParallelismCase forNumber(int value) { + switch (value) { + case 5: return INITIAL_PARALLELISM; + case 0: return OPTIONALINITIALPARALLELISM_NOT_SET; + default: return null; + } + } + public int getNumber() { + return this.value; + } + }; + + public OptionalInitialParallelismCase + getOptionalInitialParallelismCase() { + return OptionalInitialParallelismCase.forNumber( + optionalInitialParallelismCase_); + } + public static final int ENABLED_FIELD_NUMBER = 1; /** * bool enabled = 1; @@ -684,6 +736,27 @@ public org.tensorflow.proto.data.model.Model.AutotuneAlgorithm getAutotuneAlgori return org.tensorflow.proto.data.model.Model.AutotuneAlgorithm.DEFAULT; } + public static final int INITIAL_PARALLELISM_FIELD_NUMBER = 5; + /** + * int64 initial_parallelism = 5; + * @return Whether the initialParallelism field is set. + */ + @java.lang.Override + public boolean hasInitialParallelism() { + return optionalInitialParallelismCase_ == 5; + } + /** + * int64 initial_parallelism = 5; + * @return The initialParallelism. + */ + @java.lang.Override + public long getInitialParallelism() { + if (optionalInitialParallelismCase_ == 5) { + return (java.lang.Long) optionalInitialParallelism_; + } + return 0L; + } + private byte memoizedIsInitialized = -1; @java.lang.Override public final boolean isInitialized() { @@ -713,6 +786,10 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) if (optionalAutotuneAlgorithmCase_ == 4) { output.writeEnum(4, ((java.lang.Integer) optionalAutotuneAlgorithm_)); } + if (optionalInitialParallelismCase_ == 5) { + output.writeInt64( + 5, (long)((java.lang.Long) optionalInitialParallelism_)); + } getUnknownFields().writeTo(output); } @@ -741,6 +818,11 @@ public int getSerializedSize() { size += com.google.protobuf.CodedOutputStream .computeEnumSize(4, ((java.lang.Integer) optionalAutotuneAlgorithm_)); } + if (optionalInitialParallelismCase_ == 5) { + size += com.google.protobuf.CodedOutputStream + .computeInt64Size( + 5, (long)((java.lang.Long) optionalInitialParallelism_)); + } size += getUnknownFields().getSerializedSize(); memoizedSize = size; return size; @@ -792,6 +874,15 @@ public boolean equals(final java.lang.Object obj) { case 0: default: } + if (!getOptionalInitialParallelismCase().equals(other.getOptionalInitialParallelismCase())) return false; + switch (optionalInitialParallelismCase_) { + case 5: + if (getInitialParallelism() + != other.getInitialParallelism()) return false; + break; + case 0: + default: + } if (!getUnknownFields().equals(other.getUnknownFields())) return false; return true; } @@ -837,6 +928,15 @@ public int hashCode() { case 0: default: } + switch (optionalInitialParallelismCase_) { + case 5: + hash = (37 * hash) + INITIAL_PARALLELISM_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashLong( + getInitialParallelism()); + break; + case 0: + default: + } hash = (29 * hash) + getUnknownFields().hashCode(); memoizedHashCode = hash; return hash; @@ -934,7 +1034,7 @@ protected Builder newBuilderForType( } /** *
    -     * next: 5
    +     * next: 6
          * 
    * * Protobuf type {@code tensorflow.data.AutotuneOptions} @@ -977,6 +1077,8 @@ public Builder clear() { optionalRamBudget_ = null; optionalAutotuneAlgorithmCase_ = 0; optionalAutotuneAlgorithm_ = null; + optionalInitialParallelismCase_ = 0; + optionalInitialParallelism_ = null; return this; } @@ -1015,10 +1117,14 @@ public org.tensorflow.proto.data.DatasetOptions.AutotuneOptions buildPartial() { if (optionalAutotuneAlgorithmCase_ == 4) { result.optionalAutotuneAlgorithm_ = optionalAutotuneAlgorithm_; } + if (optionalInitialParallelismCase_ == 5) { + result.optionalInitialParallelism_ = optionalInitialParallelism_; + } result.optionalEnabledCase_ = optionalEnabledCase_; result.optionalCpuBudgetCase_ = optionalCpuBudgetCase_; result.optionalRamBudgetCase_ = optionalRamBudgetCase_; result.optionalAutotuneAlgorithmCase_ = optionalAutotuneAlgorithmCase_; + result.optionalInitialParallelismCase_ = optionalInitialParallelismCase_; onBuilt(); return result; } @@ -1103,6 +1209,15 @@ public Builder mergeFrom(org.tensorflow.proto.data.DatasetOptions.AutotuneOption break; } } + switch (other.getOptionalInitialParallelismCase()) { + case INITIAL_PARALLELISM: { + setInitialParallelism(other.getInitialParallelism()); + break; + } + case OPTIONALINITIALPARALLELISM_NOT_SET: { + break; + } + } this.mergeUnknownFields(other.getUnknownFields()); onChanged(); return this; @@ -1150,6 +1265,11 @@ public Builder mergeFrom( optionalAutotuneAlgorithm_ = rawValue; break; } // case 32 + case 40: { + optionalInitialParallelism_ = input.readInt64(); + optionalInitialParallelismCase_ = 5; + break; + } // case 40 default: { if (!super.parseUnknownField(input, extensionRegistry, tag)) { done = true; // was an endgroup tag @@ -1225,6 +1345,21 @@ public Builder clearOptionalAutotuneAlgorithm() { return this; } + private int optionalInitialParallelismCase_ = 0; + private java.lang.Object optionalInitialParallelism_; + public OptionalInitialParallelismCase + getOptionalInitialParallelismCase() { + return OptionalInitialParallelismCase.forNumber( + optionalInitialParallelismCase_); + } + + public Builder clearOptionalInitialParallelism() { + optionalInitialParallelismCase_ = 0; + optionalInitialParallelism_ = null; + onChanged(); + return this; + } + /** * bool enabled = 1; @@ -1419,6 +1554,47 @@ public Builder clearAutotuneAlgorithm() { } return this; } + + /** + * int64 initial_parallelism = 5; + * @return Whether the initialParallelism field is set. + */ + public boolean hasInitialParallelism() { + return optionalInitialParallelismCase_ == 5; + } + /** + * int64 initial_parallelism = 5; + * @return The initialParallelism. + */ + public long getInitialParallelism() { + if (optionalInitialParallelismCase_ == 5) { + return (java.lang.Long) optionalInitialParallelism_; + } + return 0L; + } + /** + * int64 initial_parallelism = 5; + * @param value The initialParallelism to set. + * @return This builder for chaining. + */ + public Builder setInitialParallelism(long value) { + optionalInitialParallelismCase_ = 5; + optionalInitialParallelism_ = value; + onChanged(); + return this; + } + /** + * int64 initial_parallelism = 5; + * @return This builder for chaining. + */ + public Builder clearInitialParallelism() { + if (optionalInitialParallelismCase_ == 5) { + optionalInitialParallelismCase_ = 0; + optionalInitialParallelism_ = null; + onChanged(); + } + return this; + } @java.lang.Override public final Builder setUnknownFields( final com.google.protobuf.UnknownFieldSet unknownFields) { @@ -5349,60 +5525,47 @@ public org.tensorflow.proto.data.DatasetOptions.OptimizationOptions getDefaultIn } - public interface ThreadingOptionsOrBuilder extends - // @@protoc_insertion_point(interface_extends:tensorflow.data.ThreadingOptions) + public interface ServiceOptionsOrBuilder extends + // @@protoc_insertion_point(interface_extends:tensorflow.data.ServiceOptions) com.google.protobuf.MessageOrBuilder { /** - * int32 max_intra_op_parallelism = 1; - * @return Whether the maxIntraOpParallelism field is set. - */ - boolean hasMaxIntraOpParallelism(); - /** - * int32 max_intra_op_parallelism = 1; - * @return The maxIntraOpParallelism. - */ - int getMaxIntraOpParallelism(); - - /** - * int32 private_threadpool_size = 2; - * @return Whether the privateThreadpoolSize field is set. + * bool pinned = 1; + * @return Whether the pinned field is set. */ - boolean hasPrivateThreadpoolSize(); + boolean hasPinned(); /** - * int32 private_threadpool_size = 2; - * @return The privateThreadpoolSize. + * bool pinned = 1; + * @return The pinned. */ - int getPrivateThreadpoolSize(); - - public org.tensorflow.proto.data.DatasetOptions.ThreadingOptions.OptionalMaxIntraOpParallelismCase getOptionalMaxIntraOpParallelismCase(); + boolean getPinned(); - public org.tensorflow.proto.data.DatasetOptions.ThreadingOptions.OptionalPrivateThreadpoolSizeCase getOptionalPrivateThreadpoolSizeCase(); + public org.tensorflow.proto.data.DatasetOptions.ServiceOptions.OptionalPinnedCase getOptionalPinnedCase(); } /** *
    -   * next: 3
    +   * next: 2
        * 
    * - * Protobuf type {@code tensorflow.data.ThreadingOptions} + * Protobuf type {@code tensorflow.data.ServiceOptions} */ - public static final class ThreadingOptions extends + public static final class ServiceOptions extends com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:tensorflow.data.ThreadingOptions) - ThreadingOptionsOrBuilder { + // @@protoc_insertion_point(message_implements:tensorflow.data.ServiceOptions) + ServiceOptionsOrBuilder { private static final long serialVersionUID = 0L; - // Use ThreadingOptions.newBuilder() to construct. - private ThreadingOptions(com.google.protobuf.GeneratedMessageV3.Builder builder) { + // Use ServiceOptions.newBuilder() to construct. + private ServiceOptions(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); } - private ThreadingOptions() { + private ServiceOptions() { } @java.lang.Override @SuppressWarnings({"unused"}) protected java.lang.Object newInstance( UnusedPrivateParameter unused) { - return new ThreadingOptions(); + return new ServiceOptions(); } @java.lang.Override @@ -5412,65 +5575,26 @@ protected java.lang.Object newInstance( } public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return org.tensorflow.proto.data.DatasetOptions.internal_static_tensorflow_data_ThreadingOptions_descriptor; + return org.tensorflow.proto.data.DatasetOptions.internal_static_tensorflow_data_ServiceOptions_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return org.tensorflow.proto.data.DatasetOptions.internal_static_tensorflow_data_ThreadingOptions_fieldAccessorTable + return org.tensorflow.proto.data.DatasetOptions.internal_static_tensorflow_data_ServiceOptions_fieldAccessorTable .ensureFieldAccessorsInitialized( - org.tensorflow.proto.data.DatasetOptions.ThreadingOptions.class, org.tensorflow.proto.data.DatasetOptions.ThreadingOptions.Builder.class); - } - - private int optionalMaxIntraOpParallelismCase_ = 0; - private java.lang.Object optionalMaxIntraOpParallelism_; - public enum OptionalMaxIntraOpParallelismCase - implements com.google.protobuf.Internal.EnumLite, - com.google.protobuf.AbstractMessage.InternalOneOfEnum { - MAX_INTRA_OP_PARALLELISM(1), - OPTIONALMAXINTRAOPPARALLELISM_NOT_SET(0); - private final int value; - private OptionalMaxIntraOpParallelismCase(int value) { - this.value = value; - } - /** - * @param value The number of the enum to look for. - * @return The enum associated with the given number. - * @deprecated Use {@link #forNumber(int)} instead. - */ - @java.lang.Deprecated - public static OptionalMaxIntraOpParallelismCase valueOf(int value) { - return forNumber(value); - } - - public static OptionalMaxIntraOpParallelismCase forNumber(int value) { - switch (value) { - case 1: return MAX_INTRA_OP_PARALLELISM; - case 0: return OPTIONALMAXINTRAOPPARALLELISM_NOT_SET; - default: return null; - } - } - public int getNumber() { - return this.value; - } - }; - - public OptionalMaxIntraOpParallelismCase - getOptionalMaxIntraOpParallelismCase() { - return OptionalMaxIntraOpParallelismCase.forNumber( - optionalMaxIntraOpParallelismCase_); + org.tensorflow.proto.data.DatasetOptions.ServiceOptions.class, org.tensorflow.proto.data.DatasetOptions.ServiceOptions.Builder.class); } - private int optionalPrivateThreadpoolSizeCase_ = 0; - private java.lang.Object optionalPrivateThreadpoolSize_; - public enum OptionalPrivateThreadpoolSizeCase + private int optionalPinnedCase_ = 0; + private java.lang.Object optionalPinned_; + public enum OptionalPinnedCase implements com.google.protobuf.Internal.EnumLite, com.google.protobuf.AbstractMessage.InternalOneOfEnum { - PRIVATE_THREADPOOL_SIZE(2), - OPTIONALPRIVATETHREADPOOLSIZE_NOT_SET(0); + PINNED(1), + OPTIONALPINNED_NOT_SET(0); private final int value; - private OptionalPrivateThreadpoolSizeCase(int value) { + private OptionalPinnedCase(int value) { this.value = value; } /** @@ -5479,14 +5603,14 @@ private OptionalPrivateThreadpoolSizeCase(int value) { * @deprecated Use {@link #forNumber(int)} instead. */ @java.lang.Deprecated - public static OptionalPrivateThreadpoolSizeCase valueOf(int value) { + public static OptionalPinnedCase valueOf(int value) { return forNumber(value); } - public static OptionalPrivateThreadpoolSizeCase forNumber(int value) { + public static OptionalPinnedCase forNumber(int value) { switch (value) { - case 2: return PRIVATE_THREADPOOL_SIZE; - case 0: return OPTIONALPRIVATETHREADPOOLSIZE_NOT_SET; + case 1: return PINNED; + case 0: return OPTIONALPINNED_NOT_SET; default: return null; } } @@ -5495,52 +5619,31 @@ public int getNumber() { } }; - public OptionalPrivateThreadpoolSizeCase - getOptionalPrivateThreadpoolSizeCase() { - return OptionalPrivateThreadpoolSizeCase.forNumber( - optionalPrivateThreadpoolSizeCase_); - } - - public static final int MAX_INTRA_OP_PARALLELISM_FIELD_NUMBER = 1; - /** - * int32 max_intra_op_parallelism = 1; - * @return Whether the maxIntraOpParallelism field is set. - */ - @java.lang.Override - public boolean hasMaxIntraOpParallelism() { - return optionalMaxIntraOpParallelismCase_ == 1; - } - /** - * int32 max_intra_op_parallelism = 1; - * @return The maxIntraOpParallelism. - */ - @java.lang.Override - public int getMaxIntraOpParallelism() { - if (optionalMaxIntraOpParallelismCase_ == 1) { - return (java.lang.Integer) optionalMaxIntraOpParallelism_; - } - return 0; + public OptionalPinnedCase + getOptionalPinnedCase() { + return OptionalPinnedCase.forNumber( + optionalPinnedCase_); } - public static final int PRIVATE_THREADPOOL_SIZE_FIELD_NUMBER = 2; + public static final int PINNED_FIELD_NUMBER = 1; /** - * int32 private_threadpool_size = 2; - * @return Whether the privateThreadpoolSize field is set. + * bool pinned = 1; + * @return Whether the pinned field is set. */ @java.lang.Override - public boolean hasPrivateThreadpoolSize() { - return optionalPrivateThreadpoolSizeCase_ == 2; + public boolean hasPinned() { + return optionalPinnedCase_ == 1; } /** - * int32 private_threadpool_size = 2; - * @return The privateThreadpoolSize. + * bool pinned = 1; + * @return The pinned. */ @java.lang.Override - public int getPrivateThreadpoolSize() { - if (optionalPrivateThreadpoolSizeCase_ == 2) { - return (java.lang.Integer) optionalPrivateThreadpoolSize_; + public boolean getPinned() { + if (optionalPinnedCase_ == 1) { + return (java.lang.Boolean) optionalPinned_; } - return 0; + return false; } private byte memoizedIsInitialized = -1; @@ -5557,13 +5660,9 @@ public final boolean isInitialized() { @java.lang.Override public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { - if (optionalMaxIntraOpParallelismCase_ == 1) { - output.writeInt32( - 1, (int)((java.lang.Integer) optionalMaxIntraOpParallelism_)); - } - if (optionalPrivateThreadpoolSizeCase_ == 2) { - output.writeInt32( - 2, (int)((java.lang.Integer) optionalPrivateThreadpoolSize_)); + if (optionalPinnedCase_ == 1) { + output.writeBool( + 1, (boolean)((java.lang.Boolean) optionalPinned_)); } getUnknownFields().writeTo(output); } @@ -5574,15 +5673,10 @@ public int getSerializedSize() { if (size != -1) return size; size = 0; - if (optionalMaxIntraOpParallelismCase_ == 1) { - size += com.google.protobuf.CodedOutputStream - .computeInt32Size( - 1, (int)((java.lang.Integer) optionalMaxIntraOpParallelism_)); - } - if (optionalPrivateThreadpoolSizeCase_ == 2) { + if (optionalPinnedCase_ == 1) { size += com.google.protobuf.CodedOutputStream - .computeInt32Size( - 2, (int)((java.lang.Integer) optionalPrivateThreadpoolSize_)); + .computeBoolSize( + 1, (boolean)((java.lang.Boolean) optionalPinned_)); } size += getUnknownFields().getSerializedSize(); memoizedSize = size; @@ -5594,25 +5688,16 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof org.tensorflow.proto.data.DatasetOptions.ThreadingOptions)) { + if (!(obj instanceof org.tensorflow.proto.data.DatasetOptions.ServiceOptions)) { return super.equals(obj); } - org.tensorflow.proto.data.DatasetOptions.ThreadingOptions other = (org.tensorflow.proto.data.DatasetOptions.ThreadingOptions) obj; + org.tensorflow.proto.data.DatasetOptions.ServiceOptions other = (org.tensorflow.proto.data.DatasetOptions.ServiceOptions) obj; - if (!getOptionalMaxIntraOpParallelismCase().equals(other.getOptionalMaxIntraOpParallelismCase())) return false; - switch (optionalMaxIntraOpParallelismCase_) { + if (!getOptionalPinnedCase().equals(other.getOptionalPinnedCase())) return false; + switch (optionalPinnedCase_) { case 1: - if (getMaxIntraOpParallelism() - != other.getMaxIntraOpParallelism()) return false; - break; - case 0: - default: - } - if (!getOptionalPrivateThreadpoolSizeCase().equals(other.getOptionalPrivateThreadpoolSizeCase())) return false; - switch (optionalPrivateThreadpoolSizeCase_) { - case 2: - if (getPrivateThreadpoolSize() - != other.getPrivateThreadpoolSize()) return false; + if (getPinned() + != other.getPinned()) return false; break; case 0: default: @@ -5628,18 +5713,693 @@ public int hashCode() { } int hash = 41; hash = (19 * hash) + getDescriptor().hashCode(); - switch (optionalMaxIntraOpParallelismCase_) { + switch (optionalPinnedCase_) { case 1: - hash = (37 * hash) + MAX_INTRA_OP_PARALLELISM_FIELD_NUMBER; - hash = (53 * hash) + getMaxIntraOpParallelism(); - break; - case 0: - default: - } - switch (optionalPrivateThreadpoolSizeCase_) { - case 2: - hash = (37 * hash) + PRIVATE_THREADPOOL_SIZE_FIELD_NUMBER; - hash = (53 * hash) + getPrivateThreadpoolSize(); + hash = (37 * hash) + PINNED_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean( + getPinned()); + break; + case 0: + default: + } + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static org.tensorflow.proto.data.DatasetOptions.ServiceOptions parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.tensorflow.proto.data.DatasetOptions.ServiceOptions parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.tensorflow.proto.data.DatasetOptions.ServiceOptions parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.tensorflow.proto.data.DatasetOptions.ServiceOptions parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.tensorflow.proto.data.DatasetOptions.ServiceOptions parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.tensorflow.proto.data.DatasetOptions.ServiceOptions parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.tensorflow.proto.data.DatasetOptions.ServiceOptions parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static org.tensorflow.proto.data.DatasetOptions.ServiceOptions parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static org.tensorflow.proto.data.DatasetOptions.ServiceOptions parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static org.tensorflow.proto.data.DatasetOptions.ServiceOptions parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static org.tensorflow.proto.data.DatasetOptions.ServiceOptions parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static org.tensorflow.proto.data.DatasetOptions.ServiceOptions parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(org.tensorflow.proto.data.DatasetOptions.ServiceOptions prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
    +     * next: 2
    +     * 
    + * + * Protobuf type {@code tensorflow.data.ServiceOptions} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:tensorflow.data.ServiceOptions) + org.tensorflow.proto.data.DatasetOptions.ServiceOptionsOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.tensorflow.proto.data.DatasetOptions.internal_static_tensorflow_data_ServiceOptions_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.tensorflow.proto.data.DatasetOptions.internal_static_tensorflow_data_ServiceOptions_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.tensorflow.proto.data.DatasetOptions.ServiceOptions.class, org.tensorflow.proto.data.DatasetOptions.ServiceOptions.Builder.class); + } + + // Construct using org.tensorflow.proto.data.DatasetOptions.ServiceOptions.newBuilder() + private Builder() { + + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + + } + @java.lang.Override + public Builder clear() { + super.clear(); + optionalPinnedCase_ = 0; + optionalPinned_ = null; + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.tensorflow.proto.data.DatasetOptions.internal_static_tensorflow_data_ServiceOptions_descriptor; + } + + @java.lang.Override + public org.tensorflow.proto.data.DatasetOptions.ServiceOptions getDefaultInstanceForType() { + return org.tensorflow.proto.data.DatasetOptions.ServiceOptions.getDefaultInstance(); + } + + @java.lang.Override + public org.tensorflow.proto.data.DatasetOptions.ServiceOptions build() { + org.tensorflow.proto.data.DatasetOptions.ServiceOptions result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public org.tensorflow.proto.data.DatasetOptions.ServiceOptions buildPartial() { + org.tensorflow.proto.data.DatasetOptions.ServiceOptions result = new org.tensorflow.proto.data.DatasetOptions.ServiceOptions(this); + if (optionalPinnedCase_ == 1) { + result.optionalPinned_ = optionalPinned_; + } + result.optionalPinnedCase_ = optionalPinnedCase_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.tensorflow.proto.data.DatasetOptions.ServiceOptions) { + return mergeFrom((org.tensorflow.proto.data.DatasetOptions.ServiceOptions)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.tensorflow.proto.data.DatasetOptions.ServiceOptions other) { + if (other == org.tensorflow.proto.data.DatasetOptions.ServiceOptions.getDefaultInstance()) return this; + switch (other.getOptionalPinnedCase()) { + case PINNED: { + setPinned(other.getPinned()); + break; + } + case OPTIONALPINNED_NOT_SET: { + break; + } + } + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 8: { + optionalPinned_ = input.readBool(); + optionalPinnedCase_ = 1; + break; + } // case 8 + default: { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + private int optionalPinnedCase_ = 0; + private java.lang.Object optionalPinned_; + public OptionalPinnedCase + getOptionalPinnedCase() { + return OptionalPinnedCase.forNumber( + optionalPinnedCase_); + } + + public Builder clearOptionalPinned() { + optionalPinnedCase_ = 0; + optionalPinned_ = null; + onChanged(); + return this; + } + + + /** + * bool pinned = 1; + * @return Whether the pinned field is set. + */ + public boolean hasPinned() { + return optionalPinnedCase_ == 1; + } + /** + * bool pinned = 1; + * @return The pinned. + */ + public boolean getPinned() { + if (optionalPinnedCase_ == 1) { + return (java.lang.Boolean) optionalPinned_; + } + return false; + } + /** + * bool pinned = 1; + * @param value The pinned to set. + * @return This builder for chaining. + */ + public Builder setPinned(boolean value) { + optionalPinnedCase_ = 1; + optionalPinned_ = value; + onChanged(); + return this; + } + /** + * bool pinned = 1; + * @return This builder for chaining. + */ + public Builder clearPinned() { + if (optionalPinnedCase_ == 1) { + optionalPinnedCase_ = 0; + optionalPinned_ = null; + onChanged(); + } + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:tensorflow.data.ServiceOptions) + } + + // @@protoc_insertion_point(class_scope:tensorflow.data.ServiceOptions) + private static final org.tensorflow.proto.data.DatasetOptions.ServiceOptions DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new org.tensorflow.proto.data.DatasetOptions.ServiceOptions(); + } + + public static org.tensorflow.proto.data.DatasetOptions.ServiceOptions getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public ServiceOptions parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public org.tensorflow.proto.data.DatasetOptions.ServiceOptions getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface ThreadingOptionsOrBuilder extends + // @@protoc_insertion_point(interface_extends:tensorflow.data.ThreadingOptions) + com.google.protobuf.MessageOrBuilder { + + /** + * int32 max_intra_op_parallelism = 1; + * @return Whether the maxIntraOpParallelism field is set. + */ + boolean hasMaxIntraOpParallelism(); + /** + * int32 max_intra_op_parallelism = 1; + * @return The maxIntraOpParallelism. + */ + int getMaxIntraOpParallelism(); + + /** + * int32 private_threadpool_size = 2; + * @return Whether the privateThreadpoolSize field is set. + */ + boolean hasPrivateThreadpoolSize(); + /** + * int32 private_threadpool_size = 2; + * @return The privateThreadpoolSize. + */ + int getPrivateThreadpoolSize(); + + public org.tensorflow.proto.data.DatasetOptions.ThreadingOptions.OptionalMaxIntraOpParallelismCase getOptionalMaxIntraOpParallelismCase(); + + public org.tensorflow.proto.data.DatasetOptions.ThreadingOptions.OptionalPrivateThreadpoolSizeCase getOptionalPrivateThreadpoolSizeCase(); + } + /** + *
    +   * next: 3
    +   * 
    + * + * Protobuf type {@code tensorflow.data.ThreadingOptions} + */ + public static final class ThreadingOptions extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:tensorflow.data.ThreadingOptions) + ThreadingOptionsOrBuilder { + private static final long serialVersionUID = 0L; + // Use ThreadingOptions.newBuilder() to construct. + private ThreadingOptions(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private ThreadingOptions() { + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new ThreadingOptions(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.tensorflow.proto.data.DatasetOptions.internal_static_tensorflow_data_ThreadingOptions_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.tensorflow.proto.data.DatasetOptions.internal_static_tensorflow_data_ThreadingOptions_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.tensorflow.proto.data.DatasetOptions.ThreadingOptions.class, org.tensorflow.proto.data.DatasetOptions.ThreadingOptions.Builder.class); + } + + private int optionalMaxIntraOpParallelismCase_ = 0; + private java.lang.Object optionalMaxIntraOpParallelism_; + public enum OptionalMaxIntraOpParallelismCase + implements com.google.protobuf.Internal.EnumLite, + com.google.protobuf.AbstractMessage.InternalOneOfEnum { + MAX_INTRA_OP_PARALLELISM(1), + OPTIONALMAXINTRAOPPARALLELISM_NOT_SET(0); + private final int value; + private OptionalMaxIntraOpParallelismCase(int value) { + this.value = value; + } + /** + * @param value The number of the enum to look for. + * @return The enum associated with the given number. + * @deprecated Use {@link #forNumber(int)} instead. + */ + @java.lang.Deprecated + public static OptionalMaxIntraOpParallelismCase valueOf(int value) { + return forNumber(value); + } + + public static OptionalMaxIntraOpParallelismCase forNumber(int value) { + switch (value) { + case 1: return MAX_INTRA_OP_PARALLELISM; + case 0: return OPTIONALMAXINTRAOPPARALLELISM_NOT_SET; + default: return null; + } + } + public int getNumber() { + return this.value; + } + }; + + public OptionalMaxIntraOpParallelismCase + getOptionalMaxIntraOpParallelismCase() { + return OptionalMaxIntraOpParallelismCase.forNumber( + optionalMaxIntraOpParallelismCase_); + } + + private int optionalPrivateThreadpoolSizeCase_ = 0; + private java.lang.Object optionalPrivateThreadpoolSize_; + public enum OptionalPrivateThreadpoolSizeCase + implements com.google.protobuf.Internal.EnumLite, + com.google.protobuf.AbstractMessage.InternalOneOfEnum { + PRIVATE_THREADPOOL_SIZE(2), + OPTIONALPRIVATETHREADPOOLSIZE_NOT_SET(0); + private final int value; + private OptionalPrivateThreadpoolSizeCase(int value) { + this.value = value; + } + /** + * @param value The number of the enum to look for. + * @return The enum associated with the given number. + * @deprecated Use {@link #forNumber(int)} instead. + */ + @java.lang.Deprecated + public static OptionalPrivateThreadpoolSizeCase valueOf(int value) { + return forNumber(value); + } + + public static OptionalPrivateThreadpoolSizeCase forNumber(int value) { + switch (value) { + case 2: return PRIVATE_THREADPOOL_SIZE; + case 0: return OPTIONALPRIVATETHREADPOOLSIZE_NOT_SET; + default: return null; + } + } + public int getNumber() { + return this.value; + } + }; + + public OptionalPrivateThreadpoolSizeCase + getOptionalPrivateThreadpoolSizeCase() { + return OptionalPrivateThreadpoolSizeCase.forNumber( + optionalPrivateThreadpoolSizeCase_); + } + + public static final int MAX_INTRA_OP_PARALLELISM_FIELD_NUMBER = 1; + /** + * int32 max_intra_op_parallelism = 1; + * @return Whether the maxIntraOpParallelism field is set. + */ + @java.lang.Override + public boolean hasMaxIntraOpParallelism() { + return optionalMaxIntraOpParallelismCase_ == 1; + } + /** + * int32 max_intra_op_parallelism = 1; + * @return The maxIntraOpParallelism. + */ + @java.lang.Override + public int getMaxIntraOpParallelism() { + if (optionalMaxIntraOpParallelismCase_ == 1) { + return (java.lang.Integer) optionalMaxIntraOpParallelism_; + } + return 0; + } + + public static final int PRIVATE_THREADPOOL_SIZE_FIELD_NUMBER = 2; + /** + * int32 private_threadpool_size = 2; + * @return Whether the privateThreadpoolSize field is set. + */ + @java.lang.Override + public boolean hasPrivateThreadpoolSize() { + return optionalPrivateThreadpoolSizeCase_ == 2; + } + /** + * int32 private_threadpool_size = 2; + * @return The privateThreadpoolSize. + */ + @java.lang.Override + public int getPrivateThreadpoolSize() { + if (optionalPrivateThreadpoolSizeCase_ == 2) { + return (java.lang.Integer) optionalPrivateThreadpoolSize_; + } + return 0; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (optionalMaxIntraOpParallelismCase_ == 1) { + output.writeInt32( + 1, (int)((java.lang.Integer) optionalMaxIntraOpParallelism_)); + } + if (optionalPrivateThreadpoolSizeCase_ == 2) { + output.writeInt32( + 2, (int)((java.lang.Integer) optionalPrivateThreadpoolSize_)); + } + getUnknownFields().writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (optionalMaxIntraOpParallelismCase_ == 1) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size( + 1, (int)((java.lang.Integer) optionalMaxIntraOpParallelism_)); + } + if (optionalPrivateThreadpoolSizeCase_ == 2) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size( + 2, (int)((java.lang.Integer) optionalPrivateThreadpoolSize_)); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof org.tensorflow.proto.data.DatasetOptions.ThreadingOptions)) { + return super.equals(obj); + } + org.tensorflow.proto.data.DatasetOptions.ThreadingOptions other = (org.tensorflow.proto.data.DatasetOptions.ThreadingOptions) obj; + + if (!getOptionalMaxIntraOpParallelismCase().equals(other.getOptionalMaxIntraOpParallelismCase())) return false; + switch (optionalMaxIntraOpParallelismCase_) { + case 1: + if (getMaxIntraOpParallelism() + != other.getMaxIntraOpParallelism()) return false; + break; + case 0: + default: + } + if (!getOptionalPrivateThreadpoolSizeCase().equals(other.getOptionalPrivateThreadpoolSizeCase())) return false; + switch (optionalPrivateThreadpoolSizeCase_) { + case 2: + if (getPrivateThreadpoolSize() + != other.getPrivateThreadpoolSize()) return false; + break; + case 0: + default: + } + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + switch (optionalMaxIntraOpParallelismCase_) { + case 1: + hash = (37 * hash) + MAX_INTRA_OP_PARALLELISM_FIELD_NUMBER; + hash = (53 * hash) + getMaxIntraOpParallelism(); + break; + case 0: + default: + } + switch (optionalPrivateThreadpoolSizeCase_) { + case 2: + hash = (37 * hash) + PRIVATE_THREADPOOL_SIZE_FIELD_NUMBER; + hash = (53 * hash) + getPrivateThreadpoolSize(); break; case 0: default: @@ -6261,6 +7021,33 @@ public interface OptionsOrBuilder extends */ org.tensorflow.proto.data.DatasetOptions.OptimizationOptionsOrBuilder getOptimizationOptionsOrBuilder(); + /** + *
    +     * The tf.data service options associated with the dataset.
    +     * 
    + * + * .tensorflow.data.ServiceOptions service_options = 12; + * @return Whether the serviceOptions field is set. + */ + boolean hasServiceOptions(); + /** + *
    +     * The tf.data service options associated with the dataset.
    +     * 
    + * + * .tensorflow.data.ServiceOptions service_options = 12; + * @return The serviceOptions. + */ + org.tensorflow.proto.data.DatasetOptions.ServiceOptions getServiceOptions(); + /** + *
    +     * The tf.data service options associated with the dataset.
    +     * 
    + * + * .tensorflow.data.ServiceOptions service_options = 12; + */ + org.tensorflow.proto.data.DatasetOptions.ServiceOptionsOrBuilder getServiceOptionsOrBuilder(); + /** * bool slack = 4; * @return Whether the slack field is set. @@ -6353,7 +7140,7 @@ public interface OptionsOrBuilder extends *
        * Message stored with Dataset objects to control how datasets are processed and
        * optimized.
    -   * next: 12
    +   * next: 13
        * 
    * * Protobuf type {@code tensorflow.data.Options} @@ -6868,6 +7655,44 @@ public org.tensorflow.proto.data.DatasetOptions.OptimizationOptionsOrBuilder get return getOptimizationOptions(); } + public static final int SERVICE_OPTIONS_FIELD_NUMBER = 12; + private org.tensorflow.proto.data.DatasetOptions.ServiceOptions serviceOptions_; + /** + *
    +     * The tf.data service options associated with the dataset.
    +     * 
    + * + * .tensorflow.data.ServiceOptions service_options = 12; + * @return Whether the serviceOptions field is set. + */ + @java.lang.Override + public boolean hasServiceOptions() { + return serviceOptions_ != null; + } + /** + *
    +     * The tf.data service options associated with the dataset.
    +     * 
    + * + * .tensorflow.data.ServiceOptions service_options = 12; + * @return The serviceOptions. + */ + @java.lang.Override + public org.tensorflow.proto.data.DatasetOptions.ServiceOptions getServiceOptions() { + return serviceOptions_ == null ? org.tensorflow.proto.data.DatasetOptions.ServiceOptions.getDefaultInstance() : serviceOptions_; + } + /** + *
    +     * The tf.data service options associated with the dataset.
    +     * 
    + * + * .tensorflow.data.ServiceOptions service_options = 12; + */ + @java.lang.Override + public org.tensorflow.proto.data.DatasetOptions.ServiceOptionsOrBuilder getServiceOptionsOrBuilder() { + return getServiceOptions(); + } + public static final int SLACK_FIELD_NUMBER = 4; /** * bool slack = 4; @@ -7052,6 +7877,9 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) for (int i = 0; i < frameworkType_.size(); i++) { com.google.protobuf.GeneratedMessageV3.writeString(output, 11, frameworkType_.getRaw(i)); } + if (serviceOptions_ != null) { + output.writeMessage(12, getServiceOptions()); + } getUnknownFields().writeTo(output); } @@ -7112,6 +7940,10 @@ public int getSerializedSize() { size += dataSize; size += 1 * getFrameworkTypeList().size(); } + if (serviceOptions_ != null) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(12, getServiceOptions()); + } size += getUnknownFields().getSerializedSize(); memoizedSize = size; return size; @@ -7144,6 +7976,11 @@ public boolean equals(final java.lang.Object obj) { if (!getOptimizationOptions() .equals(other.getOptimizationOptions())) return false; } + if (hasServiceOptions() != other.hasServiceOptions()) return false; + if (hasServiceOptions()) { + if (!getServiceOptions() + .equals(other.getServiceOptions())) return false; + } if (hasThreadingOptions() != other.hasThreadingOptions()) return false; if (hasThreadingOptions()) { if (!getThreadingOptions() @@ -7230,6 +8067,10 @@ public int hashCode() { hash = (37 * hash) + OPTIMIZATION_OPTIONS_FIELD_NUMBER; hash = (53 * hash) + getOptimizationOptions().hashCode(); } + if (hasServiceOptions()) { + hash = (37 * hash) + SERVICE_OPTIONS_FIELD_NUMBER; + hash = (53 * hash) + getServiceOptions().hashCode(); + } if (hasThreadingOptions()) { hash = (37 * hash) + THREADING_OPTIONS_FIELD_NUMBER; hash = (53 * hash) + getThreadingOptions().hashCode(); @@ -7385,7 +8226,7 @@ protected Builder newBuilderForType( *
          * Message stored with Dataset objects to control how datasets are processed and
          * optimized.
    -     * next: 12
    +     * next: 13
          * 
    * * Protobuf type {@code tensorflow.data.Options} @@ -7440,6 +8281,12 @@ public Builder clear() { optimizationOptions_ = null; optimizationOptionsBuilder_ = null; } + if (serviceOptionsBuilder_ == null) { + serviceOptions_ = null; + } else { + serviceOptions_ = null; + serviceOptionsBuilder_ = null; + } if (threadingOptionsBuilder_ == null) { threadingOptions_ = null; } else { @@ -7511,6 +8358,11 @@ public org.tensorflow.proto.data.DatasetOptions.Options buildPartial() { } else { result.optimizationOptions_ = optimizationOptionsBuilder_.build(); } + if (serviceOptionsBuilder_ == null) { + result.serviceOptions_ = serviceOptions_; + } else { + result.serviceOptions_ = serviceOptionsBuilder_.build(); + } if (optionalSlackCase_ == 4) { result.optionalSlack_ = optionalSlack_; } @@ -7601,6 +8453,9 @@ public Builder mergeFrom(org.tensorflow.proto.data.DatasetOptions.Options other) if (other.hasOptimizationOptions()) { mergeOptimizationOptions(other.getOptimizationOptions()); } + if (other.hasServiceOptions()) { + mergeServiceOptions(other.getServiceOptions()); + } if (other.hasThreadingOptions()) { mergeThreadingOptions(other.getThreadingOptions()); } @@ -7752,6 +8607,13 @@ public Builder mergeFrom( frameworkType_.add(s); break; } // case 90 + case 98: { + input.readMessage( + getServiceOptionsFieldBuilder().getBuilder(), + extensionRegistry); + + break; + } // case 98 default: { if (!super.parseUnknownField(input, extensionRegistry, tag)) { done = true; // was an endgroup tag @@ -8608,6 +9470,161 @@ public org.tensorflow.proto.data.DatasetOptions.OptimizationOptionsOrBuilder get return optimizationOptionsBuilder_; } + private org.tensorflow.proto.data.DatasetOptions.ServiceOptions serviceOptions_; + private com.google.protobuf.SingleFieldBuilderV3< + org.tensorflow.proto.data.DatasetOptions.ServiceOptions, org.tensorflow.proto.data.DatasetOptions.ServiceOptions.Builder, org.tensorflow.proto.data.DatasetOptions.ServiceOptionsOrBuilder> serviceOptionsBuilder_; + /** + *
    +       * The tf.data service options associated with the dataset.
    +       * 
    + * + * .tensorflow.data.ServiceOptions service_options = 12; + * @return Whether the serviceOptions field is set. + */ + public boolean hasServiceOptions() { + return serviceOptionsBuilder_ != null || serviceOptions_ != null; + } + /** + *
    +       * The tf.data service options associated with the dataset.
    +       * 
    + * + * .tensorflow.data.ServiceOptions service_options = 12; + * @return The serviceOptions. + */ + public org.tensorflow.proto.data.DatasetOptions.ServiceOptions getServiceOptions() { + if (serviceOptionsBuilder_ == null) { + return serviceOptions_ == null ? org.tensorflow.proto.data.DatasetOptions.ServiceOptions.getDefaultInstance() : serviceOptions_; + } else { + return serviceOptionsBuilder_.getMessage(); + } + } + /** + *
    +       * The tf.data service options associated with the dataset.
    +       * 
    + * + * .tensorflow.data.ServiceOptions service_options = 12; + */ + public Builder setServiceOptions(org.tensorflow.proto.data.DatasetOptions.ServiceOptions value) { + if (serviceOptionsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + serviceOptions_ = value; + onChanged(); + } else { + serviceOptionsBuilder_.setMessage(value); + } + + return this; + } + /** + *
    +       * The tf.data service options associated with the dataset.
    +       * 
    + * + * .tensorflow.data.ServiceOptions service_options = 12; + */ + public Builder setServiceOptions( + org.tensorflow.proto.data.DatasetOptions.ServiceOptions.Builder builderForValue) { + if (serviceOptionsBuilder_ == null) { + serviceOptions_ = builderForValue.build(); + onChanged(); + } else { + serviceOptionsBuilder_.setMessage(builderForValue.build()); + } + + return this; + } + /** + *
    +       * The tf.data service options associated with the dataset.
    +       * 
    + * + * .tensorflow.data.ServiceOptions service_options = 12; + */ + public Builder mergeServiceOptions(org.tensorflow.proto.data.DatasetOptions.ServiceOptions value) { + if (serviceOptionsBuilder_ == null) { + if (serviceOptions_ != null) { + serviceOptions_ = + org.tensorflow.proto.data.DatasetOptions.ServiceOptions.newBuilder(serviceOptions_).mergeFrom(value).buildPartial(); + } else { + serviceOptions_ = value; + } + onChanged(); + } else { + serviceOptionsBuilder_.mergeFrom(value); + } + + return this; + } + /** + *
    +       * The tf.data service options associated with the dataset.
    +       * 
    + * + * .tensorflow.data.ServiceOptions service_options = 12; + */ + public Builder clearServiceOptions() { + if (serviceOptionsBuilder_ == null) { + serviceOptions_ = null; + onChanged(); + } else { + serviceOptions_ = null; + serviceOptionsBuilder_ = null; + } + + return this; + } + /** + *
    +       * The tf.data service options associated with the dataset.
    +       * 
    + * + * .tensorflow.data.ServiceOptions service_options = 12; + */ + public org.tensorflow.proto.data.DatasetOptions.ServiceOptions.Builder getServiceOptionsBuilder() { + + onChanged(); + return getServiceOptionsFieldBuilder().getBuilder(); + } + /** + *
    +       * The tf.data service options associated with the dataset.
    +       * 
    + * + * .tensorflow.data.ServiceOptions service_options = 12; + */ + public org.tensorflow.proto.data.DatasetOptions.ServiceOptionsOrBuilder getServiceOptionsOrBuilder() { + if (serviceOptionsBuilder_ != null) { + return serviceOptionsBuilder_.getMessageOrBuilder(); + } else { + return serviceOptions_ == null ? + org.tensorflow.proto.data.DatasetOptions.ServiceOptions.getDefaultInstance() : serviceOptions_; + } + } + /** + *
    +       * The tf.data service options associated with the dataset.
    +       * 
    + * + * .tensorflow.data.ServiceOptions service_options = 12; + */ + private com.google.protobuf.SingleFieldBuilderV3< + org.tensorflow.proto.data.DatasetOptions.ServiceOptions, org.tensorflow.proto.data.DatasetOptions.ServiceOptions.Builder, org.tensorflow.proto.data.DatasetOptions.ServiceOptionsOrBuilder> + getServiceOptionsFieldBuilder() { + if (serviceOptionsBuilder_ == null) { + serviceOptionsBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + org.tensorflow.proto.data.DatasetOptions.ServiceOptions, org.tensorflow.proto.data.DatasetOptions.ServiceOptions.Builder, org.tensorflow.proto.data.DatasetOptions.ServiceOptionsOrBuilder>( + getServiceOptions(), + getParentForChildren(), + isClean()); + serviceOptions_ = null; + } + return serviceOptionsBuilder_; + } + /** * bool slack = 4; * @return Whether the slack field is set. @@ -9040,6 +10057,11 @@ public org.tensorflow.proto.data.DatasetOptions.Options getDefaultInstanceForTyp private static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internal_static_tensorflow_data_OptimizationOptions_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_tensorflow_data_ServiceOptions_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_tensorflow_data_ServiceOptions_fieldAccessorTable; private static final com.google.protobuf.Descriptors.Descriptor internal_static_tensorflow_data_ThreadingOptions_descriptor; private static final @@ -9061,70 +10083,74 @@ public org.tensorflow.proto.data.DatasetOptions.Options getDefaultInstanceForTyp java.lang.String[] descriptorData = { "\n/tensorflow/core/framework/dataset_opti" + "ons.proto\022\017tensorflow.data\032%tensorflow/c" + - "ore/framework/model.proto\"\371\001\n\017AutotuneOp" + + "ore/framework/model.proto\"\270\002\n\017AutotuneOp" + "tions\022\021\n\007enabled\030\001 \001(\010H\000\022\024\n\ncpu_budget\030\002" + " \001(\005H\001\022\024\n\nram_budget\030\003 \001(\003H\002\022F\n\022autotune" + "_algorithm\030\004 \001(\0162(.tensorflow.data.model" + - ".AutotuneAlgorithmH\003B\022\n\020optional_enabled" + - "B\025\n\023optional_cpu_budgetB\025\n\023optional_ram_" + - "budgetB\035\n\033optional_autotune_algorithm\"\321\001" + - "\n\022CardinalityOptions\022G\n\rcompute_level\030\001 " + - "\001(\01620.tensorflow.data.CardinalityOptions" + - ".ComputeLevel\"r\n\014ComputeLevel\022#\n\037CARDINA" + - "LITY_COMPUTE_UNSPECIFIED\020\000\022\033\n\027CARDINALIT" + - "Y_COMPUTE_LOW\020\001\022 \n\034CARDINALITY_COMPUTE_M" + - "ODERATE\020\002\"\177\n\021DistributeOptions\022;\n\021auto_s" + - "hard_policy\030\001 \001(\0162 .tensorflow.data.Auto" + - "ShardPolicy\022\025\n\013num_devices\030\002 \001(\005H\000B\026\n\024op" + - "tional_num_devices\"\271\006\n\023OptimizationOptio" + - "ns\022%\n\033apply_default_optimizations\030\001 \001(\010H" + - "\000\022\027\n\rfilter_fusion\030\006 \001(\010H\001\022\036\n\024map_and_ba" + - "tch_fusion\030\t \001(\010H\002\022\037\n\025map_and_filter_fus" + - "ion\030\n \001(\010H\003\022\024\n\nmap_fusion\030\013 \001(\010H\004\022\035\n\023map" + - "_parallelization\030\014 \001(\010H\005\022\032\n\020noop_elimina" + - "tion\030\016 \001(\010H\006\022\030\n\016parallel_batch\030\017 \001(\010H\007\022#" + - "\n\031shuffle_and_repeat_fusion\030\021 \001(\010H\010\022 \n\026f" + - "ilter_parallelization\030\022 \001(\010H\t\022\031\n\017inject_" + - "prefetch\030\023 \001(\010H\n\022!\n\027seq_interleave_prefe" + - "tch\030\025 \001(\010H\013B&\n$optional_apply_default_op" + - "timizationsB\030\n\026optional_filter_fusionB\037\n" + - "\035optional_map_and_batch_fusionB \n\036option" + - "al_map_and_filter_fusionB\025\n\023optional_map" + - "_fusionB\036\n\034optional_map_parallelizationB" + - "\033\n\031optional_noop_eliminationB\031\n\027optional" + - "_parallel_batchB$\n\"optional_shuffle_and_" + - "repeat_fusionB!\n\037optional_filter_paralle" + - "lizationB\032\n\030optional_inject_prefetchB\"\n " + - "optional_seq_interleave_prefetchJ\004\010\002\020\003J\004" + - "\010\003\020\004J\004\010\004\020\005J\004\010\005\020\006J\004\010\007\020\010J\004\010\010\020\tJ\004\010\r\020\016J\004\010\020\020\021" + - "J\004\010\024\020\025\"\242\001\n\020ThreadingOptions\022\"\n\030max_intra" + - "_op_parallelism\030\001 \001(\005H\000\022!\n\027private_threa" + - "dpool_size\030\002 \001(\005H\001B#\n!optional_max_intra" + - "_op_parallelismB\"\n optional_private_thre" + - "adpool_size\"\373\004\n\007Options\022\026\n\014dataset_name\030" + - "\n \001(\tH\000\022\026\n\016framework_type\030\013 \003(\t\022\027\n\rdeter" + - "ministic\030\001 \001(\010H\001\022:\n\020autotune_options\030\007 \001" + - "(\0132 .tensorflow.data.AutotuneOptions\022>\n\022" + - "distribute_options\030\002 \001(\0132\".tensorflow.da" + - "ta.DistributeOptions\022B\n\024optimization_opt" + - "ions\030\003 \001(\0132$.tensorflow.data.Optimizatio" + - "nOptions\022\017\n\005slack\030\004 \001(\010H\002\022<\n\021threading_o" + - "ptions\030\005 \001(\0132!.tensorflow.data.Threading" + - "Options\022E\n\025external_state_policy\030\006 \001(\0162$" + - ".tensorflow.data.ExternalStatePolicyH\003\022\035" + - "\n\023symbolic_checkpoint\030\010 \001(\010H\004\022\024\n\nwarm_st" + - "art\030\t \001(\010H\005B\027\n\025optional_dataset_nameB\030\n\026" + - "optional_deterministicB\020\n\016optional_slack" + - "B \n\036optional_external_state_policyB\036\n\034op" + - "tional_symbolic_checkpointB\025\n\023optional_w" + - "arm_start*K\n\017AutoShardPolicy\022\010\n\004AUTO\020\000\022\010" + - "\n\004FILE\020\001\022\010\n\004DATA\020\002\022\010\n\004HINT\020\003\022\020\n\003OFF\020\377\377\377\377" + - "\377\377\377\377\377\001*J\n\023ExternalStatePolicy\022\017\n\013POLICY_" + - "WARN\020\000\022\021\n\rPOLICY_IGNORE\020\001\022\017\n\013POLICY_FAIL" + - "\020\002Bs\n\031org.tensorflow.proto.dataZVgithub." + - "com/tensorflow/tensorflow/tensorflow/go/" + - "core/framework/dataset_options_go_protob" + - "\006proto3" + ".AutotuneAlgorithmH\003\022\035\n\023initial_parallel" + + "ism\030\005 \001(\003H\004B\022\n\020optional_enabledB\025\n\023optio" + + "nal_cpu_budgetB\025\n\023optional_ram_budgetB\035\n" + + "\033optional_autotune_algorithmB\036\n\034optional" + + "_initial_parallelism\"\321\001\n\022CardinalityOpti" + + "ons\022G\n\rcompute_level\030\001 \001(\01620.tensorflow." + + "data.CardinalityOptions.ComputeLevel\"r\n\014" + + "ComputeLevel\022#\n\037CARDINALITY_COMPUTE_UNSP" + + "ECIFIED\020\000\022\033\n\027CARDINALITY_COMPUTE_LOW\020\001\022 " + + "\n\034CARDINALITY_COMPUTE_MODERATE\020\002\"\177\n\021Dist" + + "ributeOptions\022;\n\021auto_shard_policy\030\001 \001(\016" + + "2 .tensorflow.data.AutoShardPolicy\022\025\n\013nu" + + "m_devices\030\002 \001(\005H\000B\026\n\024optional_num_device" + + "s\"\271\006\n\023OptimizationOptions\022%\n\033apply_defau" + + "lt_optimizations\030\001 \001(\010H\000\022\027\n\rfilter_fusio" + + "n\030\006 \001(\010H\001\022\036\n\024map_and_batch_fusion\030\t \001(\010H" + + "\002\022\037\n\025map_and_filter_fusion\030\n \001(\010H\003\022\024\n\nma" + + "p_fusion\030\013 \001(\010H\004\022\035\n\023map_parallelization\030" + + "\014 \001(\010H\005\022\032\n\020noop_elimination\030\016 \001(\010H\006\022\030\n\016p" + + "arallel_batch\030\017 \001(\010H\007\022#\n\031shuffle_and_rep" + + "eat_fusion\030\021 \001(\010H\010\022 \n\026filter_paralleliza" + + "tion\030\022 \001(\010H\t\022\031\n\017inject_prefetch\030\023 \001(\010H\n\022" + + "!\n\027seq_interleave_prefetch\030\025 \001(\010H\013B&\n$op" + + "tional_apply_default_optimizationsB\030\n\026op" + + "tional_filter_fusionB\037\n\035optional_map_and" + + "_batch_fusionB \n\036optional_map_and_filter" + + "_fusionB\025\n\023optional_map_fusionB\036\n\034option" + + "al_map_parallelizationB\033\n\031optional_noop_" + + "eliminationB\031\n\027optional_parallel_batchB$" + + "\n\"optional_shuffle_and_repeat_fusionB!\n\037" + + "optional_filter_parallelizationB\032\n\030optio" + + "nal_inject_prefetchB\"\n optional_seq_inte" + + "rleave_prefetchJ\004\010\002\020\003J\004\010\003\020\004J\004\010\004\020\005J\004\010\005\020\006J" + + "\004\010\007\020\010J\004\010\010\020\tJ\004\010\r\020\016J\004\010\020\020\021J\004\010\024\020\025\"5\n\016Service" + + "Options\022\020\n\006pinned\030\001 \001(\010H\000B\021\n\017optional_pi" + + "nned\"\242\001\n\020ThreadingOptions\022\"\n\030max_intra_o" + + "p_parallelism\030\001 \001(\005H\000\022!\n\027private_threadp" + + "ool_size\030\002 \001(\005H\001B#\n!optional_max_intra_o" + + "p_parallelismB\"\n optional_private_thread" + + "pool_size\"\265\005\n\007Options\022\026\n\014dataset_name\030\n " + + "\001(\tH\000\022\026\n\016framework_type\030\013 \003(\t\022\027\n\rdetermi" + + "nistic\030\001 \001(\010H\001\022:\n\020autotune_options\030\007 \001(\013" + + "2 .tensorflow.data.AutotuneOptions\022>\n\022di" + + "stribute_options\030\002 \001(\0132\".tensorflow.data" + + ".DistributeOptions\022B\n\024optimization_optio" + + "ns\030\003 \001(\0132$.tensorflow.data.OptimizationO" + + "ptions\0228\n\017service_options\030\014 \001(\0132\037.tensor" + + "flow.data.ServiceOptions\022\017\n\005slack\030\004 \001(\010H" + + "\002\022<\n\021threading_options\030\005 \001(\0132!.tensorflo" + + "w.data.ThreadingOptions\022E\n\025external_stat" + + "e_policy\030\006 \001(\0162$.tensorflow.data.Externa" + + "lStatePolicyH\003\022\035\n\023symbolic_checkpoint\030\010 " + + "\001(\010H\004\022\024\n\nwarm_start\030\t \001(\010H\005B\027\n\025optional_" + + "dataset_nameB\030\n\026optional_deterministicB\020" + + "\n\016optional_slackB \n\036optional_external_st" + + "ate_policyB\036\n\034optional_symbolic_checkpoi" + + "ntB\025\n\023optional_warm_start*K\n\017AutoShardPo" + + "licy\022\010\n\004AUTO\020\000\022\010\n\004FILE\020\001\022\010\n\004DATA\020\002\022\010\n\004HI" + + "NT\020\003\022\020\n\003OFF\020\377\377\377\377\377\377\377\377\377\001*J\n\023ExternalStateP" + + "olicy\022\017\n\013POLICY_WARN\020\000\022\021\n\rPOLICY_IGNORE\020" + + "\001\022\017\n\013POLICY_FAIL\020\002Bs\n\031org.tensorflow.pro" + + "to.dataZVgithub.com/tensorflow/tensorflo" + + "w/tensorflow/go/core/framework/dataset_o" + + "ptions_go_protob\006proto3" }; descriptor = com.google.protobuf.Descriptors.FileDescriptor .internalBuildGeneratedFileFrom(descriptorData, @@ -9136,7 +10162,7 @@ public org.tensorflow.proto.data.DatasetOptions.Options getDefaultInstanceForTyp internal_static_tensorflow_data_AutotuneOptions_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_tensorflow_data_AutotuneOptions_descriptor, - new java.lang.String[] { "Enabled", "CpuBudget", "RamBudget", "AutotuneAlgorithm", "OptionalEnabled", "OptionalCpuBudget", "OptionalRamBudget", "OptionalAutotuneAlgorithm", }); + new java.lang.String[] { "Enabled", "CpuBudget", "RamBudget", "AutotuneAlgorithm", "InitialParallelism", "OptionalEnabled", "OptionalCpuBudget", "OptionalRamBudget", "OptionalAutotuneAlgorithm", "OptionalInitialParallelism", }); internal_static_tensorflow_data_CardinalityOptions_descriptor = getDescriptor().getMessageTypes().get(1); internal_static_tensorflow_data_CardinalityOptions_fieldAccessorTable = new @@ -9155,18 +10181,24 @@ public org.tensorflow.proto.data.DatasetOptions.Options getDefaultInstanceForTyp com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_tensorflow_data_OptimizationOptions_descriptor, new java.lang.String[] { "ApplyDefaultOptimizations", "FilterFusion", "MapAndBatchFusion", "MapAndFilterFusion", "MapFusion", "MapParallelization", "NoopElimination", "ParallelBatch", "ShuffleAndRepeatFusion", "FilterParallelization", "InjectPrefetch", "SeqInterleavePrefetch", "OptionalApplyDefaultOptimizations", "OptionalFilterFusion", "OptionalMapAndBatchFusion", "OptionalMapAndFilterFusion", "OptionalMapFusion", "OptionalMapParallelization", "OptionalNoopElimination", "OptionalParallelBatch", "OptionalShuffleAndRepeatFusion", "OptionalFilterParallelization", "OptionalInjectPrefetch", "OptionalSeqInterleavePrefetch", }); - internal_static_tensorflow_data_ThreadingOptions_descriptor = + internal_static_tensorflow_data_ServiceOptions_descriptor = getDescriptor().getMessageTypes().get(4); + internal_static_tensorflow_data_ServiceOptions_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_tensorflow_data_ServiceOptions_descriptor, + new java.lang.String[] { "Pinned", "OptionalPinned", }); + internal_static_tensorflow_data_ThreadingOptions_descriptor = + getDescriptor().getMessageTypes().get(5); internal_static_tensorflow_data_ThreadingOptions_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_tensorflow_data_ThreadingOptions_descriptor, new java.lang.String[] { "MaxIntraOpParallelism", "PrivateThreadpoolSize", "OptionalMaxIntraOpParallelism", "OptionalPrivateThreadpoolSize", }); internal_static_tensorflow_data_Options_descriptor = - getDescriptor().getMessageTypes().get(5); + getDescriptor().getMessageTypes().get(6); internal_static_tensorflow_data_Options_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_tensorflow_data_Options_descriptor, - new java.lang.String[] { "DatasetName", "FrameworkType", "Deterministic", "AutotuneOptions", "DistributeOptions", "OptimizationOptions", "Slack", "ThreadingOptions", "ExternalStatePolicy", "SymbolicCheckpoint", "WarmStart", "OptionalDatasetName", "OptionalDeterministic", "OptionalSlack", "OptionalExternalStatePolicy", "OptionalSymbolicCheckpoint", "OptionalWarmStart", }); + new java.lang.String[] { "DatasetName", "FrameworkType", "Deterministic", "AutotuneOptions", "DistributeOptions", "OptimizationOptions", "ServiceOptions", "Slack", "ThreadingOptions", "ExternalStatePolicy", "SymbolicCheckpoint", "WarmStart", "OptionalDatasetName", "OptionalDeterministic", "OptionalSlack", "OptionalExternalStatePolicy", "OptionalSymbolicCheckpoint", "OptionalWarmStart", }); org.tensorflow.proto.data.model.Model.getDescriptor(); } diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/data/experimental/ServiceConfig.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/data/experimental/ServiceConfig.java index 5d143f7c9f8..de029b2baa5 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/data/experimental/ServiceConfig.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/data/experimental/ServiceConfig.java @@ -2261,7 +2261,11 @@ public interface WorkerConfigOrBuilder extends /** *
    -     * The protocol for the worker to use when transferring data to clients.
    +     * If set, the name of an alternative data transfer protocol for which the
    +     * worker starts an additional server ("data transfer server"); the trainer
    +     * can then get data from this server. If not set, no such server is started,
    +     * and the trainer can only get data from the regular worker server over
    +     * `protocol`.
          * 
    * * string data_transfer_protocol = 7; @@ -2270,7 +2274,11 @@ public interface WorkerConfigOrBuilder extends java.lang.String getDataTransferProtocol(); /** *
    -     * The protocol for the worker to use when transferring data to clients.
    +     * If set, the name of an alternative data transfer protocol for which the
    +     * worker starts an additional server ("data transfer server"); the trainer
    +     * can then get data from this server. If not set, no such server is started,
    +     * and the trainer can only get data from the regular worker server over
    +     * `protocol`.
          * 
    * * string data_transfer_protocol = 7; @@ -2281,9 +2289,21 @@ public interface WorkerConfigOrBuilder extends /** *
    -     * The data transfer address of the worker server. The substring "%port%", if
    -     * specified, will be replaced with the worker's bound port. This is useful
    -     * when the port is set to `0`.
    +     * If `data_transfer_protocol` is set, the port to which the data transfer
    +     * server binds. If set to `0`, the server binds to any available port.
    +     * 
    + * + * int64 data_transfer_port = 13; + * @return The dataTransferPort. + */ + long getDataTransferPort(); + + /** + *
    +     * If `data_transfer_protocol` is set, the address of the data transfer
    +     * server. The substring "%dts_port%" can be used to represent -- and is
    +     * replaced with -- the bound port of the data transfer server; this is useful
    +     * when `data_transfer_port` is set to `0`.
          * 
    * * string data_transfer_address = 8; @@ -2292,9 +2312,10 @@ public interface WorkerConfigOrBuilder extends java.lang.String getDataTransferAddress(); /** *
    -     * The data transfer address of the worker server. The substring "%port%", if
    -     * specified, will be replaced with the worker's bound port. This is useful
    -     * when the port is set to `0`.
    +     * If `data_transfer_protocol` is set, the address of the data transfer
    +     * server. The substring "%dts_port%" can be used to represent -- and is
    +     * replaced with -- the bound port of the data transfer server; this is useful
    +     * when `data_transfer_port` is set to `0`.
          * 
    * * string data_transfer_address = 8; @@ -2340,7 +2361,7 @@ public interface WorkerConfigOrBuilder extends /** *
        * Configuration for a tf.data service WorkerServer.
    -   * Next id: 13
    +   * Next id: 14
        * 
    * * Protobuf type {@code tensorflow.data.experimental.WorkerConfig} @@ -2646,7 +2667,11 @@ public long getDispatcherTimeoutMs() { private volatile java.lang.Object dataTransferProtocol_; /** *
    -     * The protocol for the worker to use when transferring data to clients.
    +     * If set, the name of an alternative data transfer protocol for which the
    +     * worker starts an additional server ("data transfer server"); the trainer
    +     * can then get data from this server. If not set, no such server is started,
    +     * and the trainer can only get data from the regular worker server over
    +     * `protocol`.
          * 
    * * string data_transfer_protocol = 7; @@ -2667,7 +2692,11 @@ public java.lang.String getDataTransferProtocol() { } /** *
    -     * The protocol for the worker to use when transferring data to clients.
    +     * If set, the name of an alternative data transfer protocol for which the
    +     * worker starts an additional server ("data transfer server"); the trainer
    +     * can then get data from this server. If not set, no such server is started,
    +     * and the trainer can only get data from the regular worker server over
    +     * `protocol`.
          * 
    * * string data_transfer_protocol = 7; @@ -2688,13 +2717,30 @@ public java.lang.String getDataTransferProtocol() { } } + public static final int DATA_TRANSFER_PORT_FIELD_NUMBER = 13; + private long dataTransferPort_; + /** + *
    +     * If `data_transfer_protocol` is set, the port to which the data transfer
    +     * server binds. If set to `0`, the server binds to any available port.
    +     * 
    + * + * int64 data_transfer_port = 13; + * @return The dataTransferPort. + */ + @java.lang.Override + public long getDataTransferPort() { + return dataTransferPort_; + } + public static final int DATA_TRANSFER_ADDRESS_FIELD_NUMBER = 8; private volatile java.lang.Object dataTransferAddress_; /** *
    -     * The data transfer address of the worker server. The substring "%port%", if
    -     * specified, will be replaced with the worker's bound port. This is useful
    -     * when the port is set to `0`.
    +     * If `data_transfer_protocol` is set, the address of the data transfer
    +     * server. The substring "%dts_port%" can be used to represent -- and is
    +     * replaced with -- the bound port of the data transfer server; this is useful
    +     * when `data_transfer_port` is set to `0`.
          * 
    * * string data_transfer_address = 8; @@ -2715,9 +2761,10 @@ public java.lang.String getDataTransferAddress() { } /** *
    -     * The data transfer address of the worker server. The substring "%port%", if
    -     * specified, will be replaced with the worker's bound port. This is useful
    -     * when the port is set to `0`.
    +     * If `data_transfer_protocol` is set, the address of the data transfer
    +     * server. The substring "%dts_port%" can be used to represent -- and is
    +     * replaced with -- the bound port of the data transfer server; this is useful
    +     * when `data_transfer_port` is set to `0`.
          * 
    * * string data_transfer_address = 8; @@ -2837,6 +2884,9 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) if (snapshotMaxChunkSizeBytes_ != 0L) { output.writeInt64(12, snapshotMaxChunkSizeBytes_); } + if (dataTransferPort_ != 0L) { + output.writeInt64(13, dataTransferPort_); + } getUnknownFields().writeTo(output); } @@ -2893,6 +2943,10 @@ public int getSerializedSize() { size += com.google.protobuf.CodedOutputStream .computeInt64Size(12, snapshotMaxChunkSizeBytes_); } + if (dataTransferPort_ != 0L) { + size += com.google.protobuf.CodedOutputStream + .computeInt64Size(13, dataTransferPort_); + } size += getUnknownFields().getSerializedSize(); memoizedSize = size; return size; @@ -2924,6 +2978,8 @@ public boolean equals(final java.lang.Object obj) { != other.getDispatcherTimeoutMs()) return false; if (!getDataTransferProtocol() .equals(other.getDataTransferProtocol())) return false; + if (getDataTransferPort() + != other.getDataTransferPort()) return false; if (!getDataTransferAddress() .equals(other.getDataTransferAddress())) return false; if (getCrossTrainerCacheSizeBytes() @@ -2964,6 +3020,9 @@ public int hashCode() { getDispatcherTimeoutMs()); hash = (37 * hash) + DATA_TRANSFER_PROTOCOL_FIELD_NUMBER; hash = (53 * hash) + getDataTransferProtocol().hashCode(); + hash = (37 * hash) + DATA_TRANSFER_PORT_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashLong( + getDataTransferPort()); hash = (37 * hash) + DATA_TRANSFER_ADDRESS_FIELD_NUMBER; hash = (53 * hash) + getDataTransferAddress().hashCode(); hash = (37 * hash) + CROSS_TRAINER_CACHE_SIZE_BYTES_FIELD_NUMBER; @@ -3073,7 +3132,7 @@ protected Builder newBuilderForType( /** *
          * Configuration for a tf.data service WorkerServer.
    -     * Next id: 13
    +     * Next id: 14
          * 
    * * Protobuf type {@code tensorflow.data.experimental.WorkerConfig} @@ -3124,6 +3183,8 @@ public Builder clear() { dataTransferProtocol_ = ""; + dataTransferPort_ = 0L; + dataTransferAddress_ = ""; crossTrainerCacheSizeBytes_ = 0L; @@ -3171,6 +3232,7 @@ public org.tensorflow.proto.data.experimental.ServiceConfig.WorkerConfig buildPa result.heartbeatIntervalMs_ = heartbeatIntervalMs_; result.dispatcherTimeoutMs_ = dispatcherTimeoutMs_; result.dataTransferProtocol_ = dataTransferProtocol_; + result.dataTransferPort_ = dataTransferPort_; result.dataTransferAddress_ = dataTransferAddress_; result.crossTrainerCacheSizeBytes_ = crossTrainerCacheSizeBytes_; result.snapshotMaxChunkSizeBytes_ = snapshotMaxChunkSizeBytes_; @@ -3258,6 +3320,9 @@ public Builder mergeFrom(org.tensorflow.proto.data.experimental.ServiceConfig.Wo dataTransferProtocol_ = other.dataTransferProtocol_; onChanged(); } + if (other.getDataTransferPort() != 0L) { + setDataTransferPort(other.getDataTransferPort()); + } if (!other.getDataTransferAddress().isEmpty()) { dataTransferAddress_ = other.dataTransferAddress_; onChanged(); @@ -3358,6 +3423,11 @@ public Builder mergeFrom( break; } // case 96 + case 104: { + dataTransferPort_ = input.readInt64(); + + break; + } // case 104 default: { if (!super.parseUnknownField(input, extensionRegistry, tag)) { done = true; // was an endgroup tag @@ -3990,7 +4060,11 @@ public Builder clearDispatcherTimeoutMs() { private java.lang.Object dataTransferProtocol_ = ""; /** *
    -       * The protocol for the worker to use when transferring data to clients.
    +       * If set, the name of an alternative data transfer protocol for which the
    +       * worker starts an additional server ("data transfer server"); the trainer
    +       * can then get data from this server. If not set, no such server is started,
    +       * and the trainer can only get data from the regular worker server over
    +       * `protocol`.
            * 
    * * string data_transfer_protocol = 7; @@ -4010,7 +4084,11 @@ public java.lang.String getDataTransferProtocol() { } /** *
    -       * The protocol for the worker to use when transferring data to clients.
    +       * If set, the name of an alternative data transfer protocol for which the
    +       * worker starts an additional server ("data transfer server"); the trainer
    +       * can then get data from this server. If not set, no such server is started,
    +       * and the trainer can only get data from the regular worker server over
    +       * `protocol`.
            * 
    * * string data_transfer_protocol = 7; @@ -4031,7 +4109,11 @@ public java.lang.String getDataTransferProtocol() { } /** *
    -       * The protocol for the worker to use when transferring data to clients.
    +       * If set, the name of an alternative data transfer protocol for which the
    +       * worker starts an additional server ("data transfer server"); the trainer
    +       * can then get data from this server. If not set, no such server is started,
    +       * and the trainer can only get data from the regular worker server over
    +       * `protocol`.
            * 
    * * string data_transfer_protocol = 7; @@ -4050,7 +4132,11 @@ public Builder setDataTransferProtocol( } /** *
    -       * The protocol for the worker to use when transferring data to clients.
    +       * If set, the name of an alternative data transfer protocol for which the
    +       * worker starts an additional server ("data transfer server"); the trainer
    +       * can then get data from this server. If not set, no such server is started,
    +       * and the trainer can only get data from the regular worker server over
    +       * `protocol`.
            * 
    * * string data_transfer_protocol = 7; @@ -4064,7 +4150,11 @@ public Builder clearDataTransferProtocol() { } /** *
    -       * The protocol for the worker to use when transferring data to clients.
    +       * If set, the name of an alternative data transfer protocol for which the
    +       * worker starts an additional server ("data transfer server"); the trainer
    +       * can then get data from this server. If not set, no such server is started,
    +       * and the trainer can only get data from the regular worker server over
    +       * `protocol`.
            * 
    * * string data_transfer_protocol = 7; @@ -4083,12 +4173,59 @@ public Builder setDataTransferProtocolBytes( return this; } + private long dataTransferPort_ ; + /** + *
    +       * If `data_transfer_protocol` is set, the port to which the data transfer
    +       * server binds. If set to `0`, the server binds to any available port.
    +       * 
    + * + * int64 data_transfer_port = 13; + * @return The dataTransferPort. + */ + @java.lang.Override + public long getDataTransferPort() { + return dataTransferPort_; + } + /** + *
    +       * If `data_transfer_protocol` is set, the port to which the data transfer
    +       * server binds. If set to `0`, the server binds to any available port.
    +       * 
    + * + * int64 data_transfer_port = 13; + * @param value The dataTransferPort to set. + * @return This builder for chaining. + */ + public Builder setDataTransferPort(long value) { + + dataTransferPort_ = value; + onChanged(); + return this; + } + /** + *
    +       * If `data_transfer_protocol` is set, the port to which the data transfer
    +       * server binds. If set to `0`, the server binds to any available port.
    +       * 
    + * + * int64 data_transfer_port = 13; + * @return This builder for chaining. + */ + public Builder clearDataTransferPort() { + + dataTransferPort_ = 0L; + onChanged(); + return this; + } + private java.lang.Object dataTransferAddress_ = ""; /** *
    -       * The data transfer address of the worker server. The substring "%port%", if
    -       * specified, will be replaced with the worker's bound port. This is useful
    -       * when the port is set to `0`.
    +       * If `data_transfer_protocol` is set, the address of the data transfer
    +       * server. The substring "%dts_port%" can be used to represent -- and is
    +       * replaced with -- the bound port of the data transfer server; this is useful
    +       * when `data_transfer_port` is set to `0`.
            * 
    * * string data_transfer_address = 8; @@ -4108,9 +4245,10 @@ public java.lang.String getDataTransferAddress() { } /** *
    -       * The data transfer address of the worker server. The substring "%port%", if
    -       * specified, will be replaced with the worker's bound port. This is useful
    -       * when the port is set to `0`.
    +       * If `data_transfer_protocol` is set, the address of the data transfer
    +       * server. The substring "%dts_port%" can be used to represent -- and is
    +       * replaced with -- the bound port of the data transfer server; this is useful
    +       * when `data_transfer_port` is set to `0`.
            * 
    * * string data_transfer_address = 8; @@ -4131,9 +4269,10 @@ public java.lang.String getDataTransferAddress() { } /** *
    -       * The data transfer address of the worker server. The substring "%port%", if
    -       * specified, will be replaced with the worker's bound port. This is useful
    -       * when the port is set to `0`.
    +       * If `data_transfer_protocol` is set, the address of the data transfer
    +       * server. The substring "%dts_port%" can be used to represent -- and is
    +       * replaced with -- the bound port of the data transfer server; this is useful
    +       * when `data_transfer_port` is set to `0`.
            * 
    * * string data_transfer_address = 8; @@ -4152,9 +4291,10 @@ public Builder setDataTransferAddress( } /** *
    -       * The data transfer address of the worker server. The substring "%port%", if
    -       * specified, will be replaced with the worker's bound port. This is useful
    -       * when the port is set to `0`.
    +       * If `data_transfer_protocol` is set, the address of the data transfer
    +       * server. The substring "%dts_port%" can be used to represent -- and is
    +       * replaced with -- the bound port of the data transfer server; this is useful
    +       * when `data_transfer_port` is set to `0`.
            * 
    * * string data_transfer_address = 8; @@ -4168,9 +4308,10 @@ public Builder clearDataTransferAddress() { } /** *
    -       * The data transfer address of the worker server. The substring "%port%", if
    -       * specified, will be replaced with the worker's bound port. This is useful
    -       * when the port is set to `0`.
    +       * If `data_transfer_protocol` is set, the address of the data transfer
    +       * server. The substring "%dts_port%" can be used to represent -- and is
    +       * replaced with -- the bound port of the data transfer server; this is useful
    +       * when `data_transfer_port` is set to `0`.
            * 
    * * string data_transfer_address = 8; @@ -4424,19 +4565,20 @@ public org.tensorflow.proto.data.experimental.ServiceConfig.WorkerConfig getDefa "s\030\006 \001(\003\022 \n\030gc_dynamic_sharding_jobs\030\013 \001(" + "\010\022\031\n\021client_timeout_ms\030\010 \001(\003\022\031\n\021worker_t" + "imeout_ms\030\n \001(\003\022\'\n\037worker_max_concurrent" + - "_snapshots\030\014 \001(\003\"\345\002\n\014WorkerConfig\022\014\n\004por" + + "_snapshots\030\014 \001(\003\"\201\003\n\014WorkerConfig\022\014\n\004por" + "t\030\001 \001(\003\022\020\n\010protocol\030\002 \001(\t\022\032\n\022dispatcher_" + "address\030\003 \001(\t\022\026\n\016worker_address\030\004 \001(\t\022\023\n" + "\013worker_tags\030\n \003(\t\022\035\n\025heartbeat_interval" + "_ms\030\005 \001(\003\022\035\n\025dispatcher_timeout_ms\030\006 \001(\003" + - "\022\036\n\026data_transfer_protocol\030\007 \001(\t\022\035\n\025data" + - "_transfer_address\030\010 \001(\t\022&\n\036cross_trainer" + - "_cache_size_bytes\030\013 \001(\003\022%\n\035snapshot_max_" + - "chunk_size_bytes\030\014 \001(\003\022 \n\030shutdown_quiet" + - "_period_ms\030\t \001(\003B\177\n&org.tensorflow.proto" + - ".data.experimentalZUgithub.com/tensorflo" + - "w/tensorflow/tensorflow/go/core/protobuf" + - "/for_core_protos_go_protob\006proto3" + "\022\036\n\026data_transfer_protocol\030\007 \001(\t\022\032\n\022data" + + "_transfer_port\030\r \001(\003\022\035\n\025data_transfer_ad" + + "dress\030\010 \001(\t\022&\n\036cross_trainer_cache_size_" + + "bytes\030\013 \001(\003\022%\n\035snapshot_max_chunk_size_b" + + "ytes\030\014 \001(\003\022 \n\030shutdown_quiet_period_ms\030\t" + + " \001(\003B\177\n&org.tensorflow.proto.data.experi" + + "mentalZUgithub.com/tensorflow/tensorflow" + + "/tensorflow/go/core/protobuf/for_core_pr" + + "otos_go_protob\006proto3" }; descriptor = com.google.protobuf.Descriptors.FileDescriptor .internalBuildGeneratedFileFrom(descriptorData, @@ -4454,7 +4596,7 @@ public org.tensorflow.proto.data.experimental.ServiceConfig.WorkerConfig getDefa internal_static_tensorflow_data_experimental_WorkerConfig_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_tensorflow_data_experimental_WorkerConfig_descriptor, - new java.lang.String[] { "Port", "Protocol", "DispatcherAddress", "WorkerAddress", "WorkerTags", "HeartbeatIntervalMs", "DispatcherTimeoutMs", "DataTransferProtocol", "DataTransferAddress", "CrossTrainerCacheSizeBytes", "SnapshotMaxChunkSizeBytes", "ShutdownQuietPeriodMs", }); + new java.lang.String[] { "Port", "Protocol", "DispatcherAddress", "WorkerAddress", "WorkerTags", "HeartbeatIntervalMs", "DispatcherTimeoutMs", "DataTransferProtocol", "DataTransferPort", "DataTransferAddress", "CrossTrainerCacheSizeBytes", "SnapshotMaxChunkSizeBytes", "ShutdownQuietPeriodMs", }); org.tensorflow.proto.data.DataService.getDescriptor(); } diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/dummy/BfcMemoryMap.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/dummy/BfcMemoryMap.java index 9ddd1a3d74f..38f0ce96ef4 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/dummy/BfcMemoryMap.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/dummy/BfcMemoryMap.java @@ -24,11 +24,11 @@ public static void registerAllExtensions( static { java.lang.String[] descriptorData = { "\n-tensorflow/core/protobuf/bfc_memory_ma" + - "p.proto\022\020tensorflow.dummy\032!tsl/protobuf/" + - "bfc_memory_map.protoBs\n\032org.tensorflow.p" + - "roto.dummyZUgithub.com/tensorflow/tensor" + - "flow/tensorflow/go/core/protobuf/for_cor" + - "e_protos_go_protoP\000b\006proto3" + "p.proto\022\020tensorflow.dummy\032%xla/tsl/proto" + + "buf/bfc_memory_map.protoBs\n\032org.tensorfl" + + "ow.proto.dummyZUgithub.com/tensorflow/te" + + "nsorflow/tensorflow/go/core/protobuf/for" + + "_core_protos_go_protoP\000b\006proto3" }; descriptor = com.google.protobuf.Descriptors.FileDescriptor .internalBuildGeneratedFileFrom(descriptorData, diff --git a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/dummy/TestLog.java b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/dummy/TestLog.java index 7f4925fa6b5..95f0ab4c9c2 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/dummy/TestLog.java +++ b/tensorflow-core/tensorflow-core-native/src/gen/java/org/tensorflow/proto/dummy/TestLog.java @@ -24,9 +24,9 @@ public static void registerAllExtensions( static { java.lang.String[] descriptorData = { "\n#tensorflow/core/util/test_log.proto\022\020t" + - "ensorflow.dummy\032\033tsl/protobuf/test_log.p" + - "rotoB\034\n\032org.tensorflow.proto.dummyP\000b\006pr" + - "oto3" + "ensorflow.dummy\032\037xla/tsl/protobuf/test_l" + + "og.protoB\034\n\032org.tensorflow.proto.dummyP\000" + + "b\006proto3" }; descriptor = com.google.protobuf.Descriptors.FileDescriptor .internalBuildGeneratedFileFrom(descriptorData, diff --git a/tensorflow-core/tensorflow-core-native/src/gen/resources/org/tensorflow/base_api/api_def_AssignVariableXlaConcatND.pbtxt b/tensorflow-core/tensorflow-core-native/src/gen/resources/org/tensorflow/base_api/api_def_AssignVariableXlaConcatND.pbtxt index 646f602af22..6bd6bcd8d05 100644 --- a/tensorflow-core/tensorflow-core-native/src/gen/resources/org/tensorflow/base_api/api_def_AssignVariableXlaConcatND.pbtxt +++ b/tensorflow-core/tensorflow-core-native/src/gen/resources/org/tensorflow/base_api/api_def_AssignVariableXlaConcatND.pbtxt @@ -5,17 +5,13 @@ op { name: "resource" description: <

    Values in {@code arr} outside of the range [0, size) are ignored. * - * @param data type for {@code output} output * @param input 1D or 2D int {@code Tensor}. * @param sizeOutput non-negative int scalar {@code Tensor}. * @param weights is an int32, int64, float32, or float64 {@code Tensor} with the same @@ -900,7 +867,6 @@ public DenseBincount denseBincount(Ope * Computes Psi, the derivative of Lgamma (the log of the absolute value of * {@code Gamma(x)}), element-wise. * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Digamma} output and operands * @return a new instance of Digamma @@ -914,7 +880,6 @@ public Digamma digamma(Operand x) { * NOTE: {@code math.Div} supports broadcasting. More about broadcasting * here * - * @param data type for {@code z} output * @param x The x value * @param y The y value * @param data type for {@code Div} output and operands @@ -929,7 +894,6 @@ public Div div(Operand x, Operand y) { * NOTE: {@code math.DivNoNan} supports broadcasting. More about broadcasting * here * - * @param data type for {@code z} output * @param x The x value * @param y The y value * @param data type for {@code DivNoNan} output and operands @@ -966,7 +930,6 @@ public Equal equal(Operand x, Operand y, Equal.Options.. /** * Computes the Gauss error function of {@code x} element-wise. In statistics, for non-negative values of $x$, the error function has the following interpretation: for a random variable $Y$ that is normally distributed with mean 0 and variance $1/\sqrt{2}$, $erf(x)$ is the probability that $Y$ falls in the range $[−x, x]$. * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Erf} output and operands * @return a new instance of Erf @@ -978,7 +941,6 @@ public Erf erf(Operand x) { /** * Computes the complementary error function of {@code x} element-wise. * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Erfc} output and operands * @return a new instance of Erfc @@ -990,7 +952,6 @@ public Erfc erfc(Operand x) { /** * The Erfinv operation * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Erfinv} output and operands * @return a new instance of erfinv @@ -1023,7 +984,6 @@ public erfinv erfinv(Operand x) { * tf.math.exp(x) ==> 1.4686939399158851+2.2873552871788423j * * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Exp} output and operands * @return a new instance of Exp @@ -1047,7 +1007,6 @@ public Exp exp(Operand x) { * tf.math.expm1(x) ==> (0.46869393991588515+2.2873552871788423j) * * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Expm1} output and operands * @return a new instance of Expm1 @@ -1068,7 +1027,6 @@ public Fact fact() { /** * Returns element-wise largest integer not greater than x. * - * @param data type for {@code y} output * @param x The x value * @param data type for {@code Floor} output and operands * @return a new instance of Floor @@ -1082,7 +1040,6 @@ public Floor floor(Operand x) { * NOTE: {@code math.FloorDiv} supports broadcasting. More about broadcasting * here * - * @param data type for {@code z} output * @param x The x value * @param y The y value * @param data type for {@code FloorDiv} output and operands @@ -1100,7 +1057,6 @@ public FloorDiv floorDiv(Operand x, Operand y) { *