Skip to content
This repository has been archived by the owner on Nov 17, 2023. It is now read-only.

[MXNET-918] Random module #13039

Merged
merged 11 commits into from
Dec 14, 2018
Merged

[MXNET-918] Random module #13039

merged 11 commits into from
Dec 14, 2018

Conversation

mdespriee
Copy link
Contributor

@mdespriee mdespriee commented Oct 30, 2018

Description

This PR introduces Symbol.random and NDArray.random modules in scala API.
This work is a further refactoring of code generation + introduction of Random module.

Functions in random module are generic and accept the following "union types": SymbolOrValue, and NDArrayOrValue. See https://github.com/apache/incubator-mxnet/blob/704ab6030c9803ac70d2726618885cef323a4420/scala-package/core/src/main/scala/org/apache/mxnet/Base.scala#L158-L171

This allow this kind of calls:

    // no need to import anything special, or any implicit
    val lam = Symbol.Variable("lam")
    val rnd = Symbol.random.poisson(lam = Some(lam), shape = Some(Shape(2, 2)))
    val rnd2 = Symbol.random.poisson(lam = Some(1f), shape = Some(Shape(2, 2)))

For multi argument functions, mixing types of params is not allowed (fails at compile time).

The code to generate Random module is more hacky than the rest, due to some discrepancies (eg. sample_normal vs random_normal). I tried to isolate that as much as possible in dedicated objects and mixin.

Following @zachgk comment in the previous PR, I also tried to organise code generation in a way that the essential of function implementations is as much as possible readable and linear.

Last thing to discuss is: should we turn off function generation of random stuff in Symbol and NDArray
(eg Symbol.sample_exponential)

Checklist

Essentials

Please feel free to remove inapplicable items for your PR.

  • The PR title starts with [MXNET-$JIRA_ID], where $JIRA_ID refers to the relevant JIRA issue created (except PRs with tiny changes)
  • Changes are complete (i.e. I finished coding on this PR)
  • All changes have test coverage:
  • Unit tests are added for small changes to verify correctness (e.g. adding a new operator)
  • Nightly tests are added for complicated/long-running ones (e.g. changing distributed kvstore)
  • Build tests will be added for build configuration changes (e.g. adding a new build option with NCCL)
  • Code is well-documented:
  • For user-facing API changes, API doc string has been updated.
  • For new C++ functions in header files, their functionalities and arguments are documented.
  • For new examples, README.md is added to explain the what the example does, the source of the dataset, expected performance on test set and reference to the original paper if applicable
  • Check the API doc at http:https://mxnet-ci-doc.s3-accelerate.dualstack.amazonaws.com/PR-$PR_ID/$BUILD_ID/index.html
  • To the my best knowledge, examples are either not affected by this change, or have been fixed to be compatible with this change

Changes

  • Symbol.random api generated by macros
  • NDArray.random api generated by macros

Comments

@mdespriee
Copy link
Contributor Author

ping @lanking520

@mdespriee mdespriee mentioned this pull request Oct 30, 2018
5 tasks
@ankkhedia
Copy link
Contributor

ankkhedia commented Oct 30, 2018

@mxnet-label-bot [ pr-awaiting-review, Scala ]
@mdespriee Thanks for your contribution!
Could you please look into CI failures for the PR

@marcoabreu marcoabreu added pr-awaiting-review PR is waiting for code review Scala labels Oct 30, 2018
@ankkhedia
Copy link
Contributor

@mdespriee Thanks for the attempt to fix CI errors but it seems it is still failing. Request you to take a look.

@mdespriee
Copy link
Contributor Author

@lanking520
Copy link
Member

Hi @mdespriee, thanks for your rebase on the code and glad to see you bring a better solution to the existing problems. Here are two recommendation I can think of:

  1. Is that necessary to bring this new API to Symbol? If users would like to use the Symbolic graph, they can call the existing random and Sample function to work and the data passing between should be strict as Symbols. So my ways of thinking is that these dynamic types should not be in the "everything is fixed" world.

  2. Do you think if that possible to extend the Existing Random package instead of creating new stuff in the Symbol API?

@mdespriee
Copy link
Contributor Author

@lanking520 Ok, there has been some confusion. I'll try.
(from our past conversations, didn't we talk about Symbol ?? #12489 (comment)...)

@lanking520
Copy link
Member

lanking520 commented Nov 6, 2018

@lanking520 Ok, there has been some confusion. I'll try.
(from our past conversations, didn't we talk about Symbol ?? #12489 (comment)...)

Sorry, it was my bad. Let's keep Symbol there.

Ask some expert in here to see their opinions about make Random Symbol:
@nswamy @yzhliu What do you guys think?

Copy link
Member

@lanking520 lanking520 left a comment

Choose a reason for hiding this comment

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

Some general thinking: do you think it would be better to move the functions that specifically used for random to somewhere else? Consider there would be more extensions in the future...

@@ -39,6 +39,7 @@ object NDArray extends NDArrayBase {
private val functions: Map[String, NDArrayFunction] = initNDArrayModule()

val api = NDArrayAPI
val random = NDArrayRandomAPI
Copy link
Member

Choose a reason for hiding this comment

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

Can we consider moving this part to random.scala?

@@ -841,6 +841,7 @@ object Symbol extends SymbolBase {
private val bindReqMap = Map("null" -> 0, "write" -> 1, "add" -> 3)

val api = SymbolAPI
val random = SymbolRandomAPI
Copy link
Member

Choose a reason for hiding this comment

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

Maybe also this part go to random.scala too...

@stu1130
Copy link
Contributor

stu1130 commented Nov 20, 2018

@mxnet-label-bot update [pr-awaiting-response, scala]
@mdespriee could you please address the comments from @lanking520? feel free to ask the question if you need any help!

@marcoabreu marcoabreu added pr-awaiting-response PR is reviewed and waiting for contributor to respond Scala and removed Scala pr-awaiting-review PR is waiting for code review labels Nov 20, 2018
@mdespriee
Copy link
Contributor Author

@lanking520 you mean putting both within Random object ? How to disambiguate NDArray vs Symbol ?

absFuncs)
}

def generateAPIDocFromBackend(func: Func, withParam: Boolean = true): String = {
val desc = func.desc.split("\n")
.mkString(" * <pre>\n", "\n * ", " * </pre>\n")
.mkString(" * <pre>", "\n * ", "\n * </pre>")
Copy link
Contributor

Choose a reason for hiding this comment

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

The problems with generateAPIDocFromBackend were addressed elsewhere

Copy link
Contributor

@zachgk zachgk left a comment

Choose a reason for hiding this comment

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

One thing was fixed elsewhere. Otherwise LGTM

# Conflicts:
#	scala-package/macros/src/main/scala/org/apache/mxnet/APIDocGenerator.scala
#	scala-package/macros/src/main/scala/org/apache/mxnet/GeneratorBase.scala
@lanking520
Copy link
Member

@mdespriee could you please trigger the test again?

@mdespriee
Copy link
Contributor Author

I'm a bit confused with these failing tests, as I can't reproduce the failure locally. I also don't get why it is environment dependant. I'll have a look asap.

@lanking520
Copy link
Member

That's strange. It looks like the code-gen doesn't work somehow on Linux

@mdespriee
Copy link
Contributor Author

That's strange. It looks like the code-gen doesn't work somehow on Linux

Actually the code gen fails this way when the getBackEndFunctions returns a function with no arg being either Symbol or Float (which are changed to generic T). I can write something more robust. But is it possible that the backend returns a different function list depending on the environment ?
(which would be a bug in a sense...)

@mdespriee
Copy link
Contributor Author

@lanking520 It seems that the following function (randint) is not returned by LIB.nnGetOpHandle in all environments. Or not in the same way and get filtered out.

Func: randint, args=[Arg(low,Any,Lower bound of the distribution.,false),Arg(high,Any,Upper bound of the distribution.,false),Arg(shape,org.apache.mxnet.Shape,Shape of the output.,true),Arg(ctx,String,Context of output, in format [cpu|gpu|cpu_pinned](n). Only used for imperative calls.,true),Arg(dtype,String,DType of the output in case this can't be inferred. Defaults to int32 if not defined (dtype=None).,true)]

Locally, I don't get this func to be generated by macros. On CI, it is generated on 3 envs, but not on centos-gpu.

Any clue on what's going on ?

@lanking520
Copy link
Member

lanking520 commented Dec 11, 2018

@mdespriee Thanks for debugging through, you seemed to hit a rock: https://github.com/apache/incubator-mxnet/blob/master/scala-package/macros/src/main/scala/org/apache/mxnet/utils/CToScalaUtils.scala#L38.
Some of the params cannot be intepreted

@lanking520
Copy link
Member

lanking520 commented Dec 11, 2018

@apeforest @samskalicky Could you please help to locate this op by any chances in C++? randint

@samskalicky
Copy link
Contributor

@ChaiBapchya wrote the randint operator

@lanking520
Copy link
Member

@ChaiBapchya what is the data type of low and high? It seemed not intepreted correctly in Scala?
@mdespriee please try to pull --rebase upstream master and then make clean and build the backend all over again to see if you can reproduce this issue

@ChaiBapchya
Copy link
Contributor

ChaiBapchya commented Dec 11, 2018

It supports int32 and int64 (default to int32)

@mdespriee
Copy link
Contributor Author

@lanking520 I reviewed my SymbolOrScalar and NDarrayOrScalar, it's now a cleaner implem of typeclass pattern, it's more robust and not failing on edge cases.
We still have an issue with randint expecting Any instead of proper types, but it may be addressed in a separate PR. What do you think ?

@lanking520
Copy link
Member

@mdespriee For sure!

Copy link
Member

@lanking520 lanking520 left a comment

Choose a reason for hiding this comment

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

Tested locally and looks good!

@lanking520
Copy link
Member

@mdespriee one last quest, could you please add the generated file into .gitignore?

@lanking520
Copy link
Member

NVM now, I will do it in my next PR. @ChaiBapchya Please find the information above and see how you can fix randint.

@lanking520 lanking520 merged commit fc5fce7 into apache:master Dec 14, 2018
mseth10 pushed a commit to mseth10/incubator-mxnet that referenced this pull request Dec 18, 2018
* introduce random API

* revert useless changes

* shorter types in APIDoc gen code

* fix after merge from master

* Trigger CI

* temp code / diag on CI

* cleanup type-class code

* cleanup type-class code

* fix scalastyle
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
pr-awaiting-response PR is reviewed and waiting for contributor to respond Scala
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants