Thank you for your interest in contributing to the Deep Java Library (DJL). In this document, we will cover everything you need to build, test, and debug your code when developing DJL.
Many of us use the IntelliJ IDEA IDE to develop DJL and we will sometimes mention it. However, there is no requirement to use this IDE.
When writing code for DJL, we usually try to follow standard Java coding conventions. In addition, here are some other conventions we use:
Convolution
and Conv2d
when making extendable buildersfinal
for members and parameters is generally discouraged in favor of readability.Alongside these conventions, we have a number of checks that are run including PMD, SpotBugs, and Checkstyle. These can all be verified by running the gradle build
target. Instructions for fixing any problems will be given by the relevant tool.
We also follow the AOSP Java Code Style. See here for plugins that can help setup your IDE to use this style. The formatting is checked very strictly. Failing the formatting check will look like:
> Task :api:verifyJava FAILED
FAILURE: Build failed with an exception.
* Where:
Script '/Volumes/Unix/projects/Joule/tools/gradle/formatter.gradle' line: 57
* What went wrong:
Execution failed for task ':api:verifyJava'.
> File not formatted: /Volumes/Unix/projects/Joule/api/src/main/java/ai/djl/nn/convolutional/Conv2d.java
See https://github.com/deepjavalibrary/djl/blob/master/docs/development/development_guideline.md#coding-conventions for formatting instructions
If you do fail the format check, the easiest way to resolve it is to run the gradle formatJava
target to reformat your code. It may be helpful to just run the formatter before you build the project rather than waiting for the formatting verification to fail.
We don’t have rule to enforce git commit message format. However, we encourage developers and reviewers to follow the good practice:
[api]
or docs:
DJL should have good and clear documentation for the sake of users learning about it and about deep learning.
The most basic element of our documentation is the javadoc. Javadoc is required in most classes and methods by checkstyle. We try to follow the javadoc standards for the most part. The javadoc should begin with a sentence ending in period. Then, there should be an empty line and then optionally some additional paragraphs of description that each are prefixed with <p>
and separated by newlines. Then, there should be the parameters, return values, and other attributes which do not end in a period.
DJL documentation will also coincide with various deep learning concepts that users may or may not be familiar with. Some of these include the various operations and blocks, activation functions, loss functions, optimizers, datasets, and models.
For all of the topics that are associated with a particular method or class (and can be defined in that javadoc), you should try to include the following information:
The goal is not to explain everything. It is to explain just enough that a user who sees it has a high level understanding of what it is and how to act on the information.
For larger topics which do not have a corresponding javadoc section, they should link to an outside source that helps explain it. If possible, that source should be the d2l-java book.
This project uses a gradle wrapper, so you don’t have to install gradle on your machine. You can just call the gradle wrapper using the following command:
./gradlew
There are several gradle build targets you can use. The following are the most common targets:
formatJava
or fJ
: clean up and reformat your Java codebuild
: build the whole project and run all testsjavadoc
: build the javadoc onlyjar
: build the project onlyYou can also run this from a subfolder to build for only the module within that folder.
Run the following command to list all available tasks:
./gradlew tasks --all
Sometimes you may need to run individual tests or examples. If you are developing with an IDE, you can run a test by selecting the test and clicking the “Run” button.
From the command line, you can run the following command to run a test:
./gradlew :<module>:run -Dmain=<class_name> --args ""
For example, if you would like to run the complete integration test, you can use the following command:
./gradlew :integration:run -Dmain=ai.djl.integration.IntegrationTest
To run an individual integration test from the command line, use the following:
./gradlew :integration:run --args="-c <class_name> -m <method_name>"
To get a better understanding of your problems when developing, you can enable logging by adding the following parameter to your test command:
-Dai.djl.logging.level=debug
The values to set the log level to can be found here.
Before you run any examples in IntelliJ, configure your Application template as follows:
Navigate to the ‘examples’ module. Open the class that you want to execute (e.g. ai.djl.examples.inference.cv.ObjectDetection). Select the triangle at the class declaration line. A popup menu appears with 3 items:
Select “Run ‘ObjectDetection.main()’”. IntelliJ executes the ObjectDetection example.
If you manually create a run configuration or the existing configuration failed to execute due to a missing example resource, you can edit the configuration. Change the “Working directory:” value to: $MODULE_WORKING_DIR$ to fix the issue.
When debugging a DJL application in IntelliJ, it is often helpful to inspect your NDArray variables. Because NDArrays may contain a large number of elements, rendering them can be resource-heavy and cause the debugger to hang.
IntelliJ allows you to customize the data view in the Debug Tools.
You can create your own NDArray renderer as follows:
Opening the IDE Settings/Preferences (⌘ ,
), in Java Type Renderer section, you can enable array display by:
toDebugString(true)
to show NDArray content.toDebugString(100, 10, 10, 20, true)
.
if you want to adjust the range of NDArray’s debug output.Please follow the Troubleshooting guide for common problems and their solutions.