And if we find incorrect declaration, we fix it, not simply assuming many of them also has problem and we cannot rely on them - otherwise the type-safe APIs in Scala also does not make sense. On Sat, Sep 29, 2018 at 7:10 PM YiZhi Liu <eazhi....@gmail.com> wrote: > > It also makes sense to me if we have it under namespace NDArray, not > creating new JavaNDArray. But again, uniform experience is important. > > What I responded is your comment "keep scala macros minimum", I don't > think "scala macro" equals "cryptic code". Even though it does, what > we need to do is to find an alternative way to do code generation, not > making code generation minimum. > > Since you agree to have 30+ operators have Builder, what prevents from > having all of them have Builder? > - They're auto-generated, the auto-generation "cryptic" code is anyway > there. And "two different paths of code" (though I don't totally > agree) is anyway there. > - What else? 200+ classes is a very tiny increasing in file size > (~3MB) compare to current status. And won't have any performance issue > on modern JVM. > > Just remind, technical discussion is not about who gives who a lecture. > On Sat, Sep 29, 2018 at 6:41 PM Naveen Swamy <mnnav...@gmail.com> wrote: > > > > Well, I am not sure(I don't think) we need Builder for every API in > > NDArray. For APIs that take long list of parameters, I agree to add Builder. > > Look at the API distribution based on number of arguments here: > > https://gist.github.com/nswamy/2dea72e514cc7bfc675f68aef9fe78bb > > about 30 APIs have 7 or more arguments.. I agree to add Builders for these > > APIs not separately but to the existing Scala APIs but not separately only > > for Java. > > APIs sorted by number of arguments is here, take a look : > > https://gist.github.com/nswamy/e941cb94658b3960eec40bf00b970ac5 > > > > Many of the arguments i think are actually mandatory but incorrectly > > declared optional on the backend, for example look at SwapAxis > > "def SwapAxis (data : NDArray, dim1 : Option[Int] = None, dim2 : > > Option[Int] = None, out : Option[NDArray] = None) : NDArrayFuncReturn" > > Why is dim1 and dim2 Optional, this is an error in the declaration on the > > backend, I think there might be many of these? > > > > My answers to your other responses are below inline: > > > > On Sat, Sep 29, 2018 at 3:37 PM YiZhi Liu <eazhi....@gmail.com> wrote: > > > > > Some of my comments inline: > > > > > > > Why can we not create the builder just for these APIs( which we > > > discussed), why is it necessary to add 200 Apis > > > It is about unified user-experience. And we get rid of annoying extra > > > "out=null" in every operator. > > > > > > > Are you suggesting to create builder for each and every API? > > > Only for those are necessary. For NDArray.XXX, yes. > > > > > I think this is a ridiculous list of Builders, I think we can keep the > > 'out' parameter > > > > > 1) The NDArray APIs in question are not following functional style of > > > programming, in fact they are just static methods defined on an > > > NDArray object - so Scala users are not losing much by using null in > > > place of None. > > > You can create a implicit to maintain backward compatibility > > > - I doubt implicit can work in such case from None -> null. > > > > > > > It is just writing getOrElse in your implicit, so it will work. > > scala> implicit def optionStringToString(a: Option[String]): String = { > > | a.getOrElse(null) > > | } > > > > 2) It is adding 220+ APIs(I understand it is generated) for NDArray alone > > > - As I explained how it can improve user experiences > > > > > I don't think we need to write builders for 221 APIs we have, may be for 30 > > or so. Uniform experience is good goal but it also has to be practical and > > make sense. > > > > 3) this is adding another 100s of APIs unnecessarily, we are starting with > > > NDArray but we can't stop there, we will have to do this for Symbol, > > > Executor, Iterators, etc., . > > > - This is a good point, actually I prefer not to make JavaExecutor, > > > JavaIterators > > > > > What I was aiming is also users have the same experience across Interfaces > > - now you are forgoing uniform experience, so like you said its all > > trade-off and a good trade-off doesn't cause too much overhead/ > > > > > > > 4) I don't want to be fixing bugs and maintaining code in 2 places. > > > - Type-safe parsing is shared. I think Qing is more qualified to comment. > > > > It creates two different paths of code for Scala and Java - how is it going > > to be shared. I am afraid we are going to make it more complicated than > > necessary by duplicating code. > > > > > > > > > 5) I want the cryptic code(# scala macros) to a minimum. > > > - MXNet decides to do operator generation in frontend bindings. It's > > > the developers' responsibility to understand the techniques they are > > > using. Maybe not a so proper analogy - "I don't know RL / RL is hard > > > to tune / ..." is not a reason for "I want to keep RL implementation > > > in MXNet as a small part as possible" > > > > > > Now, this is a response I don't like. I don't know where you were going > > with your analogy but know that it sounds condescending - I am going to > > ignore(assuming good intentions) that and explain what I mean. > > I here is I the developer/user who deploys MXNet code in production and > > have to deal with the aftermath myself not you(MXNet developers). > > From your comment it occurs to me you probably have never been on > > pager-duty. I have been on pager-duty both for the code I wrote and those > > that was written by others and thrown over the fence. > > If you get woken up by a beep at the middle of the night, that is not the > > time to prove your intelligence. Its time to mitigate the issue asap for > > that your code needs to be easy to follow, should follow well defined > > patterns, etc., -- i don't need to give you a lecture. > > IMHO It is extremely important for frameworks like Apache MXNet which are > > used by others for their production to keep code simple and *cryptic code > > to a minimum* and yes you(we - MXNet developers) are not answering the > > beepers when your(MXNet) users deploy their code in their production so > > make their life simple. > > > > 6) increased compilation time & bad developer experience - the time to > > > compile has gone up quite a bit since we added the APIs last release on my > > > 3 year old laptop already.. I think adding 400+ APIs unnecessarily would > > > significantly increase build time and bad developer experience > > > - I don't think increasing such a bit compilation time is a problem > > > compared to bad user experience. > > > > I am not suggesting bad user experience but to take a practical approach - > > having a bad developer experience is not great either. > > > > > > > > > > 7) I want to keep the core of the framework to be in Scala - because it > > > allows you to write concise code - Yes it has a bit of learning curve, not > > > everyone needs to know. I would rather invest in solidifying the Scala > > > APIs > > > and add more features in Scala(RNN, Support GluonHybridizedBlock...there > > > is > > > quite bit of work ) - do you want to rewrite everything in Scala and Java. > > > - I agree with "don't rewrite everything in Scala and Java", IMO > > > JavaNDArray is the only one good to have. JShape, JContext, etc. are > > > not so necessary. > > > > > > Either you go all Java or make accommodation in Scala code to work for > > APIs so your users know what to expect(uniform experience across). > > > > > 8) Also, the discussion is not creating NDArray class for Java, just > > > generate certain APIs to cater for Java incompatibility. > > > - Yes I agree it's about "generate certain APIs to cater for Java > > > incompatibility", though I think NDArray.api.XXX does not meet Java > > > users' demands. > > > > > On Sat, Sep 29, 2018 at 12:05 PM Naveen Swamy <mnnav...@gmail.com> wrote: > > > > > > > > I know it is about trade-off. I am suggesting a trade-off , how many > > > apis do we have that takes too many parameters ? > > > > From what I recall its around 20. Why can we not create the builder just > > > for these APIs( which we discussed), why is it necessary to add 200 Apis ? > > > > Are you suggesting to create builder for each and every API? > > > > > > > > I disagree with your opinion that they are not important and would like > > > to hear from others. > > > > > > > > I am curious to see how the #2 looks like compared to #1 > > > > Andrew/Qing, can you paste the generated Apis that you have for both > > > Scala and Java in a gist please. > > > > > > > > > On Sep 29, 2018, at 2:41 PM, YiZhi Liu <eazhi....@gmail.com> wrote: > > > > > > > > > > Naveen, software designing is all about tradeoff, every feature we > > > > > introduce causes more compiling time, more efforts to maintain, etc. > > > > > > > > > > The main difference is. > > > > > > > > > > Option #1: Java users do > > > > > NDArray.BatchNorm(data, gamma, beta, null, null, null, null, null, > > > > > null, null, null, null, null, null); > > > > > (and because every operator has an argument "out", users need to add > > > > > an extra "null" to the function call almost every time.) > > > > > > > > > > Option #2, Java users do > > > > > JavaNDArray.BatchNorm(data).setGamma(gamma).setBeta(beta).invoke(); > > > > > > > > > > I don't think any of the reasons you listed is so important as the > > > > > benefit above we got from option #2. > > > > >> On Sat, Sep 29, 2018 at 8:24 AM Naveen Swamy <mnnav...@gmail.com> > > > wrote: > > > > >> > > > > >> Java APIs are not like Clojure - The current proposal is only to > > > build a > > > > >> few thin wrappers for Inference. > > > > >> > > > > >> To better represent the two cases and this discussion in particular, > > > here > > > > >> is an example API > > > > >> > > > > >> 1) def Activation (data : org.apache.mxnet.NDArray, act_type : > > > String, out > > > > >> : Option[NDArray] = None) : org.apache.mxnet.NDArrayFuncReturn > > > > >> or > > > > >> 2) def Activation (data : org.apache.mxnet.NDArray, act_type : > > > String, out > > > > >> : NDArray) : org.apache.mxnet.NDArrayFuncReturn > > > > >> > > > > >> The discussion is should we add(generate) 200+ APIs to make it Java > > > > >> compatible, ie., remove the Option class and the None default value > > > which > > > > >> Java does not understand from Option 1) > > > > >> > > > > >> my suggestion was to remove the Option class and create a implicit > > > > >> for > > > > >> backward compatibility and use null instead of None, Andrew and I > > > disagreed > > > > >> on this, so I suggested to raise a discussion on dev@ to get more > > > opinions > > > > >> and one of us will disagree and commit. Thanks for raising it :) > > > > >> > > > > >> | * def Activation (data : org.apache.mxnet.NDArray, act_type : > > > String, out > > > > >> : NDArray = null) : org.apache.mxnet.NDArrayFuncReturn | > > > > >> -- > > > > >> > > > > >> 1) It is not true that Scala users will lose *default/optional* > > > arguments - > > > > >> if we followed the above, they will use null or None, though I do not > > > like > > > > >> using nulls, this is a fine compromise. > > > > >> To keep backward compatibility we can create a implicit to convert > > > > >> Option.None to nulls and Option.Some-> Option.get(), so you are not > > > going > > > > >> to break users who might have been using the APIs that were released > > > in > > > > >> 1.3. The current incompatibility is only this w.r.t. NDArrays. > > > > >> > > > > >> 2) Now about the Scala Macros - they are not simple to read or use, > > > When I > > > > >> and Qing started working on the #Scala Macros to improve the APIs, it > > > took > > > > >> us a good amount of time to get a hang of it. I don't want to add > > > > >> additional code when not necessary. > > > > >> > > > > >> My suggestion and vote is to modify existing Macro(i.e., #1 from the > > > > >> original email with the necessary clarification above) and make it > > > > >> compatible with Java > > > > >> Here are my reasons > > > > >> 1) The NDArray APIs in question are not following functional style of > > > > >> programming, in fact they are just static methods defined on an > > > NDArray > > > > >> object - so Scala users are not losing much by using null in place of > > > None. > > > > >> You can create a implicit to maintain backward compatibility > > > > >> 2) It is adding 220+ APIs(I understand it is generated) for NDArray > > > alone > > > > >> 3) this is adding another 100s of APIs unnecessarily, we are starting > > > with > > > > >> NDArray but we can't stop there, we will have to do this for Symbol, > > > > >> Executor, Iterators, etc., . > > > > >> 3) I don't want to be fixing bugs and maintaining code in 2 places. > > > > >> 4) I want the cryptic code(# scala macros) to a minimum. > > > > >> 5) increased compilation time & bad developer experience - the time > > > > >> to > > > > >> compile has gone up quite a bit since we added the APIs last release > > > on my > > > > >> 3 year old laptop already.. I think adding 400+ APIs unnecessarily > > > would > > > > >> significantly increase build time and bad developer experience > > > > >> 6) I want to keep the core of the framework to be in Scala - because > > > it > > > > >> allows you to write concise code - Yes it has a bit of learning > > > curve, not > > > > >> everyone needs to know. I would rather invest in solidifying the > > > Scala APIs > > > > >> and add more features in Scala(RNN, Support > > > GluonHybridizedBlock...there is > > > > >> quite bit of work ) - do you want to rewrite everything in Scala and > > > Java. > > > > >> 7) Also, the discussion is not creating NDArray class for Java, just > > > > >> generate certain APIs to cater for Java incompatibility. > > > > >> > > > > >> @Andrew: To your response to Qing's comments - you cannot just > > > consider it > > > > >> as just generating NDArray's APIs and instead I suggest to take a > > > wholistic > > > > >> view of all the various implications. > > > > >> > > > > >> @Chris: Yes, Scala has a bit of learning curve - the goal is not > > > having > > > > >> every developer to deal with how these APIs are generated, > > > > >> the problem exists either ways with the above proposal. I might agree > > > if we > > > > >> were to move away completely(with a thorough discussion and valid > > > reasons) > > > > >> and instead use AspectJ or similar to write these APIs, the > > > discussion is > > > > >> about using Scala Macros to generate 2 different types of APIs which > > > are > > > > >> functionally not different and usability wise are very very similar, > > > look > > > > >> at the example. > > > > >> Thanks for your input, I will deposit your 0.02$ in our JIRA bank :) > > > > >> > > > > >> @Carin: It requires more effort to use AspectJ or similar to generate > > > APIs > > > > >> using reflection or at compile time, here we need to generate at > > > compile > > > > >> time so Java users have the API signature on their IDEs. > > > > >> > > > > >> Thanks, Naveen > > > > >> > > > > >> P.S: I am traveling and my responses will be delayed. > > > > >> > > > > >> > > > > >>> On Fri, Sep 28, 2018 at 10:25 AM Carin Meier <carinme...@gmail.com> > > > wrote: > > > > >>> > > > > >>> Sorry bad paste on the gist - here is the good one > > > > >>> https://gist.github.com/gigasquid/01cd48f563db4739910592dd9ac9db20 > > > > >>> > > > > >>>> On Fri, Sep 28, 2018 at 10:24 AM Carin Meier <carinme...@gmail.com> > > > wrote: > > > > >>>> > > > > >>>> +1 on option #2 > > > > >>>> > > > > >>>> In the case of minimizing the the overhead for code maintenance, I > > > wanted > > > > >>>> to suggest the option of investigating generating code from the > > > > >>>> Java > > > > >>>> Reflection for the Java APIs. I did a quick gist from Clojure of > > > what > > > > >>> the > > > > >>>> generated classes look like from the current Scala Symbol.api for > > > > >>>> FullyConnected here > > > > >>>> https://gist.github.com/gigasquid/01cd48f563db4739910592 > > > > >>>> > > > > >>>> I looks like that there is always a base Java class generated will > > > all > > > > >>> the > > > > >>>> arguments. If this is the case, then there is a possibility to > > > generate a > > > > >>>> Java api based on this Java method automatically with just a > > > conversion > > > > >>> for > > > > >>>> the Scala option and it might be reusable for all the packages. > > > > >>>> > > > > >>>> Not sure if it will work for this use case, but thought I would > > > bring it > > > > >>>> up in case it's helpful. > > > > >>>> > > > > >>>> - Carin > > > > >>>> > > > > >>>> On Fri, Sep 28, 2018 at 7:05 AM Davydenko, Denis > > > <d...@amazon.com.invalid > > > > >>>> > > > > >>>> wrote: > > > > >>>> > > > > >>>>> +1 on option #2. Having clear Java interface for NDArray, from my > > > > >>>>> perspective, would be a better experience for Java users as it > > > won't > > > > >>>>> require them to deal with Scala code in any capacity. Overhead of > > > extra > > > > >>>>> code for additional macros is justified, in my mind, as it will be > > > > >>>>> introduced with option #1 either way, just in a different place. > > > > >>>>> > > > > >>>>> -- > > > > >>>>> Thanks, > > > > >>>>> Denis > > > > >>>>> > > > > >>>>> On 9/27/18, 6:14 PM, "YiZhi Liu" <eazhi....@gmail.com> 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 < > > > > >>>>> andrew.f.ay...@gmail.com> 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 <lanking...@live.com> > > > > >>>>>> 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" <andrew.f.ay...@gmail.com> > > > > >>>>> 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 > > > > > > > > > > > > > > > > > > > > -- > > > > > Yizhi Liu > > > > > DMLC member > > > > > Amazon Web Services > > > > > Vancouver, Canada > > > > > > > > > > > > -- > > > Yizhi Liu > > > DMLC member > > > Amazon Web Services > > > Vancouver, Canada > > > > > > > > > > -- > Yizhi Liu > DMLC member > Amazon Web Services > Vancouver, Canada
-- Yizhi Liu DMLC member Amazon Web Services Vancouver, Canada