1 /* 2 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @modules jdk.incubator.vector 27 * @run testng Double512VectorLoadStoreTests 28 * 29 */ 30 31 import jdk.incubator.vector.Vector.Shape; 32 import jdk.incubator.vector.Vector.Species; 33 import jdk.incubator.vector.Vector; 34 35 import jdk.incubator.vector.DoubleVector; 36 37 import org.testng.Assert; 38 import org.testng.annotations.DataProvider; 39 import org.testng.annotations.Test; 40 41 import java.nio.ByteBuffer; 42 import java.nio.DoubleBuffer; 43 import java.nio.ByteOrder; 44 import java.util.List; 45 import java.util.function.IntFunction; 46 47 @Test 48 public class Double512VectorLoadStoreTests extends AbstractVectorTest { 49 static final Species<Double> SPECIES = 50 DoubleVector.SPECIES_512; 51 52 static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 10); 53 54 static void assertArraysEquals(double[] a, double[] r, boolean[] mask) { 55 int i = 0; 56 try { 57 for (; i < a.length; i++) { 58 Assert.assertEquals(mask[i % SPECIES.length()] ? a[i] : (double) 0, r[i]); 59 } 60 } catch (AssertionError e) { 61 Assert.assertEquals(mask[i % SPECIES.length()] ? a[i] : (double) 0, r[i], "at index #" + i); 62 } 63 } 64 65 static void assertArraysEquals(double[] a, double[] r, int[] im) { 66 int i = 0; 67 try { 68 for (; i < a.length; i++) { 69 Assert.assertEquals(a[im[i]], r[i]); 70 } 71 } catch (AssertionError e) { 72 Assert.assertEquals(a[im[i]], r[i], "at index #" + i); 73 } 74 } 75 76 static void assertArraysEquals(double[] a, double[] r, int[] im, boolean[] mask) { 77 int i = 0; 78 try { 79 for (; i < a.length; i++) { 80 Assert.assertEquals(mask[i % SPECIES.length()] ? a[im[i]] : (double) 0, r[i]); 81 } 82 } catch (AssertionError e) { 83 Assert.assertEquals(mask[i % SPECIES.length()] ? a[im[i]] : (double) 0, r[i], "at index #" + i); 84 } 85 } 86 87 static final List<IntFunction<double[]>> DOUBLE_GENERATORS = List.of( 88 withToString("double[i * 5]", (int s) -> { 89 return fill(s * 1000, 90 i -> (double)(i * 5)); 91 }), 92 withToString("double[i + 1]", (int s) -> { 93 return fill(s * 1000, 94 i -> (((double)(i + 1) == 0) ? 1 : (double)(i + 1))); 95 }) 96 ); 97 98 @DataProvider 99 public Object[][] doubleProvider() { 100 return DOUBLE_GENERATORS.stream(). 101 map(f -> new Object[]{f}). 102 toArray(Object[][]::new); 103 } 104 105 @DataProvider 106 public Object[][] doubleMaskProvider() { 107 return BOOLEAN_MASK_GENERATORS.stream(). 108 flatMap(fm -> DOUBLE_GENERATORS.stream().map(fa -> { 109 return new Object[] {fa, fm}; 110 })). 111 toArray(Object[][]::new); 112 } 113 114 @DataProvider 115 public Object[][] doubleIndexMapProvider() { 116 return INDEX_GENERATORS.stream(). 117 flatMap(fim -> DOUBLE_GENERATORS.stream().map(fa -> { 118 return new Object[] {fa, fim}; 119 })). 120 toArray(Object[][]::new); 121 } 122 123 @DataProvider 124 public Object[][] doubleIndexMapMaskProvider() { 125 return BOOLEAN_MASK_GENERATORS.stream(). 126 flatMap(fm -> INDEX_GENERATORS.stream(). 127 flatMap(fim -> DOUBLE_GENERATORS.stream().map(fa -> { 128 return new Object[] {fa, fim, fm}; 129 }))). 130 toArray(Object[][]::new); 131 } 132 133 @DataProvider 134 public Object[][] doubleByteBufferProvider() { 135 return DOUBLE_GENERATORS.stream(). 136 flatMap(fa -> BYTE_BUFFER_GENERATORS.stream().map(fb -> { 137 return new Object[]{fa, fb}; 138 })). 139 toArray(Object[][]::new); 140 } 141 142 @DataProvider 143 public Object[][] doubleByteBufferMaskProvider() { 144 return BOOLEAN_MASK_GENERATORS.stream(). 145 flatMap(fm -> DOUBLE_GENERATORS.stream(). 146 flatMap(fa -> BYTE_BUFFER_GENERATORS.stream().map(fb -> { 147 return new Object[]{fa, fb, fm}; 148 }))). 149 toArray(Object[][]::new); 150 } 151 152 static ByteBuffer toBuffer(double[] a, IntFunction<ByteBuffer> fb) { 153 ByteBuffer bb = fb.apply(a.length * SPECIES.elementSize() / 8); 154 for (double v : a) { 155 bb.putDouble(v); 156 } 157 return bb.clear(); 158 } 159 160 static double[] bufferToArray(ByteBuffer bb) { 161 DoubleBuffer db = bb.asDoubleBuffer(); 162 double[] d = new double[db.capacity()]; 163 db.get(d); 164 return d; 165 } 166 167 interface ToDoubleF { 168 double apply(int i); 169 } 170 171 static double[] fill(int s , ToDoubleF f) { 172 return fill(new double[s], f); 173 } 174 175 static double[] fill(double[] a, ToDoubleF f) { 176 for (int i = 0; i < a.length; i++) { 177 a[i] = f.apply(i); 178 } 179 return a; 180 } 181 182 @Test(dataProvider = "doubleProvider") 183 static void loadStoreArray(IntFunction<double[]> fa) { 184 double[] a = fa.apply(SPECIES.length()); 185 double[] r = new double[a.length]; 186 187 for (int ic = 0; ic < INVOC_COUNT; ic++) { 188 for (int i = 0; i < a.length; i += SPECIES.length()) { 189 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); 190 av.intoArray(r, i); 191 } 192 } 193 Assert.assertEquals(a, r); 194 } 195 196 @Test(dataProvider = "doubleMaskProvider") 197 static void loadStoreMaskArray(IntFunction<double[]> fa, 198 IntFunction<boolean[]> fm) { 199 double[] a = fa.apply(SPECIES.length()); 200 double[] r = new double[a.length]; 201 boolean[] mask = fm.apply(SPECIES.length()); 202 Vector.Mask<Double> vmask = DoubleVector.maskFromValues(SPECIES, mask); 203 204 for (int ic = 0; ic < INVOC_COUNT; ic++) { 205 for (int i = 0; i < a.length; i += SPECIES.length()) { 206 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i, vmask); 207 av.intoArray(r, i); 208 } 209 } 210 assertArraysEquals(a, r, mask); 211 212 r = new double[a.length]; 213 for (int ic = 0; ic < INVOC_COUNT; ic++) { 214 for (int i = 0; i < a.length; i += SPECIES.length()) { 215 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); 216 av.intoArray(r, i, vmask); 217 } 218 } 219 220 assertArraysEquals(a, r, mask); 221 } 222 223 224 @Test(dataProvider = "doubleByteBufferProvider") 225 static void loadStoreByteBuffer(IntFunction<double[]> fa, 226 IntFunction<ByteBuffer> fb) { 227 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), fb); 228 ByteBuffer r = fb.apply(a.limit()); 229 230 int l = a.limit(); 231 int s = SPECIES.length() * SPECIES.elementSize() / 8; 232 233 for (int ic = 0; ic < INVOC_COUNT; ic++) { 234 for (int i = 0; i < l; i += s) { 235 DoubleVector av = DoubleVector.fromByteBuffer(SPECIES, a, i); 236 av.intoByteBuffer(r, i); 237 } 238 } 239 Assert.assertEquals(a.position(), 0, "Input buffer position changed"); 240 Assert.assertEquals(a.limit(), l, "Input buffer limit changed"); 241 Assert.assertEquals(r.position(), 0, "Result buffer position changed"); 242 Assert.assertEquals(r.limit(), l, "Result buffer limit changed"); 243 Assert.assertEquals(a, r, "Buffers not equal"); 244 } 245 246 @Test(dataProvider = "doubleByteBufferProvider") 247 static void loadReadOnlyStoreByteBuffer(IntFunction<double[]> fa, 248 IntFunction<ByteBuffer> fb) { 249 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), fb); 250 a = a.asReadOnlyBuffer().order(a.order()); 251 ByteBuffer r = fb.apply(a.limit()); 252 253 int l = a.limit(); 254 int s = SPECIES.length() * SPECIES.elementSize() / 8; 255 256 for (int ic = 0; ic < INVOC_COUNT; ic++) { 257 for (int i = 0; i < l; i += s) { 258 DoubleVector av = DoubleVector.fromByteBuffer(SPECIES, a, i); 259 av.intoByteBuffer(r, i); 260 } 261 } 262 Assert.assertEquals(a.position(), 0, "Input buffer position changed"); 263 Assert.assertEquals(a.limit(), l, "Input buffer limit changed"); 264 Assert.assertEquals(r.position(), 0, "Result buffer position changed"); 265 Assert.assertEquals(r.limit(), l, "Result buffer limit changed"); 266 Assert.assertEquals(a, r, "Buffers not equal"); 267 } 268 269 @Test(dataProvider = "doubleByteBufferMaskProvider") 270 static void loadStoreByteBufferMask(IntFunction<double[]> fa, 271 IntFunction<ByteBuffer> fb, 272 IntFunction<boolean[]> fm) { 273 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), fb); 274 ByteBuffer r = fb.apply(a.limit()); 275 boolean[] mask = fm.apply(SPECIES.length()); 276 Vector.Mask<Double> vmask = DoubleVector.maskFromValues(SPECIES, mask); 277 278 int l = a.limit(); 279 int s = SPECIES.length() * SPECIES.elementSize() / 8; 280 281 for (int ic = 0; ic < INVOC_COUNT; ic++) { 282 for (int i = 0; i < l; i += s) { 283 DoubleVector av = DoubleVector.fromByteBuffer(SPECIES, a, i, vmask); 284 av.intoByteBuffer(r, i); 285 } 286 } 287 Assert.assertEquals(a.position(), 0, "Input buffer position changed"); 288 Assert.assertEquals(a.limit(), l, "Input buffer limit changed"); 289 Assert.assertEquals(r.position(), 0, "Result buffer position changed"); 290 Assert.assertEquals(r.limit(), l, "Result buffer limit changed"); 291 assertArraysEquals(bufferToArray(a), bufferToArray(r), mask); 292 293 a = toBuffer(fa.apply(SPECIES.length()), fb); 294 r = fb.apply(a.limit()); 295 for (int ic = 0; ic < INVOC_COUNT; ic++) { 296 for (int i = 0; i < l; i += s) { 297 DoubleVector av = DoubleVector.fromByteBuffer(SPECIES, a, i); 298 av.intoByteBuffer(r, i, vmask); 299 } 300 } 301 Assert.assertEquals(a.position(), 0, "Input buffer position changed"); 302 Assert.assertEquals(a.limit(), l, "Input buffer limit changed"); 303 Assert.assertEquals(r.position(), 0, "Result buffer position changed"); 304 Assert.assertEquals(r.limit(), l, "Result buffer limit changed"); 305 assertArraysEquals(bufferToArray(a), bufferToArray(r), mask); 306 } 307 308 @Test(dataProvider = "doubleByteBufferMaskProvider") 309 static void loadReadOnlyStoreByteBufferMask(IntFunction<double[]> fa, 310 IntFunction<ByteBuffer> fb, 311 IntFunction<boolean[]> fm) { 312 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), fb); 313 a = a.asReadOnlyBuffer().order(a.order()); 314 ByteBuffer r = fb.apply(a.limit()); 315 boolean[] mask = fm.apply(SPECIES.length()); 316 Vector.Mask<Double> vmask = DoubleVector.maskFromValues(SPECIES, mask); 317 318 int l = a.limit(); 319 int s = SPECIES.length() * SPECIES.elementSize() / 8; 320 321 for (int ic = 0; ic < INVOC_COUNT; ic++) { 322 for (int i = 0; i < l; i += s) { 323 DoubleVector av = DoubleVector.fromByteBuffer(SPECIES, a, i, vmask); 324 av.intoByteBuffer(r, i); 325 } 326 } 327 Assert.assertEquals(a.position(), 0, "Input buffer position changed"); 328 Assert.assertEquals(a.limit(), l, "Input buffer limit changed"); 329 Assert.assertEquals(r.position(), 0, "Result buffer position changed"); 330 Assert.assertEquals(r.limit(), l, "Result buffer limit changed"); 331 assertArraysEquals(bufferToArray(a), bufferToArray(r), mask); 332 } 333 }