Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extract tf.function decorator keyword arguments #144

Open
wants to merge 78 commits into
base: main
Choose a base branch
from

Conversation

tatianacv
Copy link
Member

@tatianacv tatianacv commented Feb 10, 2023

Fixes #136 .

Commits

  • I slowed down and took a deep breadth before committing. Otherwise, I will start a pristine branch and reissue this pull request.
  • Before committing my changes, I checked my working directory carefully. I only staged the changes I wanted and ensured it was of the utmost quality.
  • I used git diff and git status to check my work carefully before committing.
  • I completely understand what I am committing and why.
  • I completely understand why things are the way they are.
  • The change I am proposing makes complete sense to me.
  • For the most part, the changes in this pull request correspond to the problem or task I am solving or performing. In other words, only the changes that are supposed to be there are the ones included in this pull request.

Expectations

Extract tf.function decorator keyword parameter values. We are obtaining the decorator’s argument literal values. We throw an exception when we find something we cannot process, like for example, non-literal values.

Testing

  • If this is a bug fix, I was able to reproduce the problem locally before I made any changes (can use git stash to temporarily reset the working directory).
  • When I made (or put back) my changes, the problem I reproduced above was fixed.

I added tests for many possible values that could arise for each tf.function arguments. I used the tf.function documentation to understand and make tests for different possible values. I also added test to make sure that for when we are not working with literals, we throw an exception.

Final Checks

  • The changes I am proposing meet the expectations I have described above.
  • I have performed a self-review of my code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have made corresponding changes to the documentation if applicable.
  • I have added tests that prove my fix is effective or that my feature works if applicable.
  • New and existing unit tests pass locally with my changes.

@tatianacv
Copy link
Member Author

Also add a URL for each parameter using an HTML anchor for where it is described in the docs for the specific version (permalink) we are considering.

There is no URL for each tf.function parameter. The most specific permalink would be https://www.tensorflow.org/versions/r2.9/api_docs/python/tf/function#args

@khatchad
Copy link
Member

Also add a URL for each parameter using an HTML anchor for where it is described in the docs for the specific version (permalink) we are considering.

There is no URL for each tf.function parameter. The most specific permalink would be https://www.tensorflow.org/versions/r2.9/api_docs/python/tf/function#args

Yeah? Like this one? https://www.tensorflow.org/versions/r2.9/api_docs/python/tf/function#input_signature

Copy link
Member

@khatchad khatchad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Getting there.


/**
* Value of this {@link Function}'s {@link decoratorsType} parameter experimental_autograph_options. The values could be an optional
* tuple or value of tf.autograph.experimental.Feature values or None.
*/
private String experimentalAutographOptionsParamValue;
private String experimentalAutographOptionsParam;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

String isn't a good type to represent these values. The docs even say, "this enumeration represents optional conversion options.". That's a hint at what Java (also in C++) type can be used here.

P.S. It's unfortunate that even the example there is using a decorator value from a variable.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be an enumeration or tuple of enumerations (https://www.tensorflow.org/versions/r2.9/api_docs/python/tf/function#experimental_autograph_options). How can this be represented?

Copy link
Member Author


/**
* Value of this {@link Function}'s {@link decoratorsType} parameter experimental_autograph_options. The values could be an optional
* tuple or value of tf.autograph.experimental.Feature values or None.
*/
private String experimentalAutographOptionsParamValue;
private String experimentalAutographOptionsParam;

/**
* Value of this {@link Function}'s {@link decoratorsType} parameter experimental_implements. The value could be None or a name of a
* "known" function this implements.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add an example value. This can be in HTML using <code>...</code>.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

*/
private String inputSignatureParamValue;
private ArrayList<TensorSpec> inputSignatureParam;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this need to specifically be an ArrayList? Is it important that the list be contiguous in memory (this is not a question).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to List

@@ -204,8 +207,13 @@ public HybridizationParameters(IProgressMonitor monitor) throws BadLocationExcep
// Example of value: True, False, None
if (keyword.value instanceof Name) {
Name value = (Name) keyword.value;
if (value.id == "True" || value.id == "False" || value.id == "None") // Checking only literals
this.jitCompileParamValue = value.id;
if (value.id == "True") // Checking only literals
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per our conversations, we need to be able to tell when a literal value is not used. Thus, we need an exception thrown when a variable is used. Is that what is happening below (this is a question).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct


TensorSpec tensor = (TensorSpec) tensorObject;

return shape.equals(tensor.shape) && dtype.equals(tensor.dtype);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are hashCode and equals being overridden for this class? Are you comparing these or putting them into a Set (this is a question)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

* True if the {@link TensorSpec} is using keyword arguments for the type.
*/
private boolean dtypeKeyword;

public TensorSpec() {
this.shape = "";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there more useful representation for a shape than a String?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a List

* True if the {@link TensorSpec} is using keyword arguments for the type.
*/
private boolean dtypeKeyword;

public TensorSpec() {
this.shape = "";
this.dtype = "";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same with dtype. Aren't dtypes finite sets? Or, does it take any arbitrary type (this is a question).

Copy link
Member Author

@tatianacv tatianacv Mar 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -845,7 +846,7 @@ public void testDecoratorArguments() throws Exception {
if (!args.hasFuncParam() && args.hasInputSignatureParam() & !args.hasAutoGraphParam() && !args.hasJitCompileParam()
&& !args.hasReduceRetracingParam() && !args.hasExperimentalImplementsParam() && !args.hasExperimentalAutographOptParam()
&& !args.hasExperimentalFollowTypeHintsParam())
assertEquals("None", args.getInputSignatureArg());
assertEquals(null, args.getInputSignatureArg());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@tatianacv
Copy link
Member Author

Also add a URL for each parameter using an HTML anchor for where it is described in the docs for the specific version (permalink) we are considering.

There is no URL for each tf.function parameter. The most specific permalink would be https://www.tensorflow.org/versions/r2.9/api_docs/python/tf/function#args

Yeah? Like this one? https://www.tensorflow.org/versions/r2.9/api_docs/python/tf/function#input_signature

Thanks! I didn't know I could do that. I didn't see the option of getting the specific link on the site; I thought I couldn't. Thanks so letting me know.

@khatchad
Copy link
Member

Also add a URL for each parameter using an HTML anchor for where it is described in the docs for the specific version (permalink) we are considering.

There is no URL for each tf.function parameter. The most specific permalink would be https://www.tensorflow.org/versions/r2.9/api_docs/python/tf/function#args

Yeah? Like this one? https://www.tensorflow.org/versions/r2.9/api_docs/python/tf/function#input_signature

Thanks! I didn't know I could do that. I didn't see the option of getting the specific link on the site; I thought I couldn't. Thanks so letting me know.

It's in the HTML.

@khatchad
Copy link
Member

Also add a URL for each parameter using an HTML anchor for where it is described in the docs for the specific version (permalink) we are considering.

There is no URL for each tf.function parameter. The most specific permalink would be https://www.tensorflow.org/versions/r2.9/api_docs/python/tf/function#args

Yeah? Like this one? https://www.tensorflow.org/versions/r2.9/api_docs/python/tf/function#input_signature

Thanks! I didn't know I could do that. I didn't see the option of getting the specific link on the site; I thought I couldn't. Thanks so letting me know.

https://khatchad.commons.gc.cuny.edu/research/background/#link-6074

Copy link
Member

@khatchad khatchad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Javadoc comments are outdated. Many of them say return String but the methods don't return String. Because of this reason, it doesn't make sense to to use types in the comments. The comments are used to explain what the code doesn't tell us. We can see from the method signature what the return type is. The javadoc should explain the concept of what is being returned.

@@ -38,10 +39,14 @@
*/
public class Function extends RefactorableProgramEntity {

public enum TfAutographExperimentalFeature {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need a javadoc comment here explaining what this is and a URL for more info.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

@@ -38,10 +39,14 @@
*/
public class Function extends RefactorableProgramEntity {

public enum TfAutographExperimentalFeature {
ALL, AUTO_CONTROL_DEPS, ASSERT_STATEMENTS, BUILTIN_FUNCTIONS, EQUALITY_OPERATORS, LISTS, NAME_SCOPES
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do each of these mean? What is the URL where we can find out more info?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added an URL in the javadoc

@@ -101,7 +107,7 @@ public class HybridizationParameters {
* Value of this {@link Function}'s {@link decoratorsType} parameter input_signature. The value could be None, or a possibly nested
* sequence of tf.TensorSpec objects specifying the shapes and dtypes of the Tensors that will be supplied to this function.
*/
private ArrayList<TensorSpec> inputSignatureParam;
private java.util.List<TensorSpec> inputSignatureParam;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Why not just List?
  2. Why use List? Is ordering important? Can you have duplicates?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. We already have another import for List (org.python.pydev.parser.jython.ast.List). Therefore, I had to specify which List it was by doing java.util.List<TensorSpec>.
  2. Order is important, and we can have duplicates.

int count = 0;
String tempString = "";
private java.util.List<Integer> processTupleOrListForShape(exprType[] exprTupleOrList) {
java.util.List<Integer> shape = new ArrayList<>();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Javadoc says it's returning a String. Is that still true?
  • Why not just List?
  • I don't know how a list of integers represents tensor shape. Why a list? Doesn't a tensor shape just have two integers?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already have another import for List (org.python.pydev.parser.jython.ast.List). Therefore, I had to specify which List it was by doing java.util.List. It is a list of dimensions (https://www.tensorflow.org/versions/r2.9/api_docs/python/tf/TensorShape) which can be integers or None.

@khatchad
Copy link
Member

A lot of problems here. The build is failing, and I'm unsure whether the data types make any sense. There also so many comments now that it is difficult to read the code, and the comments are getting out-of-sync with the code. Comments are needed for things the code doesn't tell us.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Extract tf.function decorator arguments
2 participants