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 Float128VectorLoadStoreTests 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.FloatVector; 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.FloatBuffer; 43 import java.nio.ByteOrder; 44 import java.util.List; 45 import java.util.function.IntFunction; 46 47 @Test 48 public class Float128VectorLoadStoreTests extends AbstractVectorTest { 49 static final Species<Float> SPECIES = 50 FloatVector.SPECIES_128; 51 52 static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 10); 53 54 static void assertArraysEquals(float[] a, float[] r, boolean[] mask) { 55 int i = 0; 56 try { 57 for (; i < a.length; i++) { 58 Assert.assertEquals(mask[i % SPECIES.length()] ? a[i] : (float) 0, r[i]); 59 } 60 } catch (AssertionError e) { 61 Assert.assertEquals(mask[i % SPECIES.length()] ? a[i] : (float) 0, r[i], "at index #" + i); 62 } 63 } 64 65 static void assertArraysEquals(float[] a, float[] 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(float[] a, float[] 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]] : (float) 0, r[i]); 81 } 82 } catch (AssertionError e) { 83 Assert.assertEquals(mask[i % SPECIES.length()] ? a[im[i]] : (float) 0, r[i], "at index #" + i); 84 } 85 } 86 87 static final List<IntFunction<float[]>> FLOAT_GENERATORS = List.of( 88 withToString("float[i * 5]", (int s) -> { 89 return fill(s * 1000, 90 i -> (float)(i * 5)); 91 }), 92 withToString("float[i + 1]", (int s) -> { 93 return fill(s * 1000, 94 i -> (((float)(i + 1) == 0) ? 1 : (float)(i + 1))); 95 }) 96 ); 97 98 @DataProvider 99 public Object[][] floatProvider() { 100 return FLOAT_GENERATORS.stream(). 101 map(f -> new Object[]{f}). 102 toArray(Object[][]::new); 103 } 104 105 @DataProvider 106 public Object[][] floatMaskProvider() { 107 return BOOLEAN_MASK_GENERATORS.stream(). 108 flatMap(fm -> FLOAT_GENERATORS.stream().map(fa -> { 109 return new Object[] {fa, fm}; 110 })). 111 toArray(Object[][]::new); 112 } 113 114 @DataProvider 115 public Object[][] floatIndexMapProvider() { 116 return INDEX_GENERATORS.stream(). 117 flatMap(fim -> FLOAT_GENERATORS.stream().map(fa -> { 118 return new Object[] {fa, fim}; 119 })). 120 toArray(Object[][]::new); 121 } 122 123 @DataProvider 124 public Object[][] floatIndexMapMaskProvider() { 125 return BOOLEAN_MASK_GENERATORS.stream(). 126 flatMap(fm -> INDEX_GENERATORS.stream(). 127 flatMap(fim -> FLOAT_GENERATORS.stream().map(fa -> { 128 return new Object[] {fa, fim, fm}; 129 }))). 130 toArray(Object[][]::new); 131 } 132 133 @DataProvider 134 public Object[][] floatByteBufferProvider() { 135 return FLOAT_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[][] floatByteBufferMaskProvider() { 144 return BOOLEAN_MASK_GENERATORS.stream(). 145 flatMap(fm -> FLOAT_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(float[] a, IntFunction<ByteBuffer> fb) { 153 ByteBuffer bb = fb.apply(a.length * SPECIES.elementSize() / 8); 154 for (float v : a) { 155 bb.putFloat(v); 156 } 157 return bb.clear(); 158 } 159 160 static float[] bufferToArray(ByteBuffer bb) { 161 FloatBuffer db = bb.asFloatBuffer(); 162 float[] d = new float[db.capacity()]; 163 db.get(d); 164 return d; 165 } 166 167 interface ToFloatF { 168 float apply(int i); 169 } 170 171 static float[] fill(int s , ToFloatF f) { 172 return fill(new float[s], f); 173 } 174 175 static float[] fill(float[] a, ToFloatF 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 = "floatProvider") 183 static void loadStoreArray(IntFunction<float[]> fa) { 184 float[] a = fa.apply(SPECIES.length()); 185 float[] r = new float[a.length]; 186 187 for (int ic = 0; ic < INVOC_COUNT; ic++) { 188 for (int i = 0; i < a.length; i += SPECIES.length()) { 189 FloatVector av = FloatVector.fromArray(SPECIES, a, i); 190 av.intoArray(r, i); 191 } 192 } 193 Assert.assertEquals(a, r); 194 } 195 196 @Test(dataProvider = "floatMaskProvider") 197 static void loadStoreMaskArray(IntFunction<float[]> fa, 198 IntFunction<boolean[]> fm) { 199 float[] a = fa.apply(SPECIES.length()); 200 float[] r = new float[a.length]; 201 boolean[] mask = fm.apply(SPECIES.length()); 202 Vector.Mask<Float> vmask = FloatVector.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 FloatVector av = FloatVector.fromArray(SPECIES, a, i, vmask); 207 av.intoArray(r, i); 208 } 209 } 210 assertArraysEquals(a, r, mask); 211 212 r = new float[a.length]; 213 for (int ic = 0; ic < INVOC_COUNT; ic++) { 214 for (int i = 0; i < a.length; i += SPECIES.length()) { 215 FloatVector av = FloatVector.fromArray(SPECIES, a, i); 216 av.intoArray(r, i, vmask); 217 } 218 } 219 220 assertArraysEquals(a, r, mask); 221 } 222 223 224 @Test(dataProvider = "floatByteBufferProvider") 225 static void loadStoreByteBuffer(IntFunction<float[]> 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 FloatVector av = FloatVector.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 = "floatByteBufferProvider") 247 static void loadReadOnlyStoreByteBuffer(IntFunction<float[]> 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 FloatVector av = FloatVector.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 = "floatByteBufferMaskProvider") 270 static void loadStoreByteBufferMask(IntFunction<float[]> 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<Float> vmask = FloatVector.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 FloatVector av = FloatVector.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 FloatVector av = FloatVector.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 = "floatByteBufferMaskProvider") 309 static void loadReadOnlyStoreByteBufferMask(IntFunction<float[]> 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<Float> vmask = FloatVector.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 FloatVector av = FloatVector.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 }