Kotlin api

39 views
Skip to first unread message

Ryan Nett

unread,
Nov 30, 2020, 10:03:46 PM11/30/20
to SIG JVM, karl.l...@gmail.com
Hi everyone, I've been talking with Karl about making a Kotlin api part of the library.  I'm posting this to sketch out the approach I plan to take and get any feedback or requested additions.  In general, my strategy is to depend on the java api and make as few additions as possible, mostly using thin wrappers and extensions. 

Ops methods
Generate an idiomatic Kotlin set of Ops classes.  The main change will be using parameters with default arguments (of null) instead of Options.

Extension methods on Operand<T>
Things like +, sum, eq, matMul.  Generally, I'd seek to replicate numpy's ndarray API.  These are not possible currently as they require Operand and Ops as receivers.  We should get a multiple receivers prototype in 1.5 (March), I'll revisit this then. 

Nullability
Use @NonNull and @Nullable where it makes sense through out the library (especially in codegen).  Doesn't have to be everywhere, but should be encouraged.  Especially important in tensorflow-framework as most of those classes will be used directly from Kotlin (I don't see any pain-points in what's there now).  There's multiple options to get these annotations (see https://kotlinlang.org/docs/reference/java-interop.html#nullability-annotations), I'd go with https://github.com/JetBrains/java-annotations.  Note that this will be a java library dependency.

Utilities
Small extension functions for APIs that are particularly un-kotliny.  Largely dependent on user issues as they use the library in Kotlin and report things that feel un-kotliny.  We would want to mention this in the README.  Would include things like shape/rank/size property extensions for Shaped, invoke operator using call for framework Activations, etc.  There isn't really any overarching design here, just addressing pain points.  Please post anything you would want to be covered by this.

Alexey Zinoviev

unread,
Dec 1, 2020, 12:31:10 AM12/1/20
to Ryan Nett, SIG JVM, Karl Lessard
Hi, Ryan, I'll share my feedback here:

It's good idea to add some minor extension for popular algebraic operations and useful static methods around shapes and so on, and I agree that it should depend on pain and issues from users mostly. 

But I, personally, do not support the Ops generation in kotlin, it seems that In future we should support two codebases (kotlin and java) and two bunch of cc generation classes for code generation.

I faced with the same issue in Apache Spark Community, when to add New ML algorithms you should implement it in Scala, Java, R and Python and its really reduce the number of potential PRs and slow down the speed of development. 

Alex





вт, 1 дек. 2020 г., 6:03 Ryan Nett <jne...@gmail.com>:
--
You received this message because you are subscribed to the Google Groups "SIG JVM" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jvm+uns...@tensorflow.org.
To view this discussion on the web visit https://groups.google.com/a/tensorflow.org/d/msgid/jvm/1c95b193-50a4-4280-a946-f7477fa7d63bn%40tensorflow.org.

Ryan Nett

unread,
Dec 1, 2020, 12:42:07 AM12/1/20
to SIG JVM, zalesl...@gmail.com, SIG JVM, karl.l...@gmail.com, Ryan Nett
Let me clarify that, because I agree: the ops generation I'm setting up atm is an annotation processor that extends the existing @Operation/@Endpoint one, there's no cc generation code.  All of the method finding and processing is done in the abstract class, the only new code is code to generate the kotlin Ops classes from a list of their methods.  Once it's written, the only changes that would happen to it as opposed to the abstract class would be things that only end up in the Kotlin ops class, like withName or withSubScope.

My initial code is here: https://github.com/rnett/java/blob/rn_kotlin_api/tensorflow-core-kotlin/tensorflow-core-kotlin-generator/src/main/kotlin/org/tensorflow/processor/operator/KotlinOpsProcessor.kt.  You can see that the only things that will be Kotlin-specific are those three methods, none of which will be very complicated.

Karl Lessard

unread,
Dec 1, 2020, 8:58:21 AM12/1/20
to Ryan Nett, SIG JVM, zalesl...@gmail.com
Adding more CC generator could be difficult outside `tensorflow-core-api`, compared to adding new annotation processors.

May I drop one more suggestion: could it be interesting to define a DSL to build a graph? Something like:

        graph { // starting extension lambda on `Ops`, which is now implicitly in scope (no need of "tf.")
            val x = placeholder<TFloat32>()
            val y = placeholder<TFloat32>()
            val z = withDevice("/device:GPU:0") { // Starting subscope on a give device
                 val x2 = pow(constant(x), constant(2));
                 math.add(x2, constant(y));               
            }
            ...
        }

Note that with the ongoing effort to revamp the type system in TensorFlow, it will be possible to leverage the magic of reified inline methods in Kotlin to do something like placeholder<TFloat32>()

Jim Clarke

unread,
Dec 1, 2020, 9:35:59 AM12/1/20
to Karl Lessard, Ryan Nett, SIG JVM, zalesl...@gmail.com
I think a DSL would be helpful to define models in the Java world too.

Jim

On Dec 1, 2020, at 8:58 AM, Karl Lessard <karl.l...@gmail.com> wrote:



Frank Greco

unread,
Dec 1, 2020, 1:31:51 PM12/1/20
to Jim Clarke, Karl Lessard, Ryan Nett, SIG JVM, zalesl...@gmail.com
Totally agree Jim. Big +1

FrankG



--

Frank Greco

Karl Lessard

unread,
Dec 1, 2020, 5:01:01 PM12/1/20
to Frank Greco, Jim Clarke, Ryan Nett, SIG JVM, zalesl...@gmail.com
The thing is that Kotlin has this very simple and elegant way to build a DSL and extension lambdas can make it very powerful. So while having a DSL for Java as well could indeed be very interesting, I completely agree, I think that each language should have its own that leverages the maximum of it while sharing similar guidelines.

Ryan Nett

unread,
Dec 1, 2020, 6:03:28 PM12/1/20
to SIG JVM, karl.l...@gmail.com, jimcla...@gmail.com, Ryan Nett, SIG JVM, zalesl...@gmail.com, fgr...@javasig.com
The DSL style usage is definitely something I want.  I plan to do it, as I think you did in your example, by promoting using the kotlin Ops class as a receiver.  This is also necessary for the Operand extension functions.  I'd have a tf field just to allow the api to match Python (so that if you have a local variable tf and a receiver scope you won't have to worry about using the right tf).  We'd want to have functions like graph, eager, defaultEager, etc to promote this, again like your example.

Ryan Nett

unread,
Dec 1, 2020, 6:08:48 PM12/1/20
to SIG JVM, Ryan Nett, karl.l...@gmail.com, jimcla...@gmail.com, SIG JVM, zalesl...@gmail.com, fgr...@javasig.com
This also allows for very nice layer definitions reminiscent of PyTorch or Tensorflow v2.  Something like:
class MyLayer{
    fun KotlinOps.define(x: Operand<TFloat32>){
        return math.add(x, constant(2)) // x + 2 eventually
    }
}

Of course using that method is harder since there's no way to reverse the order of receivers (without compiler plugin shenanigans), but I'm hoping 1.5's multiple receivers will help with that.

Ryan Nett

unread,
Dec 6, 2020, 10:58:36 PM12/6/20
to SIG JVM, Ryan Nett, karl.l...@gmail.com, jimcla...@gmail.com, SIG JVM, zalesl...@gmail.com, fgr...@javasig.com
WIP PR is here: https://github.com/tensorflow/java/pull/165.  Covers most of what was discussed here, except for Java nullability annotations which will be in a separate PR.

Dean Thompson

unread,
Jan 28, 2021, 9:34:49 AM1/28/21
to SIG JVM, jne...@gmail.com, karl.l...@gmail.com, jimcla...@gmail.com, SIG JVM, zalesl...@gmail.com, fgr...@javasig.com
What's our current thinking about this Kotlin API effort versus JetBrains' own Kotlin Tensorflow API effort, JetBrains/KotlinDL? In their README, they say:

> KotlinDL is built on top of TensorFlow 1.15 Java API. The Java API for TensorFlow 2.+ has recently had first public release, and this project will be switching to it in the nearest future.

Alexey Zinoviev

unread,
Jan 28, 2021, 11:08:51 AM1/28/21
to Dean Thompson, SIG JVM, jne...@gmail.com, karl.l...@gmail.com, jimcla...@gmail.com, fgr...@javasig.com
Hi, will answer from KotlinDL side: as we discussed, if this project will include enough useful and good Kotlin API (like in Kotlin WIP from Ryan Nett), it will be used in KotlinDL highly likely when it will update on TF 2.x (as we discussed in December).
Also, we have no plans on the roadmap to prepare our own bindings to C API.

Alex


чт, 28 янв. 2021 г. в 17:34, Dean Thompson <deansher...@gmail.com>:

Dean Thompson

unread,
Jan 28, 2021, 4:13:00 PM1/28/21
to SIG JVM, zalesl...@gmail.com, SIG JVM, jne...@gmail.com, karl.l...@gmail.com, jimcla...@gmail.com, fgr...@javasig.com, Dean Thompson
Thanks for the quick response, Alex -- that seems perfect to me. (And thanks, of course, to Ryan for driving the Kotlin work in this project.)

Dean

Reply all
Reply to author
Forward
0 new messages