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