Reputation: 3154
Please consider the following code:
import tensorflow as tf
import numpy as np
with tf.device("gpu:0"):
sess = tf.InteractiveSession()
idx = tf.constant(0)
# 10 iterations
while_condition = lambda i: tf.less(i, tf.constant(10))
acc = tf.Variable(0, dtype=tf.float64)
# the body of the while adds 1 to acc in each iteration
def body_accumulator(i):
mainOp = tf.assign_add(acc, 1.0)
return tf.tuple([tf.add(i, 1)], control_inputs=[mainOp])
whileOp = tf.while_loop(while_condition, body_accumulator, [idx])
# My idea: return acc after evaluating whileOp, whose code modifies acc
def f(dummy):
with tf.control_dependencies([whileOp]):
# with return tf.identity(acc) it works
return acc
def g():
return acc
sess.run(tf.global_variables_initializer())
print('"g: return acc .eval()" - this is the only time where I would expect 0')
print(g().eval())
print('f(dummy)')
print(f(1).eval())
print('whileOp.eval()')
print(whileOp.eval())
print('acc value:')
print(acc.eval())
print('"g: return acc .eval()"')
print(g().eval())
The output is:
"g: return acc .eval()" - this is the only time where I would expect 0
0.0
f(dummy)
0.0
whileOp.eval()
10
acc value:
10.0
"g: return acc .eval()"
10.0
My question is:
why does f(1).eval()
return 0 even if there is a control dependency on the whileOp
that modifies the returned variable acc
?
After reading the documentation, I was expecting whileOp
to be evaluated before returning acc. How should I write the function f(.)
in order to force the evaluation of whileOp
?
In f(.)
, if I return tf.identity(acc)
instead of acc
, it works as I expect.
Upvotes: 1
Views: 506
Reputation: 5206
You're seeing problems because of the weird aliasing model for tensorflow variables. This is why things work with tf.identiy but not without.
If you enable resource variables (use tf.get_variable(..., use_resource=True) to create your variables) you will get the behavior you want.
Upvotes: 1