Thanks Chris for your excellent explanation! Personally I like the way we
separate the world that Scala and Java shares so Java developers don't have to
think of how to use "Scala" in order to write Java code. I think usability for
Java users and Scala users is the most important tasks we need to take care of.
A poor usability on these APIs will make them say "good bye" to a language
(like the feedback from "Zhihu"). In that case, the Java wrapper design
significantly hide the "unfriendly" Scala API and create a wall that Scala
users won't have to use them. So I would +0.5 for Andrews Approach. I also vote
for plan 2) since the new secret Java Macros do a bunch of changes that makes
them way different than Scala Macros.
But here I quote some point that Naveen mentioned me offline:
1. Compile time problem: The current build pipeline already takes a long time
to compile the code base with adding more and more to make Java ready. Although
we narrow down the scope of development to just Java Inference API. Future
development will still requires a bunch of Java methods being added. It also
makes the code base redundant a little bit. It will also introduce a "fat jar"
for both Scala and Java users.
2. The development and maintenance cost: These code would cost a lot of times
to develop and maintain than implementing them directly in Scala.
Here are the two biggest shortcomings if we go this way. These need to be
carefully considered and avoided in the implementation.
--------------------------------------------------- Break line for Code Gen
demo time ------------------
I am also a developer working on Scala Macros a long time. Here I would like to
show the usability improvement we have taken to Java users.
In v1.3, we delivered the Type-safe API which allows Scala user to do something
like:
Symbol.api.FullyConnected(data = Some(data), num_hidden = 128, name = "fc1")
Rather than the old API:
Symbol.FullyConnected("fc1")()(Map("data" -> data, "num_hidden" -> 128))
The scenario for Java user to use this API is:
1. Option is not introduced in Java and the closest Class is Optional however
introduced in 1.8 (we support MXNet Scala from 1.7)
2. Too many args field to pass. The sacrificed point from Scala to Java is we
lose all default field. For some operators, Java user may need to fill in 13
arguments (e.g BatchNorm) even if they are not willing to do so.
In this case, we have carefully re-invented the Java API with
Function+Classbuilder generated by Scala Macros:
The new Java operator API will looks like:
(Java)NDArray.BatchNorm(<Required
args>).set<OptionalArg>(<OptionalArg>).invoke()
In this case, all generated operators for Java will create a operatorBuilder
(BatchNormBuilder in above examples). The builder's setter will direct Java
users what are the optional field they can pass and the Builder constructor
clearly identify the required field for the operators. The only shortcoming for
this api is that user has to call a method "invoke()" to get it run, where the
invoke method would collect all args and call JNI code.
Thanks,
Qing
On 9/27/18, 8:53 PM, "Chris Olivier" <[email protected]> wrote:
My $0.02 since I’m working with a lot of java and scala lately, including
the interaction between the two:
Please keep in mind the more complex dependency issues that will be
introduced by requiring Java users to now have to pull in a large scala
dependency base. In addition, a lot is Scala is compiler-dependent with
different jars for 2.10,2.12,etc. and so they’re in different places than
the regular jars and having a Java person suddenly have to deal with this
is a good way to make him say “no thanks”. My day job build and runtime
environment systems, for instance, don’t handle the mixing very well
without having to hack a bunch of build files and even then it causes
problems from time to time. Scala experts won’t have problems but it’s a
steep learning curve for Java (or C++) folks.
On Thu, Sep 27, 2018 at 6:14 PM YiZhi Liu <[email protected]> wrote:
> I vote for "2.) Leave the existing macro in place and add another
> which generates a Java friendly version"
>
> @Qing @Andrew, could you give some examples, so that people can better
> understand how it provides "best possible experience" to Java users.
>
> I have no strong preference between having JavaShape & JavaContext or not.
> On Thu, Sep 27, 2018 at 5:56 PM Andrew Ayres <[email protected]>
> wrote:
> >
> > That's not really the conversation I'm wanting to have. I want a
> discussion
> > about the macros with respect to NDArray so that we can get agreement on
> > our path forward with respect to implementing the NDArray wrapper.
> >
> > The design that was put forth and agreed to was for a a Java wrapper
> around
> > the Scala API. Adding a bunch of Java friendly methods inside the Scala
> > code would create a mess for users. Maintenance would be essentially the
> > same for both because either way you're going to be updating Java
methods
> > when you make Scala changes.
> >
> > Let's please stick with the issue in the original email.
> >
> > Thanks,
> > Andrew
> >
> > On Thu, Sep 27, 2018 at 5:22 PM Qing Lan <[email protected]> wrote:
> >
> > > I would like to loop this back a layer. Current, there is a discussion
> in
> > > the MXNet Scala community on the ways to implement the Java APIs.
> Currently
> > > there are two thoughts:
> > >
> > > 1. Make Scala Java Friendly (Create Java compatible methods in the
> Scala
> > > Class. such as NDArray with Java compatible constructor)
> > > 2. Make Java friendly wrappers in Scala (Andrew's explanation below)
> > >
> > > The first approach require minimum input from our side to implement
> > > however bring user a bunch of useless api they may not want to use. It
> also
> > > makes Scala package heavier. The good thing is these two packages
> require
> > > minimum maintenance cost. As a tradeoff, if any time in the future we
> want
> > > to make Java big (make Java as the primary language supported by
> MXNet),
> > > then the migration from Scala to Java will be harmful. Spark consider
> this
> > > carefully and decide not to change much on their Scala code base to
> make it
> > > more Java.
> > >
> > > The second approach will make unique NDArray, Shape, Context and more.
> The
> > > good thing about this is we can always holds a version control on
Java.
> > > Some breaking changes on Scala may not influence much on Java. It did
> the
> > > best way to decouple the module and good for us to build unique
> pipeline
> > > for Java. The bad thing with this design is the maintenance cost as we
> need
> > > to keep two code bases, but it also make Java side easy to change to
> make
> > > it better compatible with users.
> > >
> > > Thanks,
> > > Qing
> > >
> > > On 9/27/18, 3:25 PM, "Andrew Ayres" <[email protected]> wrote:
> > >
> > > Hi,
> > >
> > > Currently, we're working to implement a new Java API and would
like
> > > some
> > > feedback from the community on an implementation detail. In short,
> the
> > > new
> > > Java API will use the existing Scala API (in a manner similar to
> how
> > > the
> > > current Clojure API works). This basically means that we're making
> Java
> > > friendly wrappers to call the existing Scala API.
> > >
> > > The feedback we're looking for is on the implementation of
NDArray.
> > > Scala's
> > > NDArray has a significant amount of code which is generated via
> macros
> > > and
> > > we've got two viable paths to move forward:
> > >
> > > 1.) Change the macro to generate Java friendly methods - To do
> this
> > > we'll
> > > modify the macro so that the generated methods won't have
> > > default/optional
> > > arguments. There may also have to be some changes to parameter
> types to
> > > make them Java friendly. The big advantage here is that ongoing
> > > maintenance
> > > will easier. The disadvantages are that we'll be changing the
> existing
> > > Scala NDArray Infer API (it's marked experimental) and Scala users
> will
> > > lose the ability to use the default and optional arguments.
> > >
> > > 2.) Leave the existing macro in place and add another which
> generates a
> > > Java friendly version - The biggest issue here is that we'll be
> > > doubling
> > > the number of macros that we've got to maintain. It'll become even
> more
> > > overhead once we start expanding the Java API with more classes
> that
> > > use
> > > generated code like this. The advantages are that the existing
> Scala
> > > NDArray Infer API would remain unchanged for Scala users and that
> the
> > > new
> > > macro could be optimized to give the best possible experience to
> the
> > > Java
> > > API.
> > >
> > > Thanks,
> > > Andrew
> > >
> > >
> > >
>
>
>
> --
> Yizhi Liu
> DMLC member
> Amazon Web Services
> Vancouver, Canada
>