aboutsummaryrefslogtreecommitdiffhomepage
path: root/tensorflow/contrib/cudnn_rnn
diff options
context:
space:
mode:
authorGravatar James Qin <jamesqin@google.com>2017-12-24 11:34:41 -0800
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2017-12-24 11:38:22 -0800
commit56da08fed6862422904411a61059b38940a57338 (patch)
tree359af242790db86b03aac7a4333b0883ea969b02 /tensorflow/contrib/cudnn_rnn
parentc975bc2b3fdc9674dd71a7ed89c74ce8ea2d46f0 (diff)
Assign subgraph created by cudnn_rnn saveable to the 1st GPU.
PiperOrigin-RevId: 180053468
Diffstat (limited to 'tensorflow/contrib/cudnn_rnn')
-rw-r--r--tensorflow/contrib/cudnn_rnn/python/kernel_tests/cudnn_rnn_test.py41
-rw-r--r--tensorflow/contrib/cudnn_rnn/python/layers/cudnn_rnn.py35
-rw-r--r--tensorflow/contrib/cudnn_rnn/python/ops/cudnn_rnn_ops.py42
3 files changed, 81 insertions, 37 deletions
diff --git a/tensorflow/contrib/cudnn_rnn/python/kernel_tests/cudnn_rnn_test.py b/tensorflow/contrib/cudnn_rnn/python/kernel_tests/cudnn_rnn_test.py
index e65394cba0..4ddd75de60 100644
--- a/tensorflow/contrib/cudnn_rnn/python/kernel_tests/cudnn_rnn_test.py
+++ b/tensorflow/contrib/cudnn_rnn/python/kernel_tests/cudnn_rnn_test.py
@@ -314,6 +314,47 @@ class CudnnRNNTestBasic(TensorFlowTestCase):
self.assertEqual(0, total_sum2_v)
self.assertEqual(0, total_sum3_v)
+ def testSaveableGraphDeviceAssignment(self):
+ num_layers = 4
+ num_units = 2
+ batch_size = 8
+ direction = CUDNN_RNN_UNIDIRECTION
+ dir_count = 1
+
+ def DeviceFn(op):
+ if op.type in ("Variable", "VariableV2"):
+ return "/cpu:0"
+ else:
+ return "/gpu:0"
+
+ with ops.Graph().as_default() as g:
+ with ops.device(DeviceFn):
+ with vs.variable_scope("main"):
+ kernel_initializer = init_ops.constant_initializer(3.14)
+ bias_initializer = init_ops.constant_initializer(1.59)
+ inputs = random_ops.random_uniform(
+ [num_layers * dir_count, batch_size, num_units],
+ dtype=dtypes.float32)
+
+ lstm = cudnn_rnn.CudnnLSTM(num_layers, num_units,
+ direction=direction,
+ kernel_initializer=kernel_initializer,
+ bias_initializer=bias_initializer,
+ name="awesome_lstm")
+ outputs = lstm(inputs)
+
+ # saver is created in the scope of DeviceFn.
+ saver = saver_lib.Saver()
+
+ with self.test_session(use_gpu=True, graph=g) as sess:
+ save_path = os.path.join(self.get_temp_dir(),
+ "test-saveable-device-assignment")
+ sess.run(variables.global_variables_initializer())
+
+ saver.save(sess, save_path)
+ saver.restore(sess, save_path)
+ sess.run(outputs)
+
# TODO(jamesqin): Transform to parameterized test after it is included in the
# TF open source codebase.
diff --git a/tensorflow/contrib/cudnn_rnn/python/layers/cudnn_rnn.py b/tensorflow/contrib/cudnn_rnn/python/layers/cudnn_rnn.py
index 37c61a71a3..3a21914041 100644
--- a/tensorflow/contrib/cudnn_rnn/python/layers/cudnn_rnn.py
+++ b/tensorflow/contrib/cudnn_rnn/python/layers/cudnn_rnn.py
@@ -450,17 +450,18 @@ class _CudnnRNN(base_layer.Layer):
raise RuntimeError(
"%s._canonical_to_opaque invoked before input shape is known" %
type(self).__name__)
- return cudnn_rnn_ops.cudnn_rnn_canonical_to_opaque_params(
- rnn_mode=self._rnn_mode,
- num_layers=self._num_layers,
- num_units=self._num_units,
- input_size=self._input_size,
- weights=cu_weights,
- biases=cu_biases,
- input_mode=self._input_mode,
- seed=self._seed,
- dropout=self._dropout,
- direction=self._direction)
+ with ops.device("/gpu:0"):
+ return cudnn_rnn_ops.cudnn_rnn_canonical_to_opaque_params(
+ rnn_mode=self._rnn_mode,
+ num_layers=self._num_layers,
+ num_units=self._num_units,
+ input_size=self._input_size,
+ weights=cu_weights,
+ biases=cu_biases,
+ input_mode=self._input_mode,
+ seed=self._seed,
+ dropout=self._dropout,
+ direction=self._direction)
def _forward(self, inputs, h, c, opaque_params, training):
output, output_h, output_c = cudnn_rnn_ops._cudnn_rnn( # pylint:disable=protected-access
@@ -489,12 +490,12 @@ class _CudnnRNN(base_layer.Layer):
if self._saveable is not None:
raise RuntimeError("Cudnn saveable already created.")
self._saveable = self._saveable_cls( # pylint:disable=not-callable
- self.trainable_variables[0],
- self.num_layers,
- self.num_units,
- self.input_size,
- self.input_mode,
- self.direction,
+ opaque_params=self.trainable_variables[0],
+ num_layers=self.num_layers,
+ num_units=self.num_units,
+ input_size=self.input_size,
+ input_mode=self.input_mode,
+ direction=self.direction,
scope=vs.get_variable_scope(),
name="%s_saveable" % self.trainable_variables[0].op.name)
ops.add_to_collection(ops.GraphKeys.SAVEABLE_OBJECTS, self._saveable)
diff --git a/tensorflow/contrib/cudnn_rnn/python/ops/cudnn_rnn_ops.py b/tensorflow/contrib/cudnn_rnn/python/ops/cudnn_rnn_ops.py
index dcd3d4732a..45a3674bed 100644
--- a/tensorflow/contrib/cudnn_rnn/python/ops/cudnn_rnn_ops.py
+++ b/tensorflow/contrib/cudnn_rnn/python/ops/cudnn_rnn_ops.py
@@ -72,7 +72,7 @@ class CudnnCompatibleLSTMCell(lstm_ops.LSTMBlockCell):
def __init__(self, num_units, reuse=None):
super(CudnnCompatibleLSTMCell, self).__init__(
num_units, forget_bias=0, cell_clip=None, use_peephole=False,
- reuse=reuse)
+ reuse=reuse, name="cudnn_compatible_lstm_cell")
self._names.update({"scope": "cudnn_compatible_lstm_cell"})
@@ -303,16 +303,17 @@ class CudnnOpaqueParamsSaveable(saver.BaseSaverBuilder.SaveableObject):
Returns:
2 list for weights and biases respectively.
"""
- weights, biases = gen_cudnn_rnn_ops.cudnn_rnn_params_to_canonical(
- num_layers=self._num_layers,
- num_units=self._num_units,
- input_size=self._input_size,
- params=self._variables,
- num_params=self._num_params,
- rnn_mode=self._rnn_mode,
- input_mode=self._input_mode,
- direction=self._direction)
- return (weights, biases)
+ with ops.device("/gpu:0"):
+ weights, biases = gen_cudnn_rnn_ops.cudnn_rnn_params_to_canonical(
+ num_layers=self._num_layers,
+ num_units=self._num_units,
+ input_size=self._input_size,
+ params=self._variables,
+ num_params=self._num_params,
+ rnn_mode=self._rnn_mode,
+ input_mode=self._input_mode,
+ direction=self._direction)
+ return (weights, biases)
def _CanonicalToOpaqueParams(self, cu_weights, cu_biases):
"""Converts from Cudnn canonical format to opaque params.
@@ -323,15 +324,16 @@ class CudnnOpaqueParamsSaveable(saver.BaseSaverBuilder.SaveableObject):
Returns:
a single opaque tensor.
"""
- return gen_cudnn_rnn_ops.cudnn_rnn_canonical_to_params(
- num_layers=self._num_layers,
- num_units=self._num_units,
- input_size=self._input_size,
- weights=cu_weights,
- biases=cu_biases,
- rnn_mode=self._rnn_mode,
- input_mode=self._input_mode,
- direction=self._direction)
+ with ops.device("/gpu:0"):
+ return gen_cudnn_rnn_ops.cudnn_rnn_canonical_to_params(
+ num_layers=self._num_layers,
+ num_units=self._num_units,
+ input_size=self._input_size,
+ weights=cu_weights,
+ biases=cu_biases,
+ rnn_mode=self._rnn_mode,
+ input_mode=self._input_mode,
+ direction=self._direction)
def _TransformCanonical(self, cu_weights, cu_biases):
r"""Transform from Cudnn canonical to tf canonical.