Skip to content

Move op generation to Java #244

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

Merged
merged 54 commits into from
Apr 8, 2021
Merged

Conversation

rnett
Copy link
Contributor

@rnett rnett commented Mar 14, 2021

This is the start of moving the op class generators to Java. It works fine on Linux, which is where I'm assuming the old op generator is normally run.

However, there are some output differences on Windows:

  • Lots of parameter descriptions are missing.
  • A few ops are missing, a few new ones are added.
  • Some class names don't line up. For example, we're currently generating BroadcastArgs with the class name BroadcastDynamicShape, and All as ReduceAll. The class name comes from the ApiDef endpoints on both generators, I am unsure why they differ.

I don't think there's really anything we can do about this at the moment, it's just a bit odd to have a java program that you can't run on all platforms.

@rnett
Copy link
Contributor Author

rnett commented Mar 14, 2021

Not sure what's up with the Javadoc generation failing on the CI. I saw it a few times locally, but a clean fixed it.

Update: seeing the same thing when I build on WSL. The artifact builds fine, but it errors with javadoc issues when building the whole project.

@rnett
Copy link
Contributor Author

rnett commented Mar 14, 2021

There's also a bunch of ops that start with _ that seem to not be detected by C++. They aren't in ops.pbtxt, so I'm assuming they are added in code rather than statically, after the point where the C++ generator gets it's defs. There's some interesting ones there like _XlaCompile, but I'm not sure if we should include them.

@rnett
Copy link
Contributor Author

rnett commented Mar 14, 2021

For people working on windows, this can be run (correctly) via WSL. You need to get the api defs from somewhere, but a clone of tensorflow on the proper release branch (i.e. r2.4) will do.

I set up the exec plugin to allow for this, although since it doesn't use the working dir when running java the command gets a bit long. I'm currently using something like mvn exec:java -Dexec.arguments=../tensorflow-core-api/src/gen/java,$clonedTensorflow/tensorflow/core/api_def/base_api,../tensorflow-core-api/src/bazel/api_def -f pom.xml -Pdef -Pjdk11. Intellij can run this on WSL as part of the run configuration with the latest EAP, see this.

@rnett
Copy link
Contributor Author

rnett commented Mar 14, 2021

Alright, I fixed the build issues (locally, at least), they are only present when including tensorflow-core-platform as a compile time dependency, and I can include it as a runtime dependency instead. However, we should make sure this doesn't affect 3rd party libraries depending on tensorflow-core-platform (they should probably use -api, but in some cases they may need the runtime).

@rnett rnett marked this pull request as ready for review March 14, 2021 23:51
@rnett
Copy link
Contributor Author

rnett commented Mar 14, 2021

Since we don't need javadocs for the generator, can we skip them? Or will that cause issues with central? I don't think it would be published with the way it is configured atm, and we certainly don't need it to be.

tensorflow-core-api doesn't fail on javadoc errors, so for now I'm going to do the same.

@saudet
Copy link
Contributor

saudet commented Mar 15, 2021

BTW, TF Core needs MSYS2 to build, it doesn't work with WSL...
https://www.tensorflow.org/install/source_windows

@Craigacp
Copy link
Collaborator

Since we don't need javadocs for the generator, can we skip them? Or will that cause issues with central? I don't think it would be published with the way it is configured atm, and we certainly don't need it to be.

tensorflow-core-api doesn't fail on javadoc errors, so for now I'm going to do the same.

Javadoc isn't just for users, it's for us in 6 months time. I think all new code in this repo should have it whether we expect people to use the class or not (excluding test code).

@rnett
Copy link
Contributor Author

rnett commented Mar 15, 2021

Yeah, that's one of the advantages of doing the op gen in Java, it works fine with dev, we don't need to build TF Core.

@rnett
Copy link
Contributor Author

rnett commented Mar 15, 2021

Since we don't need javadocs for the generator, can we skip them? Or will that cause issues with central? I don't think it would be published with the way it is configured atm, and we certainly don't need it to be.
tensorflow-core-api doesn't fail on javadoc errors, so for now I'm going to do the same.

Javadoc isn't just for users, it's for us in 6 months time. I think all new code in this repo should have it whether we expect people to use the class or not (excluding test code).

Oh yeah, the code will have it. I just mean building the javadoc jars. core-api allows the build to proceed if there's errors, so that's what I'm doing here. As this isn't being published though, we could disable it altogether.

@saudet
Copy link
Contributor

saudet commented Mar 15, 2021

Yeah, that's one of the advantages of doing the op gen in Java, it works fine with dev, we don't need to build TF Core.

Right, but if we need WSL, it's going to cause problems for CI. I imagine this can eventually be adjusted to work with MSYS2 as well. Just wanted to point it out for now.

@rnett
Copy link
Contributor Author

rnett commented Mar 15, 2021

Yeah, that's one of the advantages of doing the op gen in Java, it works fine with dev, we don't need to build TF Core.

Right, but if we need WSL, it's going to cause problems for CI. I imagine this can eventually be adjusted to work with MSYS2 as well. Just wanted to point it out for now.

Well, it turns out it works fine on Windows if I set the api docs dir correctly...

The larger issue here is that it depends on tensorflow-core-platform, so we would need a 2 phase build. I might be able to get it on it's own if that's an issue, the only thing it really needs is TF_NewApiDefMap and TensorFlow.registeredOpList(). But I would think with the new caching that shouldn't be too much overhead.

@Craigacp
Copy link
Collaborator

Since we don't need javadocs for the generator, can we skip them? Or will that cause issues with central? I don't think it would be published with the way it is configured atm, and we certainly don't need it to be.
tensorflow-core-api doesn't fail on javadoc errors, so for now I'm going to do the same.

Javadoc isn't just for users, it's for us in 6 months time. I think all new code in this repo should have it whether we expect people to use the class or not (excluding test code).

Oh yeah, the code will have it. I just mean building the javadoc jars. core-api allows the build to proceed if there's errors, so that's what I'm doing here. As this isn't being published though, we could disable it altogether.

Looks like something is currently published - https://search.maven.org/artifact/org.tensorflow/tensorflow-core-generator/0.2.0/jar, and so if we still want to publish it then it will need javadoc and sources jars.

Does this only happen on Windows? I've not had chance to look through the PR yet, is there an error message somewhere from javadoc I could look at?

@saudet
Copy link
Contributor

saudet commented Mar 15, 2021

Well, it turns out it works fine on Windows if I set the api docs dir correctly...

Oh? Weird.

The larger issue here is that it depends on tensorflow-core-platform, so we would need a 2 phase build. I might be able to get it on it's own if that's an issue, the only thing it really needs is TF_NewApiDefMap and TensorFlow.registeredOpList(). But I would think with the new caching that shouldn't be too much overhead.

That's not an issue, we just need to run the build with a specific platform like mvn -Djavacpp.platform=windows-x86_64 ..., see https://github.com/bytedeco/javacpp-presets/wiki/Reducing-the-Number-of-Dependencies

@rnett
Copy link
Contributor Author

rnett commented Mar 15, 2021

Looks like something is currently published - https://search.maven.org/artifact/org.tensorflow/tensorflow-core-generator/0.2.0/jar, and so if we still want to publish it then it will need javadoc and sources jars.

Does this only happen on Windows? I've not had chance to look through the PR yet, is there an error message somewhere from javadoc I could look at?

Huh, that's the annotation processor but if it's published this will be too.

It doesn't happen locally for me, just in the CI (quick build is on linux). I suspect what is happening is that core-api has failOnError=false for javadocs, it fails but the build succeeds, and then when op-generator tries to build it's javadocs, it errors because it can't find the core javadocs. To see it happen you'll need to remove the failOnError=false from op-generator.

@rnett
Copy link
Contributor Author

rnett commented Mar 15, 2021

Well, it turns out it works fine on Windows if I set the api docs dir correctly...

Oh? Weird.

There's one or two differences, but I think it's just because I'm building off a cloned tensorflow instead of the downloaded source archive.

The larger issue here is that it depends on tensorflow-core-platform, so we would need a 2 phase build. I might be able to get it on it's own if that's an issue, the only thing it really needs is TF_NewApiDefMap and TensorFlow.registeredOpList(). But I would think with the new caching that shouldn't be too much overhead.

That's not an issue, we just need to run the build with a specific platform like mvn -Djavacpp.platform=windows-x86_64 ..., see https://github.com/bytedeco/javacpp-presets/wiki/Reducing-the-Number-of-Dependencies

I assume that's done by the CI. My issue is more that the op generation is done in build.sh, which is used to build core-api, but the new generation depends on core-api. So we'd need to build the core artifacts with the current generation (what was pushed), regenerate the ops, then build again. Probably as part of the CI rather than in build.sh.

@rnett
Copy link
Contributor Author

rnett commented Mar 15, 2021

@Craigacp framework fails as well now, so I'm pretty sure I'm right about the reason. Not sure why that doesn't happen locally, I may have a javadoc disable setting floating around.

This may be because the newly generated op javadocs are slightly different, but I'm pretty sure this happens on master too, it was failing even before I pushed the newly generated ops and is doing so on other PRs as well. I'm not sure why the release builds don't fail.

@Craigacp
Copy link
Collaborator

It looks like a lot of the changes are because the @return javadoc param moved in the generated ops. Is it possible to move it back before we start to review this in earnest? I see there are a bunch of other small javadoc changes, but those appear to actually change the generated output and so we should review them. Given how big the PR is anything that you can do to reduce the code movement noise will make it a lot easier to review.

@rnett
Copy link
Contributor Author

rnett commented Mar 15, 2021

That's due to the way JavaPoet handles parameter javadocs. I should be able to work around it, but it may not be pretty.

@rnett
Copy link
Contributor Author

rnett commented Mar 15, 2021

I have a better solution to the two phase builds. We can still use the native code for op detection, but output the OpDef and ApiDef protos to the Java generator to do the generation. I'd like to it via pipe but I need to look into protobuf a little more. The only thing is that we need to include the proto defs in the generator. Since they are auto-generated anyways I may just be able to add the dir as a source file, otherwise we can either copy them or extract them to another module. Any preferences there?

@saudet
Copy link
Contributor

saudet commented Mar 16, 2021 via email

@karllessard
Copy link
Collaborator

Thanks @rnett , the size of that PR is quite impressive and would take time to review. I remember in the days I've written the C++ version, my Google reviewer asked me to break it down into smaller pieces and I think I understand why ;) Any chance you can do the same?

On a different note, here's just a few thoughts:

  • the tensorflow-core-generator was created having in mind to contain both the annotation processor for the Ops and the converted Java generator for the wrappers in the same JAR, since they are pretty related. Is it possible to do it?
  • what are the real gains of migrating this code to Java, other that facilitate its maintenance?
  • the cyclic dependency between the tensorflow-core-api (which contains the native artifact) and tensorflow-core-generator was an issue, indeed. Some solutions are:
    • move the Bazel build directly in the tensorflow-core parent so every submodule can access the native libraries and files, would require some additional tweaks in the tensorflow-core-api pom.
    • move all Java API def protos to the generator module instead
    • run the generator not on the native library but by consuming the ops proto file, which should be pretty accurate.

@rnett
Copy link
Contributor Author

rnett commented Mar 17, 2021

Thanks @rnett , the size of that PR is quite impressive and would take time to review. I remember in the days I've written the C++ version, my Google reviewer asked me to break it down into smaller pieces and I think I understand why ;) Any chance you can do the same?

Yeah, I can leave the actual generation for another PR, and just set it up so that we could use it in this one. I'll leave it in for now so you can see what the generated code looks like, and pull it out sometime in the next few days. Depending on how you do the review, I've tried (and I think been successful at) keeping the generated code in separate commits, so you can always just drop them locally.

The tensorflow-core-generator was created having in mind to contain both the annotation processor for the Ops and the converted Java generator for the wrappers in the same JAR, since they are pretty related. Is it possible to do it?

It should be. The reason I didn't is because I was using tensorflow-core-api as a dependency, but I'm going to move off of that anyways. Depending on how that goes I think it would be good to include a version that depends and runs based off of the core-api dependency instead of the native build so that people can work on the generator in dev mode, but how exactly I'll do that is still up in the air.

What are the real gains of migrating this code to Java, other that facilitate its maintenance?

It's mostly just maintenance. I know @JimClarke5 mentioned writing a better markdown converter. The original reason I did it is I was running into segfaults when trying to add function generation, but it turns out that's because I was running the wrong thing.

I also want to try some more complicated stuff with functions. What exactly that looks like depends on what we do with the function API, but ideally I'd like to be able to pass lambdas to ops that take functions. There's also capture handling, where ops like If take inputs that they feed to their branch functions, which enables the functions to use captures (once that's supported, anyways). Additionally, the optionally stateful ops can be disambiguated when called, i.e. we have a single If op at the Java level that calls StatelessIf or If depending on if the passed functions are stateful. All of that sort of stuff is stuff I would much rather do in Java.

  • the cyclic dependency between the tensorflow-core-api (which contains the native artifact) and tensorflow-core-generator was an issue, indeed. Some solutions are:

    • move the Bazel build directly in the tensorflow-core parent so every submodule can access the native libraries and files, would require some additional tweaks in the tensorflow-core-api pom.
    • move all Java API def protos to the generator module instead
    • run the generator not on the native library but by consuming the ops proto file, which should be pretty accurate.

I'll update this PR as I do this, but my current approach is doing something like @saudet mentioned, and creating what is essentially our own ops.pbtxt file during the native build (but with API defs included), and then doing the generation based on that. I want to see how big it is before including it in the jar, but even if we don't include it we can get the same info using the native library. You'd just end up with two generator artifacts, one that depends on core-platform and gets it's info from there, and one that accepts the file as input (streamed, if it's big).

I need access to the protos either way, do you have any preference between:

  1. a separate tensorflow-core-proto artifact that both generator and core depend on
  2. duplicating them, copying the protos to both generator and core during native build
  3. putting the protos in generator and having core depend on it. I don't like this since the main methods need to be public.
  4. adding the generated proto dir in core (possibly moving it from gen to proto or similar, if supported) as an external source root for generator in maven

@karllessard
Copy link
Collaborator

karllessard commented Mar 17, 2021

I'll update this PR as I do this, but my current approach is doing something like @saudet mentioned, and creating what is essentially our own ops.pbtxt file during the native build (but with API defs included)

I cannot figure why we would prefer to build our own ops.pbtxt file if it is already available there, in the core sources. Only maintaining our own API defs, like we do now, sounds better.

I need access to the protos either way, do you have any preference between:

Ideally my preference would be 5. :) which is to run the Bazel build at the tensorflow-core level and let it's child modules access the bazel-* folders to do whatever they need. The annoying part is that the child modules will depend on external (parent) directories but it is still manageable.

In other words, I'm dreaming since the first day of a file structure like this:

  • tensorflow-core
    • bazel-bin (created by Bazel)
    • bazel-out (created by Bazel)
    • bazel-tensorflow (created by Bazel)
    • BUILD
    • WORKSPACE
    • build.sh
    • patches
    • api-defs
    • tensorflow-core-api (access parent bazel output directories to generated JavaCPP bindings and creating native jars)
      • src/gen
      • src/main
    • tensorflow-core-generator
      • src/main/org/tensorflow/generator/ops/annotation
      • src/main/org/tensorflow/generator/ops/wrappers

When invoking the tensorflow-core-generator jar to generate the ops wrappers, the Maven task for tensorflow-core-api can pass in parameter the path to the api-defs and the ${project.parent.basedir}/bazel-out/.../ops.pbtxt file. Then, in non-dev mode, JavaCPP can also retrieve the native libraries from ${project.parent.basedir}/bazel-out/... directory the generate the Java C API bindings and packages them up with our native tensorflow-core-api-*-* artifacts.

Note that we can still do all of the above while keeping the actual file structure, that would work too, but I always got that feeling that the native libraries/files resulting from the Bazel build should be accessible to more than one module (tensorflow-core-api in this case).

@saudet
Copy link
Contributor

saudet commented Mar 17, 2021

Note that we can still do all of the above while keeping the actual file structure, that would work too, but I always got that feeling that the native libraries/files resulting from the Bazel build should be accessible to more than one module (tensorflow-core-api in this case).

All files are available to all other modules with the approach I'm talking about above with CPython. What's wrong with packaging those development files in JARs?

@karllessard
Copy link
Collaborator

All files are available to all other modules with the approach I'm talking about above with CPython. What's wrong with packaging those development files in JARs?

I'm not saying it's wrong but I would prefer avoiding having an additional JAR/module like tensorflow-core-protos and the copies of protos if we can. Why not simply have a small JNI file in the tensorflow-core-generator module that invokes TF_GetAllOpsList like it was done in the old days (https://github.com/tensorflow/tensorflow/blob/14dcf6d00e4b0cfdf8c60cc22787f1b0f954bbd8/tensorflow/java/src/main/native/tensorflow_jni.cc#L28)?

The tensorflow-core-generator could be a Maven plugin that we pass a dependency to the tensorflow-core-api-*-* jar so it can call the underlying runtime library?

@rnett
Copy link
Contributor Author

rnett commented Mar 17, 2021

A couple things:

  • Tensorflow ApiDefs are not valid protos, they don't parse (at least in Java). It's the <<<END text block syntax they use. You have to use the native ApiDefMap methods. So we'd need to load them either in C++ or using the native library, neither of which work well with dev mode.
  • The bazel dirs don't get created in dev mode. Their creation is also pretty unreliable in general. You can work around this in scripts (like the configure scripts) but it's not ideal. When I run native builds on linux and then switch to windows, it won't replace the symlinks when I run stuff from windows. Plus fetching the whole tensorflow lib takes a while.
    • This is why I wanted to bundle our ops def file as a resource, so it ran be ran properly in dev mode.
  • There's ops in the runtime that aren't in ops.pbtxt. If we want to continue to ignore them that's fine though.
  • I'm not particularly familiar with JNI, but wouldn't using a separate JNI file in generator still require the native library to run? We'd have to download it desperately in dev mode or something.

If you have a solution for providing the native library in dev mode this changes, but my thinking was if we need to produce an ApiDef map using the native library anyways, we might as well just add the op defs rather than trying to get bazel to fetch ops.pbtxt. And since we want to support dev mode, we need to save that file in the artifact. I don't even think we'd need JavaCPP, we could just put in src/main/resources (in core, and provide an accessor method).

I was thinking we'd probably end up with two generator modules. One for native builds that doesn't depend on core and takes the file as a parameter, and one that does depend on core and gets the file from core's resources (for dev mode). I don't see a way of avoiding two artifacts like that since they need different dependencies, but the dev mode one would be very light.

@JimClarke5
Copy link
Contributor

<<END is called a here document and a similar syntax is also used in Unix Shell.

Also, I have found an open source Java project to parse Markdown similar to the python code I was using. commonmark-java . This should make it easier to covert the Markdown in the apidef to JavaDoc.

@saudet
Copy link
Contributor

saudet commented Mar 18, 2021

I'm not saying it's wrong but I would prefer avoiding having an additional JAR/module like tensorflow-core-protos and the copies of protos if we can. Why not simply have a small JNI file in the tensorflow-core-generator module that invokes TF_GetAllOpsList like it was done in the old days (https://github.com/tensorflow/tensorflow/blob/14dcf6d00e4b0cfdf8c60cc22787f1b0f954bbd8/tensorflow/java/src/main/native/tensorflow_jni.cc#L28)?

The tensorflow-core-generator could be a Maven plugin that we pass a dependency to the tensorflow-core-api-*-* jar so it can call the underlying runtime library?

It doesn't need to be a plugin, but in any case, we can already call TF_GetAllOpList() from Java, yes, that's not a problem:
https://github.com/tensorflow/java/blob/master/tensorflow-core/tensorflow-core-api/src/gen/java/org/tensorflow/internal/c_api/global/tensorflow.java#L2926
Along with all those functions for TF_ApiDefMap.

If you have a solution for providing the native library in dev mode this changes, but my thinking was if we need to produce an ApiDef map using the native library anyways, we might as well just add the op defs rather than trying to get bazel to fetch ops.pbtxt. And since we want to support dev mode, we need to save that file in the artifact. I don't even think we'd need JavaCPP, we could just put in src/main/resources (in core, and provide an accessor method).

We don't need JavaCPP, but it's 1 line to copy all resources at build time, and 1 line to load them in the cache. There are other libraries that do that too, it can be (re)done manually too, sure, but what's the point.

I was thinking we'd probably end up with two generator modules. One for native builds that doesn't depend on core and takes the file as a parameter, and one that does depend on core and gets the file from core's resources (for dev mode). I don't see a way of avoiding two artifacts like that since they need different dependencies, but the dev mode one would be very light.

It doesn't need to be in the same JAR file. We can have a "dev" JAR where we just dump everything that wouldn't be needed by end users, just like Linux distributions do it. That way, the JAR file can also be downloaded with Maven automatically by developers that don't need to rebuild TF Core without having to deal with Bazel at all. With Maven profiles, the same artifact can have different dependencies, that's not a problem either.

@karllessard
Copy link
Collaborator

karllessard commented Mar 18, 2021

@rnett ok here's another idea then, why not bundling the ops.pbtxt file (generated or static, let's ignore this for now) under the classpath of the tensorflow-core-api-*-* JARs, and then add this artifact as a dependency to tensorflow-core-generator so it can retrieve the resources from it? The sequence would be:

Full build:

  1. Build native library and run other Bazel goals
  2. Package native library, JavaCPP JNI code and ops.pbtxt in a tensorflow-core-api-*-* artifact
  3. Run tensorflow-core-generator as an executable JAR (or Maven plugin?) with a dependency to tensorflow-core-api-*-* to generate the ops wrappers
  4. Build and package the tensorflow-core-api JAR

Dev build:

  1. Fetch the tensorflow-core-java-*-* JAR for the current platform from Sonatype
  2. Run tensorflow-core-generator as an executable JAR (or Maven plugin?) with a dependency to tensorflow-core-api-*-* to generate the ops wrappers
  3. Build and package the tensorflow-core-api JAR

This should be quite simple to achieve and is very close that we are already doing, without the need of reshuffling the modules at all.

It would have been interesting too to be able to call the JNI code that is already part of the tensorflow-core-api-*-* artifacts but I don't how we can do this without having its generated Java classes as well.

JimClarke5 and others added 10 commits April 6, 2021 19:22
…lt text.

Add missing description and @return  for Getters/Setters
Add fixes for missing @param's and Generic Types

Reformat code.

Signed-off-by: Ryan Nett <[email protected]>
Fix handling of oddities from Python, like illegal
html tag <bytes>
Signed-off-by: Ryan Nett <[email protected]>
Fix oddities from TF Python like @compatibility,
@end_compatibility, @tf.xxxxx

Signed-off-by: Ryan Nett <[email protected]>
Signed-off-by: Ryan Nett <[email protected]>
@rnett
Copy link
Contributor Author

rnett commented Apr 7, 2021

I made a separate PR with all the generated op changes: rnett#3

@rnett
Copy link
Contributor Author

rnett commented Apr 7, 2021

The memory leak test is failing @karllessard @saudet, it's failing on master too.

karllessard
karllessard previously approved these changes Apr 7, 2021
Copy link
Collaborator

@karllessard karllessard left a comment

Choose a reason for hiding this comment

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

Good job @rnett and @JimClarke5 ! We can merge that one now (unless @rnett you want to add that comment before) but before enabling this Java generator, I would like to configure the lint checks (as I was suppose to do in the last two years...) to double-check that the code generated with it is still compliant (like the actual one generated by the C++ generator is).

@saudet
Copy link
Contributor

saudet commented Apr 7, 2021

The memory leak test is failing @karllessard @saudet, it's failing on master too.

Which platform?

@karllessard
Copy link
Collaborator

The memory leak test is failing @karllessard @saudet, it's failing on master too.

Which platform?

That's on the latest ubuntu container in GitHub Actions, check config for the quick-build

@saudet
Copy link
Contributor

saudet commented Apr 8, 2021

The memory leak test is failing @karllessard @saudet, it's failing on master too.

Which platform?

That's on the latest ubuntu container in GitHub Actions, check config for the quick-build

Seems a bit flaky on all platforms actually yes. I'll try to make it more reliable...

@rnett
Copy link
Contributor Author

rnett commented Apr 8, 2021

@karllessard yeah I'll add the comment.

There's a slight issue wrt running the generator during the core-api build: it will never build the generator, it will always get the latest version in it's repository (downloaded or maven local). This isn't an issue if you do an install in one of the parent projects (which is what I think the CI does), but could trip people up. I think the annotation processor works the same way, so imo it's fine to just document this in the contributors doc since I don't know of a way around it.

@rnett
Copy link
Contributor Author

rnett commented Apr 8, 2021

Also, what do you think about only automatically running the generator when dev isn't enabled? Since the op def file is only generated during native builds. The generator itself could be changed, but I would think anyone doing that would run it manually anyways.

Signed-off-by: Ryan Nett <[email protected]>
@karllessard karllessard merged commit 0d73a9b into tensorflow:master Apr 8, 2021
@karllessard
Copy link
Collaborator

@karllessard yeah I'll add the comment.

There's a slight issue wrt running the generator during the core-api build: it will never build the generator, it will always get the latest version in it's repository (downloaded or maven local). This isn't an issue if you do an install in one of the parent projects (which is what I think the CI does), but could trip people up. I think the annotation processor works the same way, so imo it's fine to just document this in the contributors doc since I don't know of a way around it.

Oops, sorry, I’ve noticed your comments just after merging! But that’s fine, it’s the normal way Maven works with interdependencies inside the same project: modules added as dependencies to others needs to be build/installed first and that’s what we do.

Also, what do you think about only automatically running the generator when dev isn't enabled? Since the op def file is only generated during native builds. The generator itself could be changed, but I would think anyone doing that would run it manually anyways.

I will also leave it like that, it might be counterintuitive that you need to run it manually when you’re in dev mode. Is there any value for not running it?

@rnett
Copy link
Contributor Author

rnett commented Apr 8, 2021

Only speed, really, and not having to worry about any nondeterminism or extra changes (like with the annotation processor). It's pretty fast, but I'm not sure if it will stay that way if we have to format it. Probably not worth pulling it out though.

@karllessard
Copy link
Collaborator

Only speed, really, and not having to worry about any nondeterminism or extra changes (like with the annotation processor). It's pretty fast, but I'm not sure if it will stay that way if we have to format it. Probably not worth pulling it out though.

yeah so let’s be reactive and only readjust if needed 👍

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.

5 participants