You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@systemds.apache.org by GitBox <gi...@apache.org> on 2021/05/14 17:30:13 UTC

[GitHub] [systemds] whirgod opened a new pull request #1275: Image Manipulation Primitives

whirgod opened a new pull request #1275:
URL: https://github.com/apache/systemds/pull/1275


   Adds a couple of built-in functions for manipulating images


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [systemds] whirgod commented on a change in pull request #1275: Image Manipulation Primitives

Posted by GitBox <gi...@apache.org>.
whirgod commented on a change in pull request #1275:
URL: https://github.com/apache/systemds/pull/1275#discussion_r633098203



##########
File path: src/test/resources/org/apache/sysds/test/functions/builtin/ImageTransformInput
##########
@@ -0,0 +1,135 @@
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 255 255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  0 0 0 0 0 0 0

Review comment:
       What resource folder are you referring to? It already is in src/test/resources.
   For size reduction, I could change it to a binary representation, but that would make the read-in process more complex and the content would be more difficult to understand.
   I suppose the file format is .csv




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [systemds] asfgit closed pull request #1275: Image Manipulation Primitives

Posted by GitBox <gi...@apache.org>.
asfgit closed pull request #1275:
URL: https://github.com/apache/systemds/pull/1275


   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [systemds] mboehm7 commented on pull request #1275: Image Manipulation Primitives

Posted by GitBox <gi...@apache.org>.
mboehm7 commented on pull request #1275:
URL: https://github.com/apache/systemds/pull/1275#issuecomment-846474482


   LGTM - thanks for the patch and detailed tests @whirgod. During the merge I made a few modifications:
   
   * Removed the added but redundant hashmap-matrix conversion methods
   * Refactored the tests and resource files (in package pipelines, and expected files)
   * Fixed the expected data for the rotation test (thanks for double checking these in detail)
   * Fixed unnecessary imports and formatting issues (annotations above, not before methods)
   * Started vectorizing the parfor loop in transform (but still commented as it requires more work) 


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [systemds] whirgod commented on a change in pull request #1275: Image Manipulation Primitives

Posted by GitBox <gi...@apache.org>.
whirgod commented on a change in pull request #1275:
URL: https://github.com/apache/systemds/pull/1275#discussion_r633107021



##########
File path: src/test/java/org/apache/sysds/test/TestUtils.java
##########
@@ -3073,4 +3059,46 @@ public static int isGPUAvailable() {
 		final int[] deviceCount = new int[1];
 		return JCuda.cudaGetDeviceCount(deviceCount);
 	}
+
+	public static double[][] convertMatrix(HashMap<MatrixValue.CellIndex, Double> m, int rows, int cols) {
+		double[][] res = new double[rows][cols];
+		m.forEach((k, v) -> res[k.row - 1][k.column - 1] = v);
+		return res;
+	}
+
+	public static HashMap<MatrixValue.CellIndex, Double> convertMatrix(double[][] m) {
+		HashMap<MatrixValue.CellIndex, Double> res = new HashMap<MatrixValue.CellIndex, Double>();
+		for (int r = 0; r < m.length; ++r) {
+			double[] row = m[r];
+			for (int c = 0; c < row.length; ++c) {
+				res.put(new CellIndex(r + 1, c + 1), row[c]);
+			}
+		}
+
+		return res;
+	}
+
+	/**
+	 * Reads a matrix from a text file. Rows are separated by newline, Values are separated by space.
+	 * Take from https://www.tutorialspoint.com/How-to-read-a-2d-array-from-a-file-in-java
+	 * @param url URL to the resource file obtained by Class.getResource()
+	 * @param rows The expected number of rows
+	 * @param cols The expected number of columns
+	 * @return The matrix
+	 * @throws Exception

Review comment:
       Done




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [systemds] whirgod commented on a change in pull request #1275: Image Manipulation Primitives

Posted by GitBox <gi...@apache.org>.
whirgod commented on a change in pull request #1275:
URL: https://github.com/apache/systemds/pull/1275#discussion_r633097029



##########
File path: src/test/java/org/apache/sysds/test/functions/builtin/BuiltinImageRotateTest.java
##########
@@ -0,0 +1,102 @@
+/*
+ * 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;
+
+import org.apache.sysds.common.Types.ExecMode;
+import org.apache.sysds.lops.LopProperties.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 org.junit.Ignore;
+import org.junit.Test;
+
+import java.util.HashMap;
+
+public class BuiltinImageRotateTest extends AutomatedTestBase {
+	private final static String TEST_NAME = "image_rotate";
+	private final static String TEST_DIR = "functions/builtin/";
+	private final static String TEST_CLASS_DIR = TEST_DIR + BuiltinImageRotateTest.class.getSimpleName() + "/";
+
+	private final static double eps = 1e-10;
+	private final static int rows = 135;
+	private final static int cols = 500;
+	private final static double angle = 42 * (Math.PI / 180);
+
+	@Override public void setUp() {
+		addTestConfiguration(TEST_NAME, new TestConfiguration(TEST_CLASS_DIR, TEST_NAME, new String[] {"B"}));
+	}
+
+	@Test public void testImageRotateZero() throws Exception {
+		loadTestConfiguration(getTestConfiguration(TEST_NAME));
+		final int w = 500, h = 135;
+		final double fill_value = 128.0;
+		double[][] input = TestUtils.readMatrixFromFile(this.getClass().getResource("ImageTransformInput"), h, w);
+		double[][] reference = input;
+		String HOME = SCRIPT_DIR + TEST_DIR;
+		fullDMLScriptName = HOME + TEST_NAME + ".dml";
+		programArgs = new String[] {"-nvargs", "in_file=" + input("A"), "out_file=" + output("B"), "width=" + cols,
+				"height=" + rows, "angle=" + 0, "fill_value=" + fill_value};
+		writeInputMatrixWithMTD("A", input, true);
+		runTest(true, false, null, -1);
+
+		HashMap<MatrixValue.CellIndex, Double> dmlfile = readDMLMatrixFromOutputDir("B");
+		double[][] dml_res = TestUtils.convertMatrix(dmlfile, h, w);
+		TestUtils.compareMatrices(reference, dml_res, eps, "Input vs. DML");
+	}
+
+	@Test public void testImageRotateComplete() throws Exception {
+		loadTestConfiguration(getTestConfiguration(TEST_NAME));
+		final int w = 500, h = 135;
+		final double fill_value = 128.0;
+		double[][] input = TestUtils.readMatrixFromFile(this.getClass().getResource("ImageTransformInput"), h, w);
+		double[][] reference = input;
+		String HOME = SCRIPT_DIR + TEST_DIR;
+		fullDMLScriptName = HOME + TEST_NAME + ".dml";
+		programArgs = new String[] {"-nvargs", "in_file=" + input("A"), "out_file=" + output("B"), "width=" + cols,
+				"height=" + rows, "angle=" + (2 * Math.PI), "fill_value=" + fill_value};
+		writeInputMatrixWithMTD("A", input, true);
+		runTest(true, false, null, -1);
+
+		HashMap<MatrixValue.CellIndex, Double> dmlfile = readDMLMatrixFromOutputDir("B");
+		double[][] dml_res = TestUtils.convertMatrix(dmlfile, h, w);
+		TestUtils.compareMatrices(reference, dml_res, eps, "Input vs. DML");
+	}
+
+	@Test public void testImageRotatePillow() throws Exception {
+		loadTestConfiguration(getTestConfiguration(TEST_NAME));
+		final int w = 500, h = 135;
+		final double fill_value = 128.0;
+		double[][] input = TestUtils.readMatrixFromFile(this.getClass().getResource("ImageTransformInput"), h, w);
+		double[][] reference = TestUtils.readMatrixFromFile(this.getClass().getResource("ImageTransformRotated"), h, w);
+		String HOME = SCRIPT_DIR + TEST_DIR;
+		fullDMLScriptName = HOME + TEST_NAME + ".dml";
+		programArgs = new String[] {"-nvargs", "in_file=" + input("A"), "out_file=" + output("B"), "width=" + cols,
+				"height=" + rows, "angle=" + angle, "fill_value=" + fill_value};
+		writeInputMatrixWithMTD("A", input, true);
+		runTest(true, false, null, -1);
+
+		HashMap<MatrixValue.CellIndex, Double> dmlfile = readDMLMatrixFromOutputDir("B");
+		double[][] dml_res = TestUtils.convertMatrix(dmlfile, h, w);
+		TestUtils.compareMatrices(reference, dml_res, eps, "Pillow vs. DML");
+		// The error here seems to be in the pillow implementation. It calculates that the source coordinates of
+		// (339, 14) are (351, 87) using fixed point arithmetic, while the floating point implementation returns
+		// (351.975384 88.000514) rounded down to (351, 88). (All indices here start at 0)

Review comment:
       I analyzed the source code of the Pillow library. They use a fixed-point arithmetic implementation by default which for the given input returns 87 as y coordinate. If the given input does not satisfy some criteria they fall back on a floating-point arithmetic implementation. For the given input the floating-point implementation returns 88 as y coordinate which is the same as my floating-point implementation in dml.

##########
File path: src/test/resources/org/apache/sysds/test/functions/builtin/ImageTransformInput
##########
@@ -0,0 +1,135 @@
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 255 255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  0 0 0 0 0 0 0

Review comment:
       What resource folder are you referring to? It already is in src/test/resources.
   For size reduction, I could change it to a binary representation, but that would make the read-in process more complex and the content would be more difficult to understand.
   I suppose the file format is .csv

##########
File path: src/test/java/org/apache/sysds/test/TestUtils.java
##########
@@ -37,19 +37,8 @@
 import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
 import java.text.NumberFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
+import java.util.*;

Review comment:
       Done

##########
File path: src/test/java/org/apache/sysds/test/TestUtils.java
##########
@@ -3073,4 +3059,46 @@ public static int isGPUAvailable() {
 		final int[] deviceCount = new int[1];
 		return JCuda.cudaGetDeviceCount(deviceCount);
 	}
+
+	public static double[][] convertMatrix(HashMap<MatrixValue.CellIndex, Double> m, int rows, int cols) {
+		double[][] res = new double[rows][cols];
+		m.forEach((k, v) -> res[k.row - 1][k.column - 1] = v);
+		return res;
+	}
+
+	public static HashMap<MatrixValue.CellIndex, Double> convertMatrix(double[][] m) {
+		HashMap<MatrixValue.CellIndex, Double> res = new HashMap<MatrixValue.CellIndex, Double>();
+		for (int r = 0; r < m.length; ++r) {
+			double[] row = m[r];
+			for (int c = 0; c < row.length; ++c) {
+				res.put(new CellIndex(r + 1, c + 1), row[c]);
+			}
+		}
+
+		return res;
+	}
+
+	/**
+	 * Reads a matrix from a text file. Rows are separated by newline, Values are separated by space.
+	 * Take from https://www.tutorialspoint.com/How-to-read-a-2d-array-from-a-file-in-java
+	 * @param url URL to the resource file obtained by Class.getResource()
+	 * @param rows The expected number of rows
+	 * @param cols The expected number of columns
+	 * @return The matrix
+	 * @throws Exception

Review comment:
       Done




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [systemds] corepointer commented on pull request #1275: Image Manipulation Primitives

Posted by GitBox <gi...@apache.org>.
corepointer commented on pull request #1275:
URL: https://github.com/apache/systemds/pull/1275#issuecomment-843062760


   > > > Hello and thank you for your effort in this PR!
   > > > In general I agree with Sebastian, it looks good, but if I may chime in with additional questions:
   > > > Why is Pillow used? I'm sure there are image manipulation libraries for R and Java that could be used.
   > > > I guess the use of Pillow is the reason for the additional resource files and the methods in TestUtils? That (and the mentioned precision issues) could be avoided by using an R or Java library for comparison.
   > > > jm2c ;-)
   > > > Mark
   > > 
   > > 
   > > I use Pillow as a reference because one of the reasons I added the builtins is to reproduce the results of AutoAugment (https://arxiv.org/abs/1805.09501) and they use Pillow.
   
   OK, wasn't aware of that.
   
   > 
   > I don't think using Pillow is an issues, since it is only used in tests and not actually added to the system, since all the results seems to be added as references. Therefore nothing will not be included as a resource in the system.
   
   Spotted a double negation there :D Was that your intention? It actually fits well as there are resource files included.
   
   > 
   > That said it would be better with the actual expected results (calculated and verified not using our system), than results where we have to consider rounding errors from floating point to uint. but i consider this out of scope of this project, since the methods are tested and verified sufficiently.
   
   Another suggestion that'd be out of scope: Comparing to AutoAugment is out of scope of a unit test and should go into a dedicated script that can happily use Pillow and everything that is needed to run AutoAugment. For a unit test it is sufficient to have the correct functionality of our code confirmed. 
   
   But that is all just expressing my opinion again - no action needed on your part.
   
   Mark
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [systemds] Baunsgaard commented on a change in pull request #1275: Image Manipulation Primitives

Posted by GitBox <gi...@apache.org>.
Baunsgaard commented on a change in pull request #1275:
URL: https://github.com/apache/systemds/pull/1275#discussion_r632705658



##########
File path: src/test/java/org/apache/sysds/test/TestUtils.java
##########
@@ -37,19 +37,8 @@
 import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
 import java.text.NumberFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
+import java.util.*;

Review comment:
       we try to avoid wildcard imports.

##########
File path: src/test/resources/org/apache/sysds/test/functions/builtin/ImageTransformInput
##########
@@ -0,0 +1,135 @@
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 255 255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  0 0 0 0 0 0 0

Review comment:
       also a file ending describing the format would be nice. Is this png?

##########
File path: src/test/java/org/apache/sysds/test/functions/builtin/BuiltinImageRotateTest.java
##########
@@ -0,0 +1,102 @@
+/*
+ * 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;
+
+import org.apache.sysds.common.Types.ExecMode;
+import org.apache.sysds.lops.LopProperties.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 org.junit.Ignore;
+import org.junit.Test;
+
+import java.util.HashMap;
+
+public class BuiltinImageRotateTest extends AutomatedTestBase {
+	private final static String TEST_NAME = "image_rotate";
+	private final static String TEST_DIR = "functions/builtin/";
+	private final static String TEST_CLASS_DIR = TEST_DIR + BuiltinImageRotateTest.class.getSimpleName() + "/";
+
+	private final static double eps = 1e-10;
+	private final static int rows = 135;
+	private final static int cols = 500;
+	private final static double angle = 42 * (Math.PI / 180);
+
+	@Override public void setUp() {
+		addTestConfiguration(TEST_NAME, new TestConfiguration(TEST_CLASS_DIR, TEST_NAME, new String[] {"B"}));
+	}
+
+	@Test public void testImageRotateZero() throws Exception {
+		loadTestConfiguration(getTestConfiguration(TEST_NAME));
+		final int w = 500, h = 135;
+		final double fill_value = 128.0;
+		double[][] input = TestUtils.readMatrixFromFile(this.getClass().getResource("ImageTransformInput"), h, w);
+		double[][] reference = input;
+		String HOME = SCRIPT_DIR + TEST_DIR;
+		fullDMLScriptName = HOME + TEST_NAME + ".dml";
+		programArgs = new String[] {"-nvargs", "in_file=" + input("A"), "out_file=" + output("B"), "width=" + cols,
+				"height=" + rows, "angle=" + 0, "fill_value=" + fill_value};
+		writeInputMatrixWithMTD("A", input, true);
+		runTest(true, false, null, -1);
+
+		HashMap<MatrixValue.CellIndex, Double> dmlfile = readDMLMatrixFromOutputDir("B");
+		double[][] dml_res = TestUtils.convertMatrix(dmlfile, h, w);
+		TestUtils.compareMatrices(reference, dml_res, eps, "Input vs. DML");
+	}
+
+	@Test public void testImageRotateComplete() throws Exception {
+		loadTestConfiguration(getTestConfiguration(TEST_NAME));
+		final int w = 500, h = 135;
+		final double fill_value = 128.0;
+		double[][] input = TestUtils.readMatrixFromFile(this.getClass().getResource("ImageTransformInput"), h, w);
+		double[][] reference = input;
+		String HOME = SCRIPT_DIR + TEST_DIR;
+		fullDMLScriptName = HOME + TEST_NAME + ".dml";
+		programArgs = new String[] {"-nvargs", "in_file=" + input("A"), "out_file=" + output("B"), "width=" + cols,
+				"height=" + rows, "angle=" + (2 * Math.PI), "fill_value=" + fill_value};
+		writeInputMatrixWithMTD("A", input, true);
+		runTest(true, false, null, -1);
+
+		HashMap<MatrixValue.CellIndex, Double> dmlfile = readDMLMatrixFromOutputDir("B");
+		double[][] dml_res = TestUtils.convertMatrix(dmlfile, h, w);
+		TestUtils.compareMatrices(reference, dml_res, eps, "Input vs. DML");
+	}
+
+	@Test public void testImageRotatePillow() throws Exception {
+		loadTestConfiguration(getTestConfiguration(TEST_NAME));
+		final int w = 500, h = 135;
+		final double fill_value = 128.0;
+		double[][] input = TestUtils.readMatrixFromFile(this.getClass().getResource("ImageTransformInput"), h, w);
+		double[][] reference = TestUtils.readMatrixFromFile(this.getClass().getResource("ImageTransformRotated"), h, w);
+		String HOME = SCRIPT_DIR + TEST_DIR;
+		fullDMLScriptName = HOME + TEST_NAME + ".dml";
+		programArgs = new String[] {"-nvargs", "in_file=" + input("A"), "out_file=" + output("B"), "width=" + cols,
+				"height=" + rows, "angle=" + angle, "fill_value=" + fill_value};
+		writeInputMatrixWithMTD("A", input, true);
+		runTest(true, false, null, -1);
+
+		HashMap<MatrixValue.CellIndex, Double> dmlfile = readDMLMatrixFromOutputDir("B");
+		double[][] dml_res = TestUtils.convertMatrix(dmlfile, h, w);
+		TestUtils.compareMatrices(reference, dml_res, eps, "Pillow vs. DML");
+		// The error here seems to be in the pillow implementation. It calculates that the source coordinates of
+		// (339, 14) are (351, 87) using fixed point arithmetic, while the floating point implementation returns
+		// (351.975384 88.000514) rounded down to (351, 88). (All indices here start at 0)

Review comment:
       this difference sounds large, could it be possible to test with some other framework, or write the calculation in java?

##########
File path: src/test/resources/org/apache/sysds/test/functions/builtin/ImageTransformInput
##########
@@ -0,0 +1,135 @@
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 255 255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  0 0 0 0 0 0 0

Review comment:
       if possible it would be nice if these files were moved to the resources folder and maybe reduced in size.

##########
File path: src/test/java/org/apache/sysds/test/TestUtils.java
##########
@@ -3073,4 +3059,46 @@ public static int isGPUAvailable() {
 		final int[] deviceCount = new int[1];
 		return JCuda.cudaGetDeviceCount(deviceCount);
 	}
+
+	public static double[][] convertMatrix(HashMap<MatrixValue.CellIndex, Double> m, int rows, int cols) {
+		double[][] res = new double[rows][cols];
+		m.forEach((k, v) -> res[k.row - 1][k.column - 1] = v);
+		return res;
+	}
+
+	public static HashMap<MatrixValue.CellIndex, Double> convertMatrix(double[][] m) {
+		HashMap<MatrixValue.CellIndex, Double> res = new HashMap<MatrixValue.CellIndex, Double>();
+		for (int r = 0; r < m.length; ++r) {
+			double[] row = m[r];
+			for (int c = 0; c < row.length; ++c) {
+				res.put(new CellIndex(r + 1, c + 1), row[c]);
+			}
+		}
+
+		return res;
+	}
+
+	/**
+	 * Reads a matrix from a text file. Rows are separated by newline, Values are separated by space.
+	 * Take from https://www.tutorialspoint.com/How-to-read-a-2d-array-from-a-file-in-java
+	 * @param url URL to the resource file obtained by Class.getResource()
+	 * @param rows The expected number of rows
+	 * @param cols The expected number of columns
+	 * @return The matrix
+	 * @throws Exception

Review comment:
       would this not be an IOException.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [systemds] Baunsgaard commented on pull request #1275: Image Manipulation Primitives

Posted by GitBox <gi...@apache.org>.
Baunsgaard commented on pull request #1275:
URL: https://github.com/apache/systemds/pull/1275#issuecomment-843034161


   > > Hello and thank you for your effort in this PR!
   > > In general I agree with Sebastian, it looks good, but if I may chime in with additional questions:
   > > Why is Pillow used? I'm sure there are image manipulation libraries for R and Java that could be used.
   > > I guess the use of Pillow is the reason for the additional resource files and the methods in TestUtils? That (and the mentioned precision issues) could be avoided by using an R or Java library for comparison.
   > > jm2c ;-)
   > > Mark
   > 
   > I use Pillow as a reference because one of the reasons I added the builtins is to reproduce the results of AutoAugment (https://arxiv.org/abs/1805.09501) and they use Pillow.
   
   I don't think using Pillow is an issues, since it is only used in tests and not actually added to the system, since all the results seems to be added as references. Therefore nothing will not be included as a resource in the system.
   
   That said it would be better with the actual expected results (calculated and verified not using our system), than results where we have to consider rounding errors from floating point to uint. but i consider this out of scope of this project, since the methods are tested and verified sufficiently.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [systemds] whirgod commented on pull request #1275: Image Manipulation Primitives

Posted by GitBox <gi...@apache.org>.
whirgod commented on pull request #1275:
URL: https://github.com/apache/systemds/pull/1275#issuecomment-842405257


   > Hello and thank you for your effort in this PR!
   > In general I agree with Sebastian, it looks good, but if I may chime in with additional questions:
   > Why is Pillow used? I'm sure there are image manipulation libraries for R and Java that could be used.
   > I guess the use of Pillow is the reason for the additional resource files and the methods in TestUtils? That (and the mentioned precision issues) could be avoided by using an R or Java library for comparison.
   > jm2c ;-)
   > Mark
   
   I use Pillow as a reference because one of the reasons I added the builtins is to reproduce the results of AutoAugment (https://arxiv.org/abs/1805.09501) and they use Pillow.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [systemds] corepointer commented on pull request #1275: Image Manipulation Primitives

Posted by GitBox <gi...@apache.org>.
corepointer commented on pull request #1275:
URL: https://github.com/apache/systemds/pull/1275#issuecomment-842307021


   Hello and thank you for your effort in this PR! 
   In general I agree with Sebastian, it looks good, but if I may chime in with additional questions:
   Why is Pillow used? I'm sure there are image manipulation libraries for R and Java that could be used.
   I guess the use of Pillow is the reason for the additional resource files and the methods in TestUtils? That (and the mentioned precision issues) could be avoided by using an R or Java library for comparison. 
   jm2c ;-)
   Mark


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [systemds] corepointer commented on pull request #1275: Image Manipulation Primitives

Posted by GitBox <gi...@apache.org>.
corepointer commented on pull request #1275:
URL: https://github.com/apache/systemds/pull/1275#issuecomment-842307021


   Hello and thank you for your effort in this PR! 
   In general I agree with Sebastian, it looks good, but if I may chime in with additional questions:
   Why is Pillow used? I'm sure there are image manipulation libraries for R and Java that could be used.
   I guess the use of Pillow is the reason for the additional resource files and the methods in TestUtils? That (and the mentioned precision issues) could be avoided by using an R or Java library for comparison. 
   jm2c ;-)
   Mark


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [systemds] whirgod commented on a change in pull request #1275: Image Manipulation Primitives

Posted by GitBox <gi...@apache.org>.
whirgod commented on a change in pull request #1275:
URL: https://github.com/apache/systemds/pull/1275#discussion_r633107016



##########
File path: src/test/java/org/apache/sysds/test/TestUtils.java
##########
@@ -37,19 +37,8 @@
 import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
 import java.text.NumberFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
+import java.util.*;

Review comment:
       Done




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [systemds] Baunsgaard commented on a change in pull request #1275: Image Manipulation Primitives

Posted by GitBox <gi...@apache.org>.
Baunsgaard commented on a change in pull request #1275:
URL: https://github.com/apache/systemds/pull/1275#discussion_r634225246



##########
File path: src/test/resources/org/apache/sysds/test/functions/builtin/ImageTransformInput
##########
@@ -0,0 +1,135 @@
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 255 255 255 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  0 0 0 0 0 0 0

Review comment:
       My bad, the view i had collapsed the folders.
   But looking at this again it seems excessive to make all these folders. I understand why you replicated the folder structure since this could be considered standard.
   
   The intention behind the resources folder currently is to enable sharing of common resources between multiple tests, therefore i would suggest making a folder called img. and include these files there. 'src/test/resources/img/...'
   
   Furthermore since the file type is csv it would be nice to have a metadata file associated with each of the images, this makes it possible to read in through our standard csv parsing in systemds. If you don't want to do it i will during merge.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [systemds] whirgod commented on a change in pull request #1275: Image Manipulation Primitives

Posted by GitBox <gi...@apache.org>.
whirgod commented on a change in pull request #1275:
URL: https://github.com/apache/systemds/pull/1275#discussion_r633097029



##########
File path: src/test/java/org/apache/sysds/test/functions/builtin/BuiltinImageRotateTest.java
##########
@@ -0,0 +1,102 @@
+/*
+ * 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;
+
+import org.apache.sysds.common.Types.ExecMode;
+import org.apache.sysds.lops.LopProperties.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 org.junit.Ignore;
+import org.junit.Test;
+
+import java.util.HashMap;
+
+public class BuiltinImageRotateTest extends AutomatedTestBase {
+	private final static String TEST_NAME = "image_rotate";
+	private final static String TEST_DIR = "functions/builtin/";
+	private final static String TEST_CLASS_DIR = TEST_DIR + BuiltinImageRotateTest.class.getSimpleName() + "/";
+
+	private final static double eps = 1e-10;
+	private final static int rows = 135;
+	private final static int cols = 500;
+	private final static double angle = 42 * (Math.PI / 180);
+
+	@Override public void setUp() {
+		addTestConfiguration(TEST_NAME, new TestConfiguration(TEST_CLASS_DIR, TEST_NAME, new String[] {"B"}));
+	}
+
+	@Test public void testImageRotateZero() throws Exception {
+		loadTestConfiguration(getTestConfiguration(TEST_NAME));
+		final int w = 500, h = 135;
+		final double fill_value = 128.0;
+		double[][] input = TestUtils.readMatrixFromFile(this.getClass().getResource("ImageTransformInput"), h, w);
+		double[][] reference = input;
+		String HOME = SCRIPT_DIR + TEST_DIR;
+		fullDMLScriptName = HOME + TEST_NAME + ".dml";
+		programArgs = new String[] {"-nvargs", "in_file=" + input("A"), "out_file=" + output("B"), "width=" + cols,
+				"height=" + rows, "angle=" + 0, "fill_value=" + fill_value};
+		writeInputMatrixWithMTD("A", input, true);
+		runTest(true, false, null, -1);
+
+		HashMap<MatrixValue.CellIndex, Double> dmlfile = readDMLMatrixFromOutputDir("B");
+		double[][] dml_res = TestUtils.convertMatrix(dmlfile, h, w);
+		TestUtils.compareMatrices(reference, dml_res, eps, "Input vs. DML");
+	}
+
+	@Test public void testImageRotateComplete() throws Exception {
+		loadTestConfiguration(getTestConfiguration(TEST_NAME));
+		final int w = 500, h = 135;
+		final double fill_value = 128.0;
+		double[][] input = TestUtils.readMatrixFromFile(this.getClass().getResource("ImageTransformInput"), h, w);
+		double[][] reference = input;
+		String HOME = SCRIPT_DIR + TEST_DIR;
+		fullDMLScriptName = HOME + TEST_NAME + ".dml";
+		programArgs = new String[] {"-nvargs", "in_file=" + input("A"), "out_file=" + output("B"), "width=" + cols,
+				"height=" + rows, "angle=" + (2 * Math.PI), "fill_value=" + fill_value};
+		writeInputMatrixWithMTD("A", input, true);
+		runTest(true, false, null, -1);
+
+		HashMap<MatrixValue.CellIndex, Double> dmlfile = readDMLMatrixFromOutputDir("B");
+		double[][] dml_res = TestUtils.convertMatrix(dmlfile, h, w);
+		TestUtils.compareMatrices(reference, dml_res, eps, "Input vs. DML");
+	}
+
+	@Test public void testImageRotatePillow() throws Exception {
+		loadTestConfiguration(getTestConfiguration(TEST_NAME));
+		final int w = 500, h = 135;
+		final double fill_value = 128.0;
+		double[][] input = TestUtils.readMatrixFromFile(this.getClass().getResource("ImageTransformInput"), h, w);
+		double[][] reference = TestUtils.readMatrixFromFile(this.getClass().getResource("ImageTransformRotated"), h, w);
+		String HOME = SCRIPT_DIR + TEST_DIR;
+		fullDMLScriptName = HOME + TEST_NAME + ".dml";
+		programArgs = new String[] {"-nvargs", "in_file=" + input("A"), "out_file=" + output("B"), "width=" + cols,
+				"height=" + rows, "angle=" + angle, "fill_value=" + fill_value};
+		writeInputMatrixWithMTD("A", input, true);
+		runTest(true, false, null, -1);
+
+		HashMap<MatrixValue.CellIndex, Double> dmlfile = readDMLMatrixFromOutputDir("B");
+		double[][] dml_res = TestUtils.convertMatrix(dmlfile, h, w);
+		TestUtils.compareMatrices(reference, dml_res, eps, "Pillow vs. DML");
+		// The error here seems to be in the pillow implementation. It calculates that the source coordinates of
+		// (339, 14) are (351, 87) using fixed point arithmetic, while the floating point implementation returns
+		// (351.975384 88.000514) rounded down to (351, 88). (All indices here start at 0)

Review comment:
       I analyzed the source code of the Pillow library. They use a fixed-point arithmetic implementation by default which for the given input returns 87 as y coordinate. If the given input does not satisfy some criteria they fall back on a floating-point arithmetic implementation. For the given input the floating-point implementation returns 88 as y coordinate which is the same as my floating-point implementation in dml.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [systemds] whirgod commented on pull request #1275: Image Manipulation Primitives

Posted by GitBox <gi...@apache.org>.
whirgod commented on pull request #1275:
URL: https://github.com/apache/systemds/pull/1275#issuecomment-842405257


   > Hello and thank you for your effort in this PR!
   > In general I agree with Sebastian, it looks good, but if I may chime in with additional questions:
   > Why is Pillow used? I'm sure there are image manipulation libraries for R and Java that could be used.
   > I guess the use of Pillow is the reason for the additional resource files and the methods in TestUtils? That (and the mentioned precision issues) could be avoided by using an R or Java library for comparison.
   > jm2c ;-)
   > Mark
   
   I use Pillow as a reference because one of the reasons I added the builtins is to reproduce the results of AutoAugment (https://arxiv.org/abs/1805.09501) and they use Pillow.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org