From 039544096bcbdc7c07496d88d829454e09cc3e60 Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Tue, 11 Feb 2020 16:54:24 +0000 Subject: [PATCH 01/46] Clone draft template for new tf-types RFC. --- rfcs/20200211-tf-types.md | 90 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 rfcs/20200211-tf-types.md diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md new file mode 100644 index 000000000..ca386f181 --- /dev/null +++ b/rfcs/20200211-tf-types.md @@ -0,0 +1,90 @@ +# Title of RFC + +| Status | (Proposed / Accepted / Implemented / Obsolete) | +:-------------- |:---------------------------------------------------- | +| **RFC #** | [NNN](https://github.com/tensorflow/community/pull/NNN) (update when you have community PR #)| +| **Author(s)** | My Name (me@example.org), AN Other (you@example.org) | +| **Sponsor** | A N Expert (whomever@tensorflow.org) | +| **Updated** | YYYY-MM-DD | +| **Obsoletes** | TF-RFC it replaces, else remove this header | + +## Objective + +What are we doing and why? What problem will this solve? What are the goals and +non-goals? This is your executive summary; keep it short, elaborate below. + +## Motivation + +Why this is a valuable problem to solve? What background information is needed +to show how this design addresses the problem? + +Which users are affected by the problem? Why is it a problem? What data supports +this? What related work exists? + +## User Benefit + +How will users (or other contributors) benefit from this work? What would be the +headline in the release notes or blog post? + +## Design Proposal + +This is the meat of the document, where you explain your proposal. If you have +multiple alternatives, be sure to use sub-sections for better separation of the +idea, and list pros/cons to each approach. If there are alternatives that you +have eliminated, you should also list those here, and explain why you believe +your chosen approach is superior. + +Make sure you’ve thought through and addressed the following sections. If a section is not relevant to your specific proposal, please explain why, e.g. your RFC addresses a convention or process, not an API. + + +### Alternatives Considered +* Make sure to discuss the relative merits of alternatives to your proposal. + +### Performance Implications +* Do you expect any (speed / memory)? How will you confirm? +* There should be microbenchmarks. Are there? +* There should be end-to-end tests and benchmarks. If there are not (since this is still a design), how will you track that these will be created? + +### Dependencies +* Dependencies: does this proposal add any new dependencies to TensorFlow? +* Dependent projects: are there other areas of TensorFlow or things that use TensorFlow (TFX/pipelines, TensorBoard, etc.) that this affects? How have you identified these dependencies and are you sure they are complete? If there are dependencies, how are you managing those changes? + +### Engineering Impact +* Do you expect changes to binary size / startup time / build time / test times? +* Who will maintain this code? Is this code in its own buildable unit? Can this code be tested in its own? Is visibility suitably restricted to only a small API surface for others to use? + +### Platforms and Environments +* Platforms: does this work on all platforms supported by TensorFlow? If not, why is that ok? Will it work on embedded/mobile? Does it impact automatic code generation or mobile stripping tooling? Will it work with transformation tools? +* Execution environments (Cloud services, accelerator hardware): what impact do you expect and how will you confirm? + +### Best Practices +* Does this proposal change best practices for some aspect of using/developing TensorFlow? How will these changes be communicated/enforced? + +### Tutorials and Examples +* If design changes existing API or creates new ones, the design owner should create end-to-end examples (ideally, a tutorial) which reflects how new feature will be used. Some things to consider related to the tutorial: + - The minimum requirements for this are to consider how this would be used in a Keras-based workflow, as well as a non-Keras (low-level) workflow. If either isn’t applicable, explain why. + - It should show the usage of the new feature in an end to end example (from data reading to serving, if applicable). Many new features have unexpected effects in parts far away from the place of change that can be found by running through an end-to-end example. TFX [Examples](https://github.com/tensorflow/tfx/tree/master/tfx/examples) have historically been good in identifying such unexpected side-effects and are as such one recommended path for testing things end-to-end. + - This should be written as if it is documentation of the new feature, i.e., consumable by a user, not a TensorFlow developer. + - The code does not need to work (since the feature is not implemented yet) but the expectation is that the code does work before the feature can be merged. + +### Compatibility +* Does the design conform to the backwards & forwards compatibility [requirements](https://www.tensorflow.org/programmers_guide/version_compat)? +* How will this proposal interact with other parts of the TensorFlow Ecosystem? + - How will it work with TFLite? + - How will it work with distribution strategies? + - How will it interact with tf.function? + - Will this work on GPU/TPU? + - How will it serialize to a SavedModel? + +### User Impact +* What are the user-facing changes? How will this feature be rolled out? + +## Detailed Design + +This section is optional. Elaborate on details if they’re important to +understanding the design, but would make it hard to read the proposal section +above. + +## Questions and Discussion Topics + +Seed this with open questions you require feedback on from the RFC process. From 4e58ec3f2f0fcc62dedb4866b153690a2284ce25 Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Tue, 11 Feb 2020 12:56:56 -0500 Subject: [PATCH 02/46] Initial commit. --- rfcs/20200211-tf-types.md | 127 +++++++++++++++++++++++--------------- 1 file changed, 78 insertions(+), 49 deletions(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index ca386f181..7ecb0ad2e 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -1,90 +1,119 @@ -# Title of RFC +# TensorFlow Canonical Type System -| Status | (Proposed / Accepted / Implemented / Obsolete) | +| Status | Proposed | :-------------- |:---------------------------------------------------- | | **RFC #** | [NNN](https://github.com/tensorflow/community/pull/NNN) (update when you have community PR #)| -| **Author(s)** | My Name (me@example.org), AN Other (you@example.org) | +| **Author(s)** | Dan Moldovan (mdan@google.com) | | **Sponsor** | A N Expert (whomever@tensorflow.org) | -| **Updated** | YYYY-MM-DD | -| **Obsoletes** | TF-RFC it replaces, else remove this header | +| **Updated** | 2020-02-11 | ## Objective -What are we doing and why? What problem will this solve? What are the goals and -non-goals? This is your executive summary; keep it short, elaborate below. +Creation of a new TensorFlow module and namespace (`tf.types`) dedicated to storing implementation-free type definitions. This module has no other dependencies inside TensorFlow, so any other module can depend on it to ensure interoperability without the risk of creating circular dependencies. ## Motivation -Why this is a valuable problem to solve? What background information is needed -to show how this design addresses the problem? +**Interoperability and composability**. A set of stand types that formalize an interface and decouples it from implementation ensures composability between components, especially when multiple implementations are involved. -Which users are affected by the problem? Why is it a problem? What data supports -this? What related work exists? +**Supports the [acyclic dependencies principle](https://en.wikipedia.org/wiki/Acyclic_dependencies_principle)**. In many instances, circular dependencies are caused between low-level complex components that need to compose (e.g. autograph needs to recognize datasets, and datasets need to use autograph). Interface extraction is a common pattern for breaking such cycles. + +**Supports pytype**. A set of static types that is consistent under Python’s isinstance/issubclass is required to support pytype in TensorFlow. This module can serve as the basis for that. + +**Helps formalize requirements for new APIs**. Having a formal, implementation-independent definition for things such as tensors, variables, iterables, iterators makes it easy to document and test compatibility between APIs. ## User Benefit -How will users (or other contributors) benefit from this work? What would be the -headline in the release notes or blog post? +Application developers may use these canonical definitions for pytype annotations. + +Library developers can more easily define their API interfaces by referring to this namespace. + +Developers of modules internal to TensorFlow can use this module to avoid creating circular dependencies. ## Design Proposal -This is the meat of the document, where you explain your proposal. If you have -multiple alternatives, be sure to use sub-sections for better separation of the -idea, and list pros/cons to each approach. If there are alternatives that you -have eliminated, you should also list those here, and explain why you believe -your chosen approach is superior. +### The `tf.types` namespace / module +All the declarations exposed under the `tf.types` namespace reside in the `python/types/*.py` module. These are [abstract base classes](https://docs.python.org/3.7/library/abc.html) with a bare minimum of method definitions and minimal or no implementation, which serve to formalize and document the contract of common types such as `Tensor`, `Variable`, etc. + +These definitions may be used as [PEP 484](https://www.python.org/dev/peps/pep-0484/) type hints, although in some cases they may be type-erased (for example, `tf.types.Tensor` may not necessarily be parametrized by `dtype` or `shape`). + +The type definitions are also consistent with `isinstance` and `issubclass` checks. So for example `isinstance(tf.Tensor, tf.types.Tensor) == True`. + +### General principles +The `tf.types` module may depend on external packages (such as `numpy`) strictly for the purpose of defining type annotations and documentation. No dependencies to other TensorFlow interfaces are allowed. Any dependencies on external packages which themselves depend on TensorFlow are expressly forbidden. + +Changes definitions inside `tf.types` must be approved by TensorFlow leads, and typically should be accompanied by an RFC. + +All type declarations are compatible with [pytype](https://github.com/google/pytype). + +It is recommended that internal and external type annotations, `isinstance` and `issubclass` checks use these types, eventually deprecating helpers like `tf.is_tensor`. However, concrete types continue to exist - for example, variables are still created using `tf.Variable`, which is now a subclass of `tf.types.Variable`. -Make sure you’ve thought through and addressed the following sections. If a section is not relevant to your specific proposal, please explain why, e.g. your RFC addresses a convention or process, not an API. +### Support for `tf.function`'s `input_signature` +The type system listed here can be expanded to allow input signatures using type annotations, see for instance [this thread](https://github.com/tensorflow/tensorflow/issues/31579). +### Initial type hierarchy +The list is extensible, any types included in the list are subject to normal backward compatibility rules, which means they are unlikely to change in the future. It is therefore preferable to maintain a strict minimum of orthogonal declarations and carefully vet any additions. + +* Core types + + * `DType` + * `Shape` + * `Tensor` - generic dense tensor + + * `Symbol` - the regular graph tensor + * `Value` - eager tensors + + * `Variable` + +* Container types + + * `Composite` - low-level static structure + * `Module` - builder for structures of Variables + * `Optional` + * `List` - superclass for `TensorArray` + +* Higher-level types + * `Dataset` + * `Iterator` + * `Iterable` + * `Function` + * `Error` + + * Distributed types + * `DistributedDataset` + * `DistributedIterator` ### Alternatives Considered -* Make sure to discuss the relative merits of alternatives to your proposal. +* N/A ### Performance Implications -* Do you expect any (speed / memory)? How will you confirm? -* There should be microbenchmarks. Are there? -* There should be end-to-end tests and benchmarks. If there are not (since this is still a design), how will you track that these will be created? +* No performance implications expected. At most, we are adding a small number of levels to the class tree of some objects. ### Dependencies -* Dependencies: does this proposal add any new dependencies to TensorFlow? -* Dependent projects: are there other areas of TensorFlow or things that use TensorFlow (TFX/pipelines, TensorBoard, etc.) that this affects? How have you identified these dependencies and are you sure they are complete? If there are dependencies, how are you managing those changes? +* None, by definition. ### Engineering Impact -* Do you expect changes to binary size / startup time / build time / test times? -* Who will maintain this code? Is this code in its own buildable unit? Can this code be tested in its own? Is visibility suitably restricted to only a small API surface for others to use? +* Engineering impact: Separate interfaces allow for faster loading times by reducing coupling between modules. +* Maintenance: Minimal maintenance overhead since there is no functionality involved. The TensorFlow team and contributors will maintain the documentation up to date. Changes should be reviewed and approved by the TensorFlow team leads. ### Platforms and Environments -* Platforms: does this work on all platforms supported by TensorFlow? If not, why is that ok? Will it work on embedded/mobile? Does it impact automatic code generation or mobile stripping tooling? Will it work with transformation tools? -* Execution environments (Cloud services, accelerator hardware): what impact do you expect and how will you confirm? +* Platforms: Python only, in the first stage. However, the type system should be aligned as much as possible with the core types in the TensorFlow runtime, and be language-independent as much as possible. +* Execution environments: The type system is independent of platform. This also implies that no platform-specific types (such as `TPUTensor`) exist. ### Best Practices -* Does this proposal change best practices for some aspect of using/developing TensorFlow? How will these changes be communicated/enforced? +* This set of type definitions support the acyclic dependencies principle, by requiring that implementations avoid lateral dependencies (e.g. with a linter rule). ### Tutorials and Examples -* If design changes existing API or creates new ones, the design owner should create end-to-end examples (ideally, a tutorial) which reflects how new feature will be used. Some things to consider related to the tutorial: - - The minimum requirements for this are to consider how this would be used in a Keras-based workflow, as well as a non-Keras (low-level) workflow. If either isn’t applicable, explain why. - - It should show the usage of the new feature in an end to end example (from data reading to serving, if applicable). Many new features have unexpected effects in parts far away from the place of change that can be found by running through an end-to-end example. TFX [Examples](https://github.com/tensorflow/tfx/tree/master/tfx/examples) have historically been good in identifying such unexpected side-effects and are as such one recommended path for testing things end-to-end. - - This should be written as if it is documentation of the new feature, i.e., consumable by a user, not a TensorFlow developer. - - The code does not need to work (since the feature is not implemented yet) but the expectation is that the code does work before the feature can be merged. +* N/A ### Compatibility -* Does the design conform to the backwards & forwards compatibility [requirements](https://www.tensorflow.org/programmers_guide/version_compat)? -* How will this proposal interact with other parts of the TensorFlow Ecosystem? - - How will it work with TFLite? - - How will it work with distribution strategies? - - How will it interact with tf.function? - - Will this work on GPU/TPU? - - How will it serialize to a SavedModel? +* Minor version requirement. Existing classes (tf.Tensor) will become subclasses of the new type interfaces. +* Most subcomponents of TF (Lite, distributed, function, SavedModel) will depend on this new module, although their functionality is not impacted. +* Libraries which depend on TensorFlow are encouraged to refer to `tf.types` definitions, rather than the concrete implementations for better future compatibility. ### User Impact -* What are the user-facing changes? How will this feature be rolled out? - -## Detailed Design +* Users will see a new `tf.types` module, that may be referenced from documentation and type annotations. -This section is optional. Elaborate on details if they’re important to -understanding the design, but would make it hard to read the proposal section -above. ## Questions and Discussion Topics -Seed this with open questions you require feedback on from the RFC process. +N/A From 455362657adb78f419135c325fa2c760a1f4dd53 Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Tue, 11 Feb 2020 12:57:50 -0500 Subject: [PATCH 03/46] Capitalization --- rfcs/20200211-tf-types.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index 7ecb0ad2e..2183d1b5e 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -31,14 +31,14 @@ Developers of modules internal to TensorFlow can use this module to avoid creati ## Design Proposal -### The `tf.types` namespace / module +### The `tf.types` Namespace / Module All the declarations exposed under the `tf.types` namespace reside in the `python/types/*.py` module. These are [abstract base classes](https://docs.python.org/3.7/library/abc.html) with a bare minimum of method definitions and minimal or no implementation, which serve to formalize and document the contract of common types such as `Tensor`, `Variable`, etc. These definitions may be used as [PEP 484](https://www.python.org/dev/peps/pep-0484/) type hints, although in some cases they may be type-erased (for example, `tf.types.Tensor` may not necessarily be parametrized by `dtype` or `shape`). The type definitions are also consistent with `isinstance` and `issubclass` checks. So for example `isinstance(tf.Tensor, tf.types.Tensor) == True`. -### General principles +### General Principles The `tf.types` module may depend on external packages (such as `numpy`) strictly for the purpose of defining type annotations and documentation. No dependencies to other TensorFlow interfaces are allowed. Any dependencies on external packages which themselves depend on TensorFlow are expressly forbidden. Changes definitions inside `tf.types` must be approved by TensorFlow leads, and typically should be accompanied by an RFC. @@ -50,7 +50,7 @@ It is recommended that internal and external type annotations, `isinstance` and ### Support for `tf.function`'s `input_signature` The type system listed here can be expanded to allow input signatures using type annotations, see for instance [this thread](https://github.com/tensorflow/tensorflow/issues/31579). -### Initial type hierarchy +### Initial Type Hierarchy The list is extensible, any types included in the list are subject to normal backward compatibility rules, which means they are unlikely to change in the future. It is therefore preferable to maintain a strict minimum of orthogonal declarations and carefully vet any additions. * Core types From 001efcc9cf33f8bd22951e6255f92c1cbf680bc5 Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Tue, 11 Feb 2020 13:07:22 -0500 Subject: [PATCH 04/46] Update 20200211-tf-types.md --- rfcs/20200211-tf-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index 2183d1b5e..b50467bf2 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -9,7 +9,7 @@ ## Objective -Creation of a new TensorFlow module and namespace (`tf.types`) dedicated to storing implementation-free type definitions. This module has no other dependencies inside TensorFlow, so any other module can depend on it to ensure interoperability without the risk of creating circular dependencies. +This RFC proposed a new TensorFlow module and namespace (`tf.types`) dedicated to storing implementation-free type definitions. This module has no other dependencies inside TensorFlow, so any other module can depend on it to ensure interoperability without the risk of creating circular dependencies. ## Motivation From 71a5164810d878ae05892245e40d35117f4f6045 Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Tue, 11 Feb 2020 13:30:10 -0500 Subject: [PATCH 05/46] Update 20200211-tf-types.md --- rfcs/20200211-tf-types.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index b50467bf2..a698ead67 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -39,6 +39,8 @@ These definitions may be used as [PEP 484](https://www.python.org/dev/peps/pep-0 The type definitions are also consistent with `isinstance` and `issubclass` checks. So for example `isinstance(tf.Tensor, tf.types.Tensor) == True`. ### General Principles +This module should not contain any implementation code. An advantage of that is that users exploring the implementation of specific types will not need to inspect this module. However, users who do not wish to inspect the code may visit the documentation of these generic types to better understand specifically what are the concrete subclasses of this type expected to do. + The `tf.types` module may depend on external packages (such as `numpy`) strictly for the purpose of defining type annotations and documentation. No dependencies to other TensorFlow interfaces are allowed. Any dependencies on external packages which themselves depend on TensorFlow are expressly forbidden. Changes definitions inside `tf.types` must be approved by TensorFlow leads, and typically should be accompanied by an RFC. From 0842a2fbf134e37e9bfcca9f144bc609b89b67ee Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Tue, 11 Feb 2020 13:32:21 -0500 Subject: [PATCH 06/46] Update 20200211-tf-types.md --- rfcs/20200211-tf-types.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index a698ead67..1f86d764e 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -83,6 +83,10 @@ The list is extensible, any types included in the list are subject to normal bac * Distributed types * `DistributedDataset` * `DistributedIterator` + + * Low-level execution primitives + * Graph + * FunctionGraph ### Alternatives Considered * N/A From e4fd7fad83760cca5f4c0f8df63d92548b74a67f Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Tue, 11 Feb 2020 13:33:59 -0500 Subject: [PATCH 07/46] Update 20200211-tf-types.md --- rfcs/20200211-tf-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index 1f86d764e..1107f24c4 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -112,7 +112,7 @@ The list is extensible, any types included in the list are subject to normal bac * N/A ### Compatibility -* Minor version requirement. Existing classes (tf.Tensor) will become subclasses of the new type interfaces. +* Minor new version. Existing classes (tf.Tensor) will become subclasses of the new type interfaces. * Most subcomponents of TF (Lite, distributed, function, SavedModel) will depend on this new module, although their functionality is not impacted. * Libraries which depend on TensorFlow are encouraged to refer to `tf.types` definitions, rather than the concrete implementations for better future compatibility. From 4666892b1a80087d48c89c5d1b2d6d31c96797f6 Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Tue, 11 Feb 2020 13:34:22 -0500 Subject: [PATCH 08/46] Update 20200211-tf-types.md --- rfcs/20200211-tf-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index 1107f24c4..e4b5a2183 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -112,7 +112,7 @@ The list is extensible, any types included in the list are subject to normal bac * N/A ### Compatibility -* Minor new version. Existing classes (tf.Tensor) will become subclasses of the new type interfaces. +* New minor version. Existing classes (tf.Tensor) will become subclasses of the new type interfaces. * Most subcomponents of TF (Lite, distributed, function, SavedModel) will depend on this new module, although their functionality is not impacted. * Libraries which depend on TensorFlow are encouraged to refer to `tf.types` definitions, rather than the concrete implementations for better future compatibility. From de72ac5a759b3ebd4d268fbfbb148dbafffc4d87 Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Tue, 11 Feb 2020 13:35:42 -0500 Subject: [PATCH 09/46] Update 20200211-tf-types.md --- rfcs/20200211-tf-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index e4b5a2183..2e6be8749 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -122,4 +122,4 @@ The list is extensible, any types included in the list are subject to normal bac ## Questions and Discussion Topics -N/A +* Single flat vs. hierararchical namespace - for example: `tf.types.distribute.Dataset`, or `tf.types.DistributedDataset`? From e9720c1bda4cd3eaf25bc4566652f0c1579f400f Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Wed, 12 Feb 2020 11:53:14 -0500 Subject: [PATCH 10/46] Update 20200211-tf-types.md --- rfcs/20200211-tf-types.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index 2e6be8749..702e39f35 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -55,6 +55,8 @@ The type system listed here can be expanded to allow input signatures using type ### Initial Type Hierarchy The list is extensible, any types included in the list are subject to normal backward compatibility rules, which means they are unlikely to change in the future. It is therefore preferable to maintain a strict minimum of orthogonal declarations and carefully vet any additions. +Most of these symbols will not be initially exported as public symbols, meaning that only internal su-mbodules will be able to use them. As the need for external symbols arises, they will be gradually exposed under `tf.types`. + * Core types * `DType` From e3224da4030f8c197a7c2c56beef8f141a0774b9 Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Tue, 18 Feb 2020 08:47:56 -0500 Subject: [PATCH 11/46] Update 20200211-tf-types.md --- rfcs/20200211-tf-types.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index 702e39f35..3056e0d6c 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -57,6 +57,8 @@ The list is extensible, any types included in the list are subject to normal bac Most of these symbols will not be initially exported as public symbols, meaning that only internal su-mbodules will be able to use them. As the need for external symbols arises, they will be gradually exposed under `tf.types`. +The initial type hierarchy is focused on V2 symbols; we expect few places where these symbols would not be compatible with V1 code, though. + * Core types * `DType` From 53680e54820a8e0a974db7ab9ea420430fe1d912 Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Wed, 19 Feb 2020 09:43:07 -0500 Subject: [PATCH 12/46] Update 20200211-tf-types.md --- rfcs/20200211-tf-types.md | 68 ++++++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 26 deletions(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index 3056e0d6c..4062c5ba4 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -9,15 +9,16 @@ ## Objective -This RFC proposed a new TensorFlow module and namespace (`tf.types`) dedicated to storing implementation-free type definitions. This module has no other dependencies inside TensorFlow, so any other module can depend on it to ensure interoperability without the risk of creating circular dependencies. +This RFC proposes a new TensorFlow module and namespace (`tf.types`) dedicated to storing implementation-free type definitions, similar to C++ header files. This module has no other dependencies inside TensorFlow, so any other module can depend on it to ensure interoperability without the risk of creating circular dependencies. +The RFC focuses on the Python API, however the design should be reviewed with cross-language consistency in mind. ## Motivation -**Interoperability and composability**. A set of stand types that formalize an interface and decouples it from implementation ensures composability between components, especially when multiple implementations are involved. +**Interoperability and composability**. A set of standard types that formalize an interface and decouples it from implementation ensures composability between components, especially when multiple implementations are involved. **Supports the [acyclic dependencies principle](https://en.wikipedia.org/wiki/Acyclic_dependencies_principle)**. In many instances, circular dependencies are caused between low-level complex components that need to compose (e.g. autograph needs to recognize datasets, and datasets need to use autograph). Interface extraction is a common pattern for breaking such cycles. -**Supports pytype**. A set of static types that is consistent under Python’s isinstance/issubclass is required to support pytype in TensorFlow. This module can serve as the basis for that. +**Supports pytype**. A set of static types that is consistent under Python’s `isinstance`/`issubclass` is required to support [PEP-484 type annotations](https://www.python.org/dev/peps/pep-0484/) in TensorFlow. This module can serve as the basis for that. **Helps formalize requirements for new APIs**. Having a formal, implementation-independent definition for things such as tensors, variables, iterables, iterators makes it easy to document and test compatibility between APIs. @@ -34,32 +35,40 @@ Developers of modules internal to TensorFlow can use this module to avoid creati ### The `tf.types` Namespace / Module All the declarations exposed under the `tf.types` namespace reside in the `python/types/*.py` module. These are [abstract base classes](https://docs.python.org/3.7/library/abc.html) with a bare minimum of method definitions and minimal or no implementation, which serve to formalize and document the contract of common types such as `Tensor`, `Variable`, etc. -These definitions may be used as [PEP 484](https://www.python.org/dev/peps/pep-0484/) type hints, although in some cases they may be type-erased (for example, `tf.types.Tensor` may not necessarily be parametrized by `dtype` or `shape`). +These definitions may be used as PEP 484 type hints, although in some cases they may be type- or shape- erased (for example, `tf.types.Tensor` may not necessarily be parametrized by `dtype` or `shape`). Note however that designs which parametrize on shape do exist, see for instance [tensorflow#31579](https://github.com/tensorflow/tensorflow/issues/31579). -The type definitions are also consistent with `isinstance` and `issubclass` checks. So for example `isinstance(tf.Tensor, tf.types.Tensor) == True`. +The type definitions are consistent with `isinstance` and `issubclass`. For example, `isinstance(tf.Tensor, tf.types.Tensor) == True`. ### General Principles This module should not contain any implementation code. An advantage of that is that users exploring the implementation of specific types will not need to inspect this module. However, users who do not wish to inspect the code may visit the documentation of these generic types to better understand specifically what are the concrete subclasses of this type expected to do. -The `tf.types` module may depend on external packages (such as `numpy`) strictly for the purpose of defining type annotations and documentation. No dependencies to other TensorFlow interfaces are allowed. Any dependencies on external packages which themselves depend on TensorFlow are expressly forbidden. +The `tf.types` module may depend on external packages (such as `numpy`) _strictly for the purpose of defining type annotations and documentation_. No dependencies to other TensorFlow interfaces are allowed. Any dependencies on external packages which themselves depend on TensorFlow are expressly forbidden. Changes definitions inside `tf.types` must be approved by TensorFlow leads, and typically should be accompanied by an RFC. All type declarations are compatible with [pytype](https://github.com/google/pytype). -It is recommended that internal and external type annotations, `isinstance` and `issubclass` checks use these types, eventually deprecating helpers like `tf.is_tensor`. However, concrete types continue to exist - for example, variables are still created using `tf.Variable`, which is now a subclass of `tf.types.Variable`. +It is recommended that internal and external type annotations, `isinstance` and `issubclass` checks use these types, eventually deprecating helpers like `tf.is_tensor`. However, concrete types continue to exist - for example, variables are instances of `tf.Variable`, which is now a subclass of `tf.types.Variable`. + +Class type definitions define a minimum of abstract methods and properties which are required for pytype compatibility. ### Support for `tf.function`'s `input_signature` The type system listed here can be expanded to allow input signatures using type annotations, see for instance [this thread](https://github.com/tensorflow/tensorflow/issues/31579). ### Initial Type Hierarchy -The list is extensible, any types included in the list are subject to normal backward compatibility rules, which means they are unlikely to change in the future. It is therefore preferable to maintain a strict minimum of orthogonal declarations and carefully vet any additions. +TensorFlow generally adopts an incremental development method. This RFC aims to remain consistent with that. + +Below are listed the major types presently used in TensorFlow. All types included in this list are subject to [normal compatibility rules](https://www.tensorflow.org/guide/versions), so they are unlikely to change in the future. It is therefore preferable to maintain a strict minimum of orthogonal declarations and carefully vet any additions. + +Most of these symbols will not be initially exported as public symbols. Only internal submodules will be able to use unexported types. The unexported types may be gradually exposed under `tf.types` or under `tf.types.experimental`. + +The initial type hierarchy is focused on V2 symbols. We expect to encounter places where these symbols would not be compatible with V1 code; in such cases, the V1 symbols will not be affected. -Most of these symbols will not be initially exported as public symbols, meaning that only internal su-mbodules will be able to use them. As the need for external symbols arises, they will be gradually exposed under `tf.types`. +#### Types created by this RFC -The initial type hierarchy is focused on V2 symbols; we expect few places where these symbols would not be compatible with V1 code, though. +These types will be added with the initial creation of the `tf.types` namespace. -* Core types +* Core tensor types * `DType` * `Shape` @@ -70,27 +79,33 @@ The initial type hierarchy is focused on V2 symbols; we expect few places where * `Variable` +#### Potential types for subsequent implementation + +These types are raised for discussion by this RFC, but are not part of the original implementation, unless they are strictly required for consistency (to be determined during the initial submission). + +Many of these are expected to be required when breaking the cyclic dependencies that currently exist between submodules. However, it is hoped that opening them up for discussion early can help create a more coherent type system. + * Container types - * `Composite` - low-level static structure - * `Module` - builder for structures of Variables - * `Optional` - * `List` - superclass for `TensorArray` + * `Composite` - low-level static structure (opaque to GraphDef/IR) + * `Module` - builder for structures of `Variables` (invisible to GraphDef/IR) + * `Optional` - basic programming construct + * `List` - superclass for `TensorArray`, `Queue`, etc. (opaque to GraphDef/IR) * Higher-level types - * `Dataset` - * `Iterator` - * `Iterable` - * `Function` - * `Error` + * `Dataset` - ETL pipeline + * `Iterator` - basic stateful programming construct + * `Iterable` - basic stateless programming construct + * `Function` - basic programming construct + * `Error` - superclass of all TF-specific errors * Distributed types - * `DistributedDataset` - * `DistributedIterator` + * `DistributedDataset` - collective ETL + * `DistributedIterator` - collective iterator * Low-level execution primitives - * Graph - * FunctionGraph + * `Graph` - GraphDef/IR program + * `FunctionGraph` - IR of a single concrete function ### Alternatives Considered * N/A @@ -116,7 +131,7 @@ The initial type hierarchy is focused on V2 symbols; we expect few places where * N/A ### Compatibility -* New minor version. Existing classes (tf.Tensor) will become subclasses of the new type interfaces. +* New minor version. Existing classes (`tf.Tensor`) will become subclasses of the new type interfaces. * Most subcomponents of TF (Lite, distributed, function, SavedModel) will depend on this new module, although their functionality is not impacted. * Libraries which depend on TensorFlow are encouraged to refer to `tf.types` definitions, rather than the concrete implementations for better future compatibility. @@ -126,4 +141,5 @@ The initial type hierarchy is focused on V2 symbols; we expect few places where ## Questions and Discussion Topics -* Single flat vs. hierararchical namespace - for example: `tf.types.distribute.Dataset`, or `tf.types.DistributedDataset`? +* Single flat vs. hierarchical namespace - for example: `tf.types.distribute.Dataset`, or `tf.types.DistributedDataset`? +* The inclusion of more specialized `Graph` types, such as `FuncGraph`, `CondBranchFuncGraph`, `WhileCondFuncGraph`, `WhileBodyFuncGraph`. It’s unclear where these should be defined, however internal submodules needs these subtypes to maintain acyclic dependencies. From 7b21bf79ac25e8c6391836c8f045ec8dca161bf4 Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Wed, 19 Feb 2020 09:44:12 -0500 Subject: [PATCH 13/46] Update 20200211-tf-types.md --- rfcs/20200211-tf-types.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index 4062c5ba4..a1ec4a508 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -4,8 +4,8 @@ :-------------- |:---------------------------------------------------- | | **RFC #** | [NNN](https://github.com/tensorflow/community/pull/NNN) (update when you have community PR #)| | **Author(s)** | Dan Moldovan (mdan@google.com) | -| **Sponsor** | A N Expert (whomever@tensorflow.org) | -| **Updated** | 2020-02-11 | +| **Sponsor** | Gaurav Jain (gjn@google.com) | +| **Updated** | 2020-02-19 | ## Objective From c951112b66a183c2beb2d6329c622f6d6115b8d7 Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Wed, 19 Feb 2020 09:44:28 -0500 Subject: [PATCH 14/46] Update 20200211-tf-types.md --- rfcs/20200211-tf-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index a1ec4a508..f796eef7f 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -1,6 +1,6 @@ # TensorFlow Canonical Type System -| Status | Proposed | +| Status | Draft | :-------------- |:---------------------------------------------------- | | **RFC #** | [NNN](https://github.com/tensorflow/community/pull/NNN) (update when you have community PR #)| | **Author(s)** | Dan Moldovan (mdan@google.com) | From aae458f6a1ce1fedca21f2cdb2cc059c9f9f454f Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Thu, 20 Feb 2020 11:14:18 -0500 Subject: [PATCH 15/46] Update 20200211-tf-types.md --- rfcs/20200211-tf-types.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index f796eef7f..2bbd0e795 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -128,7 +128,8 @@ Many of these are expected to be required when breaking the cyclic dependencies * This set of type definitions support the acyclic dependencies principle, by requiring that implementations avoid lateral dependencies (e.g. with a linter rule). ### Tutorials and Examples -* N/A +* As the design matures, we plan to showcase libraries that leverage this pattern. +* Type annotations will be included in existing tutorials as definitions become final. ### Compatibility * New minor version. Existing classes (`tf.Tensor`) will become subclasses of the new type interfaces. From f92370583365dafd7035e7052a89ae87da1578ee Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Thu, 20 Feb 2020 11:31:17 -0500 Subject: [PATCH 16/46] Update 20200211-tf-types.md --- rfcs/20200211-tf-types.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index 2bbd0e795..f82d02508 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -9,9 +9,8 @@ ## Objective -This RFC proposes a new TensorFlow module and namespace (`tf.types`) dedicated to storing implementation-free type definitions, similar to C++ header files. This module has no other dependencies inside TensorFlow, so any other module can depend on it to ensure interoperability without the risk of creating circular dependencies. +This RFC proposes a new TensorFlow module and namespace (`tf.types`) dedicated to storing implementation-free type definitions, similar to C++ header files. This module has no other dependencies inside TensorFlow, so any other internal module can depend on it to ensure interoperability without the risk of creating circular dependencies. These definitions can also be used by external users, for example in pytype annotations. The RFC focuses on the Python API, however the design should be reviewed with cross-language consistency in mind. - ## Motivation **Interoperability and composability**. A set of standard types that formalize an interface and decouples it from implementation ensures composability between components, especially when multiple implementations are involved. From dc924a7685f07a24d1154149f2d37bbb405591a0 Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Thu, 20 Feb 2020 13:52:07 -0500 Subject: [PATCH 17/46] Update PR number. --- rfcs/20200211-tf-types.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index f82d02508..915a76ec0 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -1,8 +1,8 @@ # TensorFlow Canonical Type System -| Status | Draft | +| Status | Proposed | :-------------- |:---------------------------------------------------- | -| **RFC #** | [NNN](https://github.com/tensorflow/community/pull/NNN) (update when you have community PR #)| +| **RFC #** | [208](https://github.com/tensorflow/community/pull/208) | **Author(s)** | Dan Moldovan (mdan@google.com) | | **Sponsor** | Gaurav Jain (gjn@google.com) | | **Updated** | 2020-02-19 | From 5d4ce1d00423d14a273c31c40c736ccebe7d93f9 Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Thu, 20 Feb 2020 13:55:42 -0500 Subject: [PATCH 18/46] Add `TensorLike` to core types. --- rfcs/20200211-tf-types.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index 915a76ec0..f4c3e5aeb 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -76,6 +76,8 @@ These types will be added with the initial creation of the `tf.types` namespace. * `Symbol` - the regular graph tensor * `Value` - eager tensors + * `TensorLike` - any type that can be implicitly converted to `Tensor` (see for example https://github.com/tensorflow/addons/blob/master/tensorflow_addons/utils/types.py) + * `Variable` #### Potential types for subsequent implementation From fb3e2f22c0a308b4e361d34401d8046c70c4ed5b Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Thu, 20 Feb 2020 18:49:16 -0500 Subject: [PATCH 19/46] Clarify note about static checkers. --- rfcs/20200211-tf-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index f4c3e5aeb..d92a9f719 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -45,7 +45,7 @@ The `tf.types` module may depend on external packages (such as `numpy`) _strictl Changes definitions inside `tf.types` must be approved by TensorFlow leads, and typically should be accompanied by an RFC. -All type declarations are compatible with [pytype](https://github.com/google/pytype). +All type declarations are based on PEP-484 and related specifications, and defined using [typing](https://docs.python.org/3/library/typing.html), with the aim of being compatible with static type checkers like [pytype](https://github.com/google/pytype), [mypy](http://mypy-lang.org/), [pyre](https://pyre-check.org/). It is recommended that internal and external type annotations, `isinstance` and `issubclass` checks use these types, eventually deprecating helpers like `tf.is_tensor`. However, concrete types continue to exist - for example, variables are instances of `tf.Variable`, which is now a subclass of `tf.types.Variable`. From c42f292ce08fbf8c640b963745679c6e77b7a717 Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Fri, 21 Feb 2020 11:07:33 -0500 Subject: [PATCH 20/46] Add note about ABC performance concerns --- rfcs/20200211-tf-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index d92a9f719..9aa02c33d 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -112,7 +112,7 @@ Many of these are expected to be required when breaking the cyclic dependencies * N/A ### Performance Implications -* No performance implications expected. At most, we are adding a small number of levels to the class tree of some objects. +* There is a potential performance concern if using `abc` for the abstract base types, which are about an order of magnitude slower for `isinstance` checks. The cost of `isinstance` may be non-negligible for eager execution or scaling to large graphs. In such cases, we may want to avoid using `abc`. See https://github.com/tensorflow/community/pull/208#discussion_r382494902. ### Dependencies * None, by definition. From 198a1d0488ba875ee31f3b6cb73f0565b1cb83ea Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Fri, 21 Feb 2020 11:11:05 -0500 Subject: [PATCH 21/46] Clarify semantics of `Optional` --- rfcs/20200211-tf-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index 9aa02c33d..767ad7d83 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -90,7 +90,7 @@ Many of these are expected to be required when breaking the cyclic dependencies * `Composite` - low-level static structure (opaque to GraphDef/IR) * `Module` - builder for structures of `Variables` (invisible to GraphDef/IR) - * `Optional` - basic programming construct + * `Optional` - basic programming construct, currently prototyped in `tf.data.experimental.Optional`; unlike `typing.Optional`, it doesn't include `None` * `List` - superclass for `TensorArray`, `Queue`, etc. (opaque to GraphDef/IR) * Higher-level types From 5bf02fbd63e0bc6771d24616f3f5e38d536b6d96 Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Fri, 21 Feb 2020 11:30:31 -0500 Subject: [PATCH 22/46] Add details and example for `Optional` --- rfcs/20200211-tf-types.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index 767ad7d83..e349b40f1 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -107,6 +107,24 @@ Many of these are expected to be required when breaking the cyclic dependencies * Low-level execution primitives * `Graph` - GraphDef/IR program * `FunctionGraph` - IR of a single concrete function + +#### Detailed notes + +##### Optional + +`tf.types.Optional` is the [nullable type](https://en.wikipedia.org/wiki/Nullable_type) in TensorFlow. + +Example graph code: + +``` + >>> ds = tf.data.Dataset.range(3) + >>> itr = iter(ds) + >>> opt_next = tf.data.experimental.get_next_as_optional(itr) + >>> tf.print(opt_next.has_value(), opt_next.get_value()) + 1 0 +``` + +It is not fully equivalent with `typing.Optional`, as TensorFlow has no explicit type or value for `None`. ### Alternatives Considered * N/A From 2f4d14d004dedfb0cc8e37f05534d390fb2e282c Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Fri, 21 Feb 2020 18:03:38 -0500 Subject: [PATCH 23/46] Fix typo. --- rfcs/20200211-tf-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index e349b40f1..fff0944c3 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -43,7 +43,7 @@ This module should not contain any implementation code. An advantage of that is The `tf.types` module may depend on external packages (such as `numpy`) _strictly for the purpose of defining type annotations and documentation_. No dependencies to other TensorFlow interfaces are allowed. Any dependencies on external packages which themselves depend on TensorFlow are expressly forbidden. -Changes definitions inside `tf.types` must be approved by TensorFlow leads, and typically should be accompanied by an RFC. +Changes to definitions inside `tf.types` must be approved by TensorFlow leads, and typically should be accompanied by an RFC. All type declarations are based on PEP-484 and related specifications, and defined using [typing](https://docs.python.org/3/library/typing.html), with the aim of being compatible with static type checkers like [pytype](https://github.com/google/pytype), [mypy](http://mypy-lang.org/), [pyre](https://pyre-check.org/). From 52d5617dbc5cd835e95e2065707f3129ce435971 Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Fri, 21 Feb 2020 18:06:56 -0500 Subject: [PATCH 24/46] Update 20200211-tf-types.md --- rfcs/20200211-tf-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index fff0944c3..8e8bda6fa 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -9,7 +9,7 @@ ## Objective -This RFC proposes a new TensorFlow module and namespace (`tf.types`) dedicated to storing implementation-free type definitions, similar to C++ header files. This module has no other dependencies inside TensorFlow, so any other internal module can depend on it to ensure interoperability without the risk of creating circular dependencies. These definitions can also be used by external users, for example in pytype annotations. +This RFC proposes a new TensorFlow module and namespace (`tf.types`) dedicated to storing implementation-free type definitions, similar to Java interfaces or C++ forward declarations. This module has no other dependencies inside TensorFlow, so any other internal module can depend on it to ensure interoperability without the risk of creating circular dependencies. These definitions can also be used by external users, for example in pytype annotations. The RFC focuses on the Python API, however the design should be reviewed with cross-language consistency in mind. ## Motivation From d27dcb7842f349454342cfea9e4cbfa18066cd86 Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Wed, 4 Mar 2020 13:40:52 -0500 Subject: [PATCH 25/46] Add discussion topic --- rfcs/20200211-tf-types.md | 1 + 1 file changed, 1 insertion(+) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index 8e8bda6fa..c9f18dbb9 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -161,5 +161,6 @@ It is not fully equivalent with `typing.Optional`, as TensorFlow has no explicit ## Questions and Discussion Topics +* Whether to create entries for well-known types already exported like `tf.Tensor` and `tf.Variable`. Internally, superclasses for these types will be created, but the existing `tf.Tensor` can just point to those to avoid unnecessary duplication. * Single flat vs. hierarchical namespace - for example: `tf.types.distribute.Dataset`, or `tf.types.DistributedDataset`? * The inclusion of more specialized `Graph` types, such as `FuncGraph`, `CondBranchFuncGraph`, `WhileCondFuncGraph`, `WhileBodyFuncGraph`. It’s unclear where these should be defined, however internal submodules needs these subtypes to maintain acyclic dependencies. From 5bff3e724b4ae7232d86d1b6d71faede81ccbec0 Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Wed, 4 Mar 2020 14:27:09 -0500 Subject: [PATCH 26/46] Clarify intent for type checking mechanics --- rfcs/20200211-tf-types.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index c9f18dbb9..72597959d 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -1,11 +1,11 @@ # TensorFlow Canonical Type System -| Status | Proposed | +| Status | WIP | :-------------- |:---------------------------------------------------- | | **RFC #** | [208](https://github.com/tensorflow/community/pull/208) | **Author(s)** | Dan Moldovan (mdan@google.com) | | **Sponsor** | Gaurav Jain (gjn@google.com) | -| **Updated** | 2020-02-19 | +| **Updated** | 2020-03-04 | ## Objective @@ -36,7 +36,7 @@ All the declarations exposed under the `tf.types` namespace reside in the `pytho These definitions may be used as PEP 484 type hints, although in some cases they may be type- or shape- erased (for example, `tf.types.Tensor` may not necessarily be parametrized by `dtype` or `shape`). Note however that designs which parametrize on shape do exist, see for instance [tensorflow#31579](https://github.com/tensorflow/tensorflow/issues/31579). -The type definitions are consistent with `isinstance` and `issubclass`. For example, `isinstance(tf.Tensor, tf.types.Tensor) == True`. +The type definitions are consistent with standard Python [subtyping mechanics](https://docs.python.org/3.8/library/typing.html#nominal-vs-structural-subtyping) such as instance checks or protocols (in versions prior to Python 3.8, it is difficult to simultaneously support both). ### General Principles This module should not contain any implementation code. An advantage of that is that users exploring the implementation of specific types will not need to inspect this module. However, users who do not wish to inspect the code may visit the documentation of these generic types to better understand specifically what are the concrete subclasses of this type expected to do. From f692cc0b6f9588215cd409db89a21337f394e1a1 Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Sat, 7 Mar 2020 17:54:34 -0500 Subject: [PATCH 27/46] Add section on protocol for custom Tensors --- rfcs/20200211-tf-types.md | 61 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index 72597959d..40796cec4 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -51,6 +51,67 @@ It is recommended that internal and external type annotations, `isinstance` and Class type definitions define a minimum of abstract methods and properties which are required for pytype compatibility. +### Custom `Tensor` types and `tf.register_tensor_conversion_function` + +Custom objects can be used in standard TF operations using [tf.register_tensor_conversion_function](https://www.tensorflow.org/api_docs/python/tf/register_tensor_conversion_function). This dependency injection mechanism allows implicit casting from existing types such as list and tuple without modifying the type definition of these objects. + +``` +>>> class MyClass: +... pass +>>> def conversion_func(value, dtype=None, name=None, as_ref=False): +... return tf.constant(1) +>>> tf.register_tensor_conversion_function(MyClass, conversion_func) +>>> obj = MyClass() +>>> tf.add(obj, tf.constant(1)) + +``` + +However, `register_tensor_conversion_function` is not compatible with static type checking. + +As a side note, types which that can be converted to a [NumPy array](https://docs.scipy.org/doc/numpy/user/basics.dispatch.html#basics-dispatch) can leverage that mechanism instead, because TensorFlow supports implicit conversion from `ndarray`: + +``` +>>> class MyClass: +... def __array__(self): +... return np.array(1) +>>> obj = MyClass() +>>> tf.add(obj, tf.constant(1)) + +``` + +For true custom `Tensor` objects, we propose a protocol approach similar to NumPy’s: + +``` +>>> class MyClass: +... def __tf_tensor__(self): +... return tf.constant(1) +>>> obj = MyClass() +>>> tf.add(obj, tf.constant(1)) + +``` + +Note that the mechanism above can be made compatible with static type checks using [typing.Protocol](https://www.python.org/dev/peps/pep-0544/#defining-a-protocol): + +``` +>>> class SupportsTensor(Protocol): +... def __tf_tensor__(self): +... pass +>>> def f(x: SupportsTensor): +... pass +>>> obj = MyClass() +>>> f(obj) # passes static type checks +``` + +Ultimately, `TensorLike` is to become a union of the protocol type along with any other types supported through legacy mechanisms: + +``` +TensorLike = Union[List, Tuple, tf.Tensor, SupportsTensor, ...] +``` + +The `Protocol` type is only standardized in Python 3.8. Backports exist through [typing_extensions](https://github.com/python/typing/tree/master/typing_extensions), although they still don’t support Python 3.5. Therefore, typing annotations will only be supported in 3.6+, and complete support is only available in 3.8+. + +Note that `Protocol` subtypes require [@runtime_checkable](https://www.python.org/dev/peps/pep-0544/#runtime-checkable-decorator-and-narrowing-types-by-isinstance) in order to be compatible with `isinstance`. However, that degrades the performance of `isinstance` in a way similar to `abc.ABCMeta`. For that reason, TensorFlow internal logic is encouraged to use the the more direct `hasattr` test for structural type checks of this kind. + ### Support for `tf.function`'s `input_signature` The type system listed here can be expanded to allow input signatures using type annotations, see for instance [this thread](https://github.com/tensorflow/tensorflow/issues/31579). From 1b20c1f342b6ce1499879b3833a40880e0f848ac Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Sat, 7 Mar 2020 18:16:34 -0500 Subject: [PATCH 28/46] Add open question about legacy API --- rfcs/20200211-tf-types.md | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index 40796cec4..a316fac2c 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -62,8 +62,8 @@ Custom objects can be used in standard TF operations using [tf.register_tensor_c ... return tf.constant(1) >>> tf.register_tensor_conversion_function(MyClass, conversion_func) >>> obj = MyClass() ->>> tf.add(obj, tf.constant(1)) - +>>> tf.convert_to_tensor(obj) + ``` However, `register_tensor_conversion_function` is not compatible with static type checking. @@ -75,19 +75,19 @@ As a side note, types which that can be converted to a [NumPy array](https://doc ... def __array__(self): ... return np.array(1) >>> obj = MyClass() ->>> tf.add(obj, tf.constant(1)) - +>>> tf.convert_to_tensor(obj) + ``` -For true custom `Tensor` objects, we propose a protocol approach similar to NumPy’s: +For true custom `Tensor` objects, we propose a protocol approach similar to NumPy’s, as alternative to `register_tensor_conversion_function`: ``` >>> class MyClass: ... def __tf_tensor__(self): ... return tf.constant(1) >>> obj = MyClass() ->>> tf.add(obj, tf.constant(1)) - +>>> tf.convert_to_tensor(obj) + ``` Note that the mechanism above can be made compatible with static type checks using [typing.Protocol](https://www.python.org/dev/peps/pep-0544/#defining-a-protocol): @@ -112,6 +112,8 @@ The `Protocol` type is only standardized in Python 3.8. Backports exist through Note that `Protocol` subtypes require [@runtime_checkable](https://www.python.org/dev/peps/pep-0544/#runtime-checkable-decorator-and-narrowing-types-by-isinstance) in order to be compatible with `isinstance`. However, that degrades the performance of `isinstance` in a way similar to `abc.ABCMeta`. For that reason, TensorFlow internal logic is encouraged to use the the more direct `hasattr` test for structural type checks of this kind. +Although this RFC proposes the deprecation of `register_tensor_conversion_function`, it does not set a timeline for removing it. It remains an open question whether interim support for type annotations should be added to `register_tensor_conversion_function`. + ### Support for `tf.function`'s `input_signature` The type system listed here can be expanded to allow input signatures using type annotations, see for instance [this thread](https://github.com/tensorflow/tensorflow/issues/31579). @@ -225,3 +227,4 @@ It is not fully equivalent with `typing.Optional`, as TensorFlow has no explicit * Whether to create entries for well-known types already exported like `tf.Tensor` and `tf.Variable`. Internally, superclasses for these types will be created, but the existing `tf.Tensor` can just point to those to avoid unnecessary duplication. * Single flat vs. hierarchical namespace - for example: `tf.types.distribute.Dataset`, or `tf.types.DistributedDataset`? * The inclusion of more specialized `Graph` types, such as `FuncGraph`, `CondBranchFuncGraph`, `WhileCondFuncGraph`, `WhileBodyFuncGraph`. It’s unclear where these should be defined, however internal submodules needs these subtypes to maintain acyclic dependencies. +* `register_tensor_conversion_function` - should it support static type verifications (e.g. using the [ABCMeta.register](https://docs.python.org/3/library/abc.html#abc.ABCMeta.register) mechanism)? From 451b627ea41b1034507a4e565eda39135ce7088d Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Tue, 10 Mar 2020 16:53:58 -0400 Subject: [PATCH 29/46] Add discussion topic for tf.TypeSpec --- rfcs/20200211-tf-types.md | 1 + 1 file changed, 1 insertion(+) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index a316fac2c..a9c58297e 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -228,3 +228,4 @@ It is not fully equivalent with `typing.Optional`, as TensorFlow has no explicit * Single flat vs. hierarchical namespace - for example: `tf.types.distribute.Dataset`, or `tf.types.DistributedDataset`? * The inclusion of more specialized `Graph` types, such as `FuncGraph`, `CondBranchFuncGraph`, `WhileCondFuncGraph`, `WhileBodyFuncGraph`. It’s unclear where these should be defined, however internal submodules needs these subtypes to maintain acyclic dependencies. * `register_tensor_conversion_function` - should it support static type verifications (e.g. using the [ABCMeta.register](https://docs.python.org/3/library/abc.html#abc.ABCMeta.register) mechanism)? +* Unification with `tf.TypeSpec` - although largely orthogonal at the moment, the distinction is subtle and confusing even for experts, which perhaps indicates we should unify them. From c3a1c2df3262a19a87cf2fc9f8a7640053e5a290 Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Tue, 17 Mar 2020 09:04:05 -0400 Subject: [PATCH 30/46] Detail the relationship with tf.TypeSpec --- rfcs/20200211-tf-types.md | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index a9c58297e..fab49bc21 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -117,6 +117,40 @@ Although this RFC proposes the deprecation of `register_tensor_conversion_functi ### Support for `tf.function`'s `input_signature` The type system listed here can be expanded to allow input signatures using type annotations, see for instance [this thread](https://github.com/tensorflow/tensorflow/issues/31579). +Presently, the [input_signature](https://www.tensorflow.org/api_docs/python/tf/function) optional mechanism uses [tf.TensorSpec](https://www.tensorflow.org/api_docs/python/tf/TensorSpec) to describe the function arguments: + +``` +>>> @function(input_signature=[TensorSpec([3], dtype=int32)]) +... def f(x): +... tf.print(x) +>>> f(constant([1, 2, 3])) +[1 2 3] +>>> f(constant([1, 2])) # Shape mismatch +ValueError: Python inputs incompatible with input_signature +>>> f(constant([1.0, 2.0, 3.0])) # DType mismatch +ValueError: Python inputs incompatible with input_signature +``` + +It is expected however that some or all of this information will be repeated by the function's type annotations. Type annotations may be generic, for example by only specifying a dtype: + +``` +>>> @function(input_signature=[TensorSpec([3], dtype=int32)]) +... def f(x: Tensor[int32]): +... ... +``` + +In such cases, `tf.function` is expected to verify that the type annotation matches the `input_signature`. + +In the long term, this RFC recommends that type annotations fully replace the `input_signature`, so far as the Python type annotation system allows it: + +``` +>>> @function +... def f(x: Tensor[int32, [3]]): +... ... +``` + +Internally. such type annotations will still be represented as `tf.TypeSpec` objects, ensuring backward compatbility. + ### Initial Type Hierarchy TensorFlow generally adopts an incremental development method. This RFC aims to remain consistent with that. @@ -228,4 +262,3 @@ It is not fully equivalent with `typing.Optional`, as TensorFlow has no explicit * Single flat vs. hierarchical namespace - for example: `tf.types.distribute.Dataset`, or `tf.types.DistributedDataset`? * The inclusion of more specialized `Graph` types, such as `FuncGraph`, `CondBranchFuncGraph`, `WhileCondFuncGraph`, `WhileBodyFuncGraph`. It’s unclear where these should be defined, however internal submodules needs these subtypes to maintain acyclic dependencies. * `register_tensor_conversion_function` - should it support static type verifications (e.g. using the [ABCMeta.register](https://docs.python.org/3/library/abc.html#abc.ABCMeta.register) mechanism)? -* Unification with `tf.TypeSpec` - although largely orthogonal at the moment, the distinction is subtle and confusing even for experts, which perhaps indicates we should unify them. From f551da1527a3c8ef2aaaf4eb5c71dc97e1bc33f3 Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Fri, 20 Mar 2020 08:55:28 -0400 Subject: [PATCH 31/46] Formatting --- rfcs/20200211-tf-types.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index fab49bc21..ea77eeab6 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -11,6 +11,7 @@ This RFC proposes a new TensorFlow module and namespace (`tf.types`) dedicated to storing implementation-free type definitions, similar to Java interfaces or C++ forward declarations. This module has no other dependencies inside TensorFlow, so any other internal module can depend on it to ensure interoperability without the risk of creating circular dependencies. These definitions can also be used by external users, for example in pytype annotations. The RFC focuses on the Python API, however the design should be reviewed with cross-language consistency in mind. + ## Motivation **Interoperability and composability**. A set of standard types that formalize an interface and decouples it from implementation ensures composability between components, especially when multiple implementations are involved. @@ -32,6 +33,7 @@ Developers of modules internal to TensorFlow can use this module to avoid creati ## Design Proposal ### The `tf.types` Namespace / Module + All the declarations exposed under the `tf.types` namespace reside in the `python/types/*.py` module. These are [abstract base classes](https://docs.python.org/3.7/library/abc.html) with a bare minimum of method definitions and minimal or no implementation, which serve to formalize and document the contract of common types such as `Tensor`, `Variable`, etc. These definitions may be used as PEP 484 type hints, although in some cases they may be type- or shape- erased (for example, `tf.types.Tensor` may not necessarily be parametrized by `dtype` or `shape`). Note however that designs which parametrize on shape do exist, see for instance [tensorflow#31579](https://github.com/tensorflow/tensorflow/issues/31579). @@ -39,6 +41,7 @@ These definitions may be used as PEP 484 type hints, although in some cases they The type definitions are consistent with standard Python [subtyping mechanics](https://docs.python.org/3.8/library/typing.html#nominal-vs-structural-subtyping) such as instance checks or protocols (in versions prior to Python 3.8, it is difficult to simultaneously support both). ### General Principles + This module should not contain any implementation code. An advantage of that is that users exploring the implementation of specific types will not need to inspect this module. However, users who do not wish to inspect the code may visit the documentation of these generic types to better understand specifically what are the concrete subclasses of this type expected to do. The `tf.types` module may depend on external packages (such as `numpy`) _strictly for the purpose of defining type annotations and documentation_. No dependencies to other TensorFlow interfaces are allowed. Any dependencies on external packages which themselves depend on TensorFlow are expressly forbidden. @@ -115,6 +118,7 @@ Note that `Protocol` subtypes require [@runtime_checkable](https://www.python.or Although this RFC proposes the deprecation of `register_tensor_conversion_function`, it does not set a timeline for removing it. It remains an open question whether interim support for type annotations should be added to `register_tensor_conversion_function`. ### Support for `tf.function`'s `input_signature` + The type system listed here can be expanded to allow input signatures using type annotations, see for instance [this thread](https://github.com/tensorflow/tensorflow/issues/31579). Presently, the [input_signature](https://www.tensorflow.org/api_docs/python/tf/function) optional mechanism uses [tf.TensorSpec](https://www.tensorflow.org/api_docs/python/tf/TensorSpec) to describe the function arguments: @@ -152,6 +156,7 @@ In the long term, this RFC recommends that type annotations fully replace the `i Internally. such type annotations will still be represented as `tf.TypeSpec` objects, ensuring backward compatbility. ### Initial Type Hierarchy + TensorFlow generally adopts an incremental development method. This RFC aims to remain consistent with that. Below are listed the major types presently used in TensorFlow. All types included in this list are subject to [normal compatibility rules](https://www.tensorflow.org/guide/versions), so they are unlikely to change in the future. It is therefore preferable to maintain a strict minimum of orthogonal declarations and carefully vet any additions. @@ -224,35 +229,44 @@ Example graph code: It is not fully equivalent with `typing.Optional`, as TensorFlow has no explicit type or value for `None`. ### Alternatives Considered + * N/A ### Performance Implications + * There is a potential performance concern if using `abc` for the abstract base types, which are about an order of magnitude slower for `isinstance` checks. The cost of `isinstance` may be non-negligible for eager execution or scaling to large graphs. In such cases, we may want to avoid using `abc`. See https://github.com/tensorflow/community/pull/208#discussion_r382494902. ### Dependencies + * None, by definition. ### Engineering Impact + * Engineering impact: Separate interfaces allow for faster loading times by reducing coupling between modules. * Maintenance: Minimal maintenance overhead since there is no functionality involved. The TensorFlow team and contributors will maintain the documentation up to date. Changes should be reviewed and approved by the TensorFlow team leads. ### Platforms and Environments + * Platforms: Python only, in the first stage. However, the type system should be aligned as much as possible with the core types in the TensorFlow runtime, and be language-independent as much as possible. * Execution environments: The type system is independent of platform. This also implies that no platform-specific types (such as `TPUTensor`) exist. ### Best Practices + * This set of type definitions support the acyclic dependencies principle, by requiring that implementations avoid lateral dependencies (e.g. with a linter rule). ### Tutorials and Examples + * As the design matures, we plan to showcase libraries that leverage this pattern. * Type annotations will be included in existing tutorials as definitions become final. ### Compatibility + * New minor version. Existing classes (`tf.Tensor`) will become subclasses of the new type interfaces. * Most subcomponents of TF (Lite, distributed, function, SavedModel) will depend on this new module, although their functionality is not impacted. * Libraries which depend on TensorFlow are encouraged to refer to `tf.types` definitions, rather than the concrete implementations for better future compatibility. ### User Impact + * Users will see a new `tf.types` module, that may be referenced from documentation and type annotations. From cbe5eafe341cc8780cf9f003d58627f79b8a00b3 Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Fri, 20 Mar 2020 09:11:52 -0400 Subject: [PATCH 32/46] Draft guidance for adding new types --- rfcs/20200211-tf-types.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index ea77eeab6..c476296b4 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -209,7 +209,22 @@ Many of these are expected to be required when breaking the cyclic dependencies * Low-level execution primitives * `Graph` - GraphDef/IR program * `FunctionGraph` - IR of a single concrete function - + +#### Adding new types + +This module may contain public symbols, exported using `@tf_export`, and private (unexported) symbols. Private symbols are reserved exclusively for internal submodules. Only public types are subject to the normal compatibility guarantees. + +Private types should only be added here if more than one submodule requires them. + +Public types represent established, well-known types that are critical to the TensorFlow API. They may only be added with API owners approval. In general, a type should be thoroughly scrutinized before being made public. Prefer to err on the side of keeping it private, when in doubt. Ideally, new public types should be introduced using the RFC process. + +Use the following guidance when adding a new definition to `tf.types`: + * has at least two concrete implementations, and at least one is part of the core TensorFlow API + * represents a well-established programming abstraction (e.g. list, map) + * does not overlap with existing definitions + * is consistent with existing definitions + * is compatible with all applicable core APIs + #### Detailed notes ##### Optional From b8aae737fe809d0f33acb3129dab8a900be87ac3 Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Fri, 20 Mar 2020 09:17:54 -0400 Subject: [PATCH 33/46] Minor edit --- rfcs/20200211-tf-types.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index c476296b4..6bd8f9bf0 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -218,9 +218,9 @@ Private types should only be added here if more than one submodule requires them Public types represent established, well-known types that are critical to the TensorFlow API. They may only be added with API owners approval. In general, a type should be thoroughly scrutinized before being made public. Prefer to err on the side of keeping it private, when in doubt. Ideally, new public types should be introduced using the RFC process. -Use the following guidance when adding a new definition to `tf.types`: +A good candidate for a public `tf.types` definition meets the following criteria: * has at least two concrete implementations, and at least one is part of the core TensorFlow API - * represents a well-established programming abstraction (e.g. list, map) + * represents a well-established programming abstraction (e.g. list, map, object) * does not overlap with existing definitions * is consistent with existing definitions * is compatible with all applicable core APIs From e7b0fef6a5cf8d5b7d6861c1ebdcb25187080656 Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Fri, 20 Mar 2020 19:26:32 -0400 Subject: [PATCH 34/46] Use a proper example for type annotations --- rfcs/20200211-tf-types.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index 6bd8f9bf0..561d55bda 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -148,8 +148,10 @@ In such cases, `tf.function` is expected to verify that the type annotation matc In the long term, this RFC recommends that type annotations fully replace the `input_signature`, so far as the Python type annotation system allows it: ``` +>>> class BatchSize(Dimension): +... value = 32 >>> @function -... def f(x: Tensor[int32, [3]]): +... def f(x: Tensor[Int32, Shape1D[BatchSize]]): ... ... ``` From 8797e7394d7e996aee01e8e6c3fc73d7c1899b89 Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Fri, 20 Mar 2020 19:29:15 -0400 Subject: [PATCH 35/46] Update 20200211-tf-types.md --- rfcs/20200211-tf-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index 561d55bda..d5fc17926 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -149,7 +149,7 @@ In the long term, this RFC recommends that type annotations fully replace the `i ``` >>> class BatchSize(Dimension): -... value = 32 +... value = 32 >>> @function ... def f(x: Tensor[Int32, Shape1D[BatchSize]]): ... ... From 882dbb6d8dfacfbbc1a4f89bc9e21ee7d7053f68 Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Fri, 20 Mar 2020 19:30:00 -0400 Subject: [PATCH 36/46] Fix typo. --- rfcs/20200211-tf-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index d5fc17926..19afff3f2 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -155,7 +155,7 @@ In the long term, this RFC recommends that type annotations fully replace the `i ... ... ``` -Internally. such type annotations will still be represented as `tf.TypeSpec` objects, ensuring backward compatbility. +Internally, such type annotations will still be represented as `tf.TypeSpec` objects, ensuring backward compatbility. ### Initial Type Hierarchy From 97d5d8db182091c8570a03a893f2b3dd81119025 Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Sat, 21 Mar 2020 13:58:26 -0400 Subject: [PATCH 37/46] Clarify that example is non-prescriptive --- rfcs/20200211-tf-types.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index 19afff3f2..c686a2375 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -119,7 +119,7 @@ Although this RFC proposes the deprecation of `register_tensor_conversion_functi ### Support for `tf.function`'s `input_signature` -The type system listed here can be expanded to allow input signatures using type annotations, see for instance [this thread](https://github.com/tensorflow/tensorflow/issues/31579). +The type system listed here can be expanded to allow input signatures using type annotations, see for instance [`](https://github.com/tensorflow/tensorflow/issues/31579). Presently, the [input_signature](https://www.tensorflow.org/api_docs/python/tf/function) optional mechanism uses [tf.TensorSpec](https://www.tensorflow.org/api_docs/python/tf/TensorSpec) to describe the function arguments: @@ -145,7 +145,9 @@ It is expected however that some or all of this information will be repeated by In such cases, `tf.function` is expected to verify that the type annotation matches the `input_signature`. -In the long term, this RFC recommends that type annotations fully replace the `input_signature`, so far as the Python type annotation system allows it: +In the long term, this RFC recommends that type annotations fully replace the `input_signature`, so far as the Python type annotation system allows it. This RFC does not prescribe a scheme for such type annotations; the implementation should make best use of the available Python capabilities and standards. + +An example of such annotations could be: ``` >>> class BatchSize(Dimension): From e86de57bb43a9bfc7bd28cd1567d3d6d56f72285 Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Sat, 21 Mar 2020 13:58:43 -0400 Subject: [PATCH 38/46] Update status to proposed --- rfcs/20200211-tf-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index c686a2375..f8717ff4f 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -1,6 +1,6 @@ # TensorFlow Canonical Type System -| Status | WIP | +| Status | Proposed | :-------------- |:---------------------------------------------------- | | **RFC #** | [208](https://github.com/tensorflow/community/pull/208) | **Author(s)** | Dan Moldovan (mdan@google.com) | From fac8975a4bc2f1f2185bc1e5824c5ecb33e780a0 Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Sat, 21 Mar 2020 13:59:08 -0400 Subject: [PATCH 39/46] Update time stamp --- rfcs/20200211-tf-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index f8717ff4f..ed2251c5f 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -5,7 +5,7 @@ | **RFC #** | [208](https://github.com/tensorflow/community/pull/208) | **Author(s)** | Dan Moldovan (mdan@google.com) | | **Sponsor** | Gaurav Jain (gjn@google.com) | -| **Updated** | 2020-03-04 | +| **Updated** | 2020-03-21 | ## Objective From 9c2f37f59e8069506e0d4614c6f9ebaef7c2b86a Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Sat, 21 Mar 2020 14:00:49 -0400 Subject: [PATCH 40/46] Fix typo --- rfcs/20200211-tf-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index ed2251c5f..766290fb4 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -119,7 +119,7 @@ Although this RFC proposes the deprecation of `register_tensor_conversion_functi ### Support for `tf.function`'s `input_signature` -The type system listed here can be expanded to allow input signatures using type annotations, see for instance [`](https://github.com/tensorflow/tensorflow/issues/31579). +The type system listed here can be expanded to allow input signatures using type annotations, see for instance [this thread](https://github.com/tensorflow/tensorflow/issues/31579). Presently, the [input_signature](https://www.tensorflow.org/api_docs/python/tf/function) optional mechanism uses [tf.TensorSpec](https://www.tensorflow.org/api_docs/python/tf/TensorSpec) to describe the function arguments: From 8e47bc13bc5f96151ca5c0db2d1cd541141c9607 Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Sat, 21 Mar 2020 14:04:04 -0400 Subject: [PATCH 41/46] Slight update to example --- rfcs/20200211-tf-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index 766290fb4..bf8b29d86 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -153,7 +153,7 @@ An example of such annotations could be: >>> class BatchSize(Dimension): ... value = 32 >>> @function -... def f(x: Tensor[Int32, Shape1D[BatchSize]]): +... def f(x: Tensor[Int32, Shape2D[BatchSize, DynamicSize, DynamicSize]]): ... ... ``` From bc33a1aabce6483f9a8de3f95089bdf771a7807d Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Tue, 24 Mar 2020 10:47:17 -0400 Subject: [PATCH 42/46] Add link to an example --- rfcs/20200211-tf-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index bf8b29d86..05eee03a4 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -16,7 +16,7 @@ The RFC focuses on the Python API, however the design should be reviewed with cr **Interoperability and composability**. A set of standard types that formalize an interface and decouples it from implementation ensures composability between components, especially when multiple implementations are involved. -**Supports the [acyclic dependencies principle](https://en.wikipedia.org/wiki/Acyclic_dependencies_principle)**. In many instances, circular dependencies are caused between low-level complex components that need to compose (e.g. autograph needs to recognize datasets, and datasets need to use autograph). Interface extraction is a common pattern for breaking such cycles. +**Supports the [acyclic dependencies principle](https://en.wikipedia.org/wiki/Acyclic_dependencies_principle)**. In many instances, circular dependencies are caused between low-level complex components that need to compose (in this [example](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/autograph/operators/control_flow.py#L361), AutoGraph needs to recognize datasets, and datasets need to use AutoGraph). Interface extraction is a common pattern for breaking such cycles. **Supports pytype**. A set of static types that is consistent under Python’s `isinstance`/`issubclass` is required to support [PEP-484 type annotations](https://www.python.org/dev/peps/pep-0484/) in TensorFlow. This module can serve as the basis for that. From af51680b9daf5292fe7582047408aabca9a825ad Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Tue, 24 Mar 2020 19:00:34 -0400 Subject: [PATCH 43/46] Add design review notes --- rfcs/20200211-tf-types.md | 57 ++++++++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index 05eee03a4..f36afee11 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -288,10 +288,53 @@ It is not fully equivalent with `typing.Optional`, as TensorFlow has no explicit * Users will see a new `tf.types` module, that may be referenced from documentation and type annotations. - -## Questions and Discussion Topics - -* Whether to create entries for well-known types already exported like `tf.Tensor` and `tf.Variable`. Internally, superclasses for these types will be created, but the existing `tf.Tensor` can just point to those to avoid unnecessary duplication. -* Single flat vs. hierarchical namespace - for example: `tf.types.distribute.Dataset`, or `tf.types.DistributedDataset`? -* The inclusion of more specialized `Graph` types, such as `FuncGraph`, `CondBranchFuncGraph`, `WhileCondFuncGraph`, `WhileBodyFuncGraph`. It’s unclear where these should be defined, however internal submodules needs these subtypes to maintain acyclic dependencies. -* `register_tensor_conversion_function` - should it support static type verifications (e.g. using the [ABCMeta.register](https://docs.python.org/3/library/abc.html#abc.ABCMeta.register) mechanism)? +## Design Review Notes + +Changes since initial PR: + * New section discusses overlap of type system with existing register tensor conversion function: + * TLDR: The python protocol mechanism is much more compatible with type annotations compared to register_tensor_conversion_function. + * Python Protocol works with type annotations. + * We should be able to deprecate `register_tensor_conversion_function`. + * Protocol support for type annotations introduced with typing in 3.8, backported to 3.x except 3.5, so type annotations will not work correctly in 3.5. + * New section discussing relationship with TensorSpec/TypeSpec/input signatures: + * TLDR: Will continue to have input_signature in conjunction with function type annotations. A complete design for annotation-based input_signature is future work and currently out of scope. + * We will need to verify that input_signarture agrees with type annotations when both are present. + * There is concern about having two ways of expressing signatures (type annotations and input_signature). + * There were many questions around the best way to represent known and unknown shapes, interaction with concrete functions, the concrete type of the result of tf.function, etc. A few points raised: + * `input_signature` cannot be recognized as type annotation. + * Supporting parameterized types with values as required for shapes is tricky. + * Dimension values can be known or not known in today’s implementation; `Literal` may be able specify dimension sizes, but that needs to be verified. + * Supporting meta functions where signature is an argument still requires the input signature mechanism (e.g. get_concrete_function). + * If we add this to `tf.function`, should the function take a signature argument that looks like the type annotation? Unclear whether that’s possible or makes sense. + * Will need to support both at the same time at least for a while. + * If both are present then they will likely need to be merged to the most specific common signature. + * There is a concern about whether to choose specific or generic shapes when the type annotation is incomplete. + * Union types will also need to instantiate multiple concrete functions (like `tf.function` does today). + * A proposal was to allow a function with types to be passed to tf.function as long as you don’t pass a `input_signature`. +This also applies to `tf.map_fn` and other APIs, not just `tf.function`. + * Another question was about using type annotations to parametrize structures of types, e.g. where output has the same structure but different types. This may be beyond the expressivity of the current type annotation system. + * New section containing guidance on adding new public generic types: + * TLDR: The RFC only adds a very small number of types, a complete type system is out of scope. + * There is some concern about the graph-vs-eager distinction when composing `Tensor` objects, e.g. with `CompositeTensor`. + * For now we’ll try to avoid exporting specific types for Graph vs. Eager until the `CompositeTensor` issue is resolved. Most likely we’ll need some type erasure. + * RFC proposes guidance for adding new types in the future. + * Other changes: + * Added mention on `Tensor`-like types + * List of lists can be converted to tensor but only if they are not ragged. The type annotation system will not enforce that. + * Clarified difference between `tf.Optional` and `typing.Optional`. + * Added clarifications that the spirit of RFC is to be compatible with Python standards and support all python static checkers, not just pytype. + * `isinstance` is not necessary the recommended mechanism, but the type system should be compatible with it and other Python mechanisms + * Discussion on open questions + * Having multiple type definitions (e.g. `tf.Tensor`, `tf.types.Tensor`) can be confusing to users: + * We want to try to expose only one type. + * The preference is to only expose the generic type, but in some cases the specialized one is already exported. In some cases, like `tf.Tensor` we can make the switch. + * In other cases, like `tf.Variable`, we can’t because `Variable` objects are instantiated directly. + * So we’ll punt on `tf.Variable` for now. + * Flat vs. hierarchical namespace: + * Does not need to be answered now, since the initial number of types is small. + * A good default is to mimic the existing namespace structure (e.g. for datasets use `tf.types.data.Dataset`) + * Should we include highly specialized types? e.g. `FuncGraph` classes for cond/while branches: + * They may be needed for Keras. + * In general, if an external library needs a type that’s an indication that it might be useful to export that type. + * `isinstance` support for `register_tensor_conversion_function` using e.g. ABC magics. + * Decision made to accelerate the deprecation of register_tensor_conversion_function instead. From c8816c42da44aa7b5b9056c0a8d4542a3e43c44b Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Tue, 24 Mar 2020 19:02:32 -0400 Subject: [PATCH 44/46] Fix indentation in notes --- rfcs/20200211-tf-types.md | 82 +++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index f36afee11..996690188 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -292,49 +292,49 @@ It is not fully equivalent with `typing.Optional`, as TensorFlow has no explicit Changes since initial PR: * New section discusses overlap of type system with existing register tensor conversion function: - * TLDR: The python protocol mechanism is much more compatible with type annotations compared to register_tensor_conversion_function. - * Python Protocol works with type annotations. - * We should be able to deprecate `register_tensor_conversion_function`. - * Protocol support for type annotations introduced with typing in 3.8, backported to 3.x except 3.5, so type annotations will not work correctly in 3.5. + * TLDR: The python protocol mechanism is much more compatible with type annotations compared to register_tensor_conversion_function. + * Python Protocol works with type annotations. + * We should be able to deprecate `register_tensor_conversion_function`. + * Protocol support for type annotations introduced with typing in 3.8, backported to 3.x except 3.5, so type annotations will not work correctly in 3.5. * New section discussing relationship with TensorSpec/TypeSpec/input signatures: - * TLDR: Will continue to have input_signature in conjunction with function type annotations. A complete design for annotation-based input_signature is future work and currently out of scope. - * We will need to verify that input_signarture agrees with type annotations when both are present. - * There is concern about having two ways of expressing signatures (type annotations and input_signature). - * There were many questions around the best way to represent known and unknown shapes, interaction with concrete functions, the concrete type of the result of tf.function, etc. A few points raised: - * `input_signature` cannot be recognized as type annotation. - * Supporting parameterized types with values as required for shapes is tricky. - * Dimension values can be known or not known in today’s implementation; `Literal` may be able specify dimension sizes, but that needs to be verified. - * Supporting meta functions where signature is an argument still requires the input signature mechanism (e.g. get_concrete_function). - * If we add this to `tf.function`, should the function take a signature argument that looks like the type annotation? Unclear whether that’s possible or makes sense. - * Will need to support both at the same time at least for a while. - * If both are present then they will likely need to be merged to the most specific common signature. - * There is a concern about whether to choose specific or generic shapes when the type annotation is incomplete. - * Union types will also need to instantiate multiple concrete functions (like `tf.function` does today). - * A proposal was to allow a function with types to be passed to tf.function as long as you don’t pass a `input_signature`. + * TLDR: Will continue to have input_signature in conjunction with function type annotations. A complete design for annotation-based input_signature is future work and currently out of scope. + * We will need to verify that input_signarture agrees with type annotations when both are present. + * There is concern about having two ways of expressing signatures (type annotations and input_signature). + * There were many questions around the best way to represent known and unknown shapes, interaction with concrete functions, the concrete type of the result of tf.function, etc. A few points raised: + * `input_signature` cannot be recognized as type annotation. + * Supporting parameterized types with values as required for shapes is tricky. + * Dimension values can be known or not known in today’s implementation; `Literal` may be able specify dimension sizes, but that needs to be verified. + * Supporting meta functions where signature is an argument still requires the input signature mechanism (e.g. get_concrete_function). + * If we add this to `tf.function`, should the function take a signature argument that looks like the type annotation? Unclear whether that’s possible or makes sense. + * Will need to support both at the same time at least for a while. + * If both are present then they will likely need to be merged to the most specific common signature. + * There is a concern about whether to choose specific or generic shapes when the type annotation is incomplete. + * Union types will also need to instantiate multiple concrete functions (like `tf.function` does today). + * A proposal was to allow a function with types to be passed to tf.function as long as you don’t pass a `input_signature`. This also applies to `tf.map_fn` and other APIs, not just `tf.function`. - * Another question was about using type annotations to parametrize structures of types, e.g. where output has the same structure but different types. This may be beyond the expressivity of the current type annotation system. + * Another question was about using type annotations to parametrize structures of types, e.g. where output has the same structure but different types. This may be beyond the expressivity of the current type annotation system. * New section containing guidance on adding new public generic types: - * TLDR: The RFC only adds a very small number of types, a complete type system is out of scope. - * There is some concern about the graph-vs-eager distinction when composing `Tensor` objects, e.g. with `CompositeTensor`. - * For now we’ll try to avoid exporting specific types for Graph vs. Eager until the `CompositeTensor` issue is resolved. Most likely we’ll need some type erasure. - * RFC proposes guidance for adding new types in the future. + * TLDR: The RFC only adds a very small number of types, a complete type system is out of scope. + * There is some concern about the graph-vs-eager distinction when composing `Tensor` objects, e.g. with `CompositeTensor`. + * For now we’ll try to avoid exporting specific types for Graph vs. Eager until the `CompositeTensor` issue is resolved. Most likely we’ll need some type erasure. + * RFC proposes guidance for adding new types in the future. * Other changes: - * Added mention on `Tensor`-like types - * List of lists can be converted to tensor but only if they are not ragged. The type annotation system will not enforce that. - * Clarified difference between `tf.Optional` and `typing.Optional`. - * Added clarifications that the spirit of RFC is to be compatible with Python standards and support all python static checkers, not just pytype. - * `isinstance` is not necessary the recommended mechanism, but the type system should be compatible with it and other Python mechanisms + * Added mention on `Tensor`-like types + * List of lists can be converted to tensor but only if they are not ragged. The type annotation system will not enforce that. + * Clarified difference between `tf.Optional` and `typing.Optional`. + * Added clarifications that the spirit of RFC is to be compatible with Python standards and support all python static checkers, not just pytype. + * `isinstance` is not necessary the recommended mechanism, but the type system should be compatible with it and other Python mechanisms * Discussion on open questions - * Having multiple type definitions (e.g. `tf.Tensor`, `tf.types.Tensor`) can be confusing to users: - * We want to try to expose only one type. - * The preference is to only expose the generic type, but in some cases the specialized one is already exported. In some cases, like `tf.Tensor` we can make the switch. - * In other cases, like `tf.Variable`, we can’t because `Variable` objects are instantiated directly. - * So we’ll punt on `tf.Variable` for now. - * Flat vs. hierarchical namespace: - * Does not need to be answered now, since the initial number of types is small. - * A good default is to mimic the existing namespace structure (e.g. for datasets use `tf.types.data.Dataset`) - * Should we include highly specialized types? e.g. `FuncGraph` classes for cond/while branches: - * They may be needed for Keras. - * In general, if an external library needs a type that’s an indication that it might be useful to export that type. - * `isinstance` support for `register_tensor_conversion_function` using e.g. ABC magics. - * Decision made to accelerate the deprecation of register_tensor_conversion_function instead. + * Having multiple type definitions (e.g. `tf.Tensor`, `tf.types.Tensor`) can be confusing to users: + * We want to try to expose only one type. + * The preference is to only expose the generic type, but in some cases the specialized one is already exported. In some cases, like `tf.Tensor` we can make the switch. + * In other cases, like `tf.Variable`, we can’t because `Variable` objects are instantiated directly. + * So we’ll punt on `tf.Variable` for now. + * Flat vs. hierarchical namespace: + * Does not need to be answered now, since the initial number of types is small. + * A good default is to mimic the existing namespace structure (e.g. for datasets use `tf.types.data.Dataset`) + * Should we include highly specialized types? e.g. `FuncGraph` classes for cond/while branches: + * They may be needed for Keras. + * In general, if an external library needs a type that’s an indication that it might be useful to export that type. + * `isinstance` support for `register_tensor_conversion_function` using e.g. ABC magics. + * Decision made to accelerate the deprecation of register_tensor_conversion_function instead. From 327ceda727a40a83a0981dfdae46db8f3b6392c7 Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Tue, 24 Mar 2020 19:07:25 -0400 Subject: [PATCH 45/46] Minor updates following design review --- rfcs/20200211-tf-types.md | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index 996690188..e2688fc5d 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -119,6 +119,8 @@ Although this RFC proposes the deprecation of `register_tensor_conversion_functi ### Support for `tf.function`'s `input_signature` +Note: this section is non-normative, and only establishes direction for future work. + The type system listed here can be expanded to allow input signatures using type annotations, see for instance [this thread](https://github.com/tensorflow/tensorflow/issues/31579). Presently, the [input_signature](https://www.tensorflow.org/api_docs/python/tf/function) optional mechanism uses [tf.TensorSpec](https://www.tensorflow.org/api_docs/python/tf/TensorSpec) to describe the function arguments: @@ -157,7 +159,7 @@ An example of such annotations could be: ... ... ``` -Internally, such type annotations will still be represented as `tf.TypeSpec` objects, ensuring backward compatbility. +Internally, such type annotations should still be represented as `tf.TypeSpec` objects, ensuring backward compatbility. ### Initial Type Hierarchy @@ -178,20 +180,21 @@ These types will be added with the initial creation of the `tf.types` namespace. * `DType` * `Shape` * `Tensor` - generic dense tensor - - * `Symbol` - the regular graph tensor - * `Value` - eager tensors - * `TensorLike` - any type that can be implicitly converted to `Tensor` (see for example https://github.com/tensorflow/addons/blob/master/tensorflow_addons/utils/types.py) - * `Variable` - #### Potential types for subsequent implementation These types are raised for discussion by this RFC, but are not part of the original implementation, unless they are strictly required for consistency (to be determined during the initial submission). Many of these are expected to be required when breaking the cyclic dependencies that currently exist between submodules. However, it is hoped that opening them up for discussion early can help create a more coherent type system. +* Core types + + * Tensor specializations + * `Symbol` - the regular graph tensor + * `Value` - eager tensors + * `Variable` + * Container types * `Composite` - low-level static structure (opaque to GraphDef/IR) @@ -220,7 +223,7 @@ This module may contain public symbols, exported using `@tf_export`, and private Private types should only be added here if more than one submodule requires them. -Public types represent established, well-known types that are critical to the TensorFlow API. They may only be added with API owners approval. In general, a type should be thoroughly scrutinized before being made public. Prefer to err on the side of keeping it private, when in doubt. Ideally, new public types should be introduced using the RFC process. +Public types represent established, well-known types that are critical to the TensorFlow API. They may only be added with API owners approval. In general, a type should be thoroughly scrutinized before being made public. Prefer to err on the side of keeping it private, when in doubt. Ideally, new public types should be introduced using the RFC process. Using `experimental` to pilot new types before a complete implementation is encouraged. A good candidate for a public `tf.types` definition meets the following criteria: * has at least two concrete implementations, and at least one is part of the core TensorFlow API From aeff1248e2ad28e3b710dc0eecd4e19ffa84a37e Mon Sep 17 00:00:00 2001 From: Dan Moldovan Date: Tue, 24 Mar 2020 19:08:20 -0400 Subject: [PATCH 46/46] Update status --- rfcs/20200211-tf-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcs/20200211-tf-types.md b/rfcs/20200211-tf-types.md index e2688fc5d..ba027eeb2 100644 --- a/rfcs/20200211-tf-types.md +++ b/rfcs/20200211-tf-types.md @@ -1,6 +1,6 @@ # TensorFlow Canonical Type System -| Status | Proposed | +| Status | Accepted | :-------------- |:---------------------------------------------------- | | **RFC #** | [208](https://github.com/tensorflow/community/pull/208) | **Author(s)** | Dan Moldovan (mdan@google.com) |