From f1ce513693d188481e9f4184f7901225a87a5be5 Mon Sep 17 00:00:00 2001 From: annarev Date: Tue, 7 Jul 2020 02:09:41 +0000 Subject: [PATCH 01/29] Initial commit for TFRT Kernel Fallback RFC Formatting fixes Formatting fixes and removed option 2 for C API Fixed top table Adjusted some of the wording Changed kernel fallback RFC name, updated selective registration section Fix links to cs.opensource.google --- rfcs/20200712-tfrt-kernel-fallback.md | 641 ++++++++++++++++++++++++++ 1 file changed, 641 insertions(+) create mode 100644 rfcs/20200712-tfrt-kernel-fallback.md diff --git a/rfcs/20200712-tfrt-kernel-fallback.md b/rfcs/20200712-tfrt-kernel-fallback.md new file mode 100644 index 000000000..6c5e1328f --- /dev/null +++ b/rfcs/20200712-tfrt-kernel-fallback.md @@ -0,0 +1,641 @@ +# Title of RFC + +| Status | (Proposed / Accepted / Implemented / Obsolete) | +| :------------ | :------------------------------------------------------ | +| **RFC #** | [NNN](https://github.com/tensorflow/community/pull/NNN) | +| **Author(s)** | Anna Revinskaya (annarev@google.com), Jeremy Lau | +: : (lauj@google.com) : +| **Sponsor** | Jeremy Lau (lauj@google.com) | +| **Updated** | 2020-07-06 | + +## Objective + +This proposal focuses on getting majority of “well-behaved” ops running in +[TF Lite](https://www.tensorflow.org/lite) by skipping current eager runtime and +calling kernels directly in [TFRT](https://github.com/tensorflow/runtime) (a new +TensorFlow runtime). + +Note that there is an effort to call existing kernels by delegating to +TensorFlow eager runtime instead. This approach is called Runtime Fallback and +corresponding RFC will be published soon. The goals of the two fallback +mechanisms are as follows: + +* Runtime Fallback aims to reuse all current TensorFlow kernels in TFRT. +* Kernel Fallback (focus of this document) aims to get a large number of + existing kernels working in TFRT while reducing binary size to support + mobile devices. + +## Goals + +High level goals of the project: + +* Call existing kernels from new TensorFlow runtime +* Reduce size and overhead to make this a feasible option for mobile + +We address the first goal by implementing a new fallback mechanism that directly +calls TensorFlow kernels without going through Eager runtime first. We plan to +address the second high level goal by trimming down dependencies, switching to +more compact proto representation, etc.. + +### Op Coverage Goals + +First of all, we plan to target all the easier-to-support ops that don’t require +implementing extensive pieces of infrastructure, but at the same time provide +the most value to the TF Lite team. + +We analysed how many kernels we can support in the future and include our +findings in the following spreadsheets. As we describe in +[Design Proposal](#design-proposal) below, Kernel Fallback depends on +customizing +[OpKernelConstruction](https://cs.opensource.google/tensorflow/tensorflow/+/master:tensorflow/core/framework/op_kernel.h;l=256?q=OpKernelConstruction) +and +[OpKernelContext](https://cs.opensource.google/tensorflow/tensorflow/+/master:tensorflow/core/framework/op_kernel.h;l=584?q=OpKernelContext&ss=tensorflow%2Ftensorflow) +classes. Number of supported kernels will depend on the surface we manage to +customize. (Note that I have already started prototyping the implementation that +includes a few common methods such as `input`, `output`. The spreadsheet below +consideres these methods to be already *supported*). + +* List of kernels and `OpKernelConstruction`/`OpKernelContext` methods they + require: + [spreadsheet](https://docs.google.com/spreadsheets/d/18bOu2gJQnZtCRGPZ4yerEAKUHgp1V429dPdCuzoCSkU/edit?usp=sharing) +* Proposed implementation order for these methods: + [spreadsheet](https://docs.google.com/spreadsheets/d/10u6tcTE9PAi45A04nxSz61whSnwhscRLlSUNRPJugIY/edit?usp=sharing) + +Based on these estimates, we can support >= 423 kernels. Note that this number +is just based on the `OpKernelConstruction`/`OpKernelContext` coverage that we +can provide. It doesn't take into consideration other issues we might face. + +### TFRT Integration Goals + +We want to support executing a [BEF](https://github.com/tensorflow/runtime) file +on mobile device that calls kernels using Kernel Fallback mechanism. Users will +be able to generate a BEF file based on a saved model and we will provide a +script to create it. + +We might also want to support running ops using TFRT eager mode (that is, add a +custom +[OpHandler](https://github.com/tensorflow/runtime/blob/3c7a1ea02c87325f1b47aebb24b3ca6e84e7e7e7/include/tfrt/core_runtime/op_handler.h#L47)). + +## Non-goals + +* Supporting all existing ops. `OpKernelContext` surface is quite large and + implementing all of it would require a significant amount of time. Instead, + we will start by adding most common and easy functionality. If certain + functionality is only used by a handful of kernels, it might make sense to + implement TFRT native kernels instead. One notable example is + [ResourceMgr](https://cs.opensource.google/tensorflow/tensorflow/+/master:tensorflow/core/framework/resource_mgr.h;l=152?q=ResourceMgr). + We might support it later, but it is definitely not first priority due to + extra effort required. +* Gradients would not be supported by the first iteration of Kernel Fallback, + but we might revisit it later. +* Exact details of TFRT integration are still being worked out by TFRT and TF + Lite teams. Since these teams might change the plan, exact details are not a + part of this doc. The take away is that we will integrate kernel fallback + following the approach they decide on. + +## Motivation + +Currently, [TF Lite](https://www.tensorflow.org/lite) supports a +[limited set of ops](https://www.tensorflow.org/lite/guide/ops_compatibility). +As the range and variety of applications grows, it becomes essential to grow the +pool of available ops as well, ideally supporting everything that fully-fledged +TensorFlow supports now. + +However, supporting TensorFlow ops on mobile devices presents some challenges. +Specifically, binary size on mobile platforms should be restricted. TF Lite team +provided us with the following *ideal* numbers: + +* 100-200k overhead to call TF kernels +* 20k / kernel marginal size + +To get closer to the size restrictions we plan to define a call path from TFRT +to TensorFlow kernels that minimizes the amount of generated code. + +## User Benefit + +Running more kernels on mobile devices would allow TensorFlow users to implement +a wider range of models. + +## Design Proposal + +We propose to call the kernel’s Compute method directly from +[TFRT](https://github.com/tensorflow/runtime) without going through TensorFlow +Eager C API first. + +We introduce kernel context and registration implementation that support core +kernel functionality with minimal dependencies. + +## Kernel registration + +We will use a separate registry for kernels supported by TFRT forwarding. To do +so, we will define a `TFRTOpKernelFactories` class that would keep a map from +kernel name to a list of registrations. + +```cpp +class TFRTOpKernelFactories { + public: + TFRTOpKernelFactories(); + void RegisterFactory(StringPiece kernel_class_name, + TFRTOpKernelReg kernel_info); + + // Creates a kernel with the given name and passes op_kernel_construction + // to kernel constructor. + // Returns the constructed kernel on success. + // In case of failure, returns a nullptr. Kernel creation can fail in one + // of the following cases: + // 1. Kernel with the given name is not found. + // 2. Attributes in op_kernel_construction don't match type constraints + // for any of the kernels with this name. + // Note that we consider a constraint to be "not matched" if attribute + // it applies to is not in op_kernel_construction. + std::unique_ptr CreateKernel( + StringPiece kernel_class_name, + TFRTOpKernelConstruction* op_kernel_construction) const; + + private: + llvm::StringMap> factories_; +}; + +extern llvm::ManagedStatic + tfrt_forwarding_kernel_factories; +``` + +Similar to current TensorFlow kernel registartion, we will introduce a +registration macro that adds a kernel to `TFRTOpKernelFactories`. + +```cpp +#define REGISTER_KERNEL_FALLBACK_KERNEL(name, ...) \ + REGISTER_KERNEL_FALLBACK_KERNEL_UNIQ_HELPER(__COUNTER__, name, __VA_ARGS__) + +#define REGISTER_KERNEL_FALLBACK_KERNEL_UNIQ_HELPER(ctr, name, ...) \ + REGISTER_KERNEL_FALLBACK_KERNEL_UNIQ(ctr, name, __VA_ARGS__) + +#define REGISTER_KERNEL_FALLBACK_KERNEL_UNIQ(ctr, name, ...) \ + static bool global_tfrt_forwarding_kernel_##ctr##_registered_ = []() { \ + ::tensorflow::tfrt_forwarding_kernel_factories->RegisterFactory( \ + name, TFRTOpKernelReg([](TFRTOpKernelConstruction* construction) \ + -> std::unique_ptr { \ + return std::make_unique<__VA_ARGS__>(construction); \ + })); \ + return true; \ + }(); +``` + +## Op registration + +To support type specification, we will also provide a minimal Op registry and +corresponding macro `REGISTER_KERNEL_FALLBACK_OP`. + +## Kernel implementation + +TensorFlow kernels inherit from the +[OpKernel](https://cs.opensource.google/tensorflow/tensorflow/+/master:tensorflow/core/framework/op_kernel.h;l=82?q=opkernel) +class and depend on two key classes: +[OpKernelConstruction](https://cs.opensource.google/tensorflow/tensorflow/+/master:tensorflow/core/framework/op_kernel.h;l=256?q=opkernel) +and +[OpKernelContext](https://cs.opensource.google/tensorflow/tensorflow/+/master:tensorflow/core/framework/op_kernel.h;l=584?q=opkernel). +We want to provide custom implementations of these two classes in terms of data +we get from TFRT (for e.g. inputs, attributes). + +There are two main approaches to customize class implementations: + +* Use inheritance and define common interfaces. +* Use templates. + +We ran multiple benchmarks to get an idea of the trade offs between inheritance +and templating approaches. Key findings are summarized below: + +* Time difference negligible for full model benchmarks. +* A simple scalar op benchmark with Kernel Fallback (runs scalar + multiplication, division, addition) was only 0.3% slower on mobile with + inheritance compared to templates. +* [basic\_ops\_benchmark](https://cs.opensource.google/tensorflow/tensorflow/+/master:tensorflow/core/kernels/basic_ops_benchmark_test.cc?q=basic_ops_benchmark_test) + with inheritance is significantly slower: ~7% (median) or ~19% (mean) + (running on Linux). Note that this difference was measured *without* Kernel + Fallback. Adding inheritance would impact all existing TensorFlow kernels + even those that don't support Kernel Fallback. +* Binary size increase when using templates compared to inheritance is + estimated at 2.6% (based on adding `AddN` op). + +Right now, we are leaning towards using inheritance. Seems like time increase is +only significant for running many scalar ops in a sequence - probably a rare use +case in the real world. + +To use inheritance, we will define `OpKernelConstructionInterface` and +`OpKernelContextInterface` interfaces. Ideally, these interfaces should be pure +virtual. However, we will have one exception - templated `eigen_device` method +that calls per-device pure-virtual implementations. + +We will then introduce `TFRTOpKernelConstruction` and `TFRTOpKernelContext` +subclasses that implement `OpKernelConstructionInterface` and +`OpKernelContextInterface` in terms of TFRT data structures. Example how +`TFRTOpKernelConstruction` might look like: + +```cpp +class TFRTOpKernelConstruction : public OpKernelConstructionInterface { + public: + explicit TFRTOpKernelConstruction(AttrMap attributes); + ~TFRTOpKernelConstruction() override {}; + + Status GetAttr(StringPiece attr_name, int32* value) const override; + Status GetAttr(StringPiece attr_name, DataType* value) const override; + + void CtxFailure(const Status& s); + void CtxFailureWithWarning(const Status& s); + void CtxFailure(const char* file, int line, const Status& s); + void CtxFailureWithWarning(const char* file, int line, const Status& s); + ... +}; +``` + +When forwarding, we instantiate the kernel interfaces with TFRT’s lightweight +OpKernel definitions, rather than TensorFlow’s +[heavyweight OpKernel definitions](https://cs.opensource.google/android/platform/superproject/+/master:external/tensorflow/tensorflow/core/framework/op_kernel.h;l=612?q=opkernelcontext) +for example. + +Example `AddN` kernel implementation using these new interfaces: + +```cpp +class AddNOp : public OpKernelBase { + public: + explicit AddNOp(OpKernelConstructionInterface* construction) : + OpKernelBase(construction) {} + + void Compute(OpKernelContextInterface* ctx) override { + if(!ctx->ValidateInputsAreSameShape(this)) return; + ... +``` + +Here, `OpKernelBase` implementation will be minimal: + +```cpp +class OpKernelBase { + public: + explicit OpKernelBase(OpKernelConstructionInterface* context) { + } + virtual ~OpKernelBase() {} + virtual void Compute(OpKernelContextInterface* context) = 0; +}; +``` + +(For details how extending from `OpKernelBase` instead of `OpKernel` would work +with current TensorFlow runtime see [Appendix 1](#appendix-1)) + +Corresponding .cc file then registers the kernel using the correct kernel and +context classes. For example, this is how we register `AddN` kernel with TFRT: + +```cpp +REGISTER_KERNEL_FALLBACK_KERNEL( "AddN", AddNOp); +``` + +## Calling kernel + +We add a new TFRT BEF kernel called `tfd.kernel_fallback`. This kernel directly +calls a TF kernel’s `Compute` method by creating `TFRTOpKernel*` data structures +that forward to corresponding TFRT concepts. For example, the following code +accesses an input in `llvm::ArrayRef>` which +we get from TFRT: + +```cpp +const Tensor& TFRTOpKernelContext::input(int index) { + return inputs_[index]->get(); +} +``` + +Simplified definition of `tfd.kernel_fallback`: + +```cpp +// Instantiate a kernel. This would be a TensorFlow kernel converted to inherit +// from `OpKernelBase` instead of `OpKernel`. +std::unique_ptr op = …; + +// Create TFRTOpKernelContext. The variable exec_ctx here is the tfrt::ExecutionContext passed to the kernel handler. +TFRTOpKernelContext op_kernel_context(inputs, outputs.size(), op_meta, exec_ctx.host()); + +// Directly invoke the TF kernel's Compute() method. +op->Compute(&op_kernel_context); +``` + +## tfd.kernel\_fallback call structure + +We will be using the following conventions (essentially, these are based on +Runtime Fallback work that will probably have RFC coming soon): + +* Attributes are passed as key-value pairs, where both key and value are + represented as strings. +* Types have a specific string representation. We are trying to use names + consistent with BEF syntax as much as possible (for e.g. `f32` represents + `float`). +* Inputs and outputs have type `tensorflow::Tensor`. We will provide BEF + kernels to construct these from BEF data (for e.g. constant values). + +Example of invoking Conv3D kernel: + +``` +%tft_c = "tfd.kernel_fallback"(%tft_a, %tft_b) { + _op_name = "Conv3D", attr1_name="data_format", + attr1_value="string$NDHWC", attr2_name="strides", + attr2_value="list(i32)$1,1,1,1,1", attr3_name="dilations", + attr3_value="list(i32)$1,1,1,1,1", attr4_name="padding", + attr4_value="padding$SAME"}: (!tfd.tensor, !tfd.tensor) -> !tfd.tensor +``` + +For example, `dilations` attribute here has a value of `[1, 1, 1, 1, 1]`. + +## Reusing Kernels + +TensorFlow currently reuses kernels instantiated for a particular node in a +graph. It would be nice to have this optimization for Kernel fallback as well. + +BEF executor keeps track of offsets within a BEF file. We can use this offset to +cache corresponding kernel objects. + +We should make sure that Kernel Fallback is thread safe when reusing kernel +objects since Compute for the same kernel can be called from multiple threads. +We can take a simple approach and support kernel cache only for stateless +kernels. Stateless kernels only update `OpKernelContext` and not `OpKernel` +state itself. + +## C API Integration + +Modular TensorFlow effort aims to break up giant monolithic TensorFlow binaries +into smaller shared libraries. Specifically, James (@sjamesr) and Gunhan +(@gunhan) looked at splitting out kernels out of TensorFlow core. Initial Kernel +C API definition is at +[kernel.h](https://cs.opensource.google/tensorflow/tensorflow/+/master:tensorflow/c/kernels.h) +and its implementation is at +[kernel.cc](https://cs.opensource.google/tensorflow/tensorflow/+/master:tensorflow/c/kernels.cc?q=kernels.cc). + +Kernel Fallback should support kernels migrated to C API as well. We can +implement this support behind the C API, so that we don’t have to update +individual kernels. + +### C API multiple implementation structure + +There are a few important takeaways from current kernel C API implementation +that will impact decisions in the document: + +1. We register a + [COpKernel](https://cs.opensource.google/tensorflow/tensorflow/+/master:tensorflow/c/kernels.cc;l=104?q=copkernel) + object (with TensorFlow op kernel registry) for _any_ kernel defined using + the C API. +1. `OpKernelContext` and `OpKernelConstruction` are passed around as opaque + pointers on the C API surface (they get cast to `TF_OpKernelContext` and + `TF_OpKernelConstruction` aliases). +1. Most of the functions just provide accessors into + `OpKernelContext`/`OpKernelConstruction` types. + +Given current API structure, we can consider two approaches going forward: + +1. TFRT fully supports all functionality available in the C API. This way any + kernel defined using the C API would be automatically available using either + full TensorFlow or the TFRT-to-TF forwarding delegate. +1. Certain functionality is only available with TF backend. TFRT C API + implementation falls back to full TensorFlow in these cases. + +I recommend that we prioritize option 1 and try to get it working (i.e. support +all functionality with both TensorFlow and TFRT C API backend). It already takes +a significant effort to support more kernels with C API, so we can put a little +extra effort and make sure it is supported by both runtimes. + +We propose to provide two implementations of the kernel C API. First +implementation is the +[current one](https://cs.opensource.google/tensorflow/tensorflow/+/master:tensorflow/c/kernels.cc) - +implemented in terms of TensorFlow runtime. Second implementation will use TFRT +Kernel Fallback instead. We can select between the two kernel C API +implementations by adding a build config setting: + +``` +# Whether to use TFRT-based implementation of the kernel C API. +config_setting( + name = "tfrt_kernel_c_api", + define_values = { + "tfrt_kernel_c_api": "True", + }, +) +``` + +Most of the kernel C API implementation will be the same between the two with a +few notable exceptions: + +* TFRT Kernel Fallback implementation will cast `TF_OpKernelContext` and + `TF_OpKernelConstruction` to `TFRTOpKernelContext` and + `TFRTOpKernelConstruction` respectively. +* TFRT Kernel Fallback implementation will use Kernel Fallback registration + mechanism. + +### TFRT forwarding kernel registration using C API + +We plan to implement C API for TFRT kernel registration that calls TFRT Kernel +Fallback registration mechanism. Note that this is analogous to TF Lite +providing +[their own C API registration mechanism](https://cs.opensource.google/tensorflow/tensorflow/+/master:tensorflow/lite/c/common.h;l=739?q=tfliteregistration&ss=tensorflow%2Ftensorflow). + +```cpp +TF_KernelBuilder* TF_NewKernelBuilder( + const char* op_name, const char* device_name, + void* (*create_func)(TF_OpKernelConstruction*), + void (*compute_func)(void*, TF_OpKernelContext*), + void (*delete_func)(void*)) { + TF_KernelBuilder* result = new TF_KernelBuilder; + result->create_function = create_func; + result->compute_function = compute_func; + result->delete_function = delete_func; + return result; +} + +void TF_RegisterKernelBuilder(const char* name, + TF_KernelBuilder* builder, + TF_Status* status) { + auto* create_fn = builder->create_function; + auto* compute_fn = builder->compute_function; + auto* delete_fn = builder->delete_function; + auto create_kernel = [create_fn, compute_fn, delete_fn]( + TFRTOpKernelConstruction* construction) { + return std::make_unique( + construction, create_fn, compute_fn, delete_fn); + }; + ::tensorflow::TFRTKernelReg kernelinfo(create_kernel); + kernelinfo.type_constraints = builder->attr_to_type; + ::tensorflow::tfrt_kernel_factories->RegisterFactory( + name, kernelinfo); + tensorflow::TFRTOpRegisterer(tensorflow::TFRTOpMetaBuilder(name)); + TF_DeleteKernelBuilder(builder); + TF_SetStatus(status, TF_OK, ""); +} +``` + +## TFRT integration + +Current preferred direction would generate a +[BEF](https://github.com/tensorflow/runtime) file in advance and then run that +file on a mobile device. Generated BEF file would have to call either native, TF +Lite, runtime fallback or kernel fallback kernels and provide any glue logic in +between (such as tensor conversions). + +We also need to consider how kernel or runtime fallback will be selected. This +could be a parameter at BEF file creation step. It might also be good to package +both runtime and kernel fallback implementations in a BEF file to be selected at +runtime. + +## Size Reduction + +Since we want to run on a mobile platform, we need to look for any opportunity +to cut down size. First of all, we remove dependency on current TensorFlow +runtime (for e.g. we no longer depend on `NodeDef` and `OpDef` protos). We are +also looking at ways to reduce large size contributions of +[absl libraries](https://github.com/abseil/abseil-cpp/tree/master/absl) and +[protos](https://github.com/protocolbuffers/protobuf). + +### Protos + +We are currently investigating the following options: + +* Switch to [micropb](https://github.com/protocolbuffers/upb). This proto + implementation provides C interfaces and is more compact. +* Remove dependency on protos. + +### ABSL + +We can hide ABSL references behind aliases (see +[tensorflow::StringPiece](https://cs.opensource.google/tensorflow/tensorflow/+/master:tensorflow/core/platform/stringpiece.h;l=33;drc=af7fd02ca40f362c4ac96dd064d6a2224b65d784) +for example) to make it easier to replace all references to save binary size. + +@gunhan is also starting an effort to define a library of STL utilities that +helps us cut down on binary size. + +## Selecting which kernels to register + +We want to add a script to the TF Lite build setup that can determine required +kernels based on a model. We would then only build these kernels. For now, we +will only support selective registration when building from source. + +Script details still need to be worked out. + +### Alternatives Considered + +The main alterantive to TFRT Kernel Fallback is TFRT Runtime Fallback. TFRT +Runtime Fallback will call TensorFlow Eager C API (corresponding RFC should be +published soon). Main trade offs between the two fallbacks are described in the +table below: + +Property | TFRT Kernel Fallback | TFRT Runtime Fallback +----------- | --------------------- | --------------------- +Generality | Support subset of ops | Support all ops +Performance | Lower overhead | Higher overhead +Binary size | Lower (no TF runtime) | Higher + +### Performance Implications + +* Slow down due to adding inheritance for `OpKernelContext` and + `OpKernelConsturction`. +* Speed up for lighter weight kernel calls. + +We will run benchmarks to check performance numbers as we work on the +implementation. + +### Dependencies + +No new dependencies. + +### Engineering Impact + +* Build / startup time / binary size will be impacted by additional code added + to implement Kernel Fallback. At the same time one of the goals of Kernel + Fallback is to provide a lower-binary-size way to run existing TensorFlow + kernels in TF Lite. +* Code will be maintained by TensorFlow DevInfra and TFRT teams. + +### Platforms and Environments + +* Primarily geared towards mobile platforms but should work on non-mobile + platforms as well. + +### Best Practices + +* It might be preferrable to implement future kernels that extend + `OpKernelBase` and take `OpKernelConstructionInterface`/`OpKernelContext` + interface. This would allow new kernels to be used by Kernel Fallback. + Currently, there is no plan to enforce it beyond providing advice at code + review time. + +### Tutorials and Examples + +* Would be useful to update + [Create an op](https://www.tensorflow.org/guide/create_op) documentation. + +### Compatibility + +This proposal should not impact compatibility. + +### User Impact + +* There will be a new way to implement a kernel, but it will be optional. + Current APIs should still work. + +## Questions and Discussion Topics + +Seed this with open questions you require feedback on from the RFC process. + +## Appendix 1 + +As discussed above, we want to convert (some) kernels to extend from +`OpKernelBase` instead of `OpKernel`. This lets us remove runtime-specific +information from kernel subclasses and lets us support both current and new +TensorFlow runtime. + +However, TensorFlow runtime assumes that kernel extend `OpKernel` and support +all of its functionality. In other words we want kernels to extend +`OpKernelBase` but be added to existing TensorFlow registry as `OpKernel` +objects. + +It seems easiest to me to wrap OpKernelBase some class that extends OpKernel (I +call this wrapper WrappedOpKernel below): + +```cpp + class WrappedOpKernel : public OpKernel { + public: + explicit WrappedOpKernel(OpKernelConstruction* context, + std::unique_ptr impl) + : OpKernel(context), impl_(std::move(impl)) {} + + void Compute(OpKernelContext* context) override { + impl_->Compute(context); + } + + private: + std::unique_ptr impl_; +}; +``` + +Kernels of type WrappedOpKernel will be created with corresponding +WrappedOpKernelFactory in TensorFlow: + +```cpp +struct WrappedOpKernelFactory : public OpKernelFactory { + explicit WrappedOpKernelFactory( + OpKernelBase* (*create_func)(OpKernelConstructionInterface*)) + : create_func_(create_func) {} + + OpKernel* Create(OpKernelConstruction* context) override; + OpKernelBase* (*create_func_)(OpKernelConstructionInterface*); +}; + + +OpKernel* OpKernelRegistrar::WrappedOpKernelFactory::Create( + OpKernelConstruction* context) { + std::unique_ptr impl((*create_func_)(context)); + return new WrappedOpKernel(context, std::move(impl)); +} +``` + +This approach has several benefits: + +* Existing, non-converted kernels still extend `OpKernel`, no code change + needed. +* Converted kernels registered with TensorFlow are still wrapped with OpKernel + and therefore, TensorFlow runtime can access all fields currently supported + by OpKernel. +* Converted kernels registered with TFRT only depend on `OpKernelBase` (for + example, they do not have `NodeDef`-related properties that are not + supported by TFRT). From 43ae49d0442fbfeacada5b7679204269bb2857ea Mon Sep 17 00:00:00 2001 From: Anna Revinskaya Date: Tue, 14 Jul 2020 14:59:04 -0700 Subject: [PATCH 02/29] Fix top table formatting --- rfcs/20200712-tfrt-kernel-fallback.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/rfcs/20200712-tfrt-kernel-fallback.md b/rfcs/20200712-tfrt-kernel-fallback.md index 6c5e1328f..cf4914f98 100644 --- a/rfcs/20200712-tfrt-kernel-fallback.md +++ b/rfcs/20200712-tfrt-kernel-fallback.md @@ -3,8 +3,7 @@ | Status | (Proposed / Accepted / Implemented / Obsolete) | | :------------ | :------------------------------------------------------ | | **RFC #** | [NNN](https://github.com/tensorflow/community/pull/NNN) | -| **Author(s)** | Anna Revinskaya (annarev@google.com), Jeremy Lau | -: : (lauj@google.com) : +| **Author(s)** | Anna Revinskaya (annarev@google.com), Jeremy Lau (lauj@google.com) | | **Sponsor** | Jeremy Lau (lauj@google.com) | | **Updated** | 2020-07-06 | From 8ca021ab7d7bc1c565439b41e0647d36f4d7fc13 Mon Sep 17 00:00:00 2001 From: Anna Revinskaya Date: Tue, 14 Jul 2020 14:59:39 -0700 Subject: [PATCH 03/29] Add title --- rfcs/20200712-tfrt-kernel-fallback.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/20200712-tfrt-kernel-fallback.md b/rfcs/20200712-tfrt-kernel-fallback.md index cf4914f98..6cae5cdc1 100644 --- a/rfcs/20200712-tfrt-kernel-fallback.md +++ b/rfcs/20200712-tfrt-kernel-fallback.md @@ -1,4 +1,4 @@ -# Title of RFC +# TFRT Kernel Fallback | Status | (Proposed / Accepted / Implemented / Obsolete) | | :------------ | :------------------------------------------------------ | From ebda0eac727196fd0b15401ac1175e4f27f2dd28 Mon Sep 17 00:00:00 2001 From: Anna Revinskaya Date: Tue, 14 Jul 2020 16:30:18 -0700 Subject: [PATCH 04/29] Aligned attrs, added comment about naming, wording updates --- rfcs/20200712-tfrt-kernel-fallback.md | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/rfcs/20200712-tfrt-kernel-fallback.md b/rfcs/20200712-tfrt-kernel-fallback.md index 6cae5cdc1..26dd1a429 100644 --- a/rfcs/20200712-tfrt-kernel-fallback.md +++ b/rfcs/20200712-tfrt-kernel-fallback.md @@ -66,7 +66,7 @@ can provide. It doesn't take into consideration other issues we might face. ### TFRT Integration Goals -We want to support executing a [BEF](https://github.com/tensorflow/runtime) file +We want to support executing a [BEF](https://github.com/tensorflow/runtime/blob/master/documents/binary_executable_format.md ) file on mobile device that calls kernels using Kernel Fallback mechanism. Users will be able to generate a BEF file based on a saved model and we will provide a script to create it. @@ -81,7 +81,7 @@ custom implementing all of it would require a significant amount of time. Instead, we will start by adding most common and easy functionality. If certain functionality is only used by a handful of kernels, it might make sense to - implement TFRT native kernels instead. One notable example is + implement TFRT native kernels or rely on runtime fallback instead. One notable example is [ResourceMgr](https://cs.opensource.google/tensorflow/tensorflow/+/master:tensorflow/core/framework/resource_mgr.h;l=152?q=ResourceMgr). We might support it later, but it is definitely not first priority due to extra effort required. @@ -112,7 +112,7 @@ to TensorFlow kernels that minimizes the amount of generated code. ## User Benefit -Running more kernels on mobile devices would allow TensorFlow users to implement +Running more kernels on mobile devices would allow TensorFlow Lite users to implement a wider range of models. ## Design Proposal @@ -315,7 +315,7 @@ TFRTOpKernelContext op_kernel_context(inputs, outputs.size(), op_meta, exec_ctx. op->Compute(&op_kernel_context); ``` -## tfd.kernel\_fallback call structure +## tf\_fallback.kernel\_fallback call structure We will be using the following conventions (essentially, these are based on Runtime Fallback work that will probably have RFC coming soon): @@ -332,14 +332,15 @@ Example of invoking Conv3D kernel: ``` %tft_c = "tfd.kernel_fallback"(%tft_a, %tft_b) { - _op_name = "Conv3D", attr1_name="data_format", - attr1_value="string$NDHWC", attr2_name="strides", - attr2_value="list(i32)$1,1,1,1,1", attr3_name="dilations", - attr3_value="list(i32)$1,1,1,1,1", attr4_name="padding", - attr4_value="padding$SAME"}: (!tfd.tensor, !tfd.tensor) -> !tfd.tensor + _op_name = "Conv3D", + attr1_name="data_format", attr1_value="string$NDHWC", + attr2_name="strides", attr2_value="list(i32)$1,1,1,1,1", + attr3_name="dilations", attr3_value="list(i32)$1,1,1,1,1", + attr4_name="padding", attr4_value="padding$SAME"}: (!tfd.tensor, !tfd.tensor) -> !tfd.tensor ``` For example, `dilations` attribute here has a value of `[1, 1, 1, 1, 1]`. +Note: TFRT orders attributes by name, alphabetically, which is why we use `attrN_value` and `attrN_name` pattern pair. ## Reusing Kernels @@ -388,7 +389,7 @@ Given current API structure, we can consider two approaches going forward: 1. TFRT fully supports all functionality available in the C API. This way any kernel defined using the C API would be automatically available using either - full TensorFlow or the TFRT-to-TF forwarding delegate. + full TensorFlow or the TFRT kernel fallback. 1. Certain functionality is only available with TF backend. TFRT C API implementation falls back to full TensorFlow in these cases. @@ -467,7 +468,7 @@ void TF_RegisterKernelBuilder(const char* name, ## TFRT integration Current preferred direction would generate a -[BEF](https://github.com/tensorflow/runtime) file in advance and then run that +[BEF](https://github.com/tensorflow/runtime/blob/master/documents/binary_executable_format.md) file in advance and then run that file on a mobile device. Generated BEF file would have to call either native, TF Lite, runtime fallback or kernel fallback kernels and provide any glue logic in between (such as tensor conversions). @@ -588,7 +589,7 @@ all of its functionality. In other words we want kernels to extend `OpKernelBase` but be added to existing TensorFlow registry as `OpKernel` objects. -It seems easiest to me to wrap OpKernelBase some class that extends OpKernel (I +It seems easiest to me to wrap OpKernelBase with some class that extends OpKernel (I call this wrapper WrappedOpKernel below): ```cpp From 6369d6d7c070cd15daa4b86861ed7bd27dbdff10 Mon Sep 17 00:00:00 2001 From: annarev Date: Wed, 15 Jul 2020 00:28:07 +0000 Subject: [PATCH 05/29] Add diagrams for Kernel Fallback RFC --- .../KernelFallbackDiagram.png | Bin 0 -> 261400 bytes .../KernelFallbackHighLevelDiagram.png | Bin 0 -> 21003 bytes .../RuntimeFallbackHighLevelDiagram.png | Bin 0 -> 30576 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 rfcs/20200712-tfrt-kernel-fallback/KernelFallbackDiagram.png create mode 100644 rfcs/20200712-tfrt-kernel-fallback/KernelFallbackHighLevelDiagram.png create mode 100644 rfcs/20200712-tfrt-kernel-fallback/RuntimeFallbackHighLevelDiagram.png diff --git a/rfcs/20200712-tfrt-kernel-fallback/KernelFallbackDiagram.png b/rfcs/20200712-tfrt-kernel-fallback/KernelFallbackDiagram.png new file mode 100644 index 0000000000000000000000000000000000000000..3c58b63316c31e79ea2469bace72302730443343 GIT binary patch literal 261400 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 T;#R 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

$C65fctparM{kykS@b4s5eOa>jn7(oOICagS2Di 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 UvMzw-9{NW`K~ug$)->pU0ruy}*#H0l literal 0 HcmV?d00001 diff --git a/rfcs/20200712-tfrt-kernel-fallback/KernelFallbackHighLevelDiagram.png b/rfcs/20200712-tfrt-kernel-fallback/KernelFallbackHighLevelDiagram.png new file mode 100644 index 0000000000000000000000000000000000000000..f1e7ce183f52278c8d20caaf575b11cac2764c02 GIT binary patch literal 21003 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 literal 0 HcmV?d00001 diff --git a/rfcs/20200712-tfrt-kernel-fallback/RuntimeFallbackHighLevelDiagram.png b/rfcs/20200712-tfrt-kernel-fallback/RuntimeFallbackHighLevelDiagram.png new file mode 100644 index 0000000000000000000000000000000000000000..f7a2cdc8af18eca4e624fea59ff2f7f4bd51bcac GIT binary patch literal 30576 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 s|F$JvHT~Z=^xseD|6 Date: Tue, 14 Jul 2020 17:49:36 -0700 Subject: [PATCH 06/29] Included diagrams in the doc --- rfcs/20200712-tfrt-kernel-fallback.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/rfcs/20200712-tfrt-kernel-fallback.md b/rfcs/20200712-tfrt-kernel-fallback.md index 26dd1a429..c7823317b 100644 --- a/rfcs/20200712-tfrt-kernel-fallback.md +++ b/rfcs/20200712-tfrt-kernel-fallback.md @@ -24,6 +24,10 @@ mechanisms are as follows: existing kernels working in TFRT while reducing binary size to support mobile devices. +| Runtime Fallback | Kernel Fallback | +:------------------------:|:-----------------: +Runtime Fallback high-level diagram. | Kernel Fallback high-level diagram. + ## Goals High level goals of the project: @@ -119,11 +123,13 @@ a wider range of models. We propose to call the kernel’s Compute method directly from [TFRT](https://github.com/tensorflow/runtime) without going through TensorFlow -Eager C API first. - -We introduce kernel context and registration implementation that support core +Eager C API first. We introduce kernel context and registration implementation that support core kernel functionality with minimal dependencies. +High-level diagram of the proposed design: + +Kernel Fallback design diagram. + ## Kernel registration We will use a separate registry for kernels supported by TFRT forwarding. To do From c0e5d5b642d284196e0b5f5c804d48465261b9e9 Mon Sep 17 00:00:00 2001 From: Anna Revinskaya Date: Tue, 14 Jul 2020 17:59:01 -0700 Subject: [PATCH 07/29] tfd.kernel_fallback --> tfrt_fallback.kernel_fallback --- rfcs/20200712-tfrt-kernel-fallback.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rfcs/20200712-tfrt-kernel-fallback.md b/rfcs/20200712-tfrt-kernel-fallback.md index c7823317b..995781b1e 100644 --- a/rfcs/20200712-tfrt-kernel-fallback.md +++ b/rfcs/20200712-tfrt-kernel-fallback.md @@ -11,7 +11,7 @@ This proposal focuses on getting majority of “well-behaved” ops running in [TF Lite](https://www.tensorflow.org/lite) by skipping current eager runtime and -calling kernels directly in [TFRT](https://github.com/tensorflow/runtime) (a new +calling kernels directly from [TFRT](https://github.com/tensorflow/runtime) (a new TensorFlow runtime). Note that there is an effort to call existing kernels by delegating to @@ -295,7 +295,7 @@ REGISTER_KERNEL_FALLBACK_KERNEL( "AddN", AddNOp); ## Calling kernel -We add a new TFRT BEF kernel called `tfd.kernel_fallback`. This kernel directly +We add a new TFRT BEF kernel called `tfrt_fallback.kernel_fallback`. This kernel directly calls a TF kernel’s `Compute` method by creating `TFRTOpKernel*` data structures that forward to corresponding TFRT concepts. For example, the following code accesses an input in `llvm::ArrayRef>` which @@ -307,7 +307,7 @@ const Tensor& TFRTOpKernelContext::input(int index) { } ``` -Simplified definition of `tfd.kernel_fallback`: +Simplified definition of `tfrt_fallback.kernel_fallback`: ```cpp // Instantiate a kernel. This would be a TensorFlow kernel converted to inherit @@ -321,7 +321,7 @@ TFRTOpKernelContext op_kernel_context(inputs, outputs.size(), op_meta, exec_ctx. op->Compute(&op_kernel_context); ``` -## tf\_fallback.kernel\_fallback call structure +## tfrt\_fallback.kernel\_fallback call structure We will be using the following conventions (essentially, these are based on Runtime Fallback work that will probably have RFC coming soon): From 2a8f7920dbbadbceefe7772ef1264d37324c32ff Mon Sep 17 00:00:00 2001 From: annarev Date: Wed, 15 Jul 2020 04:25:40 +0000 Subject: [PATCH 08/29] Supplemental tables for Kernel Fallback RFC --- .../kernel_to_unsupported.md | 936 ++++++++++++++++++ .../support_priority.md | 56 ++ 2 files changed, 992 insertions(+) create mode 100644 rfcs/20200712-tfrt-kernel-fallback/kernel_to_unsupported.md create mode 100644 rfcs/20200712-tfrt-kernel-fallback/support_priority.md diff --git a/rfcs/20200712-tfrt-kernel-fallback/kernel_to_unsupported.md b/rfcs/20200712-tfrt-kernel-fallback/kernel_to_unsupported.md new file mode 100644 index 000000000..9084b7108 --- /dev/null +++ b/rfcs/20200712-tfrt-kernel-fallback/kernel_to_unsupported.md @@ -0,0 +1,936 @@ +| OpKernel | Unsupported context methods | +| :---------- | :---------- | +| _HostConstantOp | | +| AbortOp | | +| AccumulatorApplyGradientOp | tensorflow::OpKernelContext::MatchSignature,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::mutable_input,tensorflow::OpKernelContext::resource_manager | +| AccumulatorNumAccumulatedOp | tensorflow::OpKernelContext::MatchSignature,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::mutable_input,tensorflow::OpKernelContext::resource_manager | +| AccumulatorSetGlobalStepOp | tensorflow::OpKernelContext::MatchSignature,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::mutable_input,tensorflow::OpKernelContext::resource_manager | +| AccumulatorTakeGradientOp | tensorflow::OpKernelContext::MatchSignature,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::mutable_input,tensorflow::OpKernelContext::resource_manager | +| AddManySparseToTensorsMapOp | tensorflow::OpKernelContext::resource_manager | +| AddNOp | tensorflow::OpKernelContext::forward_input_to_output_with_shape | +| AddSparseToTensorsMapOp | tensorflow::OpKernelContext::resource_manager | +| AdjustContrastOp | tensorflow::OpKernelContext::allocate_temp | +| AdjustContrastOpv2 | tensorflow::OpKernelContext::allocate_temp | +| AdjustContrastOpV2Base | | +| AdjustHueOp | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::eigen_gpu_device,tensorflow::OpKernelContext::forward_input_or_allocate_output | +| AdjustHueOpBase | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| AdjustSaturationOp | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::eigen_gpu_device | +| AdjustSaturationOpBase | | +| AllCandidateSamplerOp | | +| AnonymousIteratorHandleOp | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::function_library,tensorflow::OpKernelContext::resource_manager | +| AnonymousMemoryCacheHandleOp | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::function_library,tensorflow::OpKernelContext::resource_manager | +| AnonymousMultiDeviceIteratorOp | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::env,tensorflow::OpKernelContext::function_library,tensorflow::OpKernelContext::resource_manager | +| AnonymousResourceOp | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::function_library,tensorflow::OpKernelContext::resource_manager | +| AnonymousSeedGeneratorHandleOp | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::function_library,tensorflow::OpKernelContext::resource_manager | +| ApplyAdadeltaOp | tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::mutable_input | +| ApplyAdagradDAOp | tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::mutable_input | +| ApplyAdagradOp | tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::mutable_input | +| ApplyAdagradV2Op | tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::mutable_input | +| ApplyAdaMaxOp | tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::mutable_input | +| ApplyAdamOp | tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::mutable_input | +| ApplyAdamWithAmsgradOp | tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::mutable_input | +| ApplyAddSignOp | tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::mutable_input | +| ApplyCenteredRMSPropOp | tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::mutable_input | +| ApplyFtrlOp | tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::mutable_input | +| ApplyGradientDescentOp | tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::mutable_input | +| ApplyKerasMomentumOp | tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::mutable_input | +| ApplyMomentumOp | tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::mutable_input | +| ApplyPowerSignOp | tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::mutable_input | +| ApplyProximalAdagradOp | tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::mutable_input | +| ApplyProximalGradientDescentOp | tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::mutable_input | +| ApplyRMSPropOp | tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::mutable_input | +| ApproximateEqualOp | | +| AreAllKernelsInlineOp | tensorflow::OpKernelContext::run_all_kernels_inline | +| ArgMaxOp | | +| ArgMinOp | | +| ArgOp | | +| AssertCardinalityDatasetOp | | +| AssertNextDatasetOp | | +| AssertOp | | +| AssignOp | tensorflow::OpKernelConstruction::input_type,tensorflow::OpKernelContext::allocate_persistent,tensorflow::OpKernelContext::clear_recorded_memory,tensorflow::OpKernelContext::forward_input,tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::mutable_input,tensorflow::OpKernelContext::replace_ref_input | +| AssignOpT | tensorflow::OpKernelConstruction::input_type,tensorflow::OpKernelContext::allocate_persistent,tensorflow::OpKernelContext::clear_recorded_memory,tensorflow::OpKernelContext::forward_input,tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::mutable_input,tensorflow::OpKernelContext::replace_ref_input | +| AssignUpdateVariableOp | tensorflow::OpKernelContext::allocate_persistent,tensorflow::OpKernelContext::resource_manager | +| AssignVariableOp | tensorflow::OpKernelContext::allocate_persistent,tensorflow::OpKernelContext::forward_input,tensorflow::OpKernelContext::resource_manager | +| AsStringOp | | +| AsyncOpKernel | | +| AudioSpectrogramOp | | +| AutoShardDatasetOp | | +| AvgPooling3dGradOp | tensorflow::OpKernelConstruction::device_type | +| AvgPoolingGradOp | tensorflow::OpKernelConstruction::device_type,tensorflow::OpKernelContext::device | +| AvgPoolingGradOpCustomGPUKernel | | +| AvgPoolingOp | tensorflow::OpKernelConstruction::device_type,tensorflow::OpKernelContext::device | +| BarrierCloseOp | tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::mutable_input,tensorflow::OpKernelContext::resource_manager | +| BarrierIncompleteSizeOp | tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::mutable_input,tensorflow::OpKernelContext::resource_manager | +| BarrierOp | tensorflow::OpKernelConstruction::allocate_persistent,tensorflow::OpKernelConstruction::output_type,tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::resource_manager,tensorflow::OpKernelContext::set_output_ref | +| BarrierOpKernel | tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::mutable_input,tensorflow::OpKernelContext::resource_manager | +| BarrierReadySizeOp | tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::mutable_input,tensorflow::OpKernelContext::resource_manager | +| BaseBatchMatMulOp | | +| BaseCandidateSamplerOp | | +| BaseDebugOp | | +| BaseKernel | | +| BaseMatrixTriangularSolveOp | | +| BatchDatasetOp | | +| BatchFunctionKernel | tensorflow::OpKernelConstruction::function_library,tensorflow::OpKernelContext::resource_manager | +| BatchKernel | tensorflow::OpKernelContext::resource_manager | +| BatchMatMulOp | | +| BatchMatMulV2Op | | +| BatchNormGradOp | tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::forward_input_or_allocate_output | +| BatchNormOp | | +| BatchToSpaceNDOp | | +| BatchToSpaceOp | | +| BCastArgsOp | | +| BCastGradArgsOp | | +| BeginEpochOp | | +| BetaincOp | tensorflow::OpKernelContext::SetStatus | +| BiasGradOp | tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::op_device_context | +| BiasOp | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| BinaryDatasetOpKernel | | +| BinaryElementWiseOp | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::forward_input_or_allocate_output | +| BinaryOp | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| BinaryOpBase | | +| BinaryOpShared | | +| BincountOp | | +| BlockingOp | | +| BlockLSTMGradOp | tensorflow::OpKernelContext::allocate_temp | +| BlockLSTMOp | tensorflow::OpKernelConstruction::HasAttr,tensorflow::OpKernelContext::allocate_temp | +| BoostedTreesAggregateStatsOp | tensorflow::OpKernelContext::allocate_temp | +| BoostedTreesBucketizeOp | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::input_list,tensorflow::OpKernelContext::output_list | +| BoostedTreesCalculateBestFeatureSplitOp | | +| BoostedTreesCalculateBestFeatureSplitV2 | tensorflow::OpKernelContext::input_list | +| BoostedTreesCalculateBestGainsPerFeatureOp | tensorflow::OpKernelContext::input_list,tensorflow::OpKernelContext::output_list | +| BoostedTreesCenterBiasOp | tensorflow::OpKernelContext::resource_manager | +| BoostedTreesCreateEnsembleOp | tensorflow::OpKernelContext::resource_manager | +| BoostedTreesCreateQuantileStreamResourceOp | tensorflow::OpKernelContext::resource_manager | +| BoostedTreesDeserializeEnsembleOp | tensorflow::OpKernelContext::resource_manager | +| BoostedTreesExampleDebugOutputsOp | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::input_list,tensorflow::OpKernelContext::resource_manager | +| BoostedTreesFlushQuantileSummariesOp | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::output_list,tensorflow::OpKernelContext::resource_manager | +| BoostedTreesGetEnsembleStatesOp | tensorflow::OpKernelContext::resource_manager | +| BoostedTreesMakeQuantileSummariesOp | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::input_list,tensorflow::OpKernelContext::output_list | +| BoostedTreesMakeStatsSummaryOp | tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::input_list | +| BoostedTreesPredictOp | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::input_list,tensorflow::OpKernelContext::resource_manager | +| BoostedTreesQuantileStreamResourceAddSummariesOp | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::input_list,tensorflow::OpKernelContext::resource_manager | +| BoostedTreesQuantileStreamResourceDeserializeOp | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::input_list,tensorflow::OpKernelContext::resource_manager | +| BoostedTreesQuantileStreamResourceFlushOp | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::resource_manager | +| BoostedTreesQuantileStreamResourceGetBucketBoundariesOp | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::output_list,tensorflow::OpKernelContext::resource_manager | +| BoostedTreesSerializeEnsembleOp | tensorflow::OpKernelContext::resource_manager | +| BoostedTreesSparseAggregateStatsOp | | +| BoostedTreesSparseCalculateBestFeatureSplitOp | | +| BoostedTreesTrainingPredictOp | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::input_list,tensorflow::OpKernelContext::resource_manager | +| BoostedTreesUpdateEnsembleOp | tensorflow::OpKernelContext::input_list,tensorflow::OpKernelContext::resource_manager | +| BoostedTreesUpdateEnsembleV2Op | tensorflow::OpKernelContext::input_list,tensorflow::OpKernelContext::resource_manager | +| BroadcastToOp | | +| BrokenOp | tensorflow::OpKernelConstruction::SetStatus,tensorflow::OpKernelContext::SetStatus | +| BucketizeOp | | +| BytesProducedStatsDatasetOp | | +| CacheDatasetOp | | +| CallOp | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::cancellation_manager,tensorflow::OpKernelContext::collective_executor,tensorflow::OpKernelContext::function_library,tensorflow::OpKernelContext::rendezvous,tensorflow::OpKernelContext::run_all_kernels_inline,tensorflow::OpKernelContext::runner,tensorflow::OpKernelContext::stats_collector,tensorflow::OpKernelContext::step_container,tensorflow::OpKernelContext::step_id | +| CancellationMgrPollingOp | tensorflow::OpKernelContext::cancellation_manager,tensorflow::OpKernelContext::env | +| CaseOp | tensorflow::OpKernelConstruction::function_library,tensorflow::OpKernelContext::cancellation_manager,tensorflow::OpKernelContext::function_library,tensorflow::OpKernelContext::rendezvous,tensorflow::OpKernelContext::run_all_kernels_inline,tensorflow::OpKernelContext::runner,tensorflow::OpKernelContext::stats_collector,tensorflow::OpKernelContext::step_container | +| CastOpBase | | +| CheckNumericsOp | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::op_device_context | +| CheckNumericsV2Op | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::op_device_context | +| CholeskyGrad | | +| CholeskyOp | | +| CholeskyOpGpu | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| ChooseFastestBranchDatasetOp | tensorflow::OpKernelContext::input_list | +| ChooseFastestDatasetOp | tensorflow::OpKernelContext::input_list | +| ClipOp | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| CloseSummaryWriterOp | tensorflow::OpKernelContext::resource_manager | +| CollectiveBcastRecvOpKernel | tensorflow::OpKernelConstruction::device_type,tensorflow::OpKernelContext::collective_executor,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::frame_iter,tensorflow::OpKernelContext::mutable_output,tensorflow::OpKernelContext::op_kernel | +| CollectiveBcastSendOpKernel | tensorflow::OpKernelConstruction::device_type,tensorflow::OpKernelContext::collective_executor,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::forward_input_or_allocate_output,tensorflow::OpKernelContext::frame_iter,tensorflow::OpKernelContext::mutable_output,tensorflow::OpKernelContext::op_kernel | +| CollectiveGatherOpKernel | tensorflow::OpKernelConstruction::def,tensorflow::OpKernelConstruction::device_type,tensorflow::OpKernelContext::collective_executor,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::frame_iter,tensorflow::OpKernelContext::mutable_output,tensorflow::OpKernelContext::op_kernel | +| CollectiveOpKernel | tensorflow::OpKernelContext::frame_iter | +| CollectiveReduceOpKernel | tensorflow::OpKernelConstruction::def,tensorflow::OpKernelConstruction::device,tensorflow::OpKernelConstruction::device_type,tensorflow::OpKernelConstruction::graph_def_version,tensorflow::OpKernelContext::collective_executor,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::forward_input_or_allocate_output,tensorflow::OpKernelContext::frame_iter,tensorflow::OpKernelContext::mutable_output,tensorflow::OpKernelContext::op_kernel | +| CombinedNonMaxSuppressionOp | | +| CompareAndBitpackOp | | +| ComputeAccidentalHitsOp | | +| ConcatBaseOp | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::eigen_gpu_device | +| ConcatenateDatasetOp | | +| ConcatOffsetOp | | +| ConditionalAccumulatorBaseApplyGradientOp | tensorflow::OpKernelContext::MatchSignature,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::mutable_input,tensorflow::OpKernelContext::resource_manager | +| ConditionalAccumulatorBaseAsyncOpKernel | tensorflow::OpKernelContext::MatchSignature,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::mutable_input,tensorflow::OpKernelContext::resource_manager | +| ConditionalAccumulatorBaseOp | tensorflow::OpKernelConstruction::allocate_persistent,tensorflow::OpKernelContext::resource_manager | +| ConditionalAccumulatorBaseSyncOpKernel | tensorflow::OpKernelContext::MatchSignature,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::mutable_input,tensorflow::OpKernelContext::resource_manager | +| ConditionalAccumulatorBaseTakeGradientOp | tensorflow::OpKernelContext::MatchSignature,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::mutable_input,tensorflow::OpKernelContext::resource_manager | +| ConditionalAccumulatorOp | tensorflow::OpKernelConstruction::allocate_persistent,tensorflow::OpKernelContext::MatchSignature,tensorflow::OpKernelContext::resource_manager | +| ConjugateTransposeCpuOp | | +| ConjugateTransposeGpuOp | | +| ConstantOp | | +| ConsumeMutexLockOp | | +| ControlTriggerOp | | +| Conv2DBackpropFilterOp | | +| Conv2DBackpropInputOp | | +| Conv2DCustomBackpropFilterOp | tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::eigen_cpu_device | +| Conv2DCustomBackpropInputOp | tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::eigen_cpu_device | +| Conv2DOp | tensorflow::OpKernelConstruction::HasAttr | +| Conv3DBackpropFilterOp | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::op_device_context | +| Conv3DBackpropInputOp | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::op_device_context | +| Conv3DCustomBackpropFilterOp | tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::eigen_cpu_device | +| Conv3DCustomBackpropInputOp | tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::eigen_cpu_device | +| Conv3DOp | | +| CopyFromGpuToHostKernel | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::input_alloc_attr,tensorflow::OpKernelContext::op_device_context | +| CopyFromHostToGpuKernel | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::input_alloc_attr,tensorflow::OpKernelContext::op_device_context | +| CopyOp | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::input_alloc_attr,tensorflow::OpKernelContext::op_device_context | +| CopyOpBase | | +| CountUpToOp | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::mutable_input | +| CpuCastOp | | +| CreateSummaryDbWriterOp | tensorflow::OpKernelContext::env,tensorflow::OpKernelContext::resource_manager | +| CreateSummaryFileWriterOp | tensorflow::OpKernelContext::env,tensorflow::OpKernelContext::resource_manager | +| CreateTestVariantOp | | +| CropAndResizeGradBoxesOp | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::op_device_context | +| CropAndResizeGradImageOp | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::op_device_context | +| CropAndResizeOp | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::op_device_context | +| CrossOp | | +| CSRAddOp | | +| CSRMatMulCPUOp | tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::device | +| CSRMatMulGPUOp | tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::forward_input_or_allocate_temp | +| CSRMatMulOp | | +| CSRMulOp | | +| CSRNNZOp | | +| CSROrderingAMDCPUOp | tensorflow::OpKernelContext::device | +| CSRSoftmaxGradOp | tensorflow::OpKernelContext::allocate_persistent | +| CSRSoftmaxOp | tensorflow::OpKernelContext::allocate_temp | +| CSRSparseCholeskyCPUOp | tensorflow::OpKernelContext::device | +| CSRSparseMatMulCPUOp | tensorflow::OpKernelContext::device | +| CSRSparseMatMulGPUOp | tensorflow::OpKernelContext::allocate_temp | +| CSRSparseMatrixComponentsOp | | +| CSRSparseMatrixToDenseCPUOp | tensorflow::OpKernelContext::device | +| CSRSparseMatrixToDenseGPUOp | tensorflow::OpKernelContext::allocate_temp | +| CSRSparseMatrixToSparseTensorCPUOp | tensorflow::OpKernelContext::device | +| CSRSparseMatrixToSparseTensorGPUOp | tensorflow::OpKernelContext::allocate_temp | +| CSRTransposeOp | | +| CSRZerosOp | | +| CSVDatasetOp | tensorflow::OpKernelContext::input_list | +| CTCBeamSearchDecoderOp | | +| CTCGreedyDecoderOp | tensorflow::OpKernelContext::device | +| CTCLossOp | tensorflow::OpKernelContext::device | +| CTCLossOpGPU | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::op_device_context | +| CudnnRNNBackwardOp | tensorflow::OpKernelContext::op_device_context | +| CudnnRNNBackwardOpV2 | tensorflow::OpKernelContext::op_device_context | +| CudnnRNNBackwardOpV3 | tensorflow::OpKernelConstruction::HasAttr,tensorflow::OpKernelContext::op_device_context | +| CudnnRNNCanonicalToParams | tensorflow::OpKernelConstruction::HasAttr,tensorflow::OpKernelContext::input_list,tensorflow::OpKernelContext::op_device_context | +| CudnnRNNForwardOp | tensorflow::OpKernelContext::op_device_context | +| CudnnRNNForwardOpV2 | tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::op_device_context | +| CudnnRNNForwardOpV3 | tensorflow::OpKernelConstruction::HasAttr,tensorflow::OpKernelContext::op_device_context | +| CudnnRNNKernelCommon | tensorflow::OpKernelContext::op_device_context | +| CudnnRNNParamsSizeOp | tensorflow::OpKernelConstruction::HasAttr,tensorflow::OpKernelContext::op_device_context | +| CudnnRNNParamsToCanonical | tensorflow::OpKernelConstruction::HasAttr,tensorflow::OpKernelContext::op_device_context | +| DarthOp | | +| DataFormatDimMapOp | | +| DataFormatVecPermuteOp | | +| DataServiceDatasetOp | | +| DatasetCardinalityOp | | +| DatasetFromGraphOp | | +| DatasetOpKernel | | +| DatasetToGraphOp | | +| DebugIdentityOp | | +| DebugIdentityV2Op | tensorflow::OpKernelConstruction::device | +| DebugNanCountOp | | +| DebugNumericSummaryOp | | +| DebugNumericSummaryV2Op | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::op_device_context | +| DecodeBase64Op | | +| DecodeBmpOp | | +| DecodeCompressedOp | | +| DecodeCSVOp | tensorflow::OpKernelContext::input_list,tensorflow::OpKernelContext::output_list | +| DecodeImageOp | tensorflow::OpKernelContext::SetStatus | +| DecodePaddedRawOp | | +| DecodeProtoOp | tensorflow::OpKernelConstruction::env | +| DecodeRawOp | | +| DecodeWavOp | | +| DelayOp | tensorflow::OpKernelContext::env | +| DeleteIteratorOp | | +| DeleteMemoryCacheOp | | +| DeleteMultiDeviceIteratorOp | tensorflow::OpKernelContext::resource_manager | +| DeleteSeedGeneratorOp | | +| DeleteSessionTensorOp | tensorflow::OpKernelContext::session_state | +| DenseToCSRSparseMatrixCPUOp | tensorflow::OpKernelContext::allocate_temp | +| DenseToCSRSparseMatrixGPUOp | tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::op_device_context | +| DenseToDenseSetOperationOp | | +| DenseToSparseBatchDatasetOp | | +| DenseToSparseSetOperationOp | | +| DenseUpdateOp | tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_ref_mutex | +| DepthToSpaceOp | | +| DepthwiseConv2dGroupedConvBackpropFilterOp | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| DepthwiseConv2dGroupedConvBackpropInputOp | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| DepthwiseConv2dGroupedConvOp | | +| DepthwiseConv2dNativeBackpropFilterOp | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| DepthwiseConv2dNativeBackpropInputOp | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| DepthwiseConv2dNativeOp | | +| DequantizeOp | tensorflow::OpKernelConstruction::output_type | +| DequeueManyOp | | +| DequeueOp | | +| DequeueUpToOp | | +| DeserializeIteratorOp | | +| DeserializeSparseOp | | +| DestroyResourceOp | | +| DestroyTemporaryVariableOp | tensorflow::OpKernelConstruction::input_type,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::mutable_input,tensorflow::OpKernelContext::record_persistent_memory_allocation,tensorflow::OpKernelContext::resource_manager,tensorflow::OpKernelContext::step_container,tensorflow::OpKernelContext::track_allocations | +| DeterminantOp | | +| DeterminantOpGpu | | +| DiagOp | | +| DiagPartOp | | +| DilationBackpropFilterOp | | +| DilationBackpropInputOp | | +| DilationOp | | +| DirectedInterleaveDatasetOp | | +| DrawBoundingBoxesOp | | +| DummyKernel | | +| DummyOp | | +| DynamicPartitionOp | tensorflow::OpKernelContext::output_list | +| DynamicPartitionOp_Shared | tensorflow::OpKernelContext::output_list | +| DynamicStitchOpCPU | tensorflow::OpKernelContext::device | +| DynamicStitchOpGPU | tensorflow::OpKernelContext::eigen_gpu_device,tensorflow::OpKernelContext::input_list | +| DynamicStitchOpImplBase | tensorflow::OpKernelContext::input_list | +| DynamicStitchOpImplCPU | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::input_list | +| EditDistanceOp | | +| EigOp | | +| EinsumOp | tensorflow::OpKernelContext::input_list | +| EluGradOp | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::forward_input_or_allocate_output | +| EluOp | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| EmptyOp | | +| EmptyTensorList | | +| EncodeBase64Op | | +| EncodeJpegOp | | +| EncodeJpegVariableQualityOp | | +| EncodePngOp | tensorflow::OpKernelConstruction::input_type | +| EncodeProtoOp | tensorflow::OpKernelConstruction::env,tensorflow::OpKernelContext::input_list | +| EncodeWavOp | | +| EnqueueManyOp | | +| EnqueueOp | | +| EnsureShapeOp | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_dtype | +| EnterOp | | +| ErrorOp | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::cancellation_manager | +| ExitOp | | +| ExpandDimsOp | tensorflow::OpKernelContext::SetStatus | +| ExpensiveNoopOp | | +| ExtractGlimpseOp | tensorflow::OpKernelContext::eigen_cpu_device | +| ExtractImagePatchesOp | | +| ExtractJpegShapeOp | | +| ExtractVolumePatchesOp | | +| FactOp | | +| FactOpKernel | tensorflow::OpKernelContext::env | +| FactOpKernel1 | tensorflow::OpKernelContext::env | +| FactOpKernel2 | tensorflow::OpKernelContext::env | +| FailureKernel | | +| FakeParamOp | tensorflow::OpKernelConstruction::allocate_persistent | +| FakeQuantWithMinMaxArgsGradientOp | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::forward_input_or_allocate_output | +| FakeQuantWithMinMaxArgsOp | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| FakeQuantWithMinMaxVarsGradientOp | | +| FakeQuantWithMinMaxVarsOp | | +| FakeQuantWithMinMaxVarsPerChannelGradientOp | | +| FakeQuantWithMinMaxVarsPerChannelOp | | +| FakeQueueOp | tensorflow::OpKernelConstruction::allocate_persistent,tensorflow::OpKernelContext::set_output_ref | +| FFTBase | | +| FFTCPU | tensorflow::OpKernelContext::allocate_temp | +| FFTGPU | tensorflow::OpKernelContext::op_device_context | +| FFTGPUBase | tensorflow::OpKernelContext::op_device_context | +| FIFOQueueOp | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::resource_manager,tensorflow::OpKernelContext::set_output_ref | +| FillOp | | +| FilterDatasetOp | | +| FindDeviceOpKernel | tensorflow::OpKernelContext::function_library | +| FingerprintOp | tensorflow::OpKernelContext::allocate_temp | +| FixedLengthRecordDatasetOp | | +| FixedLengthRecordReaderOp | tensorflow::OpKernelConstruction::env,tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::cancellation_manager | +| FixedUnigramCandidateSamplerOp | tensorflow::OpKernelConstruction::env | +| FlatMapDatasetOp | | +| FlushSummaryWriterOp | tensorflow::OpKernelContext::resource_manager | +| ForOp | tensorflow::OpKernelConstruction::function_library,tensorflow::OpKernelContext::cancellation_manager,tensorflow::OpKernelContext::function_library,tensorflow::OpKernelContext::rendezvous,tensorflow::OpKernelContext::run_all_kernels_inline,tensorflow::OpKernelContext::runner,tensorflow::OpKernelContext::stats_collector,tensorflow::OpKernelContext::step_container | +| FractionalAvgPoolGradOp | tensorflow::OpKernelContext::forward_input_or_allocate_output,tensorflow::OpKernelContext::forward_input_or_allocate_temp | +| FractionalAvgPoolOp | | +| FractionalMaxPoolGradOp | tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::forward_input_or_allocate_output,tensorflow::OpKernelContext::forward_input_or_allocate_temp | +| FractionalMaxPoolOp | | +| FusedBatchNormGradOp | | +| FusedBatchNormGradOpBase | | +| FusedBatchNormGradOpV3 | | +| FusedBatchNormOp | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| FusedBatchNormOpBase | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| FusedBatchNormOpEx | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| FusedBatchNormOpV3 | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| FusedConv2DOp | tensorflow::OpKernelConstruction::HasAttr | +| FusedMatMulOp | | +| FusedResizeConv2DUsingGemmOp | | +| GatherNdOp | tensorflow::OpKernelContext::allocate_temp | +| GatherOp | tensorflow::OpKernelConstruction::HasAttr | +| GenerateVocabRemappingOp | tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::env | +| GeneratorDatasetOp | | +| GetAttrKernel | | +| GetSessionHandleOp | tensorflow::OpKernelConstruction::device,tensorflow::OpKernelConstruction::resource_manager,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::expected_output_dtype,tensorflow::OpKernelContext::resource_manager,tensorflow::OpKernelContext::session_state,tensorflow::OpKernelContext::tensor_store | +| GetSessionTensorOp | tensorflow::OpKernelContext::session_state | +| GpuCastOp | | +| GroupByReducerDatasetOp | | +| GroupByWindowDatasetOp | | +| GRUBlockCellGradOp | tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::forward_input_or_allocate_output | +| GRUCellBlockOp | tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::forward_input_or_allocate_output | +| GuaranteeConstOp | tensorflow::OpKernelContext::forward_input_to_output_with_shape,tensorflow::OpKernelContext::input_dtype | +| HistogramFixedWidthOp | | +| HSVToRGBOp | | +| HybridAsyncOpKernel | | +| IdentityNOp | tensorflow::OpKernelContext::input_list,tensorflow::OpKernelContext::output_list | +| IdentityOp | tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_dtype | +| IdentityReaderOp | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::cancellation_manager | +| IfOp | tensorflow::OpKernelConstruction::function_library,tensorflow::OpKernelContext::cancellation_manager,tensorflow::OpKernelContext::function_library,tensorflow::OpKernelContext::rendezvous,tensorflow::OpKernelContext::run_all_kernels_inline,tensorflow::OpKernelContext::runner,tensorflow::OpKernelContext::stats_collector,tensorflow::OpKernelContext::step_container | +| IgnoreErrorsDatasetOp | | +| ImageProjectiveTransformV2 | | +| ImmutableConstantOp | | +| ImportEventOp | tensorflow::OpKernelContext::resource_manager | +| InitializeTableFromDatasetOp | tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::resource_manager | +| InitializeTableFromTextFileOp | tensorflow::OpKernelContext::MatchSignature,tensorflow::OpKernelContext::env,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::record_persistent_memory_allocation,tensorflow::OpKernelContext::resource_manager,tensorflow::OpKernelContext::track_allocations | +| InitializeTableOp | tensorflow::OpKernelContext::MatchSignature,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::record_persistent_memory_allocation,tensorflow::OpKernelContext::resource_manager,tensorflow::OpKernelContext::track_allocations | +| InplaceOp | | +| InplaceOpBase | | +| InsertManyOp | tensorflow::OpKernelContext::MatchSignature,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::mutable_input,tensorflow::OpKernelContext::resource_manager | +| InterleaveDatasetOp | | +| InTopK | | +| InvalidRefType | tensorflow::OpKernelContext::set_output_ref | +| InvertPermutationOp | | +| IsResourceInitialized | tensorflow::OpKernelContext::resource_manager | +| IsVariableInitializedOp | tensorflow::OpKernelContext::mutable_input | +| IteratorFromStringHandleOp | | +| IteratorGetDeviceOp | tensorflow::OpKernelContext::device | +| IteratorGetNextAsOptionalOp | | +| IteratorGetNextOp | | +| IteratorHandleOp | | +| IteratorToStringHandleOp | | +| KMC2ChainInitializationOp | | +| KmeansPlusPlusInitializationOp | | +| L2LossOp | | +| LabeledKernel | | +| LatencyStatsDatasetOp | | +| LeakyReluGradOp | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::forward_input_or_allocate_output | +| LeakyReluOp | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| LegacyStringToHashBucketOp | | +| LinearAlgebraOp | tensorflow::OpKernelContext::device | +| LinSpaceOp | | +| ListDiffOp | | +| LMDBDatasetOp | | +| LMDBReaderOp | tensorflow::OpKernelConstruction::env,tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::cancellation_manager | +| LoadAndRemapMatrixOp | tensorflow::OpKernelContext::env | +| LogDeterminantOp | | +| LogDeterminantOpGpu | | +| LookupTableExportOp | tensorflow::OpKernelConstruction::input_type,tensorflow::OpKernelContext::resource_manager | +| LookupTableFindOp | tensorflow::OpKernelConstruction::input_type,tensorflow::OpKernelContext::MatchSignature,tensorflow::OpKernelContext::resource_manager | +| LookupTableImportOp | tensorflow::OpKernelConstruction::input_type,tensorflow::OpKernelContext::MatchSignature,tensorflow::OpKernelContext::record_persistent_memory_allocation,tensorflow::OpKernelContext::resource_manager,tensorflow::OpKernelContext::track_allocations | +| LookupTableInsertOp | tensorflow::OpKernelConstruction::input_type,tensorflow::OpKernelContext::MatchSignature,tensorflow::OpKernelContext::record_persistent_memory_allocation,tensorflow::OpKernelContext::resource_manager,tensorflow::OpKernelContext::track_allocations | +| LookupTableOp | tensorflow::OpKernelConstruction::allocate_persistent,tensorflow::OpKernelConstruction::device,tensorflow::OpKernelConstruction::output_type,tensorflow::OpKernelConstruction::resource_manager,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::expected_output_dtype,tensorflow::OpKernelContext::record_persistent_memory_allocation,tensorflow::OpKernelContext::resource_manager,tensorflow::OpKernelContext::set_output_ref,tensorflow::OpKernelContext::track_allocations | +| LookupTableOpKernel | tensorflow::OpKernelConstruction::input_type,tensorflow::OpKernelContext::resource_manager | +| LookupTableRemoveOp | tensorflow::OpKernelConstruction::input_type,tensorflow::OpKernelContext::MatchSignature,tensorflow::OpKernelContext::record_persistent_memory_allocation,tensorflow::OpKernelContext::resource_manager,tensorflow::OpKernelContext::track_allocations | +| LookupTableSizeOp | tensorflow::OpKernelConstruction::input_type,tensorflow::OpKernelContext::resource_manager | +| LoopCondOp | | +| LowerBoundOp | | +| LRNGradOp | | +| LRNOp | | +| LSTMBlockCellGradOp | tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::forward_input_or_allocate_output | +| LSTMBlockCellOp | tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::forward_input_or_allocate_output | +| LuOp | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::forward_input_or_allocate_output | +| MakeDataServiceIteratorOp | | +| MakeIteratorOp | | +| MapAndBatchDatasetOp | | +| MapClearOp | tensorflow::OpKernelContext::resource_manager | +| MapDatasetOp | | +| MapDefunOp | | +| MapIncompleteSizeOp | tensorflow::OpKernelContext::resource_manager | +| MapPeekOp | tensorflow::OpKernelContext::resource_manager | +| MapSizeOp | tensorflow::OpKernelContext::resource_manager | +| MapStageOp | tensorflow::OpKernelContext::input_list,tensorflow::OpKernelContext::resource_manager | +| MapUnstageNoKeyOp | tensorflow::OpKernelContext::resource_manager | +| MapUnstageOp | tensorflow::OpKernelContext::resource_manager | +| MatchingFilesDatasetOp | | +| MatchingFilesOp | tensorflow::OpKernelContext::env | +| MatMulOp | tensorflow::OpKernelContext::allocate_temp | +| MatrixBandPartOp | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| MatrixDiagOp | tensorflow::OpKernelConstruction::HasAttr | +| MatrixDiagPartOp | tensorflow::OpKernelConstruction::HasAttr | +| MatrixExponentialOp | | +| MatrixInverseOp | | +| MatrixInverseOpGpu | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| MatrixLogarithmOp | | +| MatrixSetDiagOp | tensorflow::OpKernelConstruction::HasAttr,tensorflow::OpKernelContext::forward_input_or_allocate_output | +| MatrixSolveLsOp | | +| MatrixSolveOp | | +| MatrixSolveOpGpu | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| MatrixSquareRootOp | | +| MatrixTriangularSolveOp | | +| MaxIntraOpParallelismDatasetOp | | +| MaxPooling3dGradGradOp | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| MaxPooling3dGradOp | tensorflow::OpKernelConstruction::device_type | +| MaxPoolingGradGradOp | tensorflow::OpKernelConstruction::device_type,tensorflow::OpKernelContext::forward_input_or_allocate_output | +| MaxPoolingGradGradWithArgmaxOp | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| MaxPoolingGradOp | tensorflow::OpKernelConstruction::device_type,tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::forward_input_or_allocate_output,tensorflow::OpKernelContext::forward_input_or_allocate_temp | +| MaxPoolingGradWithArgmaxOp | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| MaxPoolingNoMaskOp | tensorflow::OpKernelConstruction::device_type | +| MaxPoolingNoMaskV2Op | tensorflow::OpKernelConstruction::device_type | +| MaxPoolingOp | tensorflow::OpKernelConstruction::device_type,tensorflow::OpKernelContext::device | +| MaxPoolingV2Op | tensorflow::OpKernelContext::device | +| MaxPoolingWithArgmaxOp | | +| MergeOp | | +| MergeV2Checkpoints | | +| MfccOp | | +| MirrorPadGradOp | tensorflow::OpKernelContext::allocate_temp | +| MirrorPadOp | | +| ModelDatasetOp | tensorflow::OpKernelConstruction::HasAttr | +| MultiDeviceIteratorFromStringHandleOp | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::resource_manager | +| MultiDeviceIteratorGetNextFromShardOp | tensorflow::OpKernelConstruction::env,tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::resource_manager | +| MultiDeviceIteratorHandleOp | tensorflow::OpKernelConstruction::graph_def_version,tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::env,tensorflow::OpKernelContext::function_library,tensorflow::OpKernelContext::resource_manager | +| MultiDeviceIteratorInitOp | tensorflow::OpKernelContext::cancellation_manager,tensorflow::OpKernelContext::resource_manager | +| MultiDeviceIteratorToStringHandleOp | tensorflow::OpKernelContext::resource_manager | +| MultiIdentity | | +| MultinomialOp | tensorflow::OpKernelContext::allocate_temp | +| MutexLockOp | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::resource_manager | +| NcclAllReduceOpKernel | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::forward_input_or_allocate_output,tensorflow::OpKernelContext::frame_iter,tensorflow::OpKernelContext::op_device_context,tensorflow::OpKernelContext::step_id | +| NcclAsyncOpBase | tensorflow::OpKernelContext::frame_iter,tensorflow::OpKernelContext::step_id | +| NcclBroadcastRecvKernel | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::frame_iter,tensorflow::OpKernelContext::op_device_context,tensorflow::OpKernelContext::step_id | +| NcclBroadcastSendKernel | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::frame_iter,tensorflow::OpKernelContext::op_device_context,tensorflow::OpKernelContext::step_id | +| NcclReduceOpBase | tensorflow::OpKernelContext::frame_iter,tensorflow::OpKernelContext::step_id | +| NcclReduceRecvKernel | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::frame_iter,tensorflow::OpKernelContext::op_device_context,tensorflow::OpKernelContext::step_id | +| NcclReduceSendKernel | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::frame_iter,tensorflow::OpKernelContext::op_device_context,tensorflow::OpKernelContext::step_id | +| NcclStubKernel | tensorflow::OpKernelContext::SetStatus | +| NearestNeighborsOp | tensorflow::OpKernelContext::device | +| NegTrainOp | tensorflow::OpKernelContext::mutable_input | +| NeonDepthwiseConv2dNativeOp | | +| NextIterationOp | | +| NonDeterministicIntsOp | | +| NonMaxSuppressionOp | | +| NonMaxSuppressionV2Op | | +| NonMaxSuppressionV3Op | | +| NonMaxSuppressionV4Op | | +| NonMaxSuppressionV5Op | | +| NonMaxSuppressionWithOverlapsOp | | +| NonSerializableDatasetOp | | +| NoOp | | +| NthElementOp | | +| OneHotOp | | +| OneShotIteratorOp | tensorflow::OpKernelConstruction::device,tensorflow::OpKernelConstruction::env,tensorflow::OpKernelConstruction::resource_manager,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::op_kernel,tensorflow::OpKernelContext::resource_manager | +| OnesLikeOp | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| OptimizeDatasetOp | | +| OptionalFromValueOp | | +| OptionalGetValueOp | | +| OptionalHasValueOp | | +| OptionalNoneOp | | +| PackOp | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::eigen_gpu_device | +| PaddedBatchDatasetOp | | +| PaddingFIFOQueueOp | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::resource_manager,tensorflow::OpKernelContext::set_output_ref | +| PadOp | tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::input_memory_type | +| ParallelConcatStart | | +| ParallelConcatUpdate | | +| ParallelDynamicStitchOpCPU | tensorflow::OpKernelContext::device | +| ParallelInterleaveDatasetOp | | +| ParallelMapDatasetOp | | +| ParameterizedTruncatedNormalOp | | +| ParseExampleDatasetOp | tensorflow::OpKernelConstruction::graph_def_version,tensorflow::OpKernelContext::input_list | +| ParseExampleOp | tensorflow::OpKernelConstruction::def,tensorflow::OpKernelContext::input_list | +| ParseSequenceExampleOp | tensorflow::OpKernelConstruction::def,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::input_list | +| ParseSingleExampleOp | tensorflow::OpKernelContext::input_list,tensorflow::OpKernelContext::output_list | +| ParseSingleSequenceExampleOp | tensorflow::OpKernelContext::input_list,tensorflow::OpKernelContext::output_list | +| ParseTensorOp | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::output_alloc_attr | +| PartitionedCallOp | | +| PassOn | | +| PhiloxRandomOp | | +| PlaceholderOp | | +| Pooling3DOp | tensorflow::OpKernelConstruction::device_type | +| PopulationCountOp | | +| PrefetchDatasetOp | | +| PrintOp | tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_dtype | +| PrintV2Op | tensorflow::OpKernelContext::env | +| PriorityQueueOp | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::resource_manager,tensorflow::OpKernelContext::set_output_ref | +| PrivateThreadPoolDatasetOp | tensorflow::OpKernelContext::env | +| QrOp | | +| QrOpGpu | | +| QuantizeAndDequantizeOp | | +| QuantizeAndDequantizeV2Op | tensorflow::OpKernelContext::allocate_temp | +| QuantizeAndDequantizeV3Op | tensorflow::OpKernelContext::allocate_temp | +| QuantizedAddOp | tensorflow::OpKernelContext::SetStatus | +| QuantizedAvgPoolingOp | tensorflow::OpKernelContext::device | +| QuantizedBatchNormOp | | +| QuantizedBiasAddOp | | +| QuantizedConcatOp | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::input_list | +| QuantizedConv2DOp | | +| QuantizedInstanceNorm | | +| QuantizedMatMulOp | tensorflow::OpKernelContext::device | +| QuantizedMaxPoolingOp | tensorflow::OpKernelConstruction::device_type,tensorflow::OpKernelContext::device | +| QuantizedMulOp | tensorflow::OpKernelContext::SetStatus | +| QuantizeDownAndShrinkRangeOp | | +| QuantizedRelu6Op | tensorflow::OpKernelContext::eigen_cpu_device | +| QuantizedReluOp | tensorflow::OpKernelContext::eigen_cpu_device | +| QuantizedReshapeOp | | +| QuantizedResizeBilinearOp | | +| QuantizeV2Op | | +| QueueAccessOpKernel | | +| QueueCloseOp | | +| QueueIsClosedOp | | +| QueueOp | tensorflow::OpKernelConstruction::allocate_persistent,tensorflow::OpKernelConstruction::output_type,tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::resource_manager,tensorflow::OpKernelContext::set_output_ref | +| QueueOpKernel | | +| QueueSizeOp | | +| RaggedCrossOp | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::input_list | +| RaggedGatherOp | tensorflow::OpKernelContext::input_list | +| RaggedGatherOpBase | tensorflow::OpKernelContext::input_list | +| RaggedRangeOp | | +| RaggedTensorFromVariantOp | tensorflow::OpKernelContext::output_list | +| RaggedTensorToSparseOp | tensorflow::OpKernelContext::input_list | +| RaggedTensorToTensorBaseOp | | +| RaggedTensorToTensorOp | tensorflow::OpKernelContext::allocate_temp | +| RaggedTensorToVariantOp | tensorflow::OpKernelContext::input_list | +| RandomBinomialOp | tensorflow::OpKernelContext::allocate_persistent,tensorflow::OpKernelContext::resource_manager | +| RandomCropOp | | +| RandomDatasetOp | | +| RandomGammaOp | tensorflow::OpKernelContext::device | +| RandomPoissonOp | | +| RandomShuffleOp | tensorflow::OpKernelContext::mutable_output | +| RandomShuffleQueueOp | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::resource_manager,tensorflow::OpKernelContext::set_output_ref | +| RandomUniformIntOp | | +| RangeDatasetOp | | +| RangeOp | | +| RankOp | | +| ReaderNumRecordsProducedOp | tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::mutable_input,tensorflow::OpKernelContext::resource_manager | +| ReaderNumWorkUnitsCompletedOp | tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::mutable_input,tensorflow::OpKernelContext::resource_manager | +| ReaderOpKernel | tensorflow::OpKernelConstruction::allocate_persistent,tensorflow::OpKernelConstruction::output_type,tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::cancellation_manager,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::resource_manager,tensorflow::OpKernelContext::set_output_ref | +| ReaderReadOp | tensorflow::OpKernelConstruction::env,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::mutable_input,tensorflow::OpKernelContext::resource_manager | +| ReaderReadUpToOp | tensorflow::OpKernelConstruction::env,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::mutable_input,tensorflow::OpKernelContext::resource_manager | +| ReaderResetOp | tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::mutable_input,tensorflow::OpKernelContext::resource_manager | +| ReaderRestoreStateOp | tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::mutable_input,tensorflow::OpKernelContext::resource_manager | +| ReaderSerializeStateOp | tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::mutable_input,tensorflow::OpKernelContext::resource_manager | +| ReaderVerbAsyncOpKernel | tensorflow::OpKernelConstruction::env,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::mutable_input,tensorflow::OpKernelContext::resource_manager | +| ReaderVerbSyncOpKernel | tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::mutable_input,tensorflow::OpKernelContext::resource_manager | +| ReadFileOp | tensorflow::OpKernelContext::env | +| ReadVariableOp | | +| ReadVariablesOp | | +| RebatchDatasetOp | | +| RecordInputOp | | +| RecvOp | | +| ReduceDatasetOp | tensorflow::OpKernelContext::cancellation_manager,tensorflow::OpKernelContext::input_list,tensorflow::OpKernelContext::op_kernel | +| ReduceJoinOp | | +| ReductionOp | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::expected_output_dtype,tensorflow::OpKernelContext::output_alloc_attr | +| RefSelectOp | tensorflow::OpKernelContext::forward_ref_input_to_ref_output | +| RegexFullMatchOp | | +| RegexReplaceOp | tensorflow::OpKernelContext::forward_input,tensorflow::OpKernelContext::input_alloc_attr,tensorflow::OpKernelContext::input_memory_type | +| RegisterDatasetOp | | +| Relu6GradOp | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::forward_input_or_allocate_output | +| Relu6Op | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| ReluGradOp | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::forward_input_or_allocate_output | +| ReluOp | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| RemoteCallOp | | +| RemoteFusedGraphExecuteOp | | +| RepeatDatasetOp | | +| RequantizationRangeOp | | +| RequantizeOp | | +| ReshapeOp | | +| ResizeAreaOp | | +| ResizeBicubicOp | | +| ResizeBicubicOpGrad | | +| ResizeBilinearOp | | +| ResizeBilinearOpGrad | | +| ResizeNearestNeighborOp | tensorflow::OpKernelContext::SetStatus | +| ResizeNearestNeighborOpGrad | tensorflow::OpKernelContext::SetStatus | +| ResourceAccumulatorApplyGradientOp | tensorflow::OpKernelContext::MatchSignature,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::mutable_input,tensorflow::OpKernelContext::resource_manager | +| ResourceAccumulatorNumAccumulatedOp | tensorflow::OpKernelContext::MatchSignature | +| ResourceAccumulatorSetGlobalStepOp | tensorflow::OpKernelContext::MatchSignature,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::mutable_input,tensorflow::OpKernelContext::resource_manager | +| ResourceAccumulatorTakeGradientOp | tensorflow::OpKernelContext::MatchSignature,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::mutable_input,tensorflow::OpKernelContext::resource_manager | +| ResourceConditionalAccumulatorOp | tensorflow::OpKernelConstruction::allocate_persistent,tensorflow::OpKernelContext::MatchSignature,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::resource_manager | +| ResourceCountUpToOp | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::allocate_persistent,tensorflow::OpKernelContext::resource_manager | +| ResourceGatherNdOp | tensorflow::OpKernelContext::allocate_persistent,tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::resource_manager | +| ResourceGatherOp | tensorflow::OpKernelContext::allocate_persistent,tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::resource_manager | +| ResourceHandleOp | tensorflow::OpKernelConstruction::device,tensorflow::OpKernelConstruction::resource_manager,tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::resource_manager | +| ResourceHandlesOp | tensorflow::OpKernelConstruction::device,tensorflow::OpKernelConstruction::resource_manager,tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::resource_manager | +| ResourceOpKernel | tensorflow::OpKernelConstruction::allocate_persistent,tensorflow::OpKernelConstruction::output_type,tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::resource_manager,tensorflow::OpKernelContext::set_output_ref | +| ResourceScatterUpdateOp | tensorflow::OpKernelContext::allocate_persistent,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::resource_manager | +| RestoreOp | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::expected_output_dtype,tensorflow::OpKernelContext::slice_reader_cache | +| RestoreSliceOp | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::expected_output_dtype,tensorflow::OpKernelContext::slice_reader_cache | +| RestoreV2 | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::expected_output_dtype,tensorflow::OpKernelContext::mutable_output,tensorflow::OpKernelContext::slice_reader_cache | +| RetvalOp | | +| ReverseOp | | +| ReverseSequenceOp | | +| ReverseV2Op | | +| RGBToHSVOp | tensorflow::OpKernelContext::allocate_temp | +| RngSkipOp | tensorflow::OpKernelContext::allocate_persistent,tensorflow::OpKernelContext::resource_manager | +| RollOp | | +| RpcOp | | +| SampleDistortedBoundingBoxV2Op | | +| SamplingDatasetOp | | +| SaveOp | tensorflow::OpKernelContext::SetStatus | +| SaveSlicesOp | tensorflow::OpKernelContext::SetStatus | +| SaveV2 | | +| ScalarAdd | | +| ScaleAndTranslateGradOp | tensorflow::OpKernelContext::allocate_temp | +| ScaleAndTranslateOp | tensorflow::OpKernelContext::allocate_temp | +| ScanDatasetOp | tensorflow::OpKernelConstruction::HasAttr,tensorflow::OpKernelContext::input_list | +| ScanOp | | +| ScatterNdOp | tensorflow::OpKernelContext::allocate_temp | +| ScatterNdUpdateOp | tensorflow::OpKernelConstruction::input_type,tensorflow::OpKernelContext::allocate_persistent,tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::resource_manager | +| ScatterUpdateOp | tensorflow::OpKernelContext::input_ref_mutex | +| ScopedAllocatorConcatOp | tensorflow::OpKernelConstruction::device,tensorflow::OpKernelContext::op_kernel | +| ScopedAllocatorOp | tensorflow::OpKernelConstruction::device,tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::op_kernel,tensorflow::OpKernelContext::output_alloc_attr,tensorflow::OpKernelContext::step_id | +| ScopedAllocatorSplitOp | tensorflow::OpKernelConstruction::device,tensorflow::OpKernelContext::op_kernel | +| SdcaFprint | | +| SdcaOptimizer | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::eigen_cpu_device | +| SdcaShrinkL1 | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::eigen_cpu_device,tensorflow::OpKernelContext::mutable_input_list | +| SegmentReductionOp | | +| SegmentSumGPUOp | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::op_device_context | +| SelectOp | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| SelectV2Op | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::forward_input_or_allocate_output | +| SelfAdjointEigOp | | +| SelfAdjointEigV2Op | | +| SelfAdjointEigV2OpGpu | | +| SeluGradOp | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::forward_input_or_allocate_output | +| SeluOp | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| SendOp | | +| SerializeIteratorOp | | +| SerializeManySparseOp | | +| SerializeSparseOp | | +| SerializeTensorOp | | +| SessionMetadataReaderOp | tensorflow::OpKernelContext::session_metadata | +| SetOperationOp | | +| SetSizeOp | tensorflow::OpKernelContext::eigen_cpu_device | +| SetStatsAggregatorDatasetOp | tensorflow::OpKernelContext::resource_manager | +| ShapeNOp | | +| ShapeOp | | +| ShardDatasetOp | | +| ShardedFilenameOp | | +| ShardedFilespecOp | | +| ShuffleAndRepeatDatasetOp | | +| ShuffleDatasetOp | | +| ShuffleDatasetOpBase | | +| SimpleBinaryOp | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| SimpleCandidateSamplerOp | | +| SizeOp | | +| SkipDatasetOp | | +| SkipgramOp | tensorflow::OpKernelConstruction::env | +| SleepDatasetOp | | +| SliceOp | | +| SlidingWindowDatasetOp | | +| SnapshotDatasetOp | tensorflow::OpKernelConstruction::graph_def_version | +| SnapshotOp | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| SobolSampleOp | tensorflow::OpKernelContext::device | +| SoftmaxOp | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| SoftmaxXentWithLogitsOp | tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::forward_input_or_allocate_output | +| SoftplusGradOp | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::forward_input_or_allocate_output | +| SoftplusOp | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| SoftsignGradOp | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::forward_input_or_allocate_output | +| SoftsignOp | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| SpaceToBatchNDOp | | +| SpaceToBatchOp | | +| SpaceToDepthOp | | +| SparseAccumulatorApplyGradientOp | tensorflow::OpKernelContext::MatchSignature,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::mutable_input,tensorflow::OpKernelContext::resource_manager | +| SparseAccumulatorTakeGradientOp | tensorflow::OpKernelContext::MatchSignature,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::mutable_input,tensorflow::OpKernelContext::resource_manager | +| SparseAddGradOp | | +| SparseAddOp | | +| SparseApplyAdadeltaOp | tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::mutable_input | +| SparseApplyAdagradDAOp | tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::mutable_input | +| SparseApplyAdagradOp | tensorflow::OpKernelContext::eigen_cpu_device,tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::mutable_input | +| SparseApplyAdagradV2Op | tensorflow::OpKernelContext::eigen_cpu_device,tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::mutable_input | +| SparseApplyCenteredRMSPropOp | tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::mutable_input | +| SparseApplyFtrlOp | tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::mutable_input | +| SparseApplyKerasMomentumOp | tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::mutable_input | +| SparseApplyMomentumOp | tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::mutable_input | +| SparseApplyProximalAdagradOp | tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::mutable_input | +| SparseApplyProximalGradientDescentOp | tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::mutable_input | +| SparseApplyRMSPropOp | tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::mutable_input | +| SparseConcatOp | tensorflow::OpKernelContext::input_list | +| SparseConditionalAccumulatorOp | tensorflow::OpKernelConstruction::allocate_persistent,tensorflow::OpKernelContext::MatchSignature,tensorflow::OpKernelContext::resource_manager | +| SparseCrossOp | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::input_list | +| SparseDenseBinaryOpShared | tensorflow::OpKernelContext::allocate_temp | +| SparseFillEmptyRowsGradOp | tensorflow::OpKernelContext::allocate_temp | +| SparseFillEmptyRowsOp | tensorflow::OpKernelContext::output_required | +| SparseMatMulOp | tensorflow::OpKernelContext::device | +| SparseReduceOp | tensorflow::OpKernelContext::allocate_temp | +| SparseReduceSparseOp | tensorflow::OpKernelContext::allocate_temp | +| SparseReorderOp | | +| SparseReshapeOp | | +| SparseSegmentGradOpBase | | +| SparseSegmentMeanGradOp | | +| SparseSegmentReductionMeanOp | | +| SparseSegmentReductionMeanWithNumSegmentsOp | | +| SparseSegmentReductionOpBase | | +| SparseSegmentReductionSqrtNOp | | +| SparseSegmentReductionSqrtNWithNumSegmentsOp | | +| SparseSegmentReductionSumOp | | +| SparseSegmentReductionSumWithNumSegmentsOp | | +| SparseSegmentSqrtNGradOp | | +| SparseSliceGradOp | | +| SparseSliceOp | | +| SparseSoftmaxOp | tensorflow::OpKernelContext::allocate_temp | +| SparseSoftmaxXentWithLogitsOp | tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::forward_input_or_allocate_output | +| SparseSparseBinaryOpShared | | +| SparseSplitOp | | +| SparseTensorAccessingOp | tensorflow::OpKernelContext::resource_manager | +| SparseTensorDenseAddOp | | +| SparseTensorDenseMatMulOp | | +| SparseTensorSliceDatasetOp | | +| SparseTensorToCSRSparseMatrixCPUOp | | +| SparseTensorToCSRSparseMatrixGPUOp | tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::op_device_context | +| SparseToDense | | +| SparseToSparseSetOperationOp | | +| SplitOpBase | | +| SplitOpCPU | | +| SplitOpGPU | tensorflow::OpKernelContext::op_device_context | +| SplitVOpBase | | +| SplitVOpCPU | | +| SplitVOpGPU | tensorflow::OpKernelContext::op_device_context | +| SqlDatasetOp | | +| SqueezeOp | tensorflow::OpKernelContext::SetStatus | +| StackCloseOp | | +| StackOp | | +| StackPopOp | | +| StackPushOp | | +| StageClearOp | tensorflow::OpKernelContext::resource_manager | +| StageOp | tensorflow::OpKernelContext::resource_manager | +| StagePeekOp | tensorflow::OpKernelContext::resource_manager | +| StageSizeOp | tensorflow::OpKernelContext::resource_manager | +| StatefulMultinomialOp | tensorflow::OpKernelContext::allocate_temp | +| StatefulOutputRequiredOp | tensorflow::OpKernelContext::output_required | +| StatefulRandomOp | | +| StatefulRandomOpV2 | | +| StatefulUniformFullIntOp | | +| StatefulUniformIntOp | | +| StatelessMultinomialOp | tensorflow::OpKernelContext::allocate_temp | +| StatelessRandomBinomialOp | | +| StatelessRandomGammaOp | tensorflow::OpKernelContext::device | +| StatelessRandomOp | | +| StatelessRandomOpBase | | +| StatelessRandomPoissonOp | | +| StatelessRandomUniformFullIntOp | | +| StatelessRandomUniformIntOp | | +| StaticRegexFullMatchOp | | +| StaticRegexReplaceOp | tensorflow::OpKernelContext::forward_input,tensorflow::OpKernelContext::input_alloc_attr,tensorflow::OpKernelContext::input_memory_type | +| StatsAggregatorHandleOp | tensorflow::OpKernelConstruction::allocate_persistent,tensorflow::OpKernelConstruction::output_type,tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::resource_manager,tensorflow::OpKernelContext::set_output_ref | +| StatsAggregatorHandleOpV2 | tensorflow::OpKernelConstruction::allocate_persistent,tensorflow::OpKernelConstruction::output_type,tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::resource_manager,tensorflow::OpKernelContext::set_output_ref | +| StatsAggregatorSetSummaryWriterOp | tensorflow::OpKernelContext::resource_manager | +| StatsAggregatorSummaryOp | tensorflow::OpKernelContext::resource_manager | +| StridedSliceAssignOp | tensorflow::OpKernelContext::allocate_persistent,tensorflow::OpKernelContext::forward_input,tensorflow::OpKernelContext::forward_ref_input_to_ref_output,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::mutable_input,tensorflow::OpKernelContext::resource_manager | +| StridedSliceGradOp | | +| StridedSliceOp | | +| StringFormatOp | | +| StringJoinOp | tensorflow::OpKernelContext::input_list | +| StringLengthOp | | +| StringLowerOp | | +| StringNGramsOp | | +| StringSplitV2Op | | +| StringStripOp | | +| StringToHashBucketOp | | +| StringToKeyedHashBucketOp | | +| StringToNumberOp | | +| StringUpperOp | | +| StubResourceOpKernel | tensorflow::OpKernelConstruction::allocate_persistent,tensorflow::OpKernelConstruction::output_type,tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::resource_manager,tensorflow::OpKernelContext::set_output_ref | +| SubstrOp | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::allocate_temp | +| SummaryAudioOp | | +| SummaryHistoOp | tensorflow::OpKernelContext::SetStatus | +| SummaryImageOp | tensorflow::OpKernelConstruction::device | +| SummaryMergeOp | tensorflow::OpKernelContext::SetStatus | +| SummaryScalarOp | | +| SummaryTensorOp | tensorflow::OpKernelContext::op_kernel | +| SummaryTensorOpV2 | | +| SvdOp | | +| SwitchNOp | | +| SwitchOp | | +| SymbolicGradientOp | tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::cancellation_manager,tensorflow::OpKernelContext::collective_executor,tensorflow::OpKernelContext::function_library,tensorflow::OpKernelContext::rendezvous,tensorflow::OpKernelContext::run_all_kernels_inline,tensorflow::OpKernelContext::runner,tensorflow::OpKernelContext::stats_collector,tensorflow::OpKernelContext::step_container,tensorflow::OpKernelContext::step_id | +| TakeDatasetOp | | +| TakeManyOp | tensorflow::OpKernelContext::MatchSignature,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::mutable_input,tensorflow::OpKernelContext::output_list,tensorflow::OpKernelContext::resource_manager | +| TakeManySparseFromTensorsMapOp | tensorflow::OpKernelContext::resource_manager | +| TakeWhileDatasetOp | | +| TemplatedStackPushOp | | +| TemporaryVariableOp | tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::record_persistent_memory_allocation,tensorflow::OpKernelContext::resource_manager,tensorflow::OpKernelContext::set_output_ref,tensorflow::OpKernelContext::step_container,tensorflow::OpKernelContext::track_allocations | +| TensorArrayCloseOp | tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::resource_manager,tensorflow::OpKernelContext::step_container | +| TensorArrayConcatOp | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::eigen_gpu_device,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::resource_manager,tensorflow::OpKernelContext::step_container | +| TensorArrayCreationOp | tensorflow::OpKernelConstruction::device_type,tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::expected_output_dtype,tensorflow::OpKernelContext::resource_manager,tensorflow::OpKernelContext::set_output_ref | +| TensorArrayGradOp | tensorflow::OpKernelConstruction::device_type,tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::expected_output_dtype,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::mutable_input,tensorflow::OpKernelContext::resource_manager,tensorflow::OpKernelContext::set_output_ref,tensorflow::OpKernelContext::step_container | +| TensorArrayOp | tensorflow::OpKernelConstruction::HasAttr,tensorflow::OpKernelConstruction::device_type,tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::expected_output_dtype,tensorflow::OpKernelContext::resource_manager,tensorflow::OpKernelContext::set_output_ref,tensorflow::OpKernelContext::step_container | +| TensorArrayPackOrGatherOp | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::eigen_gpu_device,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::resource_manager,tensorflow::OpKernelContext::step_container | +| TensorArrayReadOp | tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::resource_manager,tensorflow::OpKernelContext::step_container | +| TensorArraySizeOp | tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::resource_manager,tensorflow::OpKernelContext::step_container | +| TensorArraySplitOp | tensorflow::OpKernelContext::allocate_persistent,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::resource_manager,tensorflow::OpKernelContext::step_container | +| TensorArrayUnpackOrScatterOp | tensorflow::OpKernelContext::allocate_persistent,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::resource_manager,tensorflow::OpKernelContext::step_container | +| TensorArrayWriteOp | tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::resource_manager,tensorflow::OpKernelContext::step_container | +| TensorDatasetOp | | +| TensorForestCreateTreeVariableOp | tensorflow::OpKernelContext::resource_manager | +| TensorForestTreeDeserializeOp | tensorflow::OpKernelContext::resource_manager | +| TensorForestTreePredictOp | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::resource_manager | +| TensorForestTreeSerializeOp | tensorflow::OpKernelContext::resource_manager | +| TensorForestTreeSizeOp | tensorflow::OpKernelContext::resource_manager | +| TensorListConcat | tensorflow::OpKernelConstruction::HasAttr,tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::eigen_gpu_device | +| TensorListConcatLists | tensorflow::OpKernelContext::forward_input | +| TensorListElementShape | | +| TensorListFromTensor | tensorflow::OpKernelContext::allocate_temp | +| TensorListGather | tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::eigen_gpu_device | +| TensorListGetItem | | +| TensorListLength | | +| TensorListPopBack | tensorflow::OpKernelContext::forward_input,tensorflow::OpKernelContext::input_memory_type | +| TensorListPushBack | tensorflow::OpKernelContext::forward_input,tensorflow::OpKernelContext::input_memory_type | +| TensorListPushBackBatch | tensorflow::OpKernelContext::allocate_persistent,tensorflow::OpKernelContext::forward_input | +| TensorListReserve | | +| TensorListResize | tensorflow::OpKernelContext::forward_input,tensorflow::OpKernelContext::input_memory_type | +| TensorListScatter | tensorflow::OpKernelContext::allocate_temp | +| TensorListScatterIntoExistingList | tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::forward_input,tensorflow::OpKernelContext::input_memory_type | +| TensorListSetItem | tensorflow::OpKernelContext::forward_input,tensorflow::OpKernelContext::input_memory_type | +| TensorListSplit | tensorflow::OpKernelContext::allocate_temp | +| TensorListStack | tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::eigen_gpu_device | +| TensorScatterOp | tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::forward_input | +| TensorSliceDatasetOp | | +| TestKernel | | +| TestOp | | +| TestOp2 | tensorflow::OpKernelConstruction::SetStatus | +| TestOp3Cpu | | +| TestOp3Gpu | | +| TestOp5Cpu | | +| TestOp5Gpu | | +| TextLineDatasetOp | | +| TextLineReaderOp | tensorflow::OpKernelConstruction::env,tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::cancellation_manager | +| TFRecordDatasetOp | | +| TFRecordReaderOp | tensorflow::OpKernelConstruction::env,tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::cancellation_manager | +| ThreadIDOp | | +| ThreadPoolDatasetOp | tensorflow::OpKernelContext::resource_manager | +| ThreadPoolHandleOp | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::env,tensorflow::OpKernelContext::resource_manager | +| TileGradientOp | | +| TileOp | | +| TimestampOp | | +| ToBoolOp | | +| TopK | | +| ToSingleElementOp | tensorflow::OpKernelContext::cancellation_manager,tensorflow::OpKernelContext::op_kernel | +| ToTFRecordOp | tensorflow::OpKernelConstruction::env,tensorflow::OpKernelContext::cancellation_manager,tensorflow::OpKernelContext::env,tensorflow::OpKernelContext::op_kernel | +| TransposeCpuOp | | +| TransposeGpuOp | | +| TransposeOp | | +| TridiagonalMatMulOp | | +| TridiagonalSolveOp | | +| TypedQueueOp | tensorflow::OpKernelConstruction::allocate_persistent,tensorflow::OpKernelConstruction::output_type,tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::resource_manager,tensorflow::OpKernelContext::set_output_ref | +| UnaryDatasetOpKernel | | +| UnaryElementWiseOp | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| UnaryOp | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| UnaryOpBase | | +| UnaryOpsComposition | tensorflow::OpKernelContext::forward_input_or_allocate_output | +| UnaryVariantOp | tensorflow::OpKernelContext::device | +| UnbatchDatasetOp | | +| UnbatchGradKernel | tensorflow::OpKernelContext::resource_manager | +| UnbatchKernel | tensorflow::OpKernelContext::resource_manager | +| UnicodeDecodeBaseOp | tensorflow::OpKernelConstruction::HasAttr | +| UnicodeDecodeOp | tensorflow::OpKernelConstruction::HasAttr | +| UnicodeDecodeWithOffsetsOp | tensorflow::OpKernelConstruction::HasAttr | +| UnicodeEncodeOp | tensorflow::OpKernelConstruction::HasAttr | +| UnicodeScriptOp | | +| UnicodeTranscodeOp | tensorflow::OpKernelConstruction::HasAttr,tensorflow::OpKernelContext::forward_input,tensorflow::OpKernelContext::input_alloc_attr,tensorflow::OpKernelContext::input_memory_type | +| UniqueDatasetOp | | +| UniqueOp | | +| UnpackOp | tensorflow::OpKernelContext::output_required | +| UnravelIndexOp | tensorflow::OpKernelContext::allocate_temp | +| UnsortedSegmentJoinOp | | +| UnsortedSegmentReductionOp | | +| UnstageOp | tensorflow::OpKernelContext::resource_manager | +| UnwrapDatasetVariantOp | | +| UpperBoundOp | | +| VarHandleOp | | +| VariableOp | | +| VariableShapeOp | tensorflow::OpKernelContext::resource_manager | +| VarIsInitializedOp | tensorflow::OpKernelContext::resource_manager | +| WhereCPUOp | | +| WhereGPUOp | tensorflow::OpKernelContext::allocate_temp,tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::op_device_context | +| WhileOp | tensorflow::OpKernelContext::cancellation_manager,tensorflow::OpKernelContext::function_library,tensorflow::OpKernelContext::rendezvous,tensorflow::OpKernelContext::run_all_kernels_inline,tensorflow::OpKernelContext::runner,tensorflow::OpKernelContext::stats_collector,tensorflow::OpKernelContext::step_container | +| WholeFileReaderOp | tensorflow::OpKernelConstruction::env,tensorflow::OpKernelContext::SetStatus,tensorflow::OpKernelContext::cancellation_manager | +| WindowDatasetOp | | +| WrapDatasetVariantOp | | +| WriteAudioSummaryOp | tensorflow::OpKernelContext::resource_manager | +| WriteFileOp | tensorflow::OpKernelContext::env | +| WriteGraphSummaryOp | tensorflow::OpKernelContext::resource_manager | +| WriteHistogramSummaryOp | tensorflow::OpKernelContext::resource_manager | +| WriteImageSummaryOp | tensorflow::OpKernelContext::resource_manager | +| WriteRawProtoSummaryOp | tensorflow::OpKernelContext::env,tensorflow::OpKernelContext::resource_manager | +| WriteScalarSummaryOp | tensorflow::OpKernelContext::resource_manager | +| WriteSummaryOp | tensorflow::OpKernelContext::resource_manager | +| ZerosLikeOp | tensorflow::OpKernelContext::device,tensorflow::OpKernelContext::forward_input_or_allocate_output | +| ZipDatasetOp | | + diff --git a/rfcs/20200712-tfrt-kernel-fallback/support_priority.md b/rfcs/20200712-tfrt-kernel-fallback/support_priority.md new file mode 100644 index 000000000..4af0cafaa --- /dev/null +++ b/rfcs/20200712-tfrt-kernel-fallback/support_priority.md @@ -0,0 +1,56 @@ +| Method | Num of kernels supported if implemented | +| :---------- | :---------- | +| tensorflow::OpKernelContext::resource_manager | 46 | +| tensorflow::OpKernelContext::forward_input_or_allocate_output | 35 | +| tensorflow::OpKernelContext::allocate_temp | 40 | +| tensorflow::OpKernelContext::device | 26 | +| tensorflow::OpKernelContext::input_list | 25 | +| tensorflow::OpKernelContext::SetStatus | 25 | +| tensorflow::OpKernelContext::op_device_context | 23 | +| tensorflow::OpKernelConstruction::HasAttr | 18 | +| tensorflow::OpKernelContext::env | 15 | +| tensorflow::OpKernelContext::output_list | 12 | +| tensorflow::OpKernelConstruction::device_type | 10 | +| tensorflow::OpKernelContext::eigen_cpu_device | 9 | +| tensorflow::OpKernelContext::eigen_gpu_device | 8 | +| tensorflow::OpKernelContext::allocate_persistent | 7 | +| tensorflow::OpKernelContext::function_library | 6 | +| tensorflow::OpKernelContext::set_output_ref | 5 | +| tensorflow::OpKernelConstruction::env | 5 | +| tensorflow::OpKernelContext::cancellation_manager | 9 | +| tensorflow::OpKernelContext::op_kernel | 4 | +| tensorflow::OpKernelContext::forward_input_or_allocate_temp | 4 | +| tensorflow::OpKernelContext::forward_input | 4 | +| tensorflow::OpKernelContext::input_memory_type | 6 | +| tensorflow::OpKernelContext::input_alloc_attr | 6 | +| tensorflow::OpKernelConstruction::input_type | 4 | +| tensorflow::OpKernelConstruction::device | 4 | +| tensorflow::OpKernelContext::output_required | 3 | +| tensorflow::OpKernelConstruction::resource_manager | 3 | +| tensorflow::OpKernelConstruction::graph_def_version | 3 | +| tensorflow::OpKernelConstruction::allocate_persistent | 3 | +| tensorflow::OpKernelConstruction::output_type | 9 | +| tensorflow::OpKernelContext::MatchSignature | 5 | +| tensorflow::OpKernelContext::session_state | 2 | +| tensorflow::OpKernelContext::mutable_input | 2 | +| tensorflow::OpKernelContext::input_ref_mutex | 2 | +| tensorflow::OpKernelContext::input_dtype | 31 | +| tensorflow::OpKernelContext::forward_ref_input_to_ref_output | 34 | +| tensorflow::OpKernelContext::step_container | 8 | +| tensorflow::OpKernelContext::expected_output_dtype | 3 | +| tensorflow::OpKernelContext::slice_reader_cache | 2 | +| tensorflow::OpKernelContext::output_alloc_attr | 2 | +| tensorflow::OpKernelContext::mutable_output | 2 | +| tensorflow::OpKernelContext::forward_input_to_output_with_shape | 2 | +| tensorflow::OpKernelConstruction::def | 2 | +| tensorflow::OpKernelConstruction::SetStatus | 2 | +| tensorflow::OpKernelContext::tensor_store | 1 | +| tensorflow::OpKernelContext::step_id | 1 | +| tensorflow::OpKernelContext::frame_iter | 8 | +| tensorflow::OpKernelContext::collective_executor | 4 | +| tensorflow::OpKernelContext::session_metadata | 1 | +| tensorflow::OpKernelContext::run_all_kernels_inline | 1 | +| tensorflow::OpKernelContext::mutable_input_list | 1 | +| tensorflow::OpKernelConstruction::function_library | 1 | +| | 1 | + From 282504ef98a86e9a0dadded0b65ebd0d400df11d Mon Sep 17 00:00:00 2001 From: Anna Revinskaya Date: Tue, 14 Jul 2020 21:35:14 -0700 Subject: [PATCH 09/29] Added header --- .../20200712-tfrt-kernel-fallback/support_priority.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/rfcs/20200712-tfrt-kernel-fallback/support_priority.md b/rfcs/20200712-tfrt-kernel-fallback/support_priority.md index 4af0cafaa..838cc6ecd 100644 --- a/rfcs/20200712-tfrt-kernel-fallback/support_priority.md +++ b/rfcs/20200712-tfrt-kernel-fallback/support_priority.md @@ -1,5 +1,12 @@ +## Order of OpKernelContext/OpKernelConstruction method support priority in Kernel Fallback + +Note that this list excludes some the methods we already support in our prototype, specifically: + +* OpKernelConstruction: `GetAttr`, `CtxFailure`, `CtxFailureWithWarning`. +* OpKernelContext: `input`, `num_inputs`, `set_output`, `num_outputs`, `allocate_output`, `expected_output_dtype`, `eigen_device`, `CtxFailure`, `CtxFailureWithWarning`. + | Method | Num of kernels supported if implemented | -| :---------- | :---------- | +| :----- | :-------------------------------------- | | tensorflow::OpKernelContext::resource_manager | 46 | | tensorflow::OpKernelContext::forward_input_or_allocate_output | 35 | | tensorflow::OpKernelContext::allocate_temp | 40 | @@ -52,5 +59,5 @@ | tensorflow::OpKernelContext::run_all_kernels_inline | 1 | | tensorflow::OpKernelContext::mutable_input_list | 1 | | tensorflow::OpKernelConstruction::function_library | 1 | -| | 1 | + From d562b7e3ddfe279c6c698c3031cf7f3902069d14 Mon Sep 17 00:00:00 2001 From: Anna Revinskaya Date: Tue, 14 Jul 2020 21:40:03 -0700 Subject: [PATCH 10/29] Added header to kernel_to_unsupported --- .../kernel_to_unsupported.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/rfcs/20200712-tfrt-kernel-fallback/kernel_to_unsupported.md b/rfcs/20200712-tfrt-kernel-fallback/kernel_to_unsupported.md index 9084b7108..6ceca0f5d 100644 --- a/rfcs/20200712-tfrt-kernel-fallback/kernel_to_unsupported.md +++ b/rfcs/20200712-tfrt-kernel-fallback/kernel_to_unsupported.md @@ -1,5 +1,14 @@ -| OpKernel | Unsupported context methods | -| :---------- | :---------- | +## Kernel OpKernelContext/OpKernelConstruction method dependencies + +Note that this spreadsheet assumes the following methods are supported: + +* OpKernelConstruction: `GetAttr`, `CtxFailure`, `CtxFailureWithWarning`, `MatchSignature`. +* OpKernelContext: `input`, `num_inputs`, `set_output`, `num_outputs`, `allocate_output`, `expected_output_dtype`, `eigen_device`, `CtxFailure`, `CtxFailureWithWarning`, `forward_input_to_output_with_shape`, `ValidateInputsAreSameShape`. + +Note: This table is created by analyzing which methods are called down to 2 function calls of indirection. As such it is an approximation. + +| OpKernel | Unsupported context methods | +| :---------- | :-------------------------- | | _HostConstantOp | | | AbortOp | | | AccumulatorApplyGradientOp | tensorflow::OpKernelContext::MatchSignature,tensorflow::OpKernelContext::input_dtype,tensorflow::OpKernelContext::input_ref_mutex,tensorflow::OpKernelContext::mutable_input,tensorflow::OpKernelContext::resource_manager | From 120f58c36d624c3a8adbf4d8a7575d24aa52594f Mon Sep 17 00:00:00 2001 From: Anna Revinskaya Date: Tue, 14 Jul 2020 21:46:00 -0700 Subject: [PATCH 11/29] Mention that the doc is an approximation --- rfcs/20200712-tfrt-kernel-fallback/support_priority.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rfcs/20200712-tfrt-kernel-fallback/support_priority.md b/rfcs/20200712-tfrt-kernel-fallback/support_priority.md index 838cc6ecd..3c436d342 100644 --- a/rfcs/20200712-tfrt-kernel-fallback/support_priority.md +++ b/rfcs/20200712-tfrt-kernel-fallback/support_priority.md @@ -1,10 +1,14 @@ ## Order of OpKernelContext/OpKernelConstruction method support priority in Kernel Fallback +Higher priority is assigned to methods that enable us to support the most number of kernels. At the same time, a high-priority method that requires a significant amount of work might be implemented later. `resource_manager` specifically is a frequently-used method, but would require a lot of work. Therefore, we might first implement other methods. Also, number of supported kernels is calculated assuming all methods above it in the table are implemented. + Note that this list excludes some the methods we already support in our prototype, specifically: * OpKernelConstruction: `GetAttr`, `CtxFailure`, `CtxFailureWithWarning`. * OpKernelContext: `input`, `num_inputs`, `set_output`, `num_outputs`, `allocate_output`, `expected_output_dtype`, `eigen_device`, `CtxFailure`, `CtxFailureWithWarning`. +Note: This table is created by analyzing which methods are called down to 2 function calls of indirection. As such it is an approximation. + | Method | Num of kernels supported if implemented | | :----- | :-------------------------------------- | | tensorflow::OpKernelContext::resource_manager | 46 | From 64845de0a6b7370e35acd2da82a0721cf6cc95a8 Mon Sep 17 00:00:00 2001 From: Anna Revinskaya Date: Tue, 14 Jul 2020 21:49:07 -0700 Subject: [PATCH 12/29] Adding links to supplemental tables --- rfcs/20200712-tfrt-kernel-fallback.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rfcs/20200712-tfrt-kernel-fallback.md b/rfcs/20200712-tfrt-kernel-fallback.md index 995781b1e..9436cbf13 100644 --- a/rfcs/20200712-tfrt-kernel-fallback.md +++ b/rfcs/20200712-tfrt-kernel-fallback.md @@ -60,9 +60,9 @@ consideres these methods to be already *supported*). * List of kernels and `OpKernelConstruction`/`OpKernelContext` methods they require: - [spreadsheet](https://docs.google.com/spreadsheets/d/18bOu2gJQnZtCRGPZ4yerEAKUHgp1V429dPdCuzoCSkU/edit?usp=sharing) + [here](https://github.com/annarev/community/blob/tfrt_kernel_fallback_rfc/rfcs/20200712-tfrt-kernel-fallback/support_priority.md) * Proposed implementation order for these methods: - [spreadsheet](https://docs.google.com/spreadsheets/d/10u6tcTE9PAi45A04nxSz61whSnwhscRLlSUNRPJugIY/edit?usp=sharing) + [here](https://github.com/annarev/community/blob/tfrt_kernel_fallback_rfc/rfcs/20200712-tfrt-kernel-fallback/kernel_to_unsupported.md) Based on these estimates, we can support >= 423 kernels. Note that this number is just based on the `OpKernelConstruction`/`OpKernelContext` coverage that we From 07f8551b63effd3c4b9546a76abe1782daba31a4 Mon Sep 17 00:00:00 2001 From: Anna Revinskaya Date: Tue, 14 Jul 2020 21:53:54 -0700 Subject: [PATCH 13/29] Updated date --- rfcs/20200712-tfrt-kernel-fallback.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/20200712-tfrt-kernel-fallback.md b/rfcs/20200712-tfrt-kernel-fallback.md index 9436cbf13..3c51b556f 100644 --- a/rfcs/20200712-tfrt-kernel-fallback.md +++ b/rfcs/20200712-tfrt-kernel-fallback.md @@ -5,7 +5,7 @@ | **RFC #** | [NNN](https://github.com/tensorflow/community/pull/NNN) | | **Author(s)** | Anna Revinskaya (annarev@google.com), Jeremy Lau (lauj@google.com) | | **Sponsor** | Jeremy Lau (lauj@google.com) | -| **Updated** | 2020-07-06 | +| **Updated** | 2020-07-14 | ## Objective From 5739ee005f7ff4b64c62804cfc9ec3f4d0cf63f3 Mon Sep 17 00:00:00 2001 From: Anna Revinskaya Date: Wed, 15 Jul 2020 10:36:56 -0700 Subject: [PATCH 14/29] Updated RFC link --- rfcs/20200712-tfrt-kernel-fallback.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/20200712-tfrt-kernel-fallback.md b/rfcs/20200712-tfrt-kernel-fallback.md index 3c51b556f..4fa8cce4e 100644 --- a/rfcs/20200712-tfrt-kernel-fallback.md +++ b/rfcs/20200712-tfrt-kernel-fallback.md @@ -2,7 +2,7 @@ | Status | (Proposed / Accepted / Implemented / Obsolete) | | :------------ | :------------------------------------------------------ | -| **RFC #** | [NNN](https://github.com/tensorflow/community/pull/NNN) | +| **RFC #** | [266](https://github.com/tensorflow/community/pull/266) | | **Author(s)** | Anna Revinskaya (annarev@google.com), Jeremy Lau (lauj@google.com) | | **Sponsor** | Jeremy Lau (lauj@google.com) | | **Updated** | 2020-07-14 | From 1ea76e1850acff9bcfa9c302b3b652903674d5cd Mon Sep 17 00:00:00 2001 From: Anna Revinskaya Date: Wed, 15 Jul 2020 10:54:44 -0700 Subject: [PATCH 15/29] Rewarded first paragraph of objective --- rfcs/20200712-tfrt-kernel-fallback.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/rfcs/20200712-tfrt-kernel-fallback.md b/rfcs/20200712-tfrt-kernel-fallback.md index 4fa8cce4e..1611701c8 100644 --- a/rfcs/20200712-tfrt-kernel-fallback.md +++ b/rfcs/20200712-tfrt-kernel-fallback.md @@ -9,10 +9,9 @@ ## Objective -This proposal focuses on getting majority of “well-behaved” ops running in -[TF Lite](https://www.tensorflow.org/lite) by skipping current eager runtime and -calling kernels directly from [TFRT](https://github.com/tensorflow/runtime) (a new -TensorFlow runtime). +This proposal focuses on getting a majority of "well-behaved" TensorFlow ops running efficiently on +mobile devices by removing the need to execute them via the TensorFlow eager runtime, instead +calling kernels directly from the new [TFRT](https://github.com/tensorflow/runtime) TensorFlow runtime. Note that there is an effort to call existing kernels by delegating to TensorFlow eager runtime instead. This approach is called Runtime Fallback and From f23f300635707e5b2f6a6ede1d8b6161f6f98dda Mon Sep 17 00:00:00 2001 From: Anna Revinskaya Date: Thu, 16 Jul 2020 12:32:14 -0700 Subject: [PATCH 16/29] Addressed some of the comments --- rfcs/20200712-tfrt-kernel-fallback.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/rfcs/20200712-tfrt-kernel-fallback.md b/rfcs/20200712-tfrt-kernel-fallback.md index 1611701c8..198ddb521 100644 --- a/rfcs/20200712-tfrt-kernel-fallback.md +++ b/rfcs/20200712-tfrt-kernel-fallback.md @@ -37,7 +37,7 @@ High level goals of the project: We address the first goal by implementing a new fallback mechanism that directly calls TensorFlow kernels without going through Eager runtime first. We plan to address the second high level goal by trimming down dependencies, switching to -more compact proto representation, etc.. +more compact proto representation, etc. ### Op Coverage Goals @@ -116,7 +116,7 @@ to TensorFlow kernels that minimizes the amount of generated code. ## User Benefit Running more kernels on mobile devices would allow TensorFlow Lite users to implement -a wider range of models. +a wider range of models. Reduced binary size will also benefit users that currently use TensorFlow Lite's experimental [TensorFlow Select ops] (https://www.tensorflow.org/lite/guide/ops_select), or users that do not use the experimental feature because of that reason. ## Design Proposal @@ -150,7 +150,7 @@ class TFRTOpKernelFactories { // 1. Kernel with the given name is not found. // 2. Attributes in op_kernel_construction don't match type constraints // for any of the kernels with this name. - // Note that we consider a constraint to be "not matched" if attribute + // Note that we consider a constraint to be "not matched" if the attribute // it applies to is not in op_kernel_construction. std::unique_ptr CreateKernel( StringPiece kernel_class_name, @@ -164,7 +164,7 @@ extern llvm::ManagedStatic tfrt_forwarding_kernel_factories; ``` -Similar to current TensorFlow kernel registartion, we will introduce a +Similar to the current TensorFlow kernel registration, we will introduce a registration macro that adds a kernel to `TFRTOpKernelFactories`. ```cpp @@ -336,7 +336,7 @@ Runtime Fallback work that will probably have RFC coming soon): Example of invoking Conv3D kernel: ``` -%tft_c = "tfd.kernel_fallback"(%tft_a, %tft_b) { +%tft_c = "tfrt_fallback.kernel_fallback"(%tft_a, %tft_b) { _op_name = "Conv3D", attr1_name="data_format", attr1_value="string$NDHWC", attr2_name="strides", attr2_value="list(i32)$1,1,1,1,1", From 0c21e43681363b23f96a1c63c5abee65342a93fc Mon Sep 17 00:00:00 2001 From: Anna Revinskaya Date: Thu, 16 Jul 2020 12:33:02 -0700 Subject: [PATCH 17/29] Fixed typo --- rfcs/20200712-tfrt-kernel-fallback.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/20200712-tfrt-kernel-fallback.md b/rfcs/20200712-tfrt-kernel-fallback.md index 198ddb521..4b4d483f8 100644 --- a/rfcs/20200712-tfrt-kernel-fallback.md +++ b/rfcs/20200712-tfrt-kernel-fallback.md @@ -55,7 +55,7 @@ and classes. Number of supported kernels will depend on the surface we manage to customize. (Note that I have already started prototyping the implementation that includes a few common methods such as `input`, `output`. The spreadsheet below -consideres these methods to be already *supported*). +considers these methods to be already *supported*). * List of kernels and `OpKernelConstruction`/`OpKernelContext` methods they require: From 7a1f0b7a9befc231dc3e60d3b96d27a8cdd84d83 Mon Sep 17 00:00:00 2001 From: Anna Revinskaya Date: Thu, 16 Jul 2020 12:44:25 -0700 Subject: [PATCH 18/29] Add details for the mobile benchmark --- rfcs/20200712-tfrt-kernel-fallback.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/20200712-tfrt-kernel-fallback.md b/rfcs/20200712-tfrt-kernel-fallback.md index 4b4d483f8..5970e2ad0 100644 --- a/rfcs/20200712-tfrt-kernel-fallback.md +++ b/rfcs/20200712-tfrt-kernel-fallback.md @@ -212,7 +212,7 @@ and templating approaches. Key findings are summarized below: * Time difference negligible for full model benchmarks. * A simple scalar op benchmark with Kernel Fallback (runs scalar multiplication, division, addition) was only 0.3% slower on mobile with - inheritance compared to templates. + inheritance compared to templates. The benchmark was run on a real device (Pixel 3) with ABI: arm64-v8a and SDK version: 29. * [basic\_ops\_benchmark](https://cs.opensource.google/tensorflow/tensorflow/+/master:tensorflow/core/kernels/basic_ops_benchmark_test.cc?q=basic_ops_benchmark_test) with inheritance is significantly slower: ~7% (median) or ~19% (mean) (running on Linux). Note that this difference was measured *without* Kernel From a0c5216c5488320033ebf6802a51fbac7254b93b Mon Sep 17 00:00:00 2001 From: Anna Revinskaya Date: Thu, 16 Jul 2020 17:24:40 -0700 Subject: [PATCH 19/29] Appendix 2: Inheritance vs templates --- rfcs/20200712-tfrt-kernel-fallback.md | 117 +++++++++++++++++++++++++- 1 file changed, 113 insertions(+), 4 deletions(-) diff --git a/rfcs/20200712-tfrt-kernel-fallback.md b/rfcs/20200712-tfrt-kernel-fallback.md index 5970e2ad0..c0f0d9df4 100644 --- a/rfcs/20200712-tfrt-kernel-fallback.md +++ b/rfcs/20200712-tfrt-kernel-fallback.md @@ -220,10 +220,10 @@ and templating approaches. Key findings are summarized below: even those that don't support Kernel Fallback. * Binary size increase when using templates compared to inheritance is estimated at 2.6% (based on adding `AddN` op). - + Right now, we are leaning towards using inheritance. Seems like time increase is only significant for running many scalar ops in a sequence - probably a rare use -case in the real world. +case in the real world. (See more details in [Appendix 2](#appendix-2-extension-options)) To use inheritance, we will define `OpKernelConstructionInterface` and `OpKernelContextInterface` interfaces. Ideally, these interfaces should be pure @@ -283,7 +283,7 @@ class OpKernelBase { ``` (For details how extending from `OpKernelBase` instead of `OpKernel` would work -with current TensorFlow runtime see [Appendix 1](#appendix-1)) +with current TensorFlow runtime see [Appendix 1](#appendix-1-kernel-wrapper)) Corresponding .cc file then registers the kernel using the correct kernel and context classes. For example, this is how we register `AddN` kernel with TFRT: @@ -582,7 +582,7 @@ This proposal should not impact compatibility. Seed this with open questions you require feedback on from the RFC process. -## Appendix 1 +## Appendix 1: Kernel wrapper As discussed above, we want to convert (some) kernels to extend from `OpKernelBase` instead of `OpKernel`. This lets us remove runtime-specific @@ -644,3 +644,112 @@ This approach has several benefits: * Converted kernels registered with TFRT only depend on `OpKernelBase` (for example, they do not have `NodeDef`-related properties that are not supported by TFRT). + +## Appendix 2: Extension options + +This document proposes to have custom versions of `OpKernel`, `OpKernelContext` and `OpKernelConstruction` classes implemented in terms of TFRT primitives. +There are a few ways we can approach this implementation. `OpKernel*` classes can be customized using inheritance or templates. + +### Inheritance + +Inheritance involves defining `OpKernelBase` base class and `OpKernelConstructionInterface`/`OpKernelContextInterface` interfaces. This approach is described in detail in the [core part of this document](#kernel-implementation). + +### Templates + +Alternatively, we can customize kernel implementation using templates by adding a `template` header to each kernel (consecutively, moving kernel implementations to header files). +Example of AddN kernel implementation with templates: + +```cpp +template +class AddNOp : public OpKernelT { +public: + explicit AddNOp(OpKernelConstructionT* construction) + : OpKernelT(construction) {} + + void Compute(OpKernelContextT* ctx) override { + if (!ctx->ValidateInputsAreSameShape(this)) return; + ... +``` +Note, this is the original approach we were thinking of going with, the [actual AddN kernel implementation](https://cs.opensource.google/tensorflow/tensorflow/+/master:tensorflow/core/kernels/aggregate_ops.h;l=231?q=aggregate_ops.h) already follows this pattern. + +Templates will be specialized at registration time: + +```cpp +REGISTER_FALLBACK_KERNEL( + "AddN", + AddNOp); +``` + +### Inheritance vs Templates trade off + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Templates + Inheritance +
Latency + Same + Increase (vtable lookups) (negligible for model benchmarks, 7% median/19% mean increase for `basic_ops_benchmark`) +
Binary size (one implementation linked in) + Same + Same +
Binary size (two implementations linked in) + Increase the most (2.6% estimate for AddN) + Increase in some cases* +
Requires kernel changes + Yes (move to header, add template declaration) + Yes (add include, change OpKernel to OpKernelBase, OpKernel* to OpKernel*Interface) +
Requires kernel changes for kernels *unsupported* by TFRT Kernel Fallback + No + No +
Effects unconverted kernels + No + Yes (OpKernelConstruction/OpKernelContext now implement interfaces) +
+ +\* Increase will happen when we have intermediate subclass of `OpKernel`. For example, [AveragePoolingOp](https://cs.opensource.google/tensorflow/tensorflow/+/master:tensorflow/core/kernels/avgpooling_op.cc;l=56?q=%22:%20public%20UnaryOp%22) extends `UnaryOp` and `UnaryOp` extends `OpKernel`. In this case, `UnaryOp` is the *intermediate subclass*. Now that a kernel can inherit either from `OpKernel` or `OpKernelBase`, we would need two implementations: `UnaryOp` and `UnaryOpBase` respectively. Kernels that support Kernel Fallback and inherit `UnaryOp` now will instead switch to inherit `UnaryOpBase`. Addition of `UnaryOpBase` increases binary size. + +### Selected approach + +Currently we are thinking of proceeding with the inheritance approach. + +Inheritance seems to add negligible overhead to kernels for most benchmarks that we ran. +However, it does introduce a ~7% median, ~19% mean penalty for [basic_ops_benchmark](https://cs.opensource.google/tensorflow/tensorflow/+/master:tensorflow/core/kernels/basic_ops_benchmark_test.cc?q=basic_ops_benchmark&ss=tensorflow%2Ftensorflow) which runs a series of scalar multiplications and is used to measure kernel overhead. + +Therefore, we expect that using inheritance would not add a noticeable overhead in most real world models. At the same time, inheritance can simplify code structure and debugging. + From a95a9404706905ba8be5b593109ef30b07f5cb8b Mon Sep 17 00:00:00 2001 From: Anna Revinskaya Date: Thu, 16 Jul 2020 17:46:06 -0700 Subject: [PATCH 20/29] Addressed more comments Most significant update: added example for op registration. --- rfcs/20200712-tfrt-kernel-fallback.md | 60 ++++++++++++++++++++------- 1 file changed, 44 insertions(+), 16 deletions(-) diff --git a/rfcs/20200712-tfrt-kernel-fallback.md b/rfcs/20200712-tfrt-kernel-fallback.md index c0f0d9df4..d59b234ff 100644 --- a/rfcs/20200712-tfrt-kernel-fallback.md +++ b/rfcs/20200712-tfrt-kernel-fallback.md @@ -1,11 +1,11 @@ # TFRT Kernel Fallback -| Status | (Proposed / Accepted / Implemented / Obsolete) | +| Status | Proposed | | :------------ | :------------------------------------------------------ | | **RFC #** | [266](https://github.com/tensorflow/community/pull/266) | | **Author(s)** | Anna Revinskaya (annarev@google.com), Jeremy Lau (lauj@google.com) | | **Sponsor** | Jeremy Lau (lauj@google.com) | -| **Updated** | 2020-07-14 | +| **Updated** | 2020-07-16 | ## Objective @@ -160,23 +160,22 @@ class TFRTOpKernelFactories { llvm::StringMap> factories_; }; -extern llvm::ManagedStatic - tfrt_forwarding_kernel_factories; +extern llvm::ManagedStatic fallback_kernel_factories; ``` Similar to the current TensorFlow kernel registration, we will introduce a registration macro that adds a kernel to `TFRTOpKernelFactories`. ```cpp -#define REGISTER_KERNEL_FALLBACK_KERNEL(name, ...) \ - REGISTER_KERNEL_FALLBACK_KERNEL_UNIQ_HELPER(__COUNTER__, name, __VA_ARGS__) +#define REGISTER_FALLBACK_KERNEL(name, ...) \ + REGISTER_FALLBACK_KERNEL_UNIQ_HELPER(__COUNTER__, name, __VA_ARGS__) -#define REGISTER_KERNEL_FALLBACK_KERNEL_UNIQ_HELPER(ctr, name, ...) \ - REGISTER_KERNEL_FALLBACK_KERNEL_UNIQ(ctr, name, __VA_ARGS__) +#define REGISTER_FALLBACK_KERNEL_UNIQ_HELPER(ctr, name, ...) \ + REGISTER_FALLBACK_KERNEL_UNIQ(ctr, name, __VA_ARGS__) -#define REGISTER_KERNEL_FALLBACK_KERNEL_UNIQ(ctr, name, ...) \ - static bool global_tfrt_forwarding_kernel_##ctr##_registered_ = []() { \ - ::tensorflow::tfrt_forwarding_kernel_factories->RegisterFactory( \ +#define REGISTER_FALLBACK_KERNEL_UNIQ(ctr, name, ...) \ + static bool global_fallback_kernel_##ctr##_registered_ = []() { \ + ::tensorflow::fallback_kernel_factories->RegisterFactory( \ name, TFRTOpKernelReg([](TFRTOpKernelConstruction* construction) \ -> std::unique_ptr { \ return std::make_unique<__VA_ARGS__>(construction); \ @@ -188,7 +187,36 @@ registration macro that adds a kernel to `TFRTOpKernelFactories`. ## Op registration To support type specification, we will also provide a minimal Op registry and -corresponding macro `REGISTER_KERNEL_FALLBACK_OP`. +corresponding macro `REGISTER_KERNEL_FALLBACK_OP`. Sample implementation: + +```cpp +// TFRTOpMetaBuilder class will provide ways to set input, output and +// attribute specifications. +class TFRTOpMetaBuilder { + public: + explicit TFRTOpMetaBuilder(StringPiece op_name); + TFRTOpMetaBuilder& Output(StringPiece output_spec); + ... +}; + +// Registration will add the op to a static map. +class TFRTOpRegisterer { + public: + TFRTOpRegisterer(const TFRTOpMetaBuilder& op_builder); +}; + +#define REGISTER_KERNEL_FALLBACK_OP(name) \ + REGISTER_KERNEL_FALLBACK_OP_UNIQ(__COUNTER__, name) + +#define REGISTER_KERNEL_FALLBACK_OP_UNIQ(ctr, name) \ + static TFRTOpRegisterer global_fallback_op_meta_builder_##ctr##_ = \ + TFRTOpMetaBuilder(name) +``` + +Usage example: +```cpp +REGISTER_KERNEL_FALLBACK_OP("AddN").Output("out: int32"); +``` ## Kernel implementation @@ -252,7 +280,7 @@ class TFRTOpKernelConstruction : public OpKernelConstructionInterface { }; ``` -When forwarding, we instantiate the kernel interfaces with TFRT’s lightweight +When running Kernel Fallback, we instantiate the kernel interfaces with TFRT’s lightweight OpKernel definitions, rather than TensorFlow’s [heavyweight OpKernel definitions](https://cs.opensource.google/android/platform/superproject/+/master:external/tensorflow/tensorflow/core/framework/op_kernel.h;l=612?q=opkernelcontext) for example. @@ -289,7 +317,7 @@ Corresponding .cc file then registers the kernel using the correct kernel and context classes. For example, this is how we register `AddN` kernel with TFRT: ```cpp -REGISTER_KERNEL_FALLBACK_KERNEL( "AddN", AddNOp); +REGISTER_FALLBACK_KERNEL( "AddN", AddNOp); ``` ## Calling kernel @@ -429,7 +457,7 @@ few notable exceptions: * TFRT Kernel Fallback implementation will use Kernel Fallback registration mechanism. -### TFRT forwarding kernel registration using C API +### TFRT Kernel Fallback registration using C API We plan to implement C API for TFRT kernel registration that calls TFRT Kernel Fallback registration mechanism. Note that this is analogous to TF Lite @@ -652,7 +680,7 @@ There are a few ways we can approach this implementation. `OpKernel*` classes ca ### Inheritance -Inheritance involves defining `OpKernelBase` base class and `OpKernelConstructionInterface`/`OpKernelContextInterface` interfaces. This approach is described in detail in the [core part of this document](#kernel-implementation). +Inheritance involves defining `OpKernelBase` base class and `OpKernelConstructionInterface`/`OpKernelContextInterface` interfaces. This approach is described in detail in the [Kernel implementation](#kernel-implementation) section above. ### Templates From b0c7152ac939f48870b6eb7b79e9ab15f3a7f3f9 Mon Sep 17 00:00:00 2001 From: Anna Revinskaya Date: Thu, 16 Jul 2020 19:30:42 -0700 Subject: [PATCH 21/29] Removed reference to TF Lite from kernel selection --- rfcs/20200712-tfrt-kernel-fallback.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/rfcs/20200712-tfrt-kernel-fallback.md b/rfcs/20200712-tfrt-kernel-fallback.md index d59b234ff..53679b070 100644 --- a/rfcs/20200712-tfrt-kernel-fallback.md +++ b/rfcs/20200712-tfrt-kernel-fallback.md @@ -539,9 +539,8 @@ helps us cut down on binary size. ## Selecting which kernels to register -We want to add a script to the TF Lite build setup that can determine required -kernels based on a model. We would then only build these kernels. For now, we -will only support selective registration when building from source. +We want to add a script to build configurations that can determine required +kernels based on a model. We would then only build these kernels. For now, we will only support selective registration when building from source. Script details still need to be worked out. @@ -552,11 +551,14 @@ Runtime Fallback will call TensorFlow Eager C API (corresponding RFC should be published soon). Main trade offs between the two fallbacks are described in the table below: -Property | TFRT Kernel Fallback | TFRT Runtime Fallback ------------ | --------------------- | --------------------- -Generality | Support subset of ops | Support all ops -Performance | Lower overhead | Higher overhead -Binary size | Lower (no TF runtime) | Higher +Property | TFRT Kernel Fallback | TFRT Runtime Fallback +----------- | ---------------------------------------------- | --------------------- +Generality | Support subset of ops (for e.g. no resources*) | Support all ops +Performance | Lower overhead | Higher overhead +Binary size | Lower (no TF runtime) | Higher + +\* Long term we might support resources, but we consider them lower priority +due to significant work involved. ### Performance Implications From 7cb88dd3c30480a9325af9b7394e6f7454b7b523 Mon Sep 17 00:00:00 2001 From: Anna Revinskaya Date: Thu, 16 Jul 2020 19:43:41 -0700 Subject: [PATCH 22/29] Added Engineering impact details --- rfcs/20200712-tfrt-kernel-fallback.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/rfcs/20200712-tfrt-kernel-fallback.md b/rfcs/20200712-tfrt-kernel-fallback.md index 53679b070..7cbcc1593 100644 --- a/rfcs/20200712-tfrt-kernel-fallback.md +++ b/rfcs/20200712-tfrt-kernel-fallback.md @@ -581,6 +581,23 @@ No new dependencies. kernels in TF Lite. * Code will be maintained by TensorFlow DevInfra and TFRT teams. +#### Current Status + +* We have a Kernel Fallback prototype +* Prototype support for two kernels: `AddN` and `Conv3D` +* Current binary size estimates (based on Android arm64 build): 1MB for framework and 100k per kernel per type. + +#### Planned work + +* Finalize integration with TFRT. +* Convert a subset of TensorFlow kernels to support Kernel Fallback. + +#### Success metrics + +* Binary size small enough to run on mobile platforms. +* Increased kernel coverage on mobile platforms. + + ### Platforms and Environments * Primarily geared towards mobile platforms but should work on non-mobile From 510f318f839e9067afb268226659103cae672ba7 Mon Sep 17 00:00:00 2001 From: Anna Revinskaya Date: Mon, 27 Jul 2020 11:50:29 -0700 Subject: [PATCH 23/29] Size benchmark details --- rfcs/20200712-tfrt-kernel-fallback.md | 36 ++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/rfcs/20200712-tfrt-kernel-fallback.md b/rfcs/20200712-tfrt-kernel-fallback.md index 7cbcc1593..664b7152f 100644 --- a/rfcs/20200712-tfrt-kernel-fallback.md +++ b/rfcs/20200712-tfrt-kernel-fallback.md @@ -585,7 +585,7 @@ No new dependencies. * We have a Kernel Fallback prototype * Prototype support for two kernels: `AddN` and `Conv3D` -* Current binary size estimates (based on Android arm64 build): 1MB for framework and 100k per kernel per type. +* Current binary size estimates (based on Android arm64 build): 900k for framework and 200k per kernel per type (see [Appendix 3](#appendix-3-benchmarking-size)). #### Planned work @@ -800,3 +800,37 @@ However, it does introduce a ~7% median, ~19% mean penalty for [basic_ops_benchm Therefore, we expect that using inheritance would not add a noticeable overhead in most real world models. At the same time, inheritance can simplify code structure and debugging. + +## Appendix 3: Benchmarking size + +To benchmark size, we created a git branch that contains Kernel Fallback prototype: +https://github.com/annarev/tensorflow/tree/kernel_fallback/tensorflow/core/tfrt_fallback/kernel (Note we had to make some other changes: [branch comparison](https://github.com/annarev/tensorflow/compare/master...annarev:kernel_fallback)). + +Android settings used when running `./configure`: + +* NDK: r18b +* NDK API level: 19 +* Android build tools version: 30.0.1 +* Android SDK API level: 28 + +We check size of a dependency by adding it to [//tensorflow/lite/java:libtensorflowlite_jni.so](https://github.com/annarev/tensorflow/blob/kernel_fallback/tensorflow/lite/java/BUILD#L415) target and running +``` +bazel build -c opt tensorflow/lite/java/libtensorflowlite_jni.so --config=android_arm64 --define=disable_rtti_and_exceptions=true --define disable_eigen_mkldnn_contraction_kernel=true --define=TENSORFLOW_PROTOS=lite + +ls -lh bazel-bin/tensorflow/lite/java/libtensorflowlite_jni.so +``` + +Findings are presented in the table below: + +| Deps | Size | +| :--------------------------------------------------------- | :--- | +| Existing TF Lite | 2.3M | +| Existing TF Lite + Kernel Fallback framework | 3.2M | +| Existing TF Lite + Kernel Fallback framework + 2 kernels\* | 3.6M | + +\* Kernels used for benchmarking: AddN registered for int32, Conv3d registered for int32. + +Therefore, we estimate the following current size measurements: + +* Kernel Fallback framework: 900k +* Per-kernel per-type: 200k From 4c01f6d170e76dec6006cd5a0883dcd9165ad673 Mon Sep 17 00:00:00 2001 From: Anna Revinskaya Date: Mon, 27 Jul 2020 22:47:15 -0700 Subject: [PATCH 24/29] Compare kernel vs runtime fallback scalability --- rfcs/20200712-tfrt-kernel-fallback.md | 1 + 1 file changed, 1 insertion(+) diff --git a/rfcs/20200712-tfrt-kernel-fallback.md b/rfcs/20200712-tfrt-kernel-fallback.md index 664b7152f..1a2bb8c57 100644 --- a/rfcs/20200712-tfrt-kernel-fallback.md +++ b/rfcs/20200712-tfrt-kernel-fallback.md @@ -554,6 +554,7 @@ table below: Property | TFRT Kernel Fallback | TFRT Runtime Fallback ----------- | ---------------------------------------------- | --------------------- Generality | Support subset of ops (for e.g. no resources*) | Support all ops +Scalability | Requires per-kernel updates | No kernel changes Performance | Lower overhead | Higher overhead Binary size | Lower (no TF runtime) | Higher From 5ebe1baf30ca955a967dc3b45e0d74c8d188fb36 Mon Sep 17 00:00:00 2001 From: Anna Revinskaya Date: Mon, 27 Jul 2020 22:50:39 -0700 Subject: [PATCH 25/29] Changed TF Lite --> mobile in some cases --- rfcs/20200712-tfrt-kernel-fallback.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rfcs/20200712-tfrt-kernel-fallback.md b/rfcs/20200712-tfrt-kernel-fallback.md index 1a2bb8c57..03a5f59e3 100644 --- a/rfcs/20200712-tfrt-kernel-fallback.md +++ b/rfcs/20200712-tfrt-kernel-fallback.md @@ -100,7 +100,7 @@ custom Currently, [TF Lite](https://www.tensorflow.org/lite) supports a [limited set of ops](https://www.tensorflow.org/lite/guide/ops_compatibility). As the range and variety of applications grows, it becomes essential to grow the -pool of available ops as well, ideally supporting everything that fully-fledged +pool of available ops on mobile devices, ideally supporting everything that fully-fledged TensorFlow supports now. However, supporting TensorFlow ops on mobile devices presents some challenges. @@ -115,8 +115,8 @@ to TensorFlow kernels that minimizes the amount of generated code. ## User Benefit -Running more kernels on mobile devices would allow TensorFlow Lite users to implement -a wider range of models. Reduced binary size will also benefit users that currently use TensorFlow Lite's experimental [TensorFlow Select ops] (https://www.tensorflow.org/lite/guide/ops_select), or users that do not use the experimental feature because of that reason. +Running more kernels on mobile devices would allow TensorFlow users to implement +a wider range of models for mobile devices. Reduced binary size will also benefit users that currently use TensorFlow Lite's experimental [TensorFlow Select ops] (https://www.tensorflow.org/lite/guide/ops_select), or users that do not use the experimental feature because of that reason. ## Design Proposal From d1a32624c4201447028ab3bce8709b9ef6917bc7 Mon Sep 17 00:00:00 2001 From: Anna Revinskaya Date: Wed, 9 Sep 2020 14:50:25 -0700 Subject: [PATCH 26/29] Benchmark update, wording update `final` keyword removes previously observed large regression --- rfcs/20200712-tfrt-kernel-fallback.md | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/rfcs/20200712-tfrt-kernel-fallback.md b/rfcs/20200712-tfrt-kernel-fallback.md index 03a5f59e3..485c2b156 100644 --- a/rfcs/20200712-tfrt-kernel-fallback.md +++ b/rfcs/20200712-tfrt-kernel-fallback.md @@ -5,7 +5,7 @@ | **RFC #** | [266](https://github.com/tensorflow/community/pull/266) | | **Author(s)** | Anna Revinskaya (annarev@google.com), Jeremy Lau (lauj@google.com) | | **Sponsor** | Jeremy Lau (lauj@google.com) | -| **Updated** | 2020-07-16 | +| **Updated** | 2020-09-09 | ## Objective @@ -242,10 +242,7 @@ and templating approaches. Key findings are summarized below: multiplication, division, addition) was only 0.3% slower on mobile with inheritance compared to templates. The benchmark was run on a real device (Pixel 3) with ABI: arm64-v8a and SDK version: 29. * [basic\_ops\_benchmark](https://cs.opensource.google/tensorflow/tensorflow/+/master:tensorflow/core/kernels/basic_ops_benchmark_test.cc?q=basic_ops_benchmark_test) - with inheritance is significantly slower: ~7% (median) or ~19% (mean) - (running on Linux). Note that this difference was measured *without* Kernel - Fallback. Adding inheritance would impact all existing TensorFlow kernels - even those that don't support Kernel Fallback. + with inheritance was originally measured to be significantly slower: ~7% (median). However, we determined that the regression goes away if we use `final` keywords. (More details in [Appendix 2](#appendix-2-extension-options).) * Binary size increase when using templates compared to inheritance is estimated at 2.6% (based on adding `AddN` op). @@ -260,7 +257,7 @@ that calls per-device pure-virtual implementations. We will then introduce `TFRTOpKernelConstruction` and `TFRTOpKernelContext` subclasses that implement `OpKernelConstructionInterface` and -`OpKernelContextInterface` in terms of TFRT data structures. Example how +`OpKernelContextInterface` in terms of TFRT data structures. Here's an example of how `TFRTOpKernelConstruction` might look like: ```cpp @@ -745,7 +742,7 @@ REGISTER_FALLBACK_KERNEL( Same - Increase (vtable lookups) (negligible for model benchmarks, 7% median/19% mean increase for `basic_ops_benchmark`) + We expect increase due to vtable lookups. However, increase is negligible (0-2%) in our benchmarks when using `final` keywords * @@ -761,7 +758,7 @@ REGISTER_FALLBACK_KERNEL( Increase the most (2.6% estimate for AddN) - Increase in some cases* + Increase in some cases** @@ -790,14 +787,15 @@ REGISTER_FALLBACK_KERNEL( -\* Increase will happen when we have intermediate subclass of `OpKernel`. For example, [AveragePoolingOp](https://cs.opensource.google/tensorflow/tensorflow/+/master:tensorflow/core/kernels/avgpooling_op.cc;l=56?q=%22:%20public%20UnaryOp%22) extends `UnaryOp` and `UnaryOp` extends `OpKernel`. In this case, `UnaryOp` is the *intermediate subclass*. Now that a kernel can inherit either from `OpKernel` or `OpKernelBase`, we would need two implementations: `UnaryOp` and `UnaryOpBase` respectively. Kernels that support Kernel Fallback and inherit `UnaryOp` now will instead switch to inherit `UnaryOpBase`. Addition of `UnaryOpBase` increases binary size. -### Selected approach +* We initially measured a ~7% increase in latency for [basic_ops_benchmark](https://cs.opensource.google/tensorflow/tensorflow/+/master:tensorflow/core/kernels/basic_ops_benchmark_test.cc;l=65;drc=51caa2b03f2975be51ab3f03999f35046b34f4af) . This benchmark runs a series of scalar multiplications and devisions and primarily measures kernel overhead. However, we determined that declaring `OpKernelContext` and `OpKernelConstruction` final gets read of this regression. `final` helps because a call made by a kernel is the tip of the iceberg - the called functions then make multiple calls to other functions in the same class. For example, [OpKernelContext::forward_input_or_allocate_output](https://cs.opensource.google/tensorflow/tensorflow/+/master:tensorflow/core/framework/op_kernel.h;l=1647;drc=b64dfc0c63defad2704f224dff2aa3cf97469f91) implementation calls >10 other functions in `OpKernelContext`. + -Currently we are thinking of proceeding with the inheritance approach. +** Increase will happen when we have intermediate subclass of `OpKernel`. For example, [AveragePoolingOp](https://cs.opensource.google/tensorflow/tensorflow/+/master:tensorflow/core/kernels/avgpooling_op.cc;l=56?q=%22:%20public%20UnaryOp%22) extends `UnaryOp` and `UnaryOp` extends `OpKernel`. In this case, `UnaryOp` is the *intermediate subclass*. Now that a kernel can inherit either from `OpKernel` or `OpKernelBase`, we would need two implementations: `UnaryOp` and `UnaryOpBase` respectively. Kernels that support Kernel Fallback and inherit `UnaryOp` now will instead switch to inherit `UnaryOpBase`. Addition of `UnaryOpBase` increases binary size. + +### Selected approach -Inheritance seems to add negligible overhead to kernels for most benchmarks that we ran. -However, it does introduce a ~7% median, ~19% mean penalty for [basic_ops_benchmark](https://cs.opensource.google/tensorflow/tensorflow/+/master:tensorflow/core/kernels/basic_ops_benchmark_test.cc?q=basic_ops_benchmark&ss=tensorflow%2Ftensorflow) which runs a series of scalar multiplications and is used to measure kernel overhead. +Currently we are thinking of proceeding with the inheritance approach as it doesn't seem to cause a significant performance regression based on our benchmarks. Therefore, we expect that using inheritance would not add a noticeable overhead in most real world models. At the same time, inheritance can simplify code structure and debugging. From d193cdad30c2283ad45ae67939a7b34e8c54e82e Mon Sep 17 00:00:00 2001 From: Anna Revinskaya Date: Wed, 9 Sep 2020 16:56:32 -0700 Subject: [PATCH 27/29] Clarify "mobile" + a few other changes --- rfcs/20200712-tfrt-kernel-fallback.md | 30 ++++++++++++--------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/rfcs/20200712-tfrt-kernel-fallback.md b/rfcs/20200712-tfrt-kernel-fallback.md index 485c2b156..0ccf63bfc 100644 --- a/rfcs/20200712-tfrt-kernel-fallback.md +++ b/rfcs/20200712-tfrt-kernel-fallback.md @@ -14,8 +14,7 @@ mobile devices by removing the need to execute them via the TensorFlow eager run calling kernels directly from the new [TFRT](https://github.com/tensorflow/runtime) TensorFlow runtime. Note that there is an effort to call existing kernels by delegating to -TensorFlow eager runtime instead. This approach is called Runtime Fallback and -corresponding RFC will be published soon. The goals of the two fallback +TensorFlow eager runtime instead. This approach is called Runtime Fallback. The goals of the two fallback mechanisms are as follows: * Runtime Fallback aims to reuse all current TensorFlow kernels in TFRT. @@ -39,11 +38,13 @@ calls TensorFlow kernels without going through Eager runtime first. We plan to address the second high level goal by trimming down dependencies, switching to more compact proto representation, etc. +Note that TensorFlow's current mobile solution is called [TensorFlow Lite](https://www.tensorflow.org/lite). At the same time, there is a work-in-progress effort to enable [TFRT](https://github.com/tensorflow/runtime) to run on mobile. This document focuses on the way TFRT would call kernels when running on mobile devices. Details of the way TFRT itself would be executed on mobile platforms are outside of the scope of this document. + + ### Op Coverage Goals First of all, we plan to target all the easier-to-support ops that don’t require -implementing extensive pieces of infrastructure, but at the same time provide -the most value to the TF Lite team. +implementing extensive pieces of infrastructure. We analysed how many kernels we can support in the future and include our findings in the following spreadsheets. As we describe in @@ -90,8 +91,7 @@ custom extra effort required. * Gradients would not be supported by the first iteration of Kernel Fallback, but we might revisit it later. -* Exact details of TFRT integration are still being worked out by TFRT and TF - Lite teams. Since these teams might change the plan, exact details are not a +* Exact details of TFRT integration are still being worked out by TFRT and TensorFlow mobile teams. Since these teams might change the plan, exact details are not a part of this doc. The take away is that we will integrate kernel fallback following the approach they decide on. @@ -104,7 +104,7 @@ pool of available ops on mobile devices, ideally supporting everything that full TensorFlow supports now. However, supporting TensorFlow ops on mobile devices presents some challenges. -Specifically, binary size on mobile platforms should be restricted. TF Lite team +Specifically, binary size on mobile platforms should be restricted. TensorFlow mobile team provided us with the following *ideal* numbers: * 100-200k overhead to call TF kernels @@ -247,12 +247,11 @@ and templating approaches. Key findings are summarized below: estimated at 2.6% (based on adding `AddN` op). Right now, we are leaning towards using inheritance. Seems like time increase is -only significant for running many scalar ops in a sequence - probably a rare use -case in the real world. (See more details in [Appendix 2](#appendix-2-extension-options)) +only not significant. (See more details in [Appendix 2](#appendix-2-extension-options)) To use inheritance, we will define `OpKernelConstructionInterface` and `OpKernelContextInterface` interfaces. Ideally, these interfaces should be pure -virtual. However, we will have one exception - templated `eigen_device` method +virtual. However, we will have some exception - for e.g. templated `eigen_device` method that calls per-device pure-virtual implementations. We will then introduce `TFRTOpKernelConstruction` and `TFRTOpKernelContext` @@ -261,7 +260,7 @@ subclasses that implement `OpKernelConstructionInterface` and `TFRTOpKernelConstruction` might look like: ```cpp -class TFRTOpKernelConstruction : public OpKernelConstructionInterface { +class TFRTOpKernelConstruction final : public OpKernelConstructionInterface { public: explicit TFRTOpKernelConstruction(AttrMap attributes); ~TFRTOpKernelConstruction() override {}; @@ -348,7 +347,7 @@ op->Compute(&op_kernel_context); ## tfrt\_fallback.kernel\_fallback call structure We will be using the following conventions (essentially, these are based on -Runtime Fallback work that will probably have RFC coming soon): +Runtime Fallback work): * Attributes are passed as key-value pairs, where both key and value are represented as strings. @@ -506,7 +505,7 @@ between (such as tensor conversions). We also need to consider how kernel or runtime fallback will be selected. This could be a parameter at BEF file creation step. It might also be good to package both runtime and kernel fallback implementations in a BEF file to be selected at -runtime. +runtime (packaging both is only relevant for non-mobile usecase since it would prevent us from reducing binary size). ## Size Reduction @@ -564,9 +563,6 @@ due to significant work involved. `OpKernelConsturction`. * Speed up for lighter weight kernel calls. -We will run benchmarks to check performance numbers as we work on the -implementation. - ### Dependencies No new dependencies. @@ -576,7 +572,7 @@ No new dependencies. * Build / startup time / binary size will be impacted by additional code added to implement Kernel Fallback. At the same time one of the goals of Kernel Fallback is to provide a lower-binary-size way to run existing TensorFlow - kernels in TF Lite. + kernels on mobile. * Code will be maintained by TensorFlow DevInfra and TFRT teams. #### Current Status From 8ff7ddf56ecd32ed0f02979ffc1ccb1111161529 Mon Sep 17 00:00:00 2001 From: Anna Revinskaya Date: Wed, 9 Sep 2020 17:07:39 -0700 Subject: [PATCH 28/29] mobile --> mobile platforms --- rfcs/20200712-tfrt-kernel-fallback.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/20200712-tfrt-kernel-fallback.md b/rfcs/20200712-tfrt-kernel-fallback.md index 0ccf63bfc..4f241fa12 100644 --- a/rfcs/20200712-tfrt-kernel-fallback.md +++ b/rfcs/20200712-tfrt-kernel-fallback.md @@ -572,7 +572,7 @@ No new dependencies. * Build / startup time / binary size will be impacted by additional code added to implement Kernel Fallback. At the same time one of the goals of Kernel Fallback is to provide a lower-binary-size way to run existing TensorFlow - kernels on mobile. + kernels on mobile platforms. * Code will be maintained by TensorFlow DevInfra and TFRT teams. #### Current Status From f3e979239c5b630f32c4956c8b7ff4a3ab109ad2 Mon Sep 17 00:00:00 2001 From: ematejska Date: Fri, 13 Nov 2020 10:50:39 -0800 Subject: [PATCH 29/29] Update 20200712-tfrt-kernel-fallback.md --- rfcs/20200712-tfrt-kernel-fallback.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/20200712-tfrt-kernel-fallback.md b/rfcs/20200712-tfrt-kernel-fallback.md index 4f241fa12..5d15e286f 100644 --- a/rfcs/20200712-tfrt-kernel-fallback.md +++ b/rfcs/20200712-tfrt-kernel-fallback.md @@ -1,6 +1,6 @@ # TFRT Kernel Fallback -| Status | Proposed | +| Status | Accepted | | :------------ | :------------------------------------------------------ | | **RFC #** | [266](https://github.com/tensorflow/community/pull/266) | | **Author(s)** | Anna Revinskaya (annarev@google.com), Jeremy Lau (lauj@google.com) |