Значение операции TensorFlow "IsExpensive()"?

В OpKernel есть метод

 // Returns true iff this op kernel is considered "expensive". The
 // runtime may use this flag to optimize graph execution for example
 // to "inline" inexpensive kernels.
 virtual bool IsExpensive() { return expensive_; }

Похоже, что по умолчанию все операции на графическом процессоре считаются недорогими, в то время как CPU, SYSL отмечены как дорогие.

Немного сложно определить определение и эффект expensive. В руководстве нет информации.

  1. Существует ли какое-либо конкретное IsExpensive когда IsExpensive должно быть false, true?
  2. Каков эффект, если операция отмечена как дорогостоящая? До сих пор могу только сказать, что активное профилирование использует это как подсказку? Единственное место, запрашивающее это свойство, находится в планировщике, но не объясняет, что значит быть встроенным.
  3. В сочетании с "1." Должен ли я беспокоиться об этом в моих собственных Ops?
  4. Хотя имеет смысл, что любой AsyncOp (например, RemoteFusedGraphExecuteOp) стоит дорого, MPIAllgatherOp, по-видимому, определяется как не дорогостоящий. Разве это не противоречие?

Я спрашиваю, потому что IdentityOp явно отмечен как недорогой. Интересно, если я должен переопределить этот метод в своих собственных операциях, так как каждая версия ЦП (даже любой пользовательский код) помечена как дорогая.

Вся логика XLA, по-видимому, связана с тем, что инструкция дорогая или нет. Поэтому это может быть важной частью. Следовательно, монетоприемник об истинном/ложном может быть не лучшим способом решить возвращаемое значение в моем обычном операторе.

Ответ 1

Прежде чем отвечать на ваши вопросы, я думаю, стоит попытаться понять, как TensorFlow использует потоки, чтобы выполнить вашу работу. Для этого я предлагаю вам прочитать эту связанную и очень хорошую публикацию SO.

Вы обнаружите, что TensorFlow использует пул потоков, чтобы заставить вас работать. Дорогие Ops планируются к исполнению в пуле потоков, тогда как дешевые Ops исполняются "inline", что означает тот же поток, который планирует задачи (Sidenote: из исходного файла, который вы связали, вы найдете только одно исключение, то есть когда очередь inline_ready пуста, поток может выполнить последнюю дорогостоящую Op самостоятельно).

Имея это в виду, попробуем ответить на ваши вопросы.

  1. Существует ли какое-либо конкретное правило, когда IsExpensive должно быть ложным, правда?

Однако в руководстве TensorFlow я не нашел конкретного руководства, однако из внутренних частей того, что мы обсуждали выше, Op должен быть отмечен как дорогостоящий, когда смещение планирования задачи в пул потоков пренебрежимо по сравнению со временем, когда задача должна быть выполнена.

  1. Каков эффект, если операция отмечена как дорогостоящая? До сих пор могу только сказать, что активное профилирование использует это как подсказку? Единственное место, запрашивающее это свойство, находится в планировщике, но не объясняет, что значит быть встроенным.

Эффект следующий: каждый раз, IsExpensive метод Ops IsExpensive возвращает false он может быть перенесен в очередь inline_ready и может блокировать поток от выполнения дальнейших задач, что останавливает вашу программу. Напротив, если метод Ops IsExpensive возвращает true, он будет запланирован для выполнения в пуле потоков, и поток планирования может продолжать выполнять свои задачи в цикле процесса.

  1. В сочетании с "1." Должен ли я беспокоиться об этом в моих собственных Ops?

Я думаю, вам стоит позаботиться и попытаться как можно больше рассуждать о времени исполнения вами Op. После этого решите, как вы реализуете метод IsExpensive.

  1. Хотя имеет смысл, что любой AsyncOp (например, RemoteFusedGraphExecuteOp) стоит дорого, MPIAllgatherOp, по-видимому, определяется как не дорогостоящий. Разве это не противоречие?

Нет, это не противоречие. Если вы прочтете комментарий MPIAllgatherOp вы найдете следующее:

// Although this op is handled asynchronously, the ComputeAsync call is
// very inexpensive. It only sets up a CollectiveOpRecord and places it
// in the table for the background thread to handle. Thus, we do not need
// a TF pool thread to perform the op.

В чём четко говорится, что планирование этой задачи для пула потоков будет почти только накладными. Поэтому выполнение его inline имеет большой смысл.