Skip to content
This repository was archived by the owner on Jul 10, 2025. It is now read-only.

Commit 9139c90

Browse files
author
ematejska
authored
Merge pull request #404 from bgdax/patch-1
TensorShape Evaluation to Bool
2 parents 4d1df1c + feb85e6 commit 9139c90

File tree

1 file changed

+108
-0
lines changed

1 file changed

+108
-0
lines changed

rfcs/20211116-tensorshape-bool.md

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# TensorShape Evaluation to Bool
2+
3+
| Status | Proposed |
4+
:-------------- |:---------------------------------------------------- |
5+
| **RFC #** | [404](https://github.com/tensorflow/community/pull/404) |
6+
| **Author(s)** | Bogdan Alexe (Google), Yu Feng (Google) |
7+
| **Sponsor** | Rohan Jain (Google) |
8+
| **Updated** | 2021-11-16 |
9+
10+
## Objective
11+
12+
Fix inconsistencies in `TensorShape` evaluation to `bool`.
13+
14+
## Motivation
15+
In the current state, a `TensorShape` object evaluates to `True` if the list of dimensions is not `None`, i.e. if the tensor shape is not unspecified.
16+
This is inconsistent with the `numpy` behavior on shapes, as well as with how the list of dimensions in `TensorShape` is evaluated to `bool`.
17+
18+
Moreover, the current behavior has inconsistencies between eager and graph execution modes. A non-scalar tensor with dynamic rank may have a shape that is:
19+
- specified in eager mode, and evaluate to True
20+
- unspecified in graph mode, and evaluate to False, which is not intuitive and can be confusing.
21+
22+
Example:
23+
```
24+
def fun():
25+
n = tf.random.poisson((1,), 3, dtype=tf.int32)
26+
s = tf.random.poisson(n, 9, dtype=tf.int32)
27+
a = tf.ones(s)
28+
return bool(a.shape)
29+
30+
fun() ## True
31+
tf.function(fun)() ## False
32+
```
33+
34+
This change will disallow the evaluation to `bool` on the unspecified shape resulting in the graph execution.
35+
36+
## Design Proposal
37+
38+
With the proposed change, a `TensorShape` will:
39+
- evaluate to `True` if the shape is specified and non-scalar, i.e. if the list of dimensions is not empty
40+
- evaluate to `False` if the shape is specified and represents a scalar, i.e. if the list of dimensions is empty
41+
- raise an error (`ValueError`) if the shape is unspecified, i.e. if the list of dimensions is undefined.
42+
43+
This will:
44+
- align the `TensorShape` behavior with `numpy`, as well as with the `bool` evaluation on the list of dimensions in the `TensorShape`.
45+
- explicitly fail by raising errors when conversions to `bool` are attempted on unknown shapes in graph execution mode. (see example above)
46+
47+
An evaluation to `bool` will only succeed on shapes that are specified, and will distinguish between scalar/non-scalar shapes.
48+
49+
| `TensorShape._dims` | Current result | Result after change |
50+
| --- | --- | --- |
51+
| `None` | `False` | Raise `ValueError` |
52+
| `[ ]` (empty list, denotes a scalar) | `True` | `False` |
53+
| `[n1, n2, …]` (non-empty list) | `True` | `True` |
54+
55+
### Performance Implications
56+
* No performance impact is expected, to be confirmed via benchmark results.
57+
58+
### Dependencies
59+
* No new dependencies added.
60+
* This will break users that rely on the existing behavior.
61+
62+
### Engineering Impact
63+
* No expected meaningful changes to binary size / startup time / build time / test times.
64+
65+
### Platforms and Environments
66+
* No expected impact in ability to run on any platform or environment.
67+
68+
### Tutorials and Examples
69+
Users who rely on evaluating a `TensorShape` to a `bool` to check if it has a known number of dimensions will have to change.
70+
71+
**Example 1:**
72+
73+
Before:
74+
```
75+
if foo.shape:
76+
bar()
77+
```
78+
After:
79+
```
80+
if foo.shape.rank is not None:
81+
bar()
82+
```
83+
84+
**Example 2:**
85+
86+
Before:
87+
```
88+
def foo(bar, shape = None):
89+
if shape:
90+
baz()
91+
```
92+
After:
93+
```
94+
def foo(bar, shape = None):
95+
if shape is not None and
96+
shape.rank is not None:
97+
baz()
98+
```
99+
100+
### Compatibility
101+
* This is a breaking change: see rollout below.
102+
* Interactions with other parts of the TensorFlow Ecosystem: no expected impact.
103+
104+
### User Impact
105+
* Existing usage that relies on the current behavior of `TensorShape` evaluation to `bool` will be broken.
106+
* Rollout:
107+
* Add warning in `TensorShape.__bool__` that behavior is changing in the next release.
108+
* In the following release, switch behavior in `TensorShape.__bool__`

0 commit comments

Comments
 (0)