generate.sh
- is provided in the project root. This can be used (at present) to generate ND4J namespace classes. It is assumed that the deeplearning4j mono repo and the dl4j-dev-tools repo both exist and have a common parent directory i.e., somedir/deeplearning4j
and somedir/dl4j-dev-tools
both exist.bitwise
, neuralnetwork
, random
, and math
Note also that all
may be passed to the script to generate all namespaces.org.nd4j.codegen.cli.CLI
class is used. Classes are written to deeplearning4j/nd4j/nd4j-backends/nd4j-api-parent/nd4j-api/src/main/java/org/nd4j/linalg/factory/ops/
src/main
directory, you will find 4 sub-directories.java
and kotlin
directories contain Java and Kotlin code respectively.ops
.stubs
. That folder contains stub classes, that are used to reference other classes available in ND4J. These stub classes are intentionally left empty, as JavaPoet only requires them for naming and automatically creating proper imports. We use stub classes instead of depending on the actual nd4j API in order to break a cyclic dependency that would otherwise be created (i.e. in order to be able to generate code for ND4J, we would need an already compiled nd4j to be available). Note: If something is stubbed here and is moved in ND4J, then it also has to be moved to the appropriate place here, otherwise the generated code will be wrong.adr
folder contains "Architecture Decision Records". These files give you more insight into the "why" of some of the bigger decisions within this project.concat
which can take multiple input tensors or ops that might take shape arguments.useMixin(mixin)
as the very first thing in the op definition. If you don't want to inherit all of the parameters of the mixin, you can pass the same additional configuration as you would pass to useMixin(mixin, ...options..)
. See Mixin for more information.javaPackage
(String): Package where the op is to be found in the java implementation.javaOpClass
(String): Name of java op class if inconsistent with opName. Default: same as opNamelibnd4jName
(String): The name the op has in libnd4j. Default: same as opNamename
, libnd4jName
and javaOpClass
.Op("opname", mixin){...}
, or with useMixin(mixin)
within the op definition. While the former version only supports a single mixin, the latter version allows you to use as many mixins as are required.useMixin(mixin)
inside a Mixin itself.useMixin(mixin, ...options...)
supports a few additional options: keepInputs
, keepArgs
, keepConfigs
, keepOutputs
, keepSignatures
, keepDoc
, keepConstraints
. They default to true
. If you want to skip including some of them, you simply set the parameter for it to false
, e.g. useMixin(mixin, keepDoc=false)
.useMixin(mixin)
, all definitions within the mixin are applied as if this invocation was replaced with the content of the mixin itself. This means, that if you have already defined anything prior to using a mixin, the mixin's definitions will be after the previously defined things. This can be very useful if the commonality between ops is that they have a few trailing options.legacy
, javaPackage
, named sections are Input
, Arg
, Output
, Config
.javaPackage
defined in both an op and a mixin. Then you can have the following two cases:javaPackage
value that is defined within the op. In the second case it will have the javaPackage
value defined in the mixin.Input(dataType, "a")
defined in both the mixin and the op. Again you can have two cases:Input
, Arg
, Constraint
and Doc
definitions.useConfig(cfg)
or val configRef = useConfig(cfg)
. The second form allows you to reference the config.configRef.input("name")
and configRef.arg("name")
. Also it allows you to use a config in a signature Signature(a, b, c, configRef)
.IllegalStateException
will be thrown.INT
, FLOATING_POINT
, NUMERIC
or BOOLEAN
) and an op unique name.Exactly(1)
.description
(String): A short description what this input represents. Setting this is recommended.count
(Count): Can take one of Exactly(n)
; AtLeast(n)
; AtMost(n)
; Range(from, to)
defaultValue
(Input): use another input as the default if this isn't set explicitly. The data type of the other input has to match the data type of this input. The other input may also have a default value.INT
, FLOATING_POINT
, NUMERIC
or BOOLEAN
) and an op unique name.Exactly(1)
.Arg(INT, "a"){ count = AtLeast(1); description = "..." }
will be turned into long... a
.description
(String): A short description what this argument represents. Setting this is recommended.count
(Count): Can take one of Exactly(n)
; AtLeast(n)
; AtMost(n)
; Range(from, to)
defaultValue
(null|Number|Boolean|int[]|double[]|boolean[]|Arg|TensorShapeValue|TensorDataTypeValue|String): Use given value as default value, if this isn't explicitly set. Can refer to inputs and outputs using x.shape()
and x.dataType()
. The given default values has to match the data type for this argument. May also refer to another Arg, and that Arg may also have a default value. Default values based on outputs are treated like without a default in SameDiff mode.possibleValues
(String[]): only available when ENUM data type is used for the argument. Takes a list of possible values for the Enum. If used in in abstract base op, the enum will only be created once. See also ADR 0006 "Op specific enums".INT
, FLOATING_POINT
, NUMERIC
or BOOLEAN
) and an op unique name.description
(String): A short description what this argument represents. Setting this is recommended.AllParamSignature()
and AllDefaultParamSignature()
are short hands for Signature(...all parameters...)
and Signature(...only parameters with no default values...)
. Their parameters include references to outputs unless disabled using withOutput=false
(e.g. AllParamSignature(withOutput=false)
).AllParamSignature()
and AllDefaultParamSignature()
are both specified.IllegalStateException
will be thrown on construction.%OPNAME%
-> operation name ("Add", "Sub", etc)%LIBND4J_OPNAME%
-> libnd4j op name ("add", "sub", etc)%INPUT_TYPE%
-> input / output type depending on the generated api, i.e. SDVariable
for SameDiff and INDArray
for ND4JDocTokens
class for more details.val name = Input(...)
. Inside the Constraint block, you can use the following operations:eq
: Compare equality (applicable to numbers and booleans), e.g. x eq 7
, x eq true
neq
: Compare inequality (applicable to numbers and booleans), e.g. x neq 3
, x neq true
lt
, lte
: less than, less than equal (applicable to numbers), e.g. x lt 3
, x lte 4
gt
, gte
: greater than, grater than equal (applicable to numbers), e.g. x gt 5
, x gte 6
and
: combine two comparisons where both have to be true, e.g. (x eq 8) and (y lt 3)
or
: combine two comparisons where one has to be true, e.g. (x eq 8) or (y eq true)
all
: combine N comparisons where all have to be true, e.g. all(x eq 8, y lt 3, z eq true)
some
: combine N comparisons where at least one has to be true, e.g. some(x eq 8, y lt 3, z eq true)
not
: negates a comparison, e.g. not(x eq 3)
sameType(...)
: true if all given inputs are the same type, e.g. sameType(x,y,z)
sameShape(...)
: true if all given inputs have the same shape, e.g. sameShape(x,y,z)
broadcastableShapes(...)
: true if all given inputs have broadcast compatible shapes, e.g. broadcastableShapes(x,y,z)
input.rank()
: Rank of the given inputinput.sizeAt(i)
: size of the given input at the i-th dimensioninput.isScalar()
: Short hand for x.rank() == 1
src/kotlin/org/nd4j/codegen/dsl/OpBuilder.kt
. The actual class definitions for the object graph we are building, can be found in src/kotlin/org/nd4j/codegen/api
.org.nd4j.codegen.api.generator.Generator
interface. For automatic detection by the CLI tool, they should also be within the org.nd4j.codegen.impl.LANGUAGE
package, where LANGUAGE
is the actual language that they generate.org.nd4j.codegen.api.generator.ConstraintCodeGenerator
interface.