Skip to content

Commit

Permalink
Fix shape documentation for tf.gather_nd and tf.scatter_nd
Browse files Browse the repository at this point in the history
The new version of the shape documentation for both ops is hopefully correct and doesn't introduce temporary variables.  Additionally, tf.scatter_nd warns about nondeterministic behavior if indices contains duplicates.

Fixes #8245.  Fixes #8102.
Change: 154581230
  • Loading branch information
girving authored and tensorflower-gardener committed Apr 28, 2017
1 parent bdd03de commit 8352c05
Showing 1 changed file with 32 additions and 39 deletions.
71 changes: 32 additions & 39 deletions tensorflow/core/ops/array_ops.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1396,20 +1396,17 @@ REGISTER_OP("GatherNd")
.Doc(R"doc(
Gather values or slices from `params` according to `indices`.
`params` is a Tensor of rank `P` and `indices` is a Tensor of rank `Q`.
`indices` is an integer tensor containing indices into `params`. The last
dimension of `indices` can be at most the rank of `params`:
`indices` must be integer tensor, containing indices into `params`.
It must be shape `[d_0, ..., d_{Q-2}, K]` where `0 < K <= P`.
indices.shape[-1] <= params.rank
The innermost dimension of `indices` (with length `K`) corresponds to
indices into elements (if `K = P`) or slices (if `K < P`) along the `K`th
dimension of `params`.
The last dimension of `indices` corresponds to elements
(if `indices.shape[-1] = params.rank`) or slices
(if `indices.shape[-1] < params.rank`) along dimension `indices.shape[-1]`
of `params`. The output tensor has shape
Produces an output tensor with shape
```
[d_0, ..., d_{Q-2}, params.shape[K], ..., params.shape[P-1]].
```
indices.shape[:-1] + params.shape[indices.shape[-1]:]
Some examples below.
Expand Down Expand Up @@ -1488,10 +1485,10 @@ Batched indexing into a 3-tensor:
output = [['b0', 'b1'], ['d0', 'c1']]
```
params: `P-D`. The tensor from which to gather values.
indices: `Q-D`. Index tensor having shape `[d_0, ..., d_{Q-2}, K]`.
output: `(P+Q-K-1)-D`. Values from `params` gathered from indices given by
`indices`.
params: The tensor from which to gather values.
indices: Index tensor.
output: Values from `params` gathered from indices given by `indices`, with
shape `indices.shape[:-1] + params.shape[indices.shape[-1]:]`.
)doc");

// --------------------------------------------------------------------------
Expand Down Expand Up @@ -4750,30 +4747,28 @@ REGISTER_OP("ScatterNd")
.Attr("T: type")
.Attr("Tindices: {int32, int64}")
.SetShapeFn(ScatterNdShape)
.Doc(
R"doc(Creates a new tensor by applying sparse `updates` to individual
values or slices within a zero tensor of the given `shape` tensor according to
.Doc(R"doc(
Scatter `updates` into a new (initially zero) tensor according to `indices`.
Creates a new tensor by applying sparse `updates` to individual
values or slices within a zero tensor of the given `shape` according to
indices. This operator is the inverse of the [tf.gather_nd](#gather_nd)
operator which extracts values or slices from a given tensor.
TODO(simister): Add a link to Variable.__getitem__ documentation on slice
syntax.
`shape` is a `TensorShape` with rank `P` and `indices` is a `Tensor` of rank
`Q`.
**WARNING**: The order in which updates are applied is nondeterministic, so the
output will be nondeterministic if `indices` contains duplicates.
`indices` must be integer tensor, containing indices into `shape`.
It must be shape `[d_0, ..., d_{Q-2}, K]` where `0 < K <= P`.
`indices` is an integer tensor containing indices into a new tensor of shape
`shape`. The last dimension of `indices` can be at most the rank of `shape`:
The innermost dimension of `indices` (with length `K`) corresponds to
indices into elements (if `K = P`) or slices (if `K < P`) along the `K`th
dimension of `shape`.
indices.shape[-1] <= shape.rank
`updates` is Tensor of rank `Q-1+P-K` with shape:
The last dimension of `indices` corresponds to indices into elements
(if `indices.shape[-1] = shape.rank`) or slices
(if `indices.shape[-1] < shape.rank`) along dimension `indices.shape[-1]` of
`shape`. `updates` is a tensor with shape
```
[d_0, ..., d_{Q-2}, shape[K], ..., shape[P-1]].
```
indices.shape[:-1] + shape[indices.shape[-1]:]
The simplest form of scatter is to insert individual elements in a tensor by
index. For example, say we want to insert 4 scattered elements in a rank-1
Expand All @@ -4791,7 +4786,7 @@ In Python, this scatter operation would look like this:
shape = tf.constant([8])
scatter = tf.scatter_nd(indices, updates, shape)
with tf.Session() as sess:
print sess.run(scatter)
print(sess.run(scatter))
```
The resulting tensor would look like this:
Expand All @@ -4817,7 +4812,7 @@ In Python, this scatter operation would look like this:
shape = tf.constant([4, 4, 4])
scatter = tf.scatter_nd(indices, updates, shape)
with tf.Session() as sess:
print sess.run(scatter)
print(sess.run(scatter))
```
The resulting tensor would look like this:
Expand All @@ -4827,11 +4822,9 @@ The resulting tensor would look like this:
[[5, 5, 5, 5], [6, 6, 6, 6], [7, 7, 7, 7], [8, 8, 8, 8]],
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]]
indices: A Tensor. Must be one of the following types: int32, int64.
A tensor of indices into ref.
updates: A Tensor. Must have the same type as tensor. A tensor of updated values
to store in ref.
shape: A vector. The shape of the resulting tensor.
indices: Index tensor.
updates: Updates to scatter into output.
shape: 1-D. The shape of the resulting tensor.
output: A new tensor with the given shape and updates applied according
to the indices.
)doc");
Expand Down

0 comments on commit 8352c05

Please sign in to comment.