Path: blob/master/test/jdk/java/util/Arrays/largeMemory/ParallelPrefix.java
41153 views
/*1* Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/**24* @test25* @bug 8014076 802506726* @summary unit test for Arrays.ParallelPrefix().27* @author Tristan Yan28* @modules java.management jdk.management29* @run testng/othervm -Xms256m -Xmx1024m ParallelPrefix30*/3132import java.lang.management.ManagementFactory;33import java.util.Arrays;34import java.util.function.BinaryOperator;35import java.util.function.DoubleBinaryOperator;36import java.util.function.Function;37import java.util.function.IntBinaryOperator;38import java.util.function.LongBinaryOperator;39import java.util.stream.IntStream;40import java.util.stream.LongStream;41import com.sun.management.OperatingSystemMXBean;42import static org.testng.Assert.*;43import org.testng.annotations.DataProvider;44import org.testng.annotations.Test;45import org.testng.annotations.BeforeSuite;4647public class ParallelPrefix {48//Array size less than MIN_PARTITION49private static final int SMALL_ARRAY_SIZE = 1 << 3;5051//Array size equals MIN_PARTITION52private static final int THRESHOLD_ARRAY_SIZE = 1 << 4;5354//Array size greater than MIN_PARTITION55private static final int MEDIUM_ARRAY_SIZE = 1 << 8;5657//Array size much greater than MIN_PARTITION58private static final int LARGE_ARRAY_SIZE = 1 << 14;5960private static int[] arraySizeCollection;6162@BeforeSuite63public static void setup() {64java.lang.management.OperatingSystemMXBean bean =65ManagementFactory.getOperatingSystemMXBean();66if (bean instanceof OperatingSystemMXBean) {67OperatingSystemMXBean os = (OperatingSystemMXBean)bean;68long physicalMemorySize = os.getTotalPhysicalMemorySize() / (1024 * 1024);69System.out.println("System memory size: " + physicalMemorySize + "M");70// when we can get system memory size, and it's larger than 2G,71// then we enable large array size test below,72// else disable large array size test below.73if (physicalMemorySize > (2 * 1024)) {74arraySizeCollection = new int[]{75SMALL_ARRAY_SIZE,76THRESHOLD_ARRAY_SIZE,77MEDIUM_ARRAY_SIZE,78LARGE_ARRAY_SIZE79};80System.out.println("System memory is large enough, add large array size test");81return;82}83}84arraySizeCollection = new int[]{85SMALL_ARRAY_SIZE,86THRESHOLD_ARRAY_SIZE,87MEDIUM_ARRAY_SIZE88};89System.out.println("System memory is not large enough, remove large array size test");90}9192@DataProvider(name = "intSet")93public static Object[][] intSet(){94return genericData(size -> IntStream.range(0, size).toArray(),95new IntBinaryOperator[]{96Integer::sum,97Integer::min});98}99100@DataProvider(name = "longSet")101public static Object[][] longSet(){102return genericData(size -> LongStream.range(0, size).toArray(),103new LongBinaryOperator[]{104Long::sum,105Long::min});106}107108@DataProvider(name = "doubleSet")109public static Object[][] doubleSet(){110return genericData(size -> IntStream.range(0, size).mapToDouble(i -> (double)i).toArray(),111new DoubleBinaryOperator[]{112Double::sum,113Double::min});114}115116@DataProvider(name = "stringSet")117public static Object[][] stringSet(){118Function<Integer, String[]> stringsFunc = size ->119IntStream.range(0, size).mapToObj(Integer::toString).toArray(String[]::new);120BinaryOperator<String> concat = String::concat;121return genericData(stringsFunc,122(BinaryOperator<String>[]) new BinaryOperator[]{123concat });124}125126private static <T, OPS> Object[][] genericData(Function<Integer, T> generateFunc, OPS[] ops) {127//test arrays which size is equals n-1, n, n+1, test random data128Object[][] data = new Object[arraySizeCollection.length * 3 * ops.length][4];129for(int n = 0; n < arraySizeCollection.length; n++ ) {130for(int testValue = -1 ; testValue <= 1; testValue++) {131int array_size = arraySizeCollection[n] + testValue;132for(int opsN = 0; opsN < ops.length; opsN++) {133int index = n * 3 * ops.length + (testValue + 1) * ops.length + opsN;134data[index][0] = generateFunc.apply(array_size);135data[index][1] = array_size / 3;136data[index][2] = 2 * array_size / 3;137data[index][3] = ops[opsN];138}139}140}141return data;142}143144@Test(dataProvider="intSet")145public void testParallelPrefixForInt(int[] data, int fromIndex, int toIndex, IntBinaryOperator op) {146int[] sequentialResult = data.clone();147for (int index = fromIndex + 1; index < toIndex; index++) {148sequentialResult[index ] = op.applyAsInt(sequentialResult[index - 1], sequentialResult[index]);149}150151int[] parallelResult = data.clone();152Arrays.parallelPrefix(parallelResult, fromIndex, toIndex, op);153assertArraysEqual(parallelResult, sequentialResult);154155int[] parallelRangeResult = Arrays.copyOfRange(data, fromIndex, toIndex);156Arrays.parallelPrefix(parallelRangeResult, op);157assertArraysEqual(parallelRangeResult, Arrays.copyOfRange(sequentialResult, fromIndex, toIndex));158}159160@Test(dataProvider="longSet")161public void testParallelPrefixForLong(long[] data, int fromIndex, int toIndex, LongBinaryOperator op) {162long[] sequentialResult = data.clone();163for (int index = fromIndex + 1; index < toIndex; index++) {164sequentialResult[index ] = op.applyAsLong(sequentialResult[index - 1], sequentialResult[index]);165}166167long[] parallelResult = data.clone();168Arrays.parallelPrefix(parallelResult, fromIndex, toIndex, op);169assertArraysEqual(parallelResult, sequentialResult);170171long[] parallelRangeResult = Arrays.copyOfRange(data, fromIndex, toIndex);172Arrays.parallelPrefix(parallelRangeResult, op);173assertArraysEqual(parallelRangeResult, Arrays.copyOfRange(sequentialResult, fromIndex, toIndex));174}175176@Test(dataProvider="doubleSet")177public void testParallelPrefixForDouble(double[] data, int fromIndex, int toIndex, DoubleBinaryOperator op) {178double[] sequentialResult = data.clone();179for (int index = fromIndex + 1; index < toIndex; index++) {180sequentialResult[index ] = op.applyAsDouble(sequentialResult[index - 1], sequentialResult[index]);181}182183double[] parallelResult = data.clone();184Arrays.parallelPrefix(parallelResult, fromIndex, toIndex, op);185assertArraysEqual(parallelResult, sequentialResult);186187double[] parallelRangeResult = Arrays.copyOfRange(data, fromIndex, toIndex);188Arrays.parallelPrefix(parallelRangeResult, op);189assertArraysEqual(parallelRangeResult, Arrays.copyOfRange(sequentialResult, fromIndex, toIndex));190}191192@Test(dataProvider="stringSet")193public void testParallelPrefixForStringr(String[] data , int fromIndex, int toIndex, BinaryOperator<String> op) {194String[] sequentialResult = data.clone();195for (int index = fromIndex + 1; index < toIndex; index++) {196sequentialResult[index ] = op.apply(sequentialResult[index - 1], sequentialResult[index]);197}198199String[] parallelResult = data.clone();200Arrays.parallelPrefix(parallelResult, fromIndex, toIndex, op);201assertArraysEqual(parallelResult, sequentialResult);202203String[] parallelRangeResult = Arrays.copyOfRange(data, fromIndex, toIndex);204Arrays.parallelPrefix(parallelRangeResult, op);205assertArraysEqual(parallelRangeResult, Arrays.copyOfRange(sequentialResult, fromIndex, toIndex));206}207208@Test209public void testNPEs() {210// null array211assertThrowsNPE(() -> Arrays.parallelPrefix((int[]) null, Integer::max));212assertThrowsNPE(() -> Arrays.parallelPrefix((long []) null, Long::max));213assertThrowsNPE(() -> Arrays.parallelPrefix((double []) null, Double::max));214assertThrowsNPE(() -> Arrays.parallelPrefix((String []) null, String::concat));215216// null array w/ range217assertThrowsNPE(() -> Arrays.parallelPrefix((int[]) null, 0, 0, Integer::max));218assertThrowsNPE(() -> Arrays.parallelPrefix((long []) null, 0, 0, Long::max));219assertThrowsNPE(() -> Arrays.parallelPrefix((double []) null, 0, 0, Double::max));220assertThrowsNPE(() -> Arrays.parallelPrefix((String []) null, 0, 0, String::concat));221222// null op223assertThrowsNPE(() -> Arrays.parallelPrefix(new int[] {}, null));224assertThrowsNPE(() -> Arrays.parallelPrefix(new long[] {}, null));225assertThrowsNPE(() -> Arrays.parallelPrefix(new double[] {}, null));226assertThrowsNPE(() -> Arrays.parallelPrefix(new String[] {}, null));227228// null op w/ range229assertThrowsNPE(() -> Arrays.parallelPrefix(new int[] {}, 0, 0, null));230assertThrowsNPE(() -> Arrays.parallelPrefix(new long[] {}, 0, 0, null));231assertThrowsNPE(() -> Arrays.parallelPrefix(new double[] {}, 0, 0, null));232assertThrowsNPE(() -> Arrays.parallelPrefix(new String[] {}, 0, 0, null));233}234235@Test236public void testIAEs() {237assertThrowsIAE(() -> Arrays.parallelPrefix(new int[] {}, 1, 0, Integer::max));238assertThrowsIAE(() -> Arrays.parallelPrefix(new long[] {}, 1, 0, Long::max));239assertThrowsIAE(() -> Arrays.parallelPrefix(new double[] {}, 1, 0, Double::max));240assertThrowsIAE(() -> Arrays.parallelPrefix(new String[] {}, 1, 0, String::concat));241}242243@Test244public void testAIOOBEs() {245// bad "fromIndex"246assertThrowsAIOOB(() -> Arrays.parallelPrefix(new int[] {}, -1, 0, Integer::max));247assertThrowsAIOOB(() -> Arrays.parallelPrefix(new long[] {}, -1, 0, Long::max));248assertThrowsAIOOB(() -> Arrays.parallelPrefix(new double[] {}, -1, 0, Double::max));249assertThrowsAIOOB(() -> Arrays.parallelPrefix(new String[] {}, -1, 0, String::concat));250251// bad "toIndex"252assertThrowsAIOOB(() -> Arrays.parallelPrefix(new int[] {}, 0, 1, Integer::max));253assertThrowsAIOOB(() -> Arrays.parallelPrefix(new long[] {}, 0, 1, Long::max));254assertThrowsAIOOB(() -> Arrays.parallelPrefix(new double[] {}, 0, 1, Double::max));255assertThrowsAIOOB(() -> Arrays.parallelPrefix(new String[] {}, 0, 1, String::concat));256}257258// "library" code259260private void assertThrowsNPE(ThrowingRunnable r) {261assertThrows(NullPointerException.class, r);262}263264private void assertThrowsIAE(ThrowingRunnable r) {265assertThrows(IllegalArgumentException.class, r);266}267268private void assertThrowsAIOOB(ThrowingRunnable r) {269assertThrows(ArrayIndexOutOfBoundsException.class, r);270}271272static void assertArraysEqual(int[] actual, int[] expected) {273try {274assertEquals(actual, expected, "");275} catch (AssertionError x) {276throw new AssertionError(String.format("Expected:%s, actual:%s",277Arrays.toString(expected), Arrays.toString(actual)), x);278}279}280281static void assertArraysEqual(long[] actual, long[] expected) {282try {283assertEquals(actual, expected, "");284} catch (AssertionError x) {285throw new AssertionError(String.format("Expected:%s, actual:%s",286Arrays.toString(expected), Arrays.toString(actual)), x);287}288}289290static void assertArraysEqual(double[] actual, double[] expected) {291try {292assertEquals(actual, expected, "");293} catch (AssertionError x) {294throw new AssertionError(String.format("Expected:%s, actual:%s",295Arrays.toString(expected), Arrays.toString(actual)), x);296}297}298299static void assertArraysEqual(String[] actual, String[] expected) {300try {301assertEquals(actual, expected, "");302} catch (AssertionError x) {303throw new AssertionError(String.format("Expected:%s, actual:%s",304Arrays.toString(expected), Arrays.toString(actual)), x);305}306}307}308309310311