diff --git a/scripts/builtin/img_mirror_linearized.dml b/scripts/builtin/img_mirror_linearized.dml new file mode 100644 index 00000000000..3a2a7049b77 --- /dev/null +++ b/scripts/builtin/img_mirror_linearized.dml @@ -0,0 +1,78 @@ +#------------------------------------------------------------- +# +# 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. +# +#------------------------------------------------------------- + +# This function has the same functionality with img_mirror but it handles multiple images at +# the same time. Each row of the input and output matrix represents a linearized image/matrix +# It flips an image on the X (horizontal) or Y (vertical) axis. +# INPUT: +# ----------------------------------------------------------------------------------------- +# img_matrix Input matrix/image (every row represents a linearized matrix/image) +# horizontal_axis flip either in X or Y axis +# original_rows number of rows in the original 2-D images +# original_cols number of cols in the original 2-D images +# ----------------------------------------------------------------------------------------- +# +# OUTPUT: +# ----------------------------------------------------------------------------------------- +# R Output matrix/image (every row represents a linearized matrix/image) +# ----------------------------------------------------------------------------------------- + +m_img_mirror_linearized = function(matrix[double] img_matrix, Boolean horizontal_axis, +Integer original_rows, Integer original_cols) return (matrix[double] R) { + n = ncol(img_matrix); + R = matrix(0, rows=nrow(img_matrix), cols=n); + rows = original_rows; + cols = original_cols; + + if (horizontal_axis) { + parfor (i in seq(1, (rows %/% 2) * cols, cols),check=0) { + start = i; + end = i + cols - 1; + mirrorStart = (n - end) + 1; + mirrorEnd = (n - start) + 1; + R[, start:end] = img_matrix[, mirrorStart:mirrorEnd]; + R[, mirrorStart:mirrorEnd] = img_matrix[, start:end]; + } + if (rows %% 2 == 1) { + midStart = ((rows %/% 2)) * cols + 1; + midEnd = midStart + cols - 1; + R[, midStart:midEnd] = img_matrix[, midStart:midEnd]; + } + } + else { + offset = 1; + while (offset <= n) { + end = min(n, offset + cols - 1); + reversed_sub_matrix = matrix(0, rows=nrow(img_matrix), cols=cols); + idx = 1; + for (j in offset:end) { + reversed_sub_matrix[, cols - idx + 1] = img_matrix[, j]; + idx = idx + 1; + } + R[, offset:end] = reversed_sub_matrix; + offset = end + 1; + } + } +} + + + + diff --git a/src/main/java/org/apache/sysds/common/Builtins.java b/src/main/java/org/apache/sysds/common/Builtins.java index 2243eeb963a..5541c53bc55 100644 --- a/src/main/java/org/apache/sysds/common/Builtins.java +++ b/src/main/java/org/apache/sysds/common/Builtins.java @@ -155,6 +155,7 @@ public enum Builtins { HYPERBAND("hyperband", true), IFELSE("ifelse", false), IMG_MIRROR("img_mirror", true), + IMG_MIRROR_LINEARIZED("img_mirror_linearized", true), IMG_BRIGHTNESS("img_brightness", true), IMG_CROP("img_crop", true), IMG_TRANSFORM("img_transform", true), diff --git a/src/test/java/org/apache/sysds/test/functions/builtin/part1/BuiltinImageMirrorLinearizedTest.java b/src/test/java/org/apache/sysds/test/functions/builtin/part1/BuiltinImageMirrorLinearizedTest.java new file mode 100644 index 00000000000..ea449254305 --- /dev/null +++ b/src/test/java/org/apache/sysds/test/functions/builtin/part1/BuiltinImageMirrorLinearizedTest.java @@ -0,0 +1,129 @@ +/* + * 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.part1; + +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.apache.sysds.common.Types.ExecMode; +import org.apache.sysds.common.Types.ExecType; +import org.apache.sysds.runtime.matrix.data.MatrixValue; +import org.apache.sysds.test.AutomatedTestBase; +import org.apache.sysds.test.TestConfiguration; +import org.apache.sysds.test.TestUtils; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; + +@RunWith(Parameterized.class) +@net.jcip.annotations.NotThreadSafe +public class BuiltinImageMirrorLinearizedTest extends AutomatedTestBase { + + private final static String TEST_NAME_LINEARIZED = "image_mirror_linearized"; + private final static String TEST_DIR = "functions/builtin/"; + private final static String TEST_CLASS_DIR = TEST_DIR + BuiltinImageMirrorLinearizedTest.class.getSimpleName() + "/"; + private final static double eps = 1e-10; + private final static double spSparse = 0.05; + private final static double spDense = 0.5; + + @Parameterized.Parameter() + public int img_rows; + @Parameterized.Parameter(1) + public int img_cols; + @Parameterized.Parameter(2) + public int rows; // number of images + public int cols; // Initialized based on img_rows * img_cols + + @Parameterized.Parameters + public static Collection data() { + return Arrays.asList(new Object[][] { + {12, 12, 4}, + {13, 11, 5}, + {64, 64, 32}, + {256, 256, 5}, + {256, 253, 5}, + {1024, 1024, 5}, + {1024, 1048, 5} + }); + } + + @Override + public void setUp() { + cols = img_rows * img_cols; + addTestConfiguration(TEST_NAME_LINEARIZED, new TestConfiguration(TEST_CLASS_DIR, TEST_NAME_LINEARIZED, new String[]{"B_x", "B_y"})); + } + + @Test + public void testImageMirrorLinearized() { + runImageMirrorLinearizedTest(false, ExecType.CP); + } + + @Test + public void testImageMirrorLinearizedSparse() { + runImageMirrorLinearizedTest(true, ExecType.CP); + } + + @Test + @Ignore + public void testImageMirrorLinearizedSP() { + runImageMirrorLinearizedTest(false, ExecType.SPARK); + } + + private void runImageMirrorLinearizedTest(boolean sparse, ExecType instType) { + ExecMode platformOld = setExecMode(instType); + disableOutAndExpectedDeletion(); + + try { + loadTestConfiguration(getTestConfiguration(TEST_NAME_LINEARIZED)); + + double sparsity = sparse ? spSparse : spDense; + String HOME = SCRIPT_DIR + TEST_DIR; + + fullDMLScriptName = HOME + TEST_NAME_LINEARIZED + ".dml"; + programArgs = new String[]{"-nvargs", + "in_file=" + input("A"), + "x_out_reshape_file=" + output("B_x_reshape"), + "y_out_reshape_file=" + output("B_y_reshape"), + "x_out_file=" + output("B_x"), + "y_out_file=" + output("B_y"), + "img_rows=" + img_rows, + "img_cols=" + img_cols + }; + + double[][] A = getRandomMatrix(rows, cols, 0, 255, sparsity, 7); + writeInputMatrixWithMTD("A", A, true); + + runTest(true, false, null, -1); + + HashMap dmlfileLinearizedX = readDMLMatrixFromOutputDir("B_x"); + HashMap dmlfileLinearizedY = readDMLMatrixFromOutputDir("B_y"); + + HashMap dmlfileX = readDMLMatrixFromOutputDir("B_x_reshape"); + HashMap dmlfileY = readDMLMatrixFromOutputDir("B_y_reshape"); + + TestUtils.compareMatrices(dmlfileLinearizedX, dmlfileX, eps, "Stat-DML-LinearizedX", "Stat-DML-X"); + TestUtils.compareMatrices(dmlfileLinearizedY, dmlfileY, eps, "Stat-DML-LinearizedY", "Stat-DML-Y"); + + } finally { + rtplatform = platformOld; + } + } +} diff --git a/src/test/scripts/functions/builtin/image_mirror_linearized.dml b/src/test/scripts/functions/builtin/image_mirror_linearized.dml new file mode 100644 index 00000000000..3501cade9d8 --- /dev/null +++ b/src/test/scripts/functions/builtin/image_mirror_linearized.dml @@ -0,0 +1,43 @@ +#------------------------------------------------------------- +# +# 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. +# +#------------------------------------------------------------- + +input_batched = read($in_file); +num_images = nrow(input_batched); +m_batched = ncol(input_batched); +img_rows = $img_rows; +img_cols = $img_cols; +img_out_flattened_x = matrix(0, rows=num_images, cols=m_batched); +img_out_flattened_y = matrix(0, rows=num_images, cols=m_batched); +input_matrix = matrix(input_batched, rows=num_images, cols=m_batched); +for(i in 1:num_images) { + image_i = matrix(input_matrix[i,], rows=img_rows, cols=img_cols); + img_out_x = img_mirror(image_i, TRUE); + img_out_y = img_mirror(image_i, FALSE); + img_out_flattened_x[i,] = matrix(img_out_x, rows=1, cols=m_batched); + img_out_flattened_y[i,] = matrix(img_out_y, rows=1, cols=m_batched); +} +write(img_out_flattened_x, $x_out_reshape_file); +write(img_out_flattened_y, $y_out_reshape_file); +imgs = matrix(input_batched, rows=num_images, cols=m_batched); +img_out_x_linearized = img_mirror_linearized(imgs, TRUE, img_rows, img_cols); +img_out_y_linearized = img_mirror_linearized(imgs, FALSE, img_rows, img_cols); +write(img_out_x_linearized, $x_out_file); +write(img_out_y_linearized, $y_out_file);