Skip to content

Commit

Permalink
Re-organize Scala maven build (apache#13626)
Browse files Browse the repository at this point in the history
* Re-organize scala maven build

1. Automatically detect which platform to build for scala.
2. Remove platform dependend submodules
3. Fix cyclic module dependencies
4. Fix scalatype style check
5. Now mvn can be executed in submodule
6. Maven build can be executed from any directory not only in root project
7. Checkin javah header file, and use verify task to detect native API changes
8. Improve incremental build performance
9. Remove unittest and integration-test profile, use proper task instead
10. Delete generated scala file during maven clean.

* Redo maven deploy related tasks.

1. Removed maven release plugin.
2. Make maven build friendly to CI, allow cli override version.
3. Moved gpg signing to deploy stage.
4. Created a separeated deploy module.
5. Updated Makefile to new maven build change.
6. Remove unused nexus-staging-plugin
7. Added nightly and staging profile for CI.

* Support mkldnn for Scala.
  • Loading branch information
frankfliu authored and lanking520 committed Apr 30, 2019
1 parent 4d0d607 commit e0dcce0
Show file tree
Hide file tree
Showing 48 changed files with 2,045 additions and 2,170 deletions.
85 changes: 9 additions & 76 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
ROOTDIR = $(CURDIR)
TPARTYDIR = $(ROOTDIR)/3rdparty

SCALA_VERSION_PROFILE := scala-2.11

ifeq ($(OS),Windows_NT)
UNAME_S := Windows
else
Expand Down Expand Up @@ -397,18 +395,13 @@ PLUGIN_OBJ =
PLUGIN_CUOBJ =
include $(MXNET_PLUGINS)

ifeq ($(UNAME_S), Windows)
# TODO(yizhi) currently scala package does not support windows
SCALA_PKG_PROFILE := windows
else
ifneq ($(UNAME_S), Windows)
ifeq ($(UNAME_S), Darwin)
WHOLE_ARCH= -all_load
NO_WHOLE_ARCH= -noall_load
SCALA_PKG_PROFILE := osx-x86_64
else
WHOLE_ARCH= --whole-archive
NO_WHOLE_ARCH= --no-whole-archive
SCALA_PKG_PROFILE := linux-x86_64
endif
endif

Expand All @@ -427,7 +420,6 @@ ifeq ($(USE_CUDA), 1)
# Make sure to add stubs as fallback in order to be able to build
# without full CUDA install (especially if run without nvidia-docker)
LDFLAGS += -L/usr/local/cuda/lib64/stubs
SCALA_PKG_PROFILE := $(SCALA_PKG_PROFILE)-gpu
ifeq ($(USE_NCCL), 1)
ifneq ($(USE_NCCL_PATH), NONE)
CFLAGS += -I$(USE_NCCL_PATH)/include
Expand All @@ -439,7 +431,6 @@ ifeq ($(USE_CUDA), 1)
CFLAGS += -DMXNET_USE_NCCL=0
endif
else
SCALA_PKG_PROFILE := $(SCALA_PKG_PROFILE)-cpu
CFLAGS += -DMXNET_USE_NCCL=0
endif

Expand Down Expand Up @@ -604,80 +595,22 @@ rpkgtest:
Rscript -e 'res<-covr:::package_coverage("R-package");fileConn<-file(paste("r-package_coverage_",toString(runif(1)),".json"));writeLines(covr:::to_codecov(res), fileConn);close(fileConn)'

scalaclean:
(cd $(ROOTDIR)/scala-package && \
mvn clean -P$(SCALA_PKG_PROFILE),$(SCALA_VERSION_PROFILE))

scalatestcompile:
(cd $(ROOTDIR)/scala-package && \
mvn test-compile -P$(SCALA_PKG_PROFILE),$(SCALA_VERSION_PROFILE) -Dcxx="$(CXX)" \
-Dbuild.platform="$(SCALA_PKG_PROFILE)" \
-Dcflags="$(CFLAGS)" -Dldflags="$(LDFLAGS)" \
-Dcurrent_libdir="$(ROOTDIR)/lib" \
-Dlddeps="$(LIB_DEP) $(ROOTDIR)/lib/libmxnet.a")
(cd $(ROOTDIR)/scala-package && mvn clean)

scalapkg:
(cd $(ROOTDIR)/scala-package && \
mvn package $(MAVEN_ARGS) -P$(SCALA_PKG_PROFILE),$(SCALA_VERSION_PROFILE) -Dcxx="$(CXX)" \
-Dbuild.platform="$(SCALA_PKG_PROFILE)" \
-Dcflags="$(CFLAGS)" -Dldflags="$(LDFLAGS)" \
-Dcurrent_libdir="$(ROOTDIR)/lib" \
-Dlddeps="$(LIB_DEP) $(ROOTDIR)/lib/libmxnet.a")
(cd $(ROOTDIR)/scala-package && mvn install -DskipTests)

scalainstall:
(cd $(ROOTDIR)/scala-package && mvn install)

scalaunittest:
(cd $(ROOTDIR)/scala-package && \
mvn integration-test $(MAVEN_ARGS) -P$(SCALA_PKG_PROFILE),$(SCALA_VERSION_PROFILE),unittest -Dcxx="$(CXX)" \
-Dcflags="$(CFLAGS)" -Dldflags="$(LDFLAGS)" \
-Dlddeps="$(LIB_DEP) $(ROOTDIR)/lib/libmxnet.a" $(SCALA_TEST_ARGS))
(cd $(ROOTDIR)/scala-package && mvn install)

scalaintegrationtest:
(cd $(ROOTDIR)/scala-package && \
mvn integration-test $(MAVEN_ARGS) -P$(SCALA_PKG_PROFILE),$(SCALA_VERSION_PROFILE),integrationtest -Dcxx="$(CXX)" \
-Dcflags="$(CFLAGS)" -Dldflags="$(LDFLAGS)" \
-Dlddeps="$(LIB_DEP) $(ROOTDIR)/lib/libmxnet.a" $(SCALA_TEST_ARGS))

scalainstall:
(cd $(ROOTDIR)/scala-package && \
mvn install $(MAVEN_ARGS) -P$(SCALA_PKG_PROFILE),$(SCALA_VERSION_PROFILE) -DskipTests=true -Dcxx="$(CXX)" \
-Dbuild.platform="$(SCALA_PKG_PROFILE)" \
-Dcflags="$(CFLAGS)" -Dldflags="$(LDFLAGS)" \
-Dlddeps="$(LIB_DEP) $(ROOTDIR)/lib/libmxnet.a")

scalarelease-dryrun:
(cd $(ROOTDIR)/scala-package && \
mvn release:clean release:prepare -DdryRun=true -DautoVersionSubmodules=true \
-Papache-release,$(SCALA_PKG_PROFILE),$(SCALA_VERSION_PROFILE) \
-Darguments=""-Dbuild\.platform=\""$(SCALA_PKG_PROFILE)\""\ -DskipTests=true\ -Dcflags=\""$(CFLAGS)\""\ -Dcxx=\""$(CXX)\""\ -Dldflags=\""$(LDFLAGS)\""\ -Dlddeps=\""$(LIB_DEP) $(ROOTDIR)/lib/libmxnet.a\"""")

scalarelease-prepare:
(cd $(ROOTDIR)/scala-package && \
mvn release:clean release:prepare -DautoVersionSubmodules=true \
-Papache-release,$(SCALA_PKG_PROFILE),$(SCALA_VERSION_PROFILE) \
-Darguments=""-Dbuild\.platform=\""$(SCALA_PKG_PROFILE)\""\ -DskipTests=true\ -Dcflags=\""$(CFLAGS)\""\ -Dcxx=\""$(CXX)\""\ -Dldflags=\""$(LDFLAGS)\""\ -Dlddeps=\""$(LIB_DEP) $(ROOTDIR)/lib/libmxnet.a\"""")

scalarelease-perform:
(cd $(ROOTDIR)/scala-package && \
mvn release:perform -DautoVersionSubmodules=true \
-Papache-release,$(SCALA_PKG_PROFILE),$(SCALA_VERSION_PROFILE) \
-Darguments=""-Dbuild\.platform=\""$(SCALA_PKG_PROFILE)\""\ -DskipTests=true\ -Dcflags=\""$(CFLAGS)\""\ -Dcxx=\""$(CXX)\""\ -Dldflags=\""$(LDFLAGS)\""\ -Dlddeps=\""$(LIB_DEP) $(ROOTDIR)/lib/libmxnet.a\"""")

scaladeploy:
(cd $(ROOTDIR)/scala-package && \
mvn deploy $(MAVEN_ARGS) -Papache-release,$(SCALA_PKG_PROFILE),$(SCALA_VERSION_PROFILE) \-DskipTests=true -Dcxx="$(CXX)" \
-Dbuild.platform="$(SCALA_PKG_PROFILE)" \
-Dcflags="$(CFLAGS)" -Dldflags="$(LDFLAGS)" \
-Dlddeps="$(LIB_DEP) $(ROOTDIR)/lib/libmxnet.a")

scaladeploylocal:
(cd $(ROOTDIR)/scala-package && \
mvn deploy $(MAVEN_ARGS) -Papache-release,deployLocal,$(SCALA_PKG_PROFILE),$(SCALA_VERSION_PROFILE) \-DskipTests=true -Dcxx="$(CXX)" \
-DaltDeploymentRepository=snapshot-repo::default::file:local-snapshot \
-Dgpg.skip \
-Dbuild.platform="$(SCALA_PKG_PROFILE)" \
-Dcflags="$(CFLAGS)" -Dldflags="$(LDFLAGS)" \
-Dlddeps="$(LIB_DEP) $(ROOTDIR)/lib/libmxnet.a")
(cd $(ROOTDIR)/scala-package && mvn integration-test -DskipTests=false)

jnilint:
3rdparty/dmlc-core/scripts/lint.py mxnet-jnicpp cpp scala-package/native/src
3rdparty/dmlc-core/scripts/lint.py mxnet-jnicpp cpp scala-package/native/src --exclude_path scala-package/native/src/main/native/org_apache_mxnet_native_c_api.h

rclean:
$(RM) -r R-package/src/image_recordio.h R-package/NAMESPACE R-package/man R-package/R/mxnet_generated.R \
Expand Down
2 changes: 1 addition & 1 deletion contrib/clojure-package/project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
;[org.apache.mxnet/mxnet-full_2.11-linux-x86_64-gpu "1.2.1"]

;;; CI
[org.apache.mxnet/mxnet-full_2.11-linux-x86_64-cpu "1.4.1-SNAPSHOT"]
[org.apache.mxnet/mxnet-full_2.11 "INTERNAL"]

[org.clojure/tools.logging "0.4.0"]
[org.apache.logging.log4j/log4j-core "2.8.1"]
Expand Down
12 changes: 6 additions & 6 deletions docs/mxdoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,9 @@ def build_scala_docs(app):
scala_doc_sources = 'find . -type f -name "*.scala" | egrep \"\.\/core|\.\/infer\" | egrep -v \"\/javaapi\" | egrep -v \"Suite\"'
scala_doc_classpath = ':'.join([
'`find native -name "*.jar" | grep "target/lib/" | tr "\\n" ":" `',
'`find macros -name "*-SNAPSHOT.jar" | tr "\\n" ":" `',
'`find core -name "*-SNAPSHOT.jar" | tr "\\n" ":" `',
'`find infer -name "*-SNAPSHOT.jar" | tr "\\n" ":" `'
'`find macros -name "*-INTERNAL.jar" | tr "\\n" ":" `',
'`find core -name "*-INTERNAL.jar" | tr "\\n" ":" `',
'`find infer -name "*-INTERNAL.jar" | tr "\\n" ":" `'
])
# There are unresolvable errors on mxnet 1.2.x. We are ignoring those errors while aborting the ci on newer versions
scala_ignore_errors = '; exit 0' if '1.2.' in _BUILD_VER else ''
Expand All @@ -135,9 +135,9 @@ def build_java_docs(app):
java_doc_sources = 'find . -type f -name "*.scala" | egrep \"\.\/core|\.\/infer\" | egrep \"\/javaapi\" | egrep -v \"Suite\"'
java_doc_classpath = ':'.join([
'`find native -name "*.jar" | grep "target/lib/" | tr "\\n" ":" `',
'`find macros -name "*-SNAPSHOT.jar" | tr "\\n" ":" `',
'`find core -name "*-SNAPSHOT.jar" | tr "\\n" ":" `',
'`find infer -name "*-SNAPSHOT.jar" | tr "\\n" ":" `'
'`find macros -name "*-INTERNAL.jar" | tr "\\n" ":" `',
'`find core -name "*-INTERNAL.jar" | tr "\\n" ":" `',
'`find infer -name "*-INTERNAL.jar" | tr "\\n" ":" `'
])
_run_cmd('cd {}; scaladoc `{}` -classpath {} -feature -deprecation'
.format(java_path, java_doc_sources, java_doc_classpath))
Expand Down
2 changes: 2 additions & 0 deletions scala-package/.gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
.flattened-pom.xml
core/src/main/scala/org/apache/mxnet/NDArrayAPIBase.scala
core/src/main/scala/org/apache/mxnet/NDArrayBase.scala
core/src/main/scala/org/apache/mxnet/NDArrayRandomAPIBase.scala
core/src/main/scala/org/apache/mxnet/javaapi/NDArrayBase.scala
core/src/main/scala/org/apache/mxnet/SymbolAPIBase.scala
core/src/main/scala/org/apache/mxnet/SymbolBase.scala
core/src/main/scala/org/apache/mxnet/SymbolRandomAPIBase.scala
examples/scripts/infer/images/
examples/scripts/infer/models/
local-snapshot
100 changes: 91 additions & 9 deletions scala-package/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,63 @@ It brings flexible and efficient GPU/CPU computing and state-of-art deep learnin
in Scala, Java and other languages built on JVM.
- It also enables you to construct and customize the state-of-art deep learning models in JVM languages,
and apply them to tasks such as image classification and data science challenges.
- The Scala/Java Inferece APIs provides an easy out of the box solution for loading pre-trained MXNet models and running inference on them.

Pre-Built Maven Packages
------------------------

### Stable ###

The MXNet Scala/Java packages can be easily included in your Maven managed project.
The stable jar files for the packages are available on the [MXNet Maven Package Repository](https://search.maven.org/search?q=g:org.apache.mxnet)
Currently we provide packages for Linux (Ubuntu 16.04) (CPU and GPU) and macOS (CPU only). Stable packages for Windows and CentOS will come soon. For now, if you have a CentOS machine, follow the ```Build From Source``` section below.

To add MXNet Scala/Java package to your project, add the dependency as shown below corresponding to your platform, under the ```dependencies``` tag in your project's ```pom.xml``` :

**Linux GPU**

<a href="https://mvnrepository.com/artifact/org.apache.mxnet/mxnet-full_2.11-linux-x86_64-gpu"><img src="https://img.shields.io/badge/org.apache.mxnet-linux gpu-green.svg" alt="maven badge"/></a>

```HTML
<dependency>
<groupId>org.apache.mxnet</groupId>
<artifactId>mxnet-full_2.11-linux-x86_64-gpu</artifactId>
<version>[1.3.1,)</version>
</dependency>
```

**Linux CPU**

<a href="https://mvnrepository.com/artifact/org.apache.mxnet/mxnet-full_2.11-linux-x86_64-cpu"><img src="https://img.shields.io/badge/org.apache.mxnet-linux cpu-green.svg" alt="maven badge"/></a>

```HTML
<dependency>
<groupId>org.apache.mxnet</groupId>
<artifactId>mxnet-full_2.11-linux-x86_64-cpu</artifactId>
<version>[1.3.1,)</version>
</dependency>
```

**macOS CPU**

<a href="https://mvnrepository.com/artifact/org.apache.mxnet/mxnet-full_2.11-osx-x86_64-cpu"><img src="https://img.shields.io/badge/org.apache.mxnet-macOS cpu-green.svg" alt="maven badge"/></a>

```HTML
<dependency>
<groupId>org.apache.mxnet</groupId>
<artifactId>mxnet-full_2.11-osx-x86_64-cpu</artifactId>
<version>[1.3.1,)</version>
</dependency>
```

**Note:** ```<version>[1.3.1,)<\version>``` indicates that we will fetch packages with version 1.3.1 or higher. This will always ensure that the pom.xml is able to fetch the latest and greatest jar files from Maven.

### Nightly ###

Apart from these, the nightly builds representing the bleeding edge development on Scala/Java packages are also available on the [MXNet Maven Nexus Package Repository](https://repository.apache.org/#nexus-search;gav~org.apache.mxnet~~~~).
Currently we provide nightly packages for Linux (CPU and GPU) and MacOS (CPU only). The Linux nightly jar files also work on CentOS. Nightly packages for Windows will come soon.

Add the following ```repository``` to your project's ```pom.xml``` file :

Install
------------
Expand Down Expand Up @@ -60,31 +117,52 @@ You can also use `mxnet-core_2.10-0.1.1.jar` and put the compiled native library
If you have some native libraries conflict with the ones in the provided 'full' jar (e.g., you use openblas instead of atlas), this is a recommended way.
Refer to the next section for how to build it from the very source.

Build
------------
Build From Source
-----------------

Checkout the [Installation Guide](http://mxnet.incubator.apache.org/install/index.html) contains instructions to install mxnet.
Then you can compile the Scala Package by
Checkout the [Installation Guide](http://mxnet.incubator.apache.org/install/index.html) contains instructions to install mxnet package and build it from source. Scala maven build assume you already have a ``lib/libmxnet.so`` file.
If you have built MXNet from source and are looking to setup Scala from that point, you may simply run the following from the MXNet source root, Scala build will detect your platform (OSX/Linux) and libmxnet.so flavor (CPU/GPU):

```bash
make scalapkg
cd scala-package
mvn install
```

(Optional) run unit/integration tests by

```bash
make scalaunittest
make scalaintegrationtest
cd scala-package
mvn integration-test -DskipTests=false
```

Or run a subset of unit tests by, e.g.,

```bash
make SCALA_TEST_ARGS=-Dsuites=org.apache.mxnet.NDArraySuite scalaunittest
cd scala-package
mvn -Dsuites=org.apache.mxnet.NDArraySuite integration-test
```

If everything goes well, you will find jars for `assembly`, `core` and `example` modules.
Also it produces the native library in `native/{your-architecture}/target`, which you can use to cooperate with the `core` module.
Also it produces the native library in `native/target`, which you can use to cooperate with the `core` module.

Deploy to repository
--------------------

By default, `maven deploy` will deploy artifacts to local file system, you can file then in: ``scala-package/deploy/target/repo`` folder.

For nightly build in CI, a snapshot build will be uploaded to apache repository with follow command:

```bash
cd scala-package
mvn deploy -Pnightly
```

Use following command to deploy release build (push artifacts to apache staging repository):

```bash
cd scala-package
mvn deploy -Pstaging
```

Once you've downloaded and unpacked MNIST dataset to `./data/`, run the training example by

Expand Down Expand Up @@ -207,3 +285,7 @@ Release
License
-------
MXNet Scala Package is licensed under [Apache-2](https://github.com/apache/incubator-mxnet/blob/master/scala-package/LICENSE) license.

MXNet uses some 3rd party softwares. Following 3rd party license files are bundled inside Scala jar file:
* cub/LICENSE.TXT
* mkldnn/external/mklml_mac_2019.0.1.20180928/license.txt
Loading

0 comments on commit e0dcce0

Please sign in to comment.