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 Double64VectorLoadStoreTests 28 * 29 */ 30 31 import jdk.incubator.vector.VectorShape; 32 import jdk.incubator.vector.VectorSpecies; 33 import jdk.incubator.vector.VectorMask; 34 import jdk.incubator.vector.Vector; 35 36 import jdk.incubator.vector.DoubleVector; 37 38 import org.testng.Assert; 39 import org.testng.annotations.DataProvider; 40 import org.testng.annotations.Test; 41 42 import java.nio.ByteBuffer; 43 import java.nio.DoubleBuffer; 44 import java.nio.ByteOrder; 45 import java.util.List; 46 import java.util.function.IntFunction; 47 48 @Test 49 public class Double64VectorLoadStoreTests extends AbstractVectorTest { 50 static final VectorSpecies<Double> SPECIES = 51 DoubleVector.SPECIES_64; 52 53 static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 10); 54 55 static void assertArraysEquals(double[] a, double[] r, boolean[] mask) { 56 int i = 0; 57 try { 58 for (; i < a.length; i++) { 59 Assert.assertEquals(mask[i % SPECIES.length()] ? a[i] : (double) 0, r[i]); 60 } 61 } catch (AssertionError e) { 62 Assert.assertEquals(mask[i % SPECIES.length()] ? a[i] : (double) 0, r[i], "at index #" + i); 63 } 64 } 65 66 static void assertArraysEquals(double[] a, double[] r, int[] im) { 67 int i = 0; 68 try { 69 for (; i < a.length; i++) { 70 Assert.assertEquals(a[im[i]], r[i]); 71 } 72 } catch (AssertionError e) { 73 Assert.assertEquals(a[im[i]], r[i], "at index #" + i); 74 } 75 } 76 77 static void assertArraysEquals(double[] a, double[] r, int[] im, boolean[] mask) { 78 int i = 0; 79 try { 80 for (; i < a.length; i++) { 81 Assert.assertEquals(mask[i % SPECIES.length()] ? a[im[i]] : (double) 0, r[i]); 82 } 83 } catch (AssertionError e) { 84 Assert.assertEquals(mask[i % SPECIES.length()] ? a[im[i]] : (double) 0, r[i], "at index #" + i); 85 } 86 } 87 88 static final List<IntFunction<double[]>> DOUBLE_GENERATORS = List.of( 89 withToString("double[i * 5]", (int s) -> { 90 return fill(s * 1000, 91 i -> (double)(i * 5)); 92 }), 93 withToString("double[i + 1]", (int s) -> { 94 return fill(s * 1000, 95 i -> (((double)(i + 1) == 0) ? 1 : (double)(i + 1))); 96 }) 97 ); 98 99 @DataProvider 100 public Object[][] doubleProvider() { 101 return DOUBLE_GENERATORS.stream(). 102 map(f -> new Object[]{f}). 103 toArray(Object[][]::new); 104 } 105 106 @DataProvider 107 public Object[][] doubleMaskProvider() { 108 return BOOLEAN_MASK_GENERATORS.stream(). 109 flatMap(fm -> DOUBLE_GENERATORS.stream().map(fa -> { 110 return new Object[] {fa, fm}; 111 })). 112 toArray(Object[][]::new); 113 } 114 115 @DataProvider 116 public Object[][] doubleIndexMapProvider() { 117 return INDEX_GENERATORS.stream(). 118 flatMap(fim -> DOUBLE_GENERATORS.stream().map(fa -> { 119 return new Object[] {fa, fim}; 120 })). 121 toArray(Object[][]::new); 122 } 123 124 @DataProvider 125 public Object[][] doubleIndexMapMaskProvider() { 126 return BOOLEAN_MASK_GENERATORS.stream(). 127 flatMap(fm -> INDEX_GENERATORS.stream(). 128 flatMap(fim -> DOUBLE_GENERATORS.stream().map(fa -> { 129 return new Object[] {fa, fim, fm}; 130 }))). 131 toArray(Object[][]::new); 132 } 133 134 @DataProvider 135 public Object[][] doubleByteBufferProvider() { 136 return DOUBLE_GENERATORS.stream(). 137 flatMap(fa -> BYTE_BUFFER_GENERATORS.stream().map(fb -> { 138 return new Object[]{fa, fb}; 139 })). 140 toArray(Object[][]::new); 141 } 142 143 @DataProvider 144 public Object[][] doubleByteBufferMaskProvider() { 145 return BOOLEAN_MASK_GENERATORS.stream(). 146 flatMap(fm -> DOUBLE_GENERATORS.stream(). 147 flatMap(fa -> BYTE_BUFFER_GENERATORS.stream().map(fb -> { 148 return new Object[]{fa, fb, fm}; 149 }))). 150 toArray(Object[][]::new); 151 } 152 153 static ByteBuffer toBuffer(double[] a, IntFunction<ByteBuffer> fb) { 154 ByteBuffer bb = fb.apply(a.length * SPECIES.elementSize() / 8); 155 for (double v : a) { 156 bb.putDouble(v); 157 } 158 return bb.clear(); 159 } 160 161 static double[] bufferToArray(ByteBuffer bb) { 162 DoubleBuffer db = bb.asDoubleBuffer(); 163 double[] d = new double[db.capacity()]; 164 db.get(d); 165 return d; 166 } 167 168 interface ToDoubleF { 169 double apply(int i); 170 } 171 172 static double[] fill(int s , ToDoubleF f) { 173 return fill(new double[s], f); 174 } 175 176 static double[] fill(double[] a, ToDoubleF f) { 177 for (int i = 0; i < a.length; i++) { 178 a[i] = f.apply(i); 179 } 180 return a; 181 } 182 183 @Test(dataProvider = "doubleProvider") 184 static void loadStoreArray(IntFunction<double[]> fa) { 185 double[] a = fa.apply(SPECIES.length()); 186 double[] r = new double[a.length]; 187 188 for (int ic = 0; ic < INVOC_COUNT; ic++) { 189 for (int i = 0; i < a.length; i += SPECIES.length()) { 190 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); 191 av.intoArray(r, i); 192 } 193 } 194 Assert.assertEquals(a, r); 195 } 196 197 @Test(dataProvider = "doubleMaskProvider") 198 static void loadStoreMaskArray(IntFunction<double[]> fa, 199 IntFunction<boolean[]> fm) { 200 double[] a = fa.apply(SPECIES.length()); 201 double[] r = new double[a.length]; 202 boolean[] mask = fm.apply(SPECIES.length()); 203 VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask); 204 205 for (int ic = 0; ic < INVOC_COUNT; ic++) { 206 for (int i = 0; i < a.length; i += SPECIES.length()) { 207 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i, vmask); 208 av.intoArray(r, i); 209 } 210 } 211 assertArraysEquals(a, r, mask); 212 213 r = new double[a.length]; 214 for (int ic = 0; ic < INVOC_COUNT; ic++) { 215 for (int i = 0; i < a.length; i += SPECIES.length()) { 216 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); 217 av.intoArray(r, i, vmask); 218 } 219 } 220 221 assertArraysEquals(a, r, mask); 222 } 223 224 225 @Test(dataProvider = "doubleByteBufferProvider") 226 static void loadStoreByteBuffer(IntFunction<double[]> fa, 227 IntFunction<ByteBuffer> fb) { 228 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), fb); 229 ByteBuffer r = fb.apply(a.limit()); 230 231 int l = a.limit(); 232 int s = SPECIES.length() * SPECIES.elementSize() / 8; 233 234 for (int ic = 0; ic < INVOC_COUNT; ic++) { 235 for (int i = 0; i < l; i += s) { 236 DoubleVector av = DoubleVector.fromByteBuffer(SPECIES, a, i); 237 av.intoByteBuffer(r, i); 238 } 239 } 240 Assert.assertEquals(a.position(), 0, "Input buffer position changed"); 241 Assert.assertEquals(a.limit(), l, "Input buffer limit changed"); 242 Assert.assertEquals(r.position(), 0, "Result buffer position changed"); 243 Assert.assertEquals(r.limit(), l, "Result buffer limit changed"); 244 Assert.assertEquals(a, r, "Buffers not equal"); 245 } 246 247 @Test(dataProvider = "doubleByteBufferProvider") 248 static void loadReadOnlyStoreByteBuffer(IntFunction<double[]> fa, 249 IntFunction<ByteBuffer> fb) { 250 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), fb); 251 a = a.asReadOnlyBuffer().order(a.order()); 252 ByteBuffer r = fb.apply(a.limit()); 253 254 int l = a.limit(); 255 int s = SPECIES.length() * SPECIES.elementSize() / 8; 256 257 for (int ic = 0; ic < INVOC_COUNT; ic++) { 258 for (int i = 0; i < l; i += s) { 259 DoubleVector av = DoubleVector.fromByteBuffer(SPECIES, a, i); 260 av.intoByteBuffer(r, i); 261 } 262 } 263 Assert.assertEquals(a.position(), 0, "Input buffer position changed"); 264 Assert.assertEquals(a.limit(), l, "Input buffer limit changed"); 265 Assert.assertEquals(r.position(), 0, "Result buffer position changed"); 266 Assert.assertEquals(r.limit(), l, "Result buffer limit changed"); 267 Assert.assertEquals(a, r, "Buffers not equal"); 268 } 269 270 @Test(dataProvider = "doubleByteBufferMaskProvider") 271 static void loadStoreByteBufferMask(IntFunction<double[]> fa, 272 IntFunction<ByteBuffer> fb, 273 IntFunction<boolean[]> fm) { 274 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), fb); 275 ByteBuffer r = fb.apply(a.limit()); 276 boolean[] mask = fm.apply(SPECIES.length()); 277 VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask); 278 279 int l = a.limit(); 280 int s = SPECIES.length() * SPECIES.elementSize() / 8; 281 282 for (int ic = 0; ic < INVOC_COUNT; ic++) { 283 for (int i = 0; i < l; i += s) { 284 DoubleVector av = DoubleVector.fromByteBuffer(SPECIES, a, i, vmask); 285 av.intoByteBuffer(r, i); 286 } 287 } 288 Assert.assertEquals(a.position(), 0, "Input buffer position changed"); 289 Assert.assertEquals(a.limit(), l, "Input buffer limit changed"); 290 Assert.assertEquals(r.position(), 0, "Result buffer position changed"); 291 Assert.assertEquals(r.limit(), l, "Result buffer limit changed"); 292 assertArraysEquals(bufferToArray(a), bufferToArray(r), mask); 293 294 a = toBuffer(fa.apply(SPECIES.length()), fb); 295 r = fb.apply(a.limit()); 296 for (int ic = 0; ic < INVOC_COUNT; ic++) { 297 for (int i = 0; i < l; i += s) { 298 DoubleVector av = DoubleVector.fromByteBuffer(SPECIES, a, i); 299 av.intoByteBuffer(r, i, vmask); 300 } 301 } 302 Assert.assertEquals(a.position(), 0, "Input buffer position changed"); 303 Assert.assertEquals(a.limit(), l, "Input buffer limit changed"); 304 Assert.assertEquals(r.position(), 0, "Result buffer position changed"); 305 Assert.assertEquals(r.limit(), l, "Result buffer limit changed"); 306 assertArraysEquals(bufferToArray(a), bufferToArray(r), mask); 307 } 308 309 @Test(dataProvider = "doubleByteBufferMaskProvider") 310 static void loadReadOnlyStoreByteBufferMask(IntFunction<double[]> fa, 311 IntFunction<ByteBuffer> fb, 312 IntFunction<boolean[]> fm) { 313 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), fb); 314 a = a.asReadOnlyBuffer().order(a.order()); 315 ByteBuffer r = fb.apply(a.limit()); 316 boolean[] mask = fm.apply(SPECIES.length()); 317 VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask); 318 319 int l = a.limit(); 320 int s = SPECIES.length() * SPECIES.elementSize() / 8; 321 322 for (int ic = 0; ic < INVOC_COUNT; ic++) { 323 for (int i = 0; i < l; i += s) { 324 DoubleVector av = DoubleVector.fromByteBuffer(SPECIES, a, i, vmask); 325 av.intoByteBuffer(r, i); 326 } 327 } 328 Assert.assertEquals(a.position(), 0, "Input buffer position changed"); 329 Assert.assertEquals(a.limit(), l, "Input buffer limit changed"); 330 Assert.assertEquals(r.position(), 0, "Result buffer position changed"); 331 Assert.assertEquals(r.limit(), l, "Result buffer limit changed"); 332 assertArraysEquals(bufferToArray(a), bufferToArray(r), mask); 333 } 334 }