1# Copyright 2016 The TensorFlow Authors. All Rights Reserved. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14# ============================================================================== 15 16 17"""Utilities for using generic resources.""" 18# pylint: disable=g-bad-name 19import collections 20import os 21 22from tensorflow.python.framework import dtypes 23from tensorflow.python.framework import ops 24from tensorflow.python.ops import array_ops 25from tensorflow.python.ops import control_flow_ops 26from tensorflow.python.ops import math_ops 27from tensorflow.python.util import tf_should_use 28 29 30_Resource = collections.namedtuple("_Resource", 31 ["handle", "create", "is_initialized"]) 32 33 34def register_resource(handle, create_op, is_initialized_op, is_shared=True): 35 """Registers a resource into the appropriate collections. 36 37 This makes the resource findable in either the shared or local resources 38 collection. 39 40 Args: 41 handle: op which returns a handle for the resource. 42 create_op: op which initializes the resource. 43 is_initialized_op: op which returns a scalar boolean tensor of whether 44 the resource has been initialized. 45 is_shared: if True, the resource gets added to the shared resource 46 collection; otherwise it gets added to the local resource collection. 47 48 """ 49 resource = _Resource(handle, create_op, is_initialized_op) 50 if is_shared: 51 ops.add_to_collection(ops.GraphKeys.RESOURCES, resource) 52 else: 53 ops.add_to_collection(ops.GraphKeys.LOCAL_RESOURCES, resource) 54 55 56def shared_resources(): 57 """Returns resources visible to all tasks in the cluster.""" 58 return ops.get_collection(ops.GraphKeys.RESOURCES) 59 60 61def local_resources(): 62 """Returns resources intended to be local to this session.""" 63 return ops.get_collection(ops.GraphKeys.LOCAL_RESOURCES) 64 65 66def report_uninitialized_resources(resource_list=None, 67 name="report_uninitialized_resources"): 68 """Returns the names of all uninitialized resources in resource_list. 69 70 If the returned tensor is empty then all resources have been initialized. 71 72 Args: 73 resource_list: resources to check. If None, will use shared_resources() + 74 local_resources(). 75 name: name for the resource-checking op. 76 77 Returns: 78 Tensor containing names of the handles of all resources which have not 79 yet been initialized. 80 81 """ 82 if resource_list is None: 83 resource_list = shared_resources() + local_resources() 84 with ops.name_scope(name): 85 # Run all operations on CPU 86 local_device = os.environ.get( 87 "TF_DEVICE_FOR_UNINITIALIZED_VARIABLE_REPORTING", "/cpu:0") 88 with ops.device(local_device): 89 if not resource_list: 90 # Return an empty tensor so we only need to check for returned tensor 91 # size being 0 as an indication of model ready. 92 return array_ops.constant([], dtype=dtypes.string) 93 # Get a 1-D boolean tensor listing whether each resource is initialized. 94 variables_mask = math_ops.logical_not( 95 array_ops.stack([r.is_initialized for r in resource_list])) 96 # Get a 1-D string tensor containing all the resource names. 97 variable_names_tensor = array_ops.constant( 98 [s.handle.name for s in resource_list]) 99 # Return a 1-D tensor containing all the names of uninitialized resources. 100 return array_ops.boolean_mask(variable_names_tensor, variables_mask) 101 102 103@tf_should_use.should_use_result 104def initialize_resources(resource_list, name="init"): 105 """Initializes the resources in the given list. 106 107 Args: 108 resource_list: list of resources to initialize. 109 name: name of the initialization op. 110 111 Returns: 112 op responsible for initializing all resources. 113 """ 114 if resource_list: 115 return control_flow_ops.group(*[r.create for r in resource_list], name=name) 116 return control_flow_ops.no_op(name=name) 117