tf.CriticalSection
| Просмотреть исходный код на GitHub |
Критическая секция.
tf.CriticalSection(
name=None, shared_name=None, critical_section_def=None, import_scope=None
)
Объект CriticalSection — это ресурс в графе, который выполняет подграфы в последовательном порядке. Типичный пример подграфа, который необходимо выполнить исключительно, приведён в следующей функции:
v = resource_variable_ops.ResourceVariable(0.0, name="v")
def count():
value = v.read_value()
with tf.control_dependencies([value]):
with tf.control_dependencies([v.assign_add(1)]):
return tf.identity(value)
Здесь, снимок v захватывается в value; а затем обновляется v. Возвращается значение снимка.
Если несколько рабочих процессов или потоков параллельно выполняют count, нет гарантии, что доступ к переменной v будет атомным в любой момент во время вычисления count в любом потоке. Фактически, даже реализация атомного счётчика, гарантирующего, что пользователь увидит каждое значение 0, 1, ...,, в настоящее время невозможна.
Решение состоит в том, чтобы гарантировать, что любой доступ к базовому ресурсу v обрабатывается только через критическую секцию:
cs = CriticalSection() f1 = cs.execute(count) f2 = cs.execute(count) output = f1 + f2 session.run(output)
Функции f1 и f2 будут выполнены последовательно, а обновления v будут атомными.
ПРИМЕЧАНИЯ
Все объекты ресурсов, включая критическую секцию и любые захваченные переменные функций, выполняемых в этой критической секции, будут размещены на одном устройстве (хост и cpu/gpu).
При использовании нескольких критических секций для одних и тех же ресурсов нет гарантии исключительного доступа к этим ресурсам. Это поведение по умолчанию запрещено (но см. параметр exclusive_resource_access).
Например, выполнение одной и той же функции в двух отдельных критических секциях не гарантирует последовательное выполнение:
v = tf.compat.v1.get_variable("v", initializer=0.0, use_resource=True)
def accumulate(up):
x = v.read_value()
with tf.control_dependencies([x]):
with tf.control_dependencies([v.assign_add(up)]):
return tf.identity(x)
ex1 = CriticalSection().execute(
accumulate, 1.0, exclusive_resource_access=False)
ex2 = CriticalSection().execute(
accumulate, 1.0, exclusive_resource_access=False)
bad_sum = ex1 + ex2
sess.run(v.initializer)
sess.run(bad_sum) # May return 0.0
| Атрибуты | |
|---|---|
name | |
Методы
execute
execute(
fn, exclusive_resource_access=True, name=None
)
Выполнить функцию fn() внутри критической секции.
fn не должно принимать аргументы. Чтобы добавить дополнительные аргументы при вызове fn в критической секции, создайте лямбда-функцию:
critical_section.execute(lambda: fn(*my_args, **my_kwargs))
| Аргументы | |
|---|---|
fn | Функция для выполнения. Должна возвращать как минимум один тензор. |
exclusive_resource_access | Требуется ли для fn исключительный доступ к ресурсам в этой CriticalSection. По умолчанию: True. Вы можете установить это значение в False, если вы будете обращаться к ресурсу только для чтения в двух разных CriticalSection. |
name | Имя для создания операции выполнения. |
| Возвращает | |
|---|---|
Тензоры, возвращённые из fn(). |
| Исключения | |
|---|---|
ValueError | Если fn пытается заблокировать эту CriticalSection любым вложенным или ленивым способом, который может привести к тупиковой ситуации. |
ValueError | Если exclusive_resource_access == True и другая CriticalSection имеют запрос на выполнение, запрашивающий те же ресурсы, что и fn. Note, even ifexclusive_resource_accessisTrue, if another execution in anotherCriticalSectionwas created withoutexclusive_resource_access=True, aValueError` будет поднято. |
© 2020 The TensorFlow Authors. All rights reserved.
Licensed under the Creative Commons Attribution License 3.0.
Code samples licensed under the Apache 2.0 License.
https://www.tensorflow.org/versions/r1.15/api_docs/python/tf/CriticalSection