tf.КритическаяСекция
| Просмотреть исходный код на 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 , если вы будете обращаться к ресурсу только для чтения в двух разных CriticalSections. |
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` будет поднято. |
© 2022 The TensorFlow Authors. All rights reserved.
Licensed under the Creative Commons Attribution License 4.0.
Code samples licensed under the Apache 2.0 License.
https://www.tensorflow.org/versions/r2.9/api_docs/python/tf/CriticalSection