This is an automated email from the ASF dual-hosted git repository.

mboehm7 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/systemds.git


The following commit(s) were added to refs/heads/master by this push:
     new eeffef6  [SYSTEMDS-2812] Added conv1d layer to nn library (via conv2d)
eeffef6 is described below

commit eeffef63cd8e2a5563c31f067cfe21e73a08e32d
Author: sebwrede <[email protected]>
AuthorDate: Sun Jan 31 00:28:02 2021 +0100

    [SYSTEMDS-2812] Added conv1d layer to nn library (via conv2d)
    
    Closes #1174.
---
 scripts/nn/layers/conv1d.dml                       | 100 +++++++++
 .../sysds/test/functions/dnn/Conv1DTest.java       | 247 +++++++++++++++++++++
 .../functions/tensor/Conv1DBackwardDataTest.dml    |  52 +++++
 .../functions/tensor/Conv1DBackwardFilterTest.dml  |  52 +++++
 src/test/scripts/functions/tensor/Conv1DTest.dml   |  53 +++++
 5 files changed, 504 insertions(+)

diff --git a/scripts/nn/layers/conv1d.dml b/scripts/nn/layers/conv1d.dml
new file mode 100644
index 0000000..f1beeeb
--- /dev/null
+++ b/scripts/nn/layers/conv1d.dml
@@ -0,0 +1,100 @@
+#-------------------------------------------------------------
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+source("scripts/nn/util.dml") as util
+
+forward = function(matrix[double] input, matrix[double] filter, int pad, int 
stride,
+  int numInput, int numChannels, int inputWidth, int numFilters, int 
filterSize)
+  return (matrix[double] out)
+{
+  /*
+  * Computes the forward pass for a 1D spatial convolutional layer
+  * by reshaping the input to fit conv2d.
+  *
+  * Inputs:
+  *  - input: Inputs, of shape (N, C*W).
+  *  - filter: Weights, of shape (F, C*W).
+  *  - pad: Padding for left and right sides of input elements.
+  *  - stride: Stride for moving filter.
+  *  - numInput: Number of input elements N
+  *  - numChannels: Number of input channels (dimensionality of input depth).
+  *  - inputWidth: Input width.
+  *  - numFilters: Number of filters F
+  *  - filterSize: Filter width.
+  *
+  * Outputs:
+  *  - out: Outputs, of shape (N, F*Wout).
+  */
+  out = conv2d(input, filter, padding=[0,pad], stride=[1, stride], 
+         input_shape=[numInput,numChannels,1,inputWidth], 
filter_shape=[numFilters,numChannels,1,filterSize])
+}
+
+backward_data = function(matrix[double] filter, matrix[double] dout, int pad, 
int stride,
+  int numInput, int numChannels, int inputWidth, int numFilters, int 
filterSize)
+  return (matrix[double] out)
+{
+  /*
+  * Computes the backward pass regarding the input data for a 1D spatial 
convolutional layer
+  * by reshaping the input to fit conv2d backward data pass.
+  *
+  * Inputs:
+  *  - filter: Weights, of shape (F, C*W).
+  *  - dout: Output of the forward pass
+  *  - pad: Padding for left and right sides of input elements.
+  *  - stride: Stride for moving filter.
+  *  - numInput: Number of input elements N
+  *  - numChannels: Number of input channels (dimensionality of input depth).
+  *  - inputWidth: Input width.
+  *  - numFilters: Number of filters F
+  *  - filterSize: Filter width.
+  *
+  * Outputs:
+  *  - out: gradients based on the input data of the convolution.
+  */
+  out = conv2d_backward_data(filter, dout, stride=[1,stride], padding=[0,pad], 
+         input_shape=[numInput,numChannels,1,inputWidth], 
filter_shape=[numFilters,numChannels,1,filterSize])
+}
+
+backward_filter = function(matrix[double] input, matrix[double] dout, int pad, 
int stride, 
+  int numInput, int numChannels, int inputWidth, int numFilters, int 
filterSize)
+  return (matrix[double] out)
+{
+  /*
+  * Computes the backward pass regarding the filter for a 1D spatial 
convolutional layer
+  * by reshaping the input to fit conv2d backward data pass.
+  *
+  * Inputs:
+  *  - input: Inputs, of shape (N, C*W).
+  *  - dout: Output of the forward pass
+  *  - pad: Padding for left and right sides of input elements.
+  *  - stride: Stride for moving filter.
+  *  - numInput: Number of input elements N
+  *  - numChannels: Number of input channels (dimensionality of input depth).
+  *  - inputWidth: Input width.
+  *  - numFilters: Number of filters F
+  *  - filterSize: Filter width.
+  *
+  * Outputs:
+  *  - out: gradients bsaed on the filter of the convolution.
+  */
+  out = conv2d_backward_filter(input, dout, stride=[1,stride], 
padding=[0,pad], 
+         input_shape=[numInput,numChannels,1,inputWidth], 
filter_shape=[numFilters,numChannels,1,filterSize])
+}
diff --git a/src/test/java/org/apache/sysds/test/functions/dnn/Conv1DTest.java 
b/src/test/java/org/apache/sysds/test/functions/dnn/Conv1DTest.java
new file mode 100644
index 0000000..9f5add5
--- /dev/null
+++ b/src/test/java/org/apache/sysds/test/functions/dnn/Conv1DTest.java
@@ -0,0 +1,247 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ */
+package org.apache.sysds.test.functions.dnn;
+
+import java.util.HashMap;
+import java.util.stream.IntStream;
+
+import org.junit.Test;
+import org.apache.sysds.api.DMLScript;
+import org.apache.sysds.common.Types.ExecMode;
+import org.apache.sysds.lops.LopProperties.ExecType;
+import org.apache.sysds.runtime.matrix.data.MatrixValue.CellIndex;
+import org.apache.sysds.test.AutomatedTestBase;
+import org.apache.sysds.test.TestConfiguration;
+import org.apache.sysds.test.TestUtils;
+
+public class Conv1DTest extends AutomatedTestBase
+{
+       private final static String TEST_NAME_1 = "Conv1DTest";
+       private final static String TEST_NAME_2 = "Conv1DBackwardDataTest";
+       private final static String TEST_NAME_3 = "Conv1DBackwardFilterTest";
+       private final static String TEST_DIR = "functions/tensor/";
+       private final static String TEST_CLASS_DIR = TEST_DIR + 
Conv1DTest.class.getSimpleName() + "/";
+       private final static double epsilon=0.0000000001;
+
+       @Override
+       public void setUp() {
+               TestUtils.clearAssertionInformation();
+               addTestConfiguration(TEST_NAME_1, new 
TestConfiguration(TEST_CLASS_DIR, TEST_NAME_1, new String[] {"output"}));
+               addTestConfiguration(TEST_NAME_2, new 
TestConfiguration(TEST_CLASS_DIR, TEST_NAME_2, new String[] {"output"}));
+               addTestConfiguration(TEST_NAME_3, new 
TestConfiguration(TEST_CLASS_DIR, TEST_NAME_3, new String[] {"output"}));
+       }
+
+       @Test
+       public void testSimpleConv1DDenseSingleBatchSingleChannelSingleFilter(){
+               int numImg = 1; int imgSize = 4; int numChannels = 1; int 
numFilters = 1; int filterSize = 2; int stride = 1; int pad = 0;
+               HashMap<CellIndex, Double> expected = new HashMap<>();
+               expected.put(new CellIndex(1,1), 3.0);
+               expected.put(new CellIndex(1,2), 5.0);
+               expected.put(new CellIndex(1,3), 7.0);
+               runConv1DTest(ExecType.CP, imgSize, numImg, numChannels, 
numFilters, filterSize, stride, pad, expected, TEST_NAME_1);
+       }
+
+       @Test
+       public void testConv1DDense1() {
+               int numImg = 5; int imgSize = 3; int numChannels = 3; int 
numFilters = 3; int filterSize = 2; int stride = 1; int pad = 0;
+               HashMap<CellIndex, Double> expected = new HashMap<>();
+               fillExpected(expected, 1, 6, 21.0, 39.0);
+               fillExpected(expected, 2, 6, 75.0, 93.0);
+               fillExpected(expected, 3, 6, 129.0, 147.0);
+               fillExpected(expected, 4, 6, 183.0, 201.0);
+               fillExpected(expected, 5, 6, 237.0, 255.0);
+
+               runConv1DTest(ExecType.CP, imgSize, numImg, numChannels, 
numFilters, filterSize, stride, pad, expected, TEST_NAME_1);
+       }
+
+       @Test
+       public void testConv1DDense2() {
+               int numImg = 1; int imgSize = 10; int numChannels = 4; int 
numFilters = 3; int filterSize = 4; int stride = 2; int pad = 0;
+               HashMap<CellIndex, Double> expected = new HashMap<>();
+               fillExpectedRepeated(expected, 3, new 
double[]{136.,264.,392.,520.},1);
+               runConv1DTest(ExecType.CP, imgSize, numImg, numChannels, 
numFilters, filterSize, stride, pad, expected, TEST_NAME_1);
+       }
+
+       @Test
+       public void testConv1DDense3() {
+               int numImg = 1; int imgSize = 10; int numChannels = 4; int 
numFilters = 3; int filterSize = 4; int stride = 2; int pad = 1;
+               HashMap<CellIndex, Double> expected = new HashMap<>();
+               fillExpectedRepeated(expected, 3, new 
double[]{78.,200.,328.,456.,414.},1);
+               runConv1DTest(ExecType.CP, imgSize, numImg, numChannels, 
numFilters, filterSize, stride, pad, expected, TEST_NAME_1);
+       }
+
+       @Test
+       public void testConv1DDense4() {
+               int numImg = 3; int imgSize = 10; int numChannels = 1; int 
numFilters = 3; int filterSize = 2; int stride = 2; int pad = 1;
+               HashMap<CellIndex, Double> expected = new HashMap<>();
+               fillExpectedRepeated(expected,3,new 
double[]{1.,5.,9.,13.,17.,10.},1);
+               fillExpectedRepeated(expected,3,new 
double[]{11.,25.,29.,33.,37.,20.},2);
+               fillExpectedRepeated(expected,3,new 
double[]{21.,45.,49.,53.,57.,30.},3);
+               runConv1DTest(ExecType.CP, imgSize, numImg, numChannels, 
numFilters, filterSize, stride, pad, expected, TEST_NAME_1);
+       }
+
+       @Test
+       public void testConv1DDense5() {
+               int numImg = 3; int imgSize = 8; int numChannels = 2; int 
numFilters = 3; int filterSize = 3; int stride = 1; int pad = 2;
+               HashMap<CellIndex, Double> expected = new HashMap<>();
+               fillExpectedRepeated(expected,3,new 
double[]{3.,10.,21.,33.,45.,57.,69.,81.,58.,31.},1);
+               fillExpectedRepeated(expected,3,new 
double[]{35.,74.,117.,129.,141.,153.,165.,177.,122.,63.},2);
+               fillExpectedRepeated(expected,3,new 
double[]{67.,138.,213.,225.,237.,249.,261.,273.,186.,95.},3);
+               runConv1DTest(ExecType.CP, imgSize, numImg, numChannels, 
numFilters, filterSize, stride, pad, expected, TEST_NAME_1);
+       }
+
+       @Test
+       public void testConv1DDense6() {
+               int numImg = 1; int imgSize = 10; int numChannels = 4; int 
numFilters = 3; int filterSize = 4; int stride = 1; int pad = 0;
+               HashMap<CellIndex, Double> expected = new HashMap<>();
+               fillExpectedRepeated(expected,3,new 
double[]{136.,200.,264.,328.,392.,456.,520.},1);
+               runConv1DTest(ExecType.CP, imgSize, numImg, numChannels, 
numFilters, filterSize, stride, pad, expected, TEST_NAME_1);
+       }
+
+       @Test
+       public void testConv1DDense7() {
+               int numImg = 3; int imgSize = 64; int numChannels = 1; int 
numFilters = 3; int filterSize = 2; int stride = 1; int pad = 0;
+               HashMap<CellIndex, Double> expected = new HashMap<>();
+               double[] firstExpected = IntStream.iterate(3,n -> 
n+2).limit(63).mapToDouble(i->(double)i).toArray();
+               double[] secondExpected = IntStream.iterate(131,n -> 
n+2).limit(63).mapToDouble(i->(double)i).toArray();
+               double[] thirdExpected = IntStream.iterate(259,n -> 
n+2).limit(63).mapToDouble(i->(double)i).toArray();
+               fillExpectedRepeated(expected,3,firstExpected,1);
+               fillExpectedRepeated(expected,3,secondExpected,2);
+               fillExpectedRepeated(expected,3,thirdExpected,3);
+               runConv1DTest(ExecType.CP, imgSize, numImg, numChannels, 
numFilters, filterSize, stride, pad, expected, TEST_NAME_1);
+       }
+
+       @Test
+       public void testConv1DDense1SP()
+       {
+               int numImg = 5; int imgSize = 3; int numChannels = 3; int 
numFilters = 6; int filterSize = 2; int stride = 1; int pad = 0;
+               HashMap<CellIndex, Double> expected = new HashMap<>();
+               fillExpected(expected, 1, 12, 21.0, 39.0);
+               fillExpected(expected, 2, 12, 75.0, 93.0);
+               fillExpected(expected, 3, 12, 129.0, 147.0);
+               fillExpected(expected, 4, 12, 183.0, 201.0);
+               fillExpected(expected, 5, 12, 237.0, 255.0);
+               runConv1DTest(ExecType.SPARK, imgSize, numImg, numChannels, 
numFilters, filterSize, stride, pad, expected, TEST_NAME_1);
+       }
+
+       @Test
+       public void testConv1DBackwardDataDense1() {
+               int numImg = 5; int imgSize = 3; int numChannels = 3; int 
numFilters = 3; int filterSize = 1; int stride = 1; int pad = 0;
+               HashMap<CellIndex, Double> expected = new HashMap<>();
+               fillExpectedRepeated(expected,3,new double[]{6.,15.,24.},1);
+               fillExpectedRepeated(expected,3,new double[]{33.,42.,51.},2);
+               fillExpectedRepeated(expected,3,new double[]{60.,69.,78.},3);
+               fillExpectedRepeated(expected,3,new double[]{87.,96.,105.},4);
+               fillExpectedRepeated(expected,3,new double[]{114.,123.,132.},5);
+
+               runConv1DTest(ExecType.CP, imgSize, numImg, numChannels, 
numFilters, filterSize, stride, pad, expected, TEST_NAME_2);
+       }
+
+       @Test
+       public void testConv1DBackwardFilterDense1() {
+               int numImg = 2; int imgSize = 3; int numChannels = 2; int 
numFilters = 3; int filterSize = 1; int stride = 1; int pad = 0;
+               HashMap<CellIndex, Double> expected = new HashMap<>();
+               fillExpectedRepeatedCol(expected,3,new double[]{608.,686.});
+
+               runConv1DTest(ExecType.CP, imgSize, numImg, numChannels, 
numFilters, filterSize, stride, pad, expected, TEST_NAME_3);
+       }
+
+       @Test
+       public void testConv1DBackwardFilterDense2() {
+               int numImg = 2; int imgSize = 3; int numChannels = 2; int 
numFilters = 3; int filterSize = 2; int stride = 1; int pad = 0;
+               HashMap<CellIndex, Double> expected = new HashMap<>();
+               fillExpectedRepeatedCol(expected,3,new 
double[]{680.,888.,784.,992.});
+
+               runConv1DTest(ExecType.CP, imgSize, numImg, numChannels, 
numFilters, filterSize, stride, pad, expected, TEST_NAME_3);
+       }
+
+       private static void fillExpected(HashMap<CellIndex, Double> expected,
+               int rowNum, int rowLength, double value1, double value2)
+       {
+               for ( int m = 1; m <= rowLength; m+=2){
+                       expected.put(new CellIndex(rowNum,m), value1);
+                       expected.put(new CellIndex(rowNum,m+1), value2);
+               }
+       }
+
+       private static void fillExpectedRepeated(HashMap<CellIndex, Double> 
expected,
+               int repetitionNum, double[] values, int row)
+       {
+               int colPointer = 1;
+               for (int i = 1; i <= repetitionNum;i++){
+                       for(double value : values) {
+                               expected.put(new CellIndex(row, colPointer), 
value);
+                               colPointer++;
+                       }
+               }
+       }
+
+       private static void fillExpectedRepeatedCol(HashMap<CellIndex, Double> 
expected,int repetitionRows, double[] values){
+               for ( int i = 1; i <= repetitionRows; i++){
+                       for ( int j = 1; j <= values.length; j++ ){
+                               expected.put(new CellIndex(i,j), values[j-1]);
+                       }
+               }
+       }
+
+       public void runConv1DTest( ExecType et, int imgSize, int numImg, int 
numChannels, int numFilters,
+               int filterSize, int stride, int pad, HashMap<CellIndex, Double> 
expected, String TEST_NAME)
+       {
+               ExecMode platformOld = rtplatform;
+               switch( et ){
+                       case SPARK: rtplatform = ExecMode.SPARK; break;
+                       default: rtplatform = ExecMode.HYBRID; break;
+               }
+               boolean sparkConfigOld = DMLScript.USE_LOCAL_SPARK_CONFIG;
+               if( rtplatform == ExecMode.SPARK )
+                       DMLScript.USE_LOCAL_SPARK_CONFIG = true;
+
+               try
+               {
+                       getAndLoadTestConfiguration(TEST_NAME);
+
+                       String SCRIPT_HOME = SCRIPT_DIR + TEST_DIR + TEST_NAME;
+                       fullDMLScriptName = SCRIPT_HOME + ".dml";
+
+                       programArgs = new String[] {
+                               "-nvargs",
+                               "imgSize=" + imgSize,
+                               "numImg=" + numImg,
+                               "numChannels=" + numChannels,
+                               "numFilters=" + numFilters,
+                               "filterSize=" + filterSize,
+                               "stride=" + stride,
+                               "pad=" + pad,
+                               "output=" + output("output")
+                       };
+
+                       // Run DML
+                       runTest(true, false, null, -1);
+
+                       HashMap<CellIndex, Double> dmlfile = 
readDMLMatrixFromOutputDir("output");
+                       System.out.println(dmlfile.toString());
+                       if ( expected != null)
+                               TestUtils.compareMatrices(dmlfile, expected, 
epsilon, "B-DML", "B-R");
+               }
+               finally {
+                       rtplatform = platformOld;
+                       DMLScript.USE_LOCAL_SPARK_CONFIG = sparkConfigOld;
+               }
+       }
+}
diff --git a/src/test/scripts/functions/tensor/Conv1DBackwardDataTest.dml 
b/src/test/scripts/functions/tensor/Conv1DBackwardDataTest.dml
new file mode 100644
index 0000000..0a86377
--- /dev/null
+++ b/src/test/scripts/functions/tensor/Conv1DBackwardDataTest.dml
@@ -0,0 +1,52 @@
+#-------------------------------------------------------------
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+source("scripts/nn/layers/conv1d.dml") as conv1d
+
+# Build input
+rowBuild = seq(1,$numChannels*$imgSize,$numChannels)
+if ( $numChannels > 1 & $imgSize > 1 ){
+  for ( i in 2:$numChannels ){
+    rowBuild = rbind(rowBuild, seq(i,$numChannels*$imgSize,$numChannels))
+  }
+}
+
+colBuild = rowBuild
+if ( $numImg > 1 ){
+  for ( j in 2:$numImg ){
+    rowBuild = 
seq((j-1)*$imgSize*$numChannels+1,j*$imgSize*$numChannels,$numChannels)
+    if ( $numChannels > 1 ){
+      for ( i in 2:$numChannels ){
+        rowBuild = rbind(rowBuild, 
seq((j-1)*$imgSize*$numChannels+i,j*$numChannels*$imgSize,$numChannels))
+      }
+    }
+    colBuild = cbind(colBuild, rowBuild)
+  }
+}
+
+# Set input variables
+x = t(colBuild)
+w=matrix(1,rows=$numFilters, cols=$numChannels*$filterSize)
+
+output = conv1d::backward_data(w, x, $pad, $stride, $numImg, $numChannels, 
$imgSize, $numFilters, $filterSize)
+
+#Write output
+write(output, $output)
diff --git a/src/test/scripts/functions/tensor/Conv1DBackwardFilterTest.dml 
b/src/test/scripts/functions/tensor/Conv1DBackwardFilterTest.dml
new file mode 100644
index 0000000..7364e93
--- /dev/null
+++ b/src/test/scripts/functions/tensor/Conv1DBackwardFilterTest.dml
@@ -0,0 +1,52 @@
+#-------------------------------------------------------------
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+source("scripts/nn/layers/conv1d.dml") as conv1d
+
+# Build input
+rowBuild = seq(1,$numChannels*$imgSize,$numChannels)
+if ( $numChannels > 1 & $imgSize > 1 ){
+  for ( i in 2:$numChannels ){
+    rowBuild = rbind(rowBuild, seq(i,$numChannels*$imgSize,$numChannels))
+  }
+}
+
+colBuild = rowBuild
+if ( $numImg > 1 ){
+  for ( j in 2:$numImg ){
+    rowBuild = 
seq((j-1)*$imgSize*$numChannels+1,j*$imgSize*$numChannels,$numChannels)
+    if ( $numChannels > 1 ){
+      for ( i in 2:$numChannels ){
+        rowBuild = rbind(rowBuild, 
seq((j-1)*$imgSize*$numChannels+i,j*$numChannels*$imgSize,$numChannels))
+      }
+    }
+    colBuild = cbind(colBuild, rowBuild)
+  }
+}
+
+# Set input variables
+x = t(colBuild)
+w=matrix(1,rows=$numFilters, cols=$numChannels*$filterSize)
+dout = conv1d::forward(x, w, $pad, $stride, $numImg, $numChannels, $imgSize, 
$numFilters, $filterSize)
+
+output = conv1d::backward_filter(x, dout, $pad, $stride, $numImg, 
$numChannels, $imgSize, $numFilters, $filterSize)
+#Write output
+write(output, $output)
diff --git a/src/test/scripts/functions/tensor/Conv1DTest.dml 
b/src/test/scripts/functions/tensor/Conv1DTest.dml
new file mode 100644
index 0000000..5a2f3a7
--- /dev/null
+++ b/src/test/scripts/functions/tensor/Conv1DTest.dml
@@ -0,0 +1,53 @@
+#-------------------------------------------------------------
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+source("scripts/nn/layers/conv1d.dml") as conv1d
+
+# Build input
+rowBuild = seq(1,$numChannels*$imgSize,$numChannels)
+if ( $numChannels > 1 & $imgSize > 1 ){
+  for ( i in 2:$numChannels ){
+    rowBuild = rbind(rowBuild, seq(i,$numChannels*$imgSize,$numChannels))
+  }
+}
+
+colBuild = rowBuild
+if ( $numImg > 1 ){
+  for ( j in 2:$numImg ){
+    rowBuild = 
seq((j-1)*$imgSize*$numChannels+1,j*$imgSize*$numChannels,$numChannels)
+  if ( $numChannels > 1 ){
+    for ( i in 2:$numChannels ){
+      rowBuild = rbind(rowBuild, 
seq((j-1)*$imgSize*$numChannels+i,j*$numChannels*$imgSize,$numChannels))
+    }
+  }
+  colBuild = cbind(colBuild, rowBuild)
+  }
+}
+
+# Set input variables
+x = t(colBuild)
+w=matrix(1,rows=$numFilters, cols=$numChannels*$filterSize)
+
+# Call function
+output = conv1d::forward(x, w, $pad, $stride, $numImg, $numChannels, $imgSize, 
$numFilters, $filterSize)
+
+#Write output
+write(output, $output)

Reply via email to