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

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


The following commit(s) were added to refs/heads/main by this push:
     new c4636bc59b [SYSTEMDS-3018] Edit Extrapolation of U-Net Input
c4636bc59b is described below

commit c4636bc59bfe94c0d9cf1f1c0078ba5616216d29
Author: sebwrede <[email protected]>
AuthorDate: Fri Jan 27 12:57:41 2023 +0100

    [SYSTEMDS-3018] Edit Extrapolation of U-Net Input
    
    The updated version includes both for-loop and parfor-loop versions. The 
update also includes a test.
    
    Closes #1773.
---
 scripts/nn/examples/u-net.dml                      | 168 ++++++++++++++++-----
 .../builtin/part2/BuiltinUNetExtrapolateTest.java  | 117 ++++++++++++++
 .../builtin/BuiltinUNetExtrapolateTest.dml         |  31 ++++
 3 files changed, 281 insertions(+), 35 deletions(-)

diff --git a/scripts/nn/examples/u-net.dml b/scripts/nn/examples/u-net.dml
index 202dda36e8..9110b85ab7 100644
--- a/scripts/nn/examples/u-net.dml
+++ b/scripts/nn/examples/u-net.dml
@@ -47,46 +47,144 @@ source("scripts/utils/image_utils.dml") as img_utils
 *  - C: Number of channels of X
 *  - Hin: Height of each element of X
 *  - Win: Width of each element of X
+*  - useParfor: Use parfor loop if true
 *
 *  Outputs:
 *  - X_extrapolated: X padded with extrapolated data
 *  - input_HW: Height and Width of X_extrapolated
 */
-extrapolate = function(matrix[double] X, int N, int C, int Hin, int Win) 
return (matrix[double] X_extrapolated, int input_HW){
-    input_HW = Hin + 184 # Assuming filter HW 3 and conv stride 1
-    pad_size = 92 # 184 / 2
-
-    X_extrapolated = matrix(0, rows=N, cols=C*input_HW*input_HW)
-
-    for ( i in 1:C ){
-        start_channel = ((i-1) * Hin * Win)+1
-        end_channel = i * Hin * Win
-        original_channel = X[,start_channel:end_channel]
-        # Iterate through the N rows of X each representing a single channel
-        for ( row in 1:N ){
-            img = matrix(original_channel[row], rows=Hin, cols=Win)
-
-            pad_left = t(rev(t(img[,1:pad_size])))
-            pad_right = t(rev(t(img[,(Win-(pad_size-1)):Win])))
-            pad_top = rev(img[1:(pad_size),])
-            pad_bottom = rev(img[(Hin-(pad_size-1)):Hin,])
-            pad_top_left = rev(pad_left[1:(pad_size),])
-            pad_top_right = rev(pad_right[1:(pad_size),])
-            pad_bottom_left = rev(pad_left[(Hin-(pad_size-1)):Hin,])
-            pad_bottom_right = rev(pad_right[(Hin-(pad_size-1)):Hin])
-
-            pad_left_full = rbind(pad_top_left, pad_left, pad_bottom_left)
-            pad_right_full = rbind(pad_top_right, pad_right, pad_bottom_right)
-            pad_center_full = rbind(pad_top, img, pad_bottom)
-
-            modified_channel = cbind(pad_left_full, pad_center_full, 
pad_right_full)
-
-            flat_width = input_HW*input_HW
-            start_col = ((i-1)*flat_width)+1
-            end_col = i*flat_width
-            X_extrapolated[row,start_col:end_col] = matrix(modified_channel, 
rows=1, cols=flat_width)
-        }
-    }
+extrapolate = function(matrix[double] X, int N, int C, int Hin, int Win, 
boolean useParfor = TRUE)
+    return (matrix[double] X_extrapolated, int input_HW){
+  input_HW = Hin + 184 # Assuming filter HW 3 and conv stride 1
+  pad_size = 92 # 184 / 2
+  channel_width = input_HW*input_HW
+
+  if ( useParfor ) {
+    X_extrapolated = extrapolate_images_parfor(X, N, C, Hin, Win, pad_size, 
channel_width)
+  }
+  else {
+    X_extrapolated = extrapolate_images_for(X, N, C, Hin, Win, pad_size, 
channel_width)
+  }
+}
+
+/*
+* Pad input features X with extrapolated data by mirroring.
+* Only the height and width are padded, no extra channels are added.
+* Dimensions changed from (N,C*Hin*Win) to (N,C*(Hin+184)*(Win+184)).
+*
+* For loop is used when looping over rows.
+*
+*  Inputs:
+*  - X: Features to pad
+*  - N: Number of input elements of X
+*  - C: Number of channels of X
+*  - Hin: Height of each element of X
+*  - Win: Width of each element of X
+*  - pad_size: Pad size for each side of the image
+*  - channel_width: Width of a single channel
+*
+*  Outputs:
+*  - X_extrapolated: X padded with extrapolated data
+*/
+extrapolate_images_for = function(matrix[double] X, int N, int C, int Hin, int 
Win, int pad_size, int channel_width)
+    return (matrix[double] X_extrapolated){
+  X_extrapolated = matrix(0, rows=N, cols=C*channel_width)
+  for ( row in 1:N ){
+    img = X[row,]
+    X_extrapolated[row,] = extrapolate_image(img, C, Hin, Win, pad_size, 
channel_width)
+  }
+}
+
+/*
+* Pad input features X with extrapolated data by mirroring.
+* Only the height and width are padded, no extra channels are added.
+* Dimensions changed from (N,C*Hin*Win) to (N,C*(Hin+184)*(Win+184)).
+*
+* Parfor loop is used when looping over rows.
+*
+*  Inputs:
+*  - X: Features to pad
+*  - N: Number of input elements of X
+*  - C: Number of channels of X
+*  - Hin: Height of each element of X
+*  - Win: Width of each element of X
+*  - pad_size: Pad size for each side of the image
+*  - channel_width: Width of a single channel
+*
+*  Outputs:
+*  - X_extrapolated: X padded with extrapolated data
+*/
+extrapolate_images_parfor = function(matrix[double] X, int N, int C, int Hin, 
int Win, int pad_size, int channel_width)
+    return (matrix[double] X_extrapolated){
+  X_extrapolated = matrix(0, rows=N, cols=C*channel_width)
+  parfor ( row in 1:N, check=0 ){
+    img = X[row,]
+    X_extrapolated[row,] = extrapolate_image(img, C, Hin, Win, pad_size, 
channel_width)
+  }
+}
+
+/*
+* Pad input image img with extrapolated data by mirroring.
+* Only the height and width are padded, no extra channels are added.
+* Dimensions changed from (1,C*Hin*Win) to (1,C*(Hin+184)*(Win+184)).
+*
+*
+*  Inputs:
+*  - img: Image of dimension (1,C*Hin*Win) to pad
+*  - C: Number of channels of image
+*  - Hin: Height of image
+*  - Win: Width of image
+*  - pad_size: Pad size for each side of the image
+*  - channel_width: Width of a single channel
+*
+*  Outputs:
+*  - img_extrapolated: image padded with extrapolated data
+*/
+extrapolate_image = function(matrix[double] img, int C, int Hin, int Win, int 
pad_size, int channel_width)
+    return (matrix[double] img_extrapolated){
+  img_extrapolated = matrix(0, rows=1, cols=C*channel_width)
+  for ( i in 1:C ){
+    start_channel = ((i-1) * Hin * Win)+1
+    end_channel = i * Hin * Win
+    channel_slice = matrix(img[1,start_channel:end_channel], rows=Hin, 
cols=Win)
+    start_col = ((i-1)*channel_width)+1
+    end_col = i*channel_width
+    img_extrapolated[1,start_col:end_col] = extrapolate_channel(channel_slice, 
Hin, Win, pad_size, channel_width)
+  }
+}
+
+/*
+* Pad single channel of input image img with extrapolated data by mirroring.
+* Dimensions changed from (Hin,Win) to (1,(Hin+184)*(Win+184)).
+*
+*
+*  Inputs:
+*  - img: Image of dimension (Hin,Win) to pad
+*  - Hin: Height of image
+*  - Win: Width of image
+*  - pad_size: Pad size for each side of the image
+*  - channel_width: Width of a single channel
+*
+*  Outputs:
+*  - channel_extrapolated: channel of image padded with extrapolated data
+*/
+extrapolate_channel = function(matrix[double] img, int Hin, int Win, int 
pad_size, int channel_width)
+    return (matrix[double] channel_extrapolated){
+  pad_left = t(rev(t(img[,1:pad_size])))
+  pad_right = t(rev(t(img[,(Win-(pad_size-1)):Win])))
+  pad_top = rev(img[1:(pad_size),])
+  pad_bottom = rev(img[(Hin-(pad_size-1)):Hin,])
+  pad_top_left = rev(pad_left[1:(pad_size),])
+  pad_top_right = rev(pad_right[1:(pad_size),])
+  pad_bottom_left = rev(pad_left[(Hin-(pad_size-1)):Hin,])
+  pad_bottom_right = rev(pad_right[(Hin-(pad_size-1)):Hin])
+
+  pad_left_full = rbind(pad_top_left, pad_left, pad_bottom_left)
+  pad_right_full = rbind(pad_top_right, pad_right, pad_bottom_right)
+  pad_center_full = rbind(pad_top, img, pad_bottom)
+
+  modified_channel = cbind(pad_left_full, pad_center_full, pad_right_full)
+  channel_extrapolated = matrix(modified_channel, rows=1, cols=channel_width)
 }
 
 /*
diff --git 
a/src/test/java/org/apache/sysds/test/functions/builtin/part2/BuiltinUNetExtrapolateTest.java
 
b/src/test/java/org/apache/sysds/test/functions/builtin/part2/BuiltinUNetExtrapolateTest.java
new file mode 100644
index 0000000000..5c87398b79
--- /dev/null
+++ 
b/src/test/java/org/apache/sysds/test/functions/builtin/part2/BuiltinUNetExtrapolateTest.java
@@ -0,0 +1,117 @@
+/*
+ * 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.builtin.part2;
+
+import org.apache.sysds.common.Types;
+import org.apache.sysds.runtime.meta.MatrixCharacteristics;
+import org.apache.sysds.test.AutomatedTestBase;
+import org.apache.sysds.test.TestConfiguration;
+import org.apache.sysds.test.TestUtils;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class BuiltinUNetExtrapolateTest extends AutomatedTestBase {
+       private final static String TEST_DIR = "functions/builtin/";
+       private final static String TEST_NAME = "BuiltinUNetExtrapolateTest";
+       private final static String TEST_CLASS_DIR = TEST_DIR + 
BuiltinUNetExtrapolateTest.class.getSimpleName() + "/";
+
+       @Override
+       public void setUp() {
+               TestUtils.clearAssertionInformation();
+               addTestConfiguration(TEST_NAME, new 
TestConfiguration(TEST_CLASS_DIR, TEST_NAME, new String[]{"x_out"}));
+       }
+
+       @Test
+       public void extrapolateMultiDimMultiChannel(){
+               int hin = 100;
+               int win = 100;
+               int channels = 3;
+               int rows = 10;
+               runGenericTest(rows, hin, win, channels);
+       }
+
+       @Test
+       public void extrapolateSingleChannel(){
+               int hin = 100;
+               int win = 100;
+               int channels = 1;
+               int rows = 10;
+               runGenericTest(rows, hin, win, channels);
+       }
+
+       @Test
+       public void extrapolateSingleRow(){
+               int hin = 100;
+               int win = 100;
+               int channels = 3;
+               int rows = 1;
+               runGenericTest(rows, hin, win, channels);
+       }
+
+       private void runGenericTest(int rows, int hin, int win, int channels){
+               int cols = hin*win*channels;
+               double[][] input = getRandomMatrix(rows, cols,1,10,0.9,3);
+               int colsExpected = (hin+184)*(win+184)*channels; //padded 
height x padded width x number of channels
+
+               getAndLoadTestConfiguration(TEST_NAME);
+               setExecMode(Types.ExecMode.SINGLE_NODE);
+               String HOME = SCRIPT_DIR + TEST_DIR;
+               fullDMLScriptName = HOME + TEST_NAME + ".dml";
+               String inputName = "features";
+               String outputName = "x_out";
+               String rowsName = "rows";
+               String hinName = "hin";
+               String winName = "win";
+               String channelName = "channels";
+               String useParforName = "useParfor";
+               ArrayList<String> programArgsBase = new 
ArrayList<>(Arrays.asList(
+                       "-nvargs",
+                       inputName + "=" + input(inputName),
+                       rowsName + "=" + rows,
+                       hinName + "=" + hin,
+                       winName + "=" + win,
+                       channelName + "=" + channels
+               ));
+               ArrayList<String> programArgsParfor = new 
ArrayList<>(programArgsBase);
+               programArgsParfor.addAll(List.of(outputName + "=" + 
output(outputName), useParforName + "=" + "TRUE"));
+               ArrayList<String> programArgsFor = new 
ArrayList<>(programArgsBase);
+               programArgsFor.addAll(List.of(outputName + "=" + 
expected(outputName), useParforName + "=" + "FALSE"));
+               programArgs = programArgsParfor.toArray(new String[8]);
+               writeInputMatrixWithMTD(inputName,input,false);
+               runTest(true, EXCEPTION_NOT_EXPECTED, null, -1);
+
+               MatrixCharacteristics mc = readDMLMetaDataFile(outputName);
+               Assert.assertEquals(
+                       "Number of rows should be equal to expected number of 
rows",
+                       rows, mc.getRows());
+               Assert.assertEquals(
+                       "Number of cols should be equal to expected number of 
cols",
+                       colsExpected, mc.getCols());
+
+               programArgs = programArgsFor.toArray(new String[8]);
+               runTest(true, EXCEPTION_NOT_EXPECTED, null, -1);
+
+               compareResults(1e-9,"parfor", "for");
+       }
+}
diff --git a/src/test/scripts/functions/builtin/BuiltinUNetExtrapolateTest.dml 
b/src/test/scripts/functions/builtin/BuiltinUNetExtrapolateTest.dml
new file mode 100644
index 0000000000..b4fbb37fb8
--- /dev/null
+++ b/src/test/scripts/functions/builtin/BuiltinUNetExtrapolateTest.dml
@@ -0,0 +1,31 @@
+#-------------------------------------------------------------
+#
+# 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/examples/u-net.dml") as UNet
+
+X = read($features)
+numRows = $rows
+numChannels = $channels
+hin = $hin
+win = $win
+
+X_extrapolated = UNet::extrapolate(X, numRows, numChannels, hin, win, 
$useParfor)
+write(X_extrapolated, $x_out)

Reply via email to