chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:47:05 +08:00
commit 4f3b7da785
7394 changed files with 2005594 additions and 0 deletions
@@ -0,0 +1,41 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.nd4j.codegen.dsl;
import org.apache.commons.lang3.StringUtils;
import org.junit.jupiter.api.Test;
import org.nd4j.codegen.impl.java.DocsGenerator;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.extension.ExtendWith;
@DisplayName("Docs Generator Test")
class DocsGeneratorTest {
@Test
@DisplayName("Test J Dto MD Adapter")
void testJDtoMDAdapter() {
String original = "{@code %INPUT_TYPE% eye = eye(3,2)\n" + " eye:\n" + " [ 1, 0]\n" + " [ 0, 1]\n" + " [ 0, 0]}";
String expected = "{ INDArray eye = eye(3,2)\n" + " eye:\n" + " [ 1, 0]\n" + " [ 0, 1]\n" + " [ 0, 0]}";
DocsGenerator.JavaDocToMDAdapter adapter = new DocsGenerator.JavaDocToMDAdapter(original);
String out = adapter.filter("@code", StringUtils.EMPTY).filter("%INPUT_TYPE%", "INDArray").toString();
assertEquals(out, expected);
}
}
@@ -0,0 +1,67 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.nd4j.codegen.dsl;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.nd4j.codegen.api.NamespaceOps;
import org.nd4j.codegen.impl.java.Nd4jNamespaceGenerator;
import org.nd4j.codegen.ops.RNNKt;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
class TestGeneration {
@SuppressWarnings("unused")
@TempDir
public File testDir;
@Test
void test() throws Exception {
File f = testDir;
// List<NamespaceOps> list = Arrays.asList(BitwiseKt.Bitwise(), RandomKt.Random());
List<NamespaceOps> list = Arrays.asList(RNNKt.SDRNN());
for(NamespaceOps ops : list) {
Nd4jNamespaceGenerator.generate(ops, null, f, ops.getName() + ".java", "org.nd4j.linalg.factory", StringUtils.EMPTY);
}
File[] files = f.listFiles();
Iterator<File> iter = FileUtils.iterateFiles(f, null, true);
if(files != null) {
while(iter.hasNext()){
File file = iter.next();
if(file.isDirectory())
continue;
System.out.println(FileUtils.readFileToString(file, StandardCharsets.UTF_8));
System.out.println("\n\n================\n\n");
}
}
}
}
@@ -0,0 +1,64 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.nd4j.codegen.dsl
import org.junit.jupiter.api.Test
import org.nd4j.codegen.api.DataType.FLOATING_POINT
import org.nd4j.codegen.api.Language
import org.nd4j.codegen.api.doc.DocScope
class ConfigTest {
@Test
fun allGood(){
Namespace("RNN"){
val sruWeights = Config("SRUWeights"){
Input(FLOATING_POINT, "weights"){ description = "Weights, with shape [inSize, 3*inSize]" }
Input(FLOATING_POINT, "bias"){ description = "Biases, with shape [2*inSize]" }
}
Op("SRU"){
Input(FLOATING_POINT, "x"){ description = "..." }
Input(FLOATING_POINT, "initialC"){ description = "..." }
Input(FLOATING_POINT, "mask"){ description = "..." }
useConfig(sruWeights)
Output(FLOATING_POINT, "out"){ description = "..." }
Doc(Language.ANY, DocScope.ALL){ "some doc" }
}
Op("SRUCell"){
val x = Input(FLOATING_POINT, "x"){ description = "..." }
val cLast = Input(FLOATING_POINT, "cLast"){ description = "..." }
val conf = useConfig(sruWeights)
Output(FLOATING_POINT, "out"){ description = "..." }
// Just for demonstration purposes
Signature(x, cLast, conf)
Doc(Language.ANY, DocScope.ALL){ "some doc" }
}
}
}
}
@@ -0,0 +1,99 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.nd4j.codegen.dsl
import org.junit.jupiter.api.Test
import org.nd4j.codegen.api.Arg
import org.nd4j.codegen.api.DataType
import org.nd4j.codegen.api.Expression
import org.nd4j.codegen.api.Input
import org.nd4j.codegen.impl.java.JavaConstraintCodeGenerator
import kotlin.test.assertEquals
class ConstraintTest {
private fun buildConstraint(block: ConstraintBuilder.() -> Expression): Expression {
return ConstraintBuilder().block()
}
@Test
fun simpleConstraintTest() {
val expected = "x.rank() == 3"
val input = Input(name = "x", type = DataType.INT)
val constraint = buildConstraint { input.rank() eq 3 }
val out = JavaConstraintCodeGenerator().generateExpression(constraint)
assertEquals(expected, out)
}
@Test
fun simple2ConstraintTest() {
val expected = "(x.rank() == 3) && (x.sizeAt(2) >= 7)"
val input = Input(name = "x", type = DataType.INT)
val constraint = buildConstraint { (input.rank() eq 3) and (input.sizeAt(2) gte 7) }
val out = JavaConstraintCodeGenerator().generateExpression(constraint)
assertEquals(expected, out)
}
@Test
fun simple3ConstraintTest() {
val expected = "((x.rank() == 3) || (x.sizeAt(2) >= 7)) || (x.sizeAt(4) < 5)"
val input = Input(name = "x", type = DataType.INT)
val constraint = buildConstraint { some(
input.rank() eq 3,
input.sizeAt(2) gte 7,
input.sizeAt(4) lt 5
) }
val out = JavaConstraintCodeGenerator().generateExpression(constraint)
assertEquals(expected, out)
}
@Test
fun complexConstraintTest() {
val expected = "(x.rank() == 3) == false"
val input = Input(name = "x", type = DataType.INT)
val constraint = buildConstraint { not(input.rank() eq 3) }
val out = JavaConstraintCodeGenerator().generateExpression(constraint)
assertEquals(expected, out)
}
@Test
fun argConstraintTest() {
val expected = "(x.rank() == rank) == false"
val arg = Arg(name = "rank", type = DataType.NUMERIC)
val input = Input(name = "x", type = DataType.INT)
val constraint = buildConstraint { not(input.rank() eq arg) }
val out = JavaConstraintCodeGenerator().generateExpression(constraint)
assertEquals(expected, out)
}
@Test
fun specificConstraintTest(){
val expected = "isSameType(x, y, z)"
val x = Input(name = "x", type = DataType.INT)
val y = Input(name = "y", type = DataType.INT)
val z = Input(name = "z", type = DataType.INT)
val constraint = buildConstraint { sameType(x, y, z) }
val out = JavaConstraintCodeGenerator().generateExpression(constraint)
assertEquals(expected, out)
}
}
@@ -0,0 +1,41 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.nd4j.codegen.dsl
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows
import org.nd4j.codegen.api.DataType
class NamespaceInvariantTest {
@Test
fun checkForUnusedConfigs(){
val thrown = assertThrows<IllegalStateException> {
Namespace("RNN"){
Config("SRUWeights"){
Input(DataType.FLOATING_POINT, "weights"){ description = "Weights, with shape [inSize, 3*inSize]" }
Input(DataType.FLOATING_POINT, "bias"){ description = "Biases, with shape [2*inSize]" }
}
}
}
assertEquals("Found unused configs: SRUWeights", thrown.message)
}
}
@@ -0,0 +1,171 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.nd4j.codegen.dsl
import org.apache.commons.io.FileUtils
import org.junit.jupiter.api.Test
import org.nd4j.codegen.api.AtLeast
import org.nd4j.codegen.api.AtMost
import org.nd4j.codegen.api.DataType.*
import org.nd4j.codegen.api.Exactly
import org.nd4j.codegen.api.Language
import org.nd4j.codegen.api.doc.DocScope
import org.nd4j.codegen.impl.java.JavaPoetGenerator
import java.io.File
import java.nio.charset.StandardCharsets
import kotlin.test.assertTrue
class OpBuilderTest {
private var testDir = createTempDir()
@Test
fun opBuilderTest() {
val outDir = testDir
val mathNs = Namespace("math") {
val config = Config("bla"){
val a = Input(NUMERIC, "a") { description = "This is A!"}
Input(NUMERIC, "c") { count = AtLeast(1); description = "This is C!"}
Input(NUMERIC, "e") { defaultValue = a}
val b = Arg(NUMERIC, "b") { description = "This is B!"}
Arg(NUMERIC, "d") { count = AtMost(7); description = "This is D!"}
Arg(NUMERIC, "f") { defaultValue = 12}
Constraint("Some constraint"){
a.isScalar()
}
Constraint("Some different constraint"){
b eq 7
}
Doc(Language.JAVA, DocScope.ALL){
"This is some config documentation"
}
}
Op("add") {
javaPackage = "org.nd4j.linalg.api.ops.impl.transforms.pairwise.arithmetic"
val x = Input(NUMERIC, "x") { description = "First input to add" }
Input(NUMERIC,"y") { count = AtLeast(1); description = "Second input to add"; defaultValue = x }
Arg(INT,"shape") { count = AtLeast(1); description = "shape"; defaultValue = intArrayOf(1,2,3) }
Output(NUMERIC, "z") { description = "Output (x+y)" }
Doc(Language.ANY, DocScope.ALL) {
"""
(From AddOp) Add op doc text that will appear everywhere - classes, constructors, op creators
""".trimIndent()
}
Doc(Language.ANY, DocScope.CLASS_DOC_ONLY) {
"Add op doc text that will appear in all class docs (javadoc etc)"
}
Doc(Language.ANY, DocScope.CONSTRUCTORS_ONLY) {
"Add op doc text for constructors only"
}
}
val baseArithmeticOp = Mixin("BaseArithmeticOp") {
javaPackage = "org.nd4j.linalg.api.ops.impl.transforms.pairwise.arithmetic"
Input(NUMERIC,"x") { count = Exactly(1); description = "First operand to %OPNAME%" }
Input(NUMERIC,"y") { count = Exactly(1); description = "Second operand" }
Output(NUMERIC,"z") { description = "Output" }
Doc(Language.ANY, DocScope.ALL) {
"(From BaseArithmeticOp) op doc text that will appear everywhere - classes, constructors, op creators"
}
Doc(Language.ANY, DocScope.CLASS_DOC_ONLY) {
"op doc text that will appear in all class docs (javadoc etc)"
}
Doc(Language.ANY, DocScope.CONSTRUCTORS_ONLY) {
"op doc text for constructors only"
}
}
Op("sub", extends = baseArithmeticOp)
Op("mul", extends = baseArithmeticOp)
Op("rsub", extends = baseArithmeticOp) {
isAbstract = false
javaPackage = "org.nd4j.some.other.package"
Doc(Language.ANY, DocScope.CREATORS_ONLY) {
"(From rsub) This doc section will appear only in creator method for %OPNAME%"
}
}
Op("div"){
javaPackage = "org.nd4j.linalg.api.ops.impl.transforms.pairwise.arithmetic"
val x = Input(NUMERIC,"x") { description = "First operand to div" }
val y = Input(NUMERIC,"y") { description = "Second operand to div" }
val idx = Arg(INT, "idx") { description = "Some kind of Index" }
Constraint("Compatible Rank"){
x.rank() eq idx
}
Constraint("Compatible Shapes"){
sameShape(x,y)
}
Output(NUMERIC,"z") { description = "Output" }
Doc(Language.ANY, DocScope.ALL) {
"op doc text that will appear everywhere - classes, constructors, op creators"
}
}
Op("zfoo"){
javaPackage = "bar"
javaOpClass = "FooBarOp"
val x = Input(NUMERIC,"x") { description = "First operand to %OPNAME% (%INPUT_TYPE%)" }
val y = Input(NUMERIC,"y") { description = "Second operand to div" }
val z = Arg(ENUM, "fooMode"){ description = "Something or other"; possibleValues = listOf("SOME", "value", "Spam", "eGGs")}
val bla = useConfig(config)
Constraint("foo bar"){
x.sizeAt(7) eq 7 and y.isScalar()
}
Doc(Language.ANY, DocScope.ALL) {
"op doc text that will appear everywhere - classes, constructors, op creators"
}
Signature(x, y, z, bla)
}
}
val generator = JavaPoetGenerator()
generator.generateNamespaceNd4j(mathNs, null, outDir, "Nd4jMath")
val exp = File(outDir, "org/nd4j/linalg/factory/ops/Nd4jMath.java")
assertTrue(exp.isFile)
println(FileUtils.readFileToString(exp, StandardCharsets.UTF_8))
}
}
@@ -0,0 +1,833 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.nd4j.codegen.dsl
import org.junit.jupiter.api.Assertions.assertSame
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows
import org.nd4j.codegen.api.*
import org.nd4j.codegen.api.doc.DocScope
import kotlin.test.assertEquals
import kotlin.test.assertNotSame
class OpInvariantTest {
@Test
fun opMustBeDocumented() {
val thrown = assertThrows<java.lang.IllegalStateException> {
Namespace("math") {
Op("foo") {}
}
}
assertEquals("foo: Ops must be documented!", thrown.message)
}
@Test
fun opMustBeDocumentedAndNotEmpty() {
val thrown = assertThrows<java.lang.IllegalStateException> {
Namespace("math") {
Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "" }
}
}
}
assertEquals("foo: Ops must be documented!", thrown.message)
}
@Test
fun opMustBeDocumentedWithDoc() {
Namespace("math") {
Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
}
}
}
@Test
fun opSignatureMustCoverAllParameters() {
val thrown = assertThrows<java.lang.IllegalStateException> {
Namespace("math") {
Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
val x = Input(DataType.NUMERIC, "x")
val y = Input(DataType.NUMERIC, "y")
Signature(x)
}
}
}
assertEquals("foo: Signature(x) does not cover all parameters! Missing: y", thrown.message)
}
@Test
fun opSignatureMustCoverAllParameters2() {
val thrown = assertThrows<java.lang.IllegalStateException> {
Namespace("math") {
Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
val x = Input(DataType.NUMERIC, "x")
val y = Arg(DataType.NUMERIC, "y")
Signature(x)
}
}
}
assertEquals("foo: Signature(x) does not cover all parameters! Missing: y", thrown.message)
}
@Test
fun opSignatureMustCoverAllParametersWithoutDefaults() {
Namespace("math") {
Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
val x = Input(DataType.NUMERIC, "x")
val y = Arg(DataType.NUMERIC, "y") {
defaultValue = 7
}
Signature(x)
}
}
}
@Test
fun opSignatureMustTakeEachParameterOnlyOnce() {
val thrown = assertThrows<java.lang.IllegalArgumentException> {
Namespace("math") {
Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
val x = Input(DataType.NUMERIC, "x")
val y = Arg(DataType.NUMERIC, "y")
Signature(x, x, x)
}
}
}
assertEquals("A parameter may not be used twice in a signature!", thrown.message)
}
@Test
fun opSignatureMustAllowOutputs() {
Namespace("math") {
Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
val x = Input(DataType.NUMERIC, "x")
val y = Arg(DataType.NUMERIC, "y") {
defaultValue = 7
}
val out = Output(DataType.NUMERIC, "out")
Signature(out, x)
}
}
}
@Test
fun opSignatureMustAllowOutputsOnlyOnce() {
val thrown = assertThrows<java.lang.IllegalArgumentException> {
Namespace("math") {
Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
val x = Input(DataType.NUMERIC, "x")
val y = Arg(DataType.NUMERIC, "y") {
defaultValue = 7
}
val out = Output(DataType.NUMERIC, "out")
Signature(out, x, out)
}
}
}
assertEquals("A parameter may not be used twice in a signature!", thrown.message)
}
@Test
fun opSignatureDefaultValueMustHaveCorrectShape() {
val thrown = assertThrows<java.lang.IllegalArgumentException> {
Namespace("math") {
Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
val out = Output(DataType.NUMERIC, "out")
val x = Input(DataType.NUMERIC, "x")
val y = Arg(DataType.INT, "y") {
defaultValue = x.shape()
}
Signature(x)
}
}
}
assertEquals("Illegal default value for Arg(INT, y). Got x.shape() (org.nd4j.codegen.api.TensorShapeValue)", thrown.message)
}
@Test
fun opSignatureDefaultValue() {
Namespace("math") {
Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
val out = Output(DataType.NUMERIC, "out")
val x = Input(DataType.NUMERIC, "x")
val y = Arg(DataType.INT, "y") {
defaultValue = 2
}
Signature(x)
}
}
}
@Test
fun opSignatureDefaultValueMustHaveCorrectDataType() {
val thrown = assertThrows<java.lang.IllegalArgumentException> {
Namespace("math") {
Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
val out = Output(DataType.NUMERIC, "out")
val x = Input(DataType.NUMERIC, "x")
val y = Arg(DataType.INT, "y") {
defaultValue = 1.7
}
Signature(x)
}
}
}
assertEquals("Illegal default value for Arg(INT, y). Got 1.7 (java.lang.Double)", thrown.message)
}
@Test
fun opSignatureDefaultInputReference() {
val thrown = assertThrows<java.lang.IllegalStateException> {
Namespace("math") {
Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
val out = Output(DataType.NUMERIC, "out")
val x = Input(DataType.NUMERIC, "x")
val z = Input(DataType.NUMERIC, "z")
val y = Arg(DataType.INT, "y") {
count = AtLeast(1)
defaultValue = z.shape()
}
Signature(x)
}
}
}
assertEquals("foo: Signature(x) does not cover all parameters! Missing: z, y", thrown.message)
}
@Test
fun opSignatureDefaultOutputReference() {
val thrown = assertThrows<java.lang.IllegalStateException> {
Namespace("math") {
Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
val out = Output(DataType.NUMERIC, "out")
val x = Input(DataType.NUMERIC, "x")
val y = Arg(DataType.INT, "y") {
count = AtLeast(1)
defaultValue = out.shape()
}
Signature(x)
}
}
}
assertEquals("foo: Signature(x) does not cover all parameters! Missing: y", thrown.message)
}
@Test
fun opSignatureDefaultWithOutputReference() {
Namespace("math") {
Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
val out = Output(DataType.NUMERIC, "out")
val x = Input(DataType.NUMERIC, "x")
val y = Arg(DataType.INT, "y") {
count = AtLeast(1)
defaultValue = out.shape()
}
Signature(out, x)
}
}
}
@Test
fun opSignatureDefaultReferenceChain() {
val thrown = assertThrows<java.lang.IllegalStateException> {
Namespace("math") {
Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
val out = Output(DataType.NUMERIC, "out")
val x = Input(DataType.NUMERIC, "x")
val z = Input(DataType.NUMERIC, "z")
val u = Input(DataType.NUMERIC, "u") { defaultValue = z }
val v = Input(DataType.NUMERIC, "v") { defaultValue = u }
val y = Arg(DataType.INT, "y") {
count = AtLeast(1)
defaultValue = v.shape()
}
Signature(x)
}
}
}
assertEquals("foo: Signature(x) does not cover all parameters! Missing: z, u, v, y", thrown.message)
}
@Test
fun opSignatureDefaultReferenceChainWorking() {
Namespace("math") {
Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
val out = Output(DataType.NUMERIC, "out")
val x = Input(DataType.NUMERIC, "x")
val z = Input(DataType.NUMERIC, "z") { defaultValue = x }
val u = Input(DataType.NUMERIC, "u") { defaultValue = z }
val v = Input(DataType.NUMERIC, "v") { defaultValue = u }
val y = Arg(DataType.INT, "y") {
count = AtLeast(1)
defaultValue = v.shape()
}
Signature(x)
}
}
}
@Test
fun opSignatureShorthandAllParams() {
Namespace("math") {
Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
val out = Output(DataType.NUMERIC, "out")
val x = Input(DataType.NUMERIC, "x")
val z = Input(DataType.NUMERIC, "z") { defaultValue = x }
val u = Input(DataType.NUMERIC, "u") { defaultValue = z }
val v = Input(DataType.NUMERIC, "v") { defaultValue = u }
val y = Arg(DataType.INT, "y") {
count = AtLeast(1)
defaultValue = v.shape()
}
AllParamSignature()
}
}
}
@Test
fun opSignatureNullDefaults() {
Namespace("math") {
Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
val out = Output(DataType.NUMERIC, "out")
val x = Input(DataType.NUMERIC, "x")
val y = Arg(DataType.INT, "y") {
count = AtLeast(1)
defaultValue = null
}
AllDefaultsSignature()
}
}
}
@Test
fun opSignatureNullDefaultsForInputs() {
Namespace("math") {
Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
val out = Output(DataType.NUMERIC, "out")
val x = Input(DataType.NUMERIC, "x") { defaultValue = null }
AllDefaultsSignature()
}
}
}
@Test
fun opSignatureShorthandDefaultParams() {
Namespace("math") {
Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
val out = Output(DataType.NUMERIC, "out")
val x = Input(DataType.NUMERIC, "x")
val z = Input(DataType.NUMERIC, "z") { defaultValue = x }
val u = Input(DataType.NUMERIC, "u") { defaultValue = z }
val v = Input(DataType.NUMERIC, "v") { defaultValue = u }
val y = Arg(DataType.INT, "y") {
count = AtLeast(1)
defaultValue = v.shape()
}
AllDefaultsSignature()
}
}
}
@Test
fun opSignatureSupportsArrayDefaults() {
Namespace("math") {
Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
val out = Output(DataType.NUMERIC, "out")
val x = Input(DataType.NUMERIC, "x")
val y = Arg(DataType.INT, "y") { count = AtLeast(0); defaultValue = intArrayOf() }
val z = Arg(DataType.FLOATING_POINT, "z") { count = Range(2, 5); defaultValue = doubleArrayOf(1.0, 2.0, 3.0) }
val a = Arg(DataType.BOOL, "a") { count = AtLeast(1); defaultValue = booleanArrayOf(true) }
AllDefaultsSignature()
}
}
}
@Test
fun opSignatureSupportsArrayDefaultsAtLeast() {
val thrown = assertThrows<java.lang.IllegalArgumentException> {
Namespace("math") {
Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
Output(DataType.NUMERIC, "out")
Input(DataType.NUMERIC, "x")
Arg(DataType.INT, "y") { count = AtLeast(1); defaultValue = intArrayOf() }
}
}
}
assertEquals("Illegal default value for Arg(INT, y){ count = AtLeast(min=1) }. Got [] ([I)", thrown.message)
}
@Test
fun opSignatureSupportsArrayDefaultsAtMost() {
val thrown = assertThrows<java.lang.IllegalArgumentException> {
Namespace("math") {
Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
Output(DataType.NUMERIC, "out")
Input(DataType.NUMERIC, "x")
Arg(DataType.INT, "y") { count = AtMost(1); defaultValue = intArrayOf(1, 2) }
}
}
}
assertEquals("Illegal default value for Arg(INT, y){ count = AtMost(max=1) }. Got [1, 2] ([I)", thrown.message)
}
@Test
fun opSignatureSupportsArrayDefaultsRange() {
val thrown = assertThrows<java.lang.IllegalArgumentException> {
Namespace("math") {
Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
Output(DataType.NUMERIC, "out")
Input(DataType.NUMERIC, "x")
Arg(DataType.INT, "y") { count = Range(3, 7); defaultValue = intArrayOf() }
}
}
}
assertEquals("Illegal default value for Arg(INT, y){ count = Range(from=3, to=7) }. Got [] ([I)", thrown.message)
}
@Test
fun opSignatureSupportsArrayDefaultsExactly() {
val thrown = assertThrows<java.lang.IllegalArgumentException> {
Namespace("math") {
Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
Output(DataType.NUMERIC, "out")
Input(DataType.NUMERIC, "x")
Arg(DataType.INT, "y") { count = Exactly(7); defaultValue = intArrayOf() }
}
}
}
assertEquals("Illegal default value for Arg(INT, y){ count = Exactly(count=7) }. Got [] ([I)", thrown.message)
}
@Test
fun opSignatureHasExpectedNumberOfSignatures() {
Namespace("math") {
val op = Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
val out = Output(DataType.NUMERIC, "out")
val x = Input(DataType.NUMERIC, "x")
val y = Arg(DataType.INT, "y") { count = AtLeast(0); defaultValue = intArrayOf() }
AllParamSignature()
AllDefaultsSignature()
}
assertEquals(2, op.signatures.size)
}
}
@Test
fun opSignatureHasExpectedNumberOfSignaturesWithOutput() {
Namespace("math") {
val op = Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
val out = Output(DataType.NUMERIC, "out")
val x = Input(DataType.NUMERIC, "x")
val y = Arg(DataType.INT, "y") { count = AtLeast(0); defaultValue = intArrayOf() }
AllParamSignature(true)
AllDefaultsSignature(true)
}
assertEquals(4, op.signatures.size)
}
}
@Test
fun opSignatureHasExpectedNumberOfSignaturesNoDefaults() {
Namespace("math") {
val op = Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
val out = Output(DataType.NUMERIC, "out")
val x = Input(DataType.NUMERIC, "x")
val y = Arg(DataType.INT, "y") { count = AtLeast(0); }
AllParamSignature()
AllDefaultsSignature()
}
assertEquals(1, op.signatures.size)
}
}
@Test
fun opSignatureHasExpectedNumberOfSignaturesWithOutputNoDefaults() {
Namespace("math") {
val op = Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
val out = Output(DataType.NUMERIC, "out")
val x = Input(DataType.NUMERIC, "x")
val y = Arg(DataType.INT, "y") { count = AtLeast(0); }
AllParamSignature(true)
AllDefaultsSignature(true)
}
assertEquals(2, op.signatures.size)
}
}
@Test
fun argEnum() {
Namespace("math") {
Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
val out = Output(DataType.NUMERIC, "out")
val x = Input(DataType.NUMERIC, "x")
val y = Arg(DataType.ENUM, "y") { possibleValues = listOf("FOO", "BAR", "BAZ"); description = "Enums require some docs" }
}
}
}
@Test
fun argEnumDefaultValue() {
Namespace("math") {
Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
val out = Output(DataType.NUMERIC, "out")
val x = Input(DataType.NUMERIC, "x")
val y = Arg(DataType.ENUM, "y") {
possibleValues = listOf("FOO", "BAR", "BAZ")
defaultValue = "BAZ"
description = "Enums require some docs"
}
AllDefaultsSignature()
}
}
}
@Test
fun argEnumBadDefaultValue() {
val thrown = assertThrows<java.lang.IllegalArgumentException> {
Namespace("math") {
Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
val out = Output(DataType.NUMERIC, "out")
val x = Input(DataType.NUMERIC, "x")
val y = Arg(DataType.ENUM, "y") {
possibleValues = listOf("FOO", "BAR", "BAZ")
defaultValue = "SPAM"
}
AllDefaultsSignature()
}
}
}
assertEquals("Illegal default value for Arg(ENUM(FOO, BAR, BAZ), y). Got SPAM (java.lang.String)", thrown.message)
}
@Test
fun argEnumEmptyPossibleValues() {
val thrown = assertThrows<java.lang.IllegalArgumentException> {
Namespace("math") {
Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
val out = Output(DataType.NUMERIC, "out")
val x = Input(DataType.NUMERIC, "x")
val y = Arg(DataType.ENUM, "y") {
possibleValues = listOf()
}
}
}
}
assertEquals("Arg(ENUM(null), y): Can not set empty possibleValues.", thrown.message)
}
@Test
fun argEnumBadType() {
val thrown = assertThrows<java.lang.IllegalArgumentException> {
Namespace("math") {
Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
val out = Output(DataType.NUMERIC, "out")
val x = Input(DataType.NUMERIC, "x")
val y = Arg(DataType.NUMERIC, "y") {
possibleValues = listOf("FOO", "BAR", "BAZ")
defaultValue = "SPAM"
}
AllDefaultsSignature()
}
}
}
assertEquals("Arg(NUMERIC, y): Can not set possibleValues on non ENUM typed Arg.", thrown.message)
}
@Test
fun argEnumBadCount() {
val thrown = assertThrows<java.lang.IllegalArgumentException> {
Namespace("math") {
Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
val out = Output(DataType.NUMERIC, "out")
val x = Input(DataType.NUMERIC, "x")
val y = Arg(DataType.ENUM, "y") {
count = AtLeast(1)
possibleValues = listOf("FOO", "BAR", "BAZ")
}
AllDefaultsSignature()
}
}
}
assertEquals("Arg(ENUM(null), y): ENUM typed Arg can not be array", thrown.message)
}
@Test
fun argEnumGoodCount() {
Namespace("math") {
Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
val out = Output(DataType.NUMERIC, "out")
val x = Input(DataType.NUMERIC, "x")
val y = Arg(DataType.ENUM, "y") {
count = Exactly(1)
possibleValues = listOf("FOO", "BAR", "BAZ")
description = "Enums require some docs"
}
AllDefaultsSignature()
}
}
}
@Test
fun onlyValidParametersAreUsedInSignaturesBadCase() {
val thrown = assertThrows<IllegalArgumentException> {
val mixin = Mixin("Bar") {
Input(DataType.NUMERIC, "a")
Arg(DataType.BOOL, "b")
}
Namespace("math") {
Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
val out = Output(DataType.NUMERIC, "out")
val x = Input(DataType.NUMERIC, "x")
Signature(out, x, mixin.input("a"), mixin.arg("b"))
}
}
}
assertEquals("You can only use parameters in a signature that are actually defined in Op(opName=foo, libnd4jOpName=foo, isAbstract=false)! Did you forget to useMixin(...) a mixin?", thrown.message)
}
@Test
fun onlyValidParametersAreUsedInSignaturesGoodCase() {
val mixin = Mixin("Bar") {
Input(DataType.NUMERIC, "a")
Arg(DataType.BOOL, "b")
}
Namespace("math") {
Op("foo", mixin) {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
val out = Output(DataType.NUMERIC, "out")
val x = Input(DataType.NUMERIC, "x")
Signature(out, x, mixin.input("a"), mixin.arg("b"))
}
}
}
@Test
fun lastMixinDefinitionWins(){
val mixin = Mixin("Bar") {
Input(DataType.NUMERIC, "a")
Arg(DataType.BOOL, "b")
}
Namespace("math") {
val op = Op("foo", mixin) {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
Output(DataType.NUMERIC, "out")
Input(DataType.NUMERIC, "a") { count=Exactly(1)}
}
assertNotSame(mixin.inputs.find { it.name == "a"}, op.inputs.find { it.name == "a"})
}
}
@Test
fun lastMixinDefinitionWins2(){
val mixin = Mixin("Bar") {
Input(DataType.NUMERIC, "a")
Arg(DataType.BOOL, "b")
}
Namespace("math") {
val op = Op("foo") {
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
Output(DataType.NUMERIC, "out")
Input(DataType.NUMERIC, "a")
useMixin(mixin)
}
assertSame(mixin.inputs.find { it.name == "a"}, op.inputs.find { it.name == "a"})
}
}
@Test
fun mixinDoesOnlyOverwritePropertiesIfSetNoneSetCase(){
val mixin = Mixin("Bar") {
Input(DataType.NUMERIC, "a")
Arg(DataType.BOOL, "b")
}
Namespace("math") {
val op = Op("foo") {
javaPackage = "fooPackage"
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
Output(DataType.NUMERIC, "out")
Input(DataType.NUMERIC, "a")
useMixin(mixin)
}
assertEquals("fooPackage", op.javaPackage)
}
}
@Test
fun mixinDoesOnlyOverwritePropertiesIfSetSetCase(){
val mixin = Mixin("Bar") {
javaPackage = "MixinPackage"
Input(DataType.NUMERIC, "a")
Arg(DataType.BOOL, "b")
}
Namespace("math") {
val op = Op("foo") {
javaPackage = "fooPackage"
Doc(Language.ANY, DocScope.ALL) { "Some Documentation" }
Output(DataType.NUMERIC, "out")
Input(DataType.NUMERIC, "a")
useMixin(mixin)
}
assertEquals("MixinPackage", op.javaPackage)
}
}
@Test
fun mixinDoesOnlyOverwritePropertiesIfSetNoneSetCaseOnMixins(){
val mixin = Mixin("Bar") {
Input(DataType.NUMERIC, "a")
Arg(DataType.BOOL, "b")
}
val op = Mixin("foo") {
javaPackage = "fooPackage"
useMixin(mixin)
}
assertEquals("fooPackage", op.javaPackage)
}
@Test
fun mixinDoesOnlyOverwritePropertiesIfSetSetCaseOnMixins(){
val mixin = Mixin("Bar") {
javaPackage = "MixinPackage"
Input(DataType.NUMERIC, "a")
Arg(DataType.BOOL, "b")
}
val op = Mixin("foo") {
javaPackage = "fooPackage"
useMixin(mixin)
}
assertEquals("MixinPackage", op.javaPackage)
}
}
@@ -0,0 +1,58 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.nd4j.codegen.ops
import org.junit.jupiter.api.Test
/**
* Test that each Namespace actually constructs properly.
*
* This is allows us to utilize run-time consistency checks during the build process - if tests are enabled.
*/
class ConstructionTest {
@Test
fun bitwise() { Bitwise() }
@Test
fun random() { Random() }
@Test
fun math() { Math() }
@Test
fun base() { SDBaseOps() }
@Test
fun loss() { SDLoss() }
@Test
fun cnn() { SDCNN() }
@Test
fun rnn() { SDRNN() }
@Test
fun image() { SDImage() }
@Test
fun nn() { NN() }
}