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/othervm -ea -esa $vectorteststype$
  28  */
  29 
  30 import jdk.incubator.vector.VectorShape;
  31 import jdk.incubator.vector.VectorSpecies;
  32 import jdk.incubator.vector.VectorShuffle;
  33 import jdk.incubator.vector.VectorMask;
  34 import jdk.incubator.vector.Vector;
  35 
  36 #if[Byte]
  37 import jdk.incubator.vector.ByteVector;
  38 #end[Byte]
  39 #if[Float]
  40 import jdk.incubator.vector.FloatVector;
  41 #end[Float]
  42 #if[Int]
  43 import jdk.incubator.vector.IntVector;
  44 #end[Int]
  45 #if[Double]
  46 import jdk.incubator.vector.DoubleVector;
  47 #end[Double]
  48 #if[Short]
  49 import jdk.incubator.vector.ShortVector;
  50 #end[Short]
  51 #if[Long]
  52 import jdk.incubator.vector.LongVector;
  53 #end[Long]
  54 
  55 import org.testng.Assert;
  56 import org.testng.annotations.DataProvider;
  57 import org.testng.annotations.Test;
  58 
  59 import java.lang.Integer;
  60 import java.util.List;
  61 #if[!byteOrShort]
  62 import java.util.Arrays;
  63 #end[!byteOrShort]
  64 import java.util.function.BiFunction;
  65 import java.util.function.IntFunction;
  66 import java.util.stream.Collectors;
  67 import java.util.stream.Stream;
  68 
  69 @Test
  70 public class $vectorteststype$ extends AbstractVectorTest {
  71 
  72 #if[MaxBit]
  73     static final VectorSpecies<$Wideboxtype$> SPECIES =
  74                 $Type$Vector.SPECIES_MAX;
  75 #else[MaxBit]
  76     static final VectorSpecies<$Wideboxtype$> SPECIES =
  77                 $Type$Vector.SPECIES_$bits$;
  78 #end[MaxBit]
  79 
  80     static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100);
  81 
  82 #if[MaxBit]
  83     static VectorShape getMaxBit() {
  84         return VectorShape.S_Max_BIT;
  85     }
  86 
  87 #end[MaxBit]
  88     interface FUnOp {
  89         $type$ apply($type$ a);
  90     }
  91 
  92     static void assertArraysEquals($type$[] a, $type$[] r, FUnOp f) {
  93         int i = 0;
  94         try {
  95             for (; i < a.length; i++) {
  96                 Assert.assertEquals(r[i], f.apply(a[i]));
  97             }
  98         } catch (AssertionError e) {
  99             Assert.assertEquals(r[i], f.apply(a[i]), "at index #" + i + ", input = " + a[i]);
 100         }
 101     }
 102 
 103     static void assertArraysEquals($type$[] a, $type$[] r, boolean[] mask, FUnOp f) {
 104         int i = 0;
 105         try {
 106             for (; i < a.length; i++) {
 107                 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? f.apply(a[i]) : a[i]);
 108             }
 109         } catch (AssertionError e) {
 110             Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? f.apply(a[i]) : a[i], "at index #" + i + ", input = " + a[i] + ", mask = " + mask[i % SPECIES.length()]);
 111         }
 112     }
 113 
 114     interface FReductionOp {
 115         $type$ apply($type$[] a, int idx);
 116     }
 117 
 118     interface FReductionAllOp {
 119         $type$ apply($type$[] a);
 120     }
 121 
 122     static void assertReductionArraysEquals($type$[] a, $type$[] b, $type$ c,
 123                                             FReductionOp f, FReductionAllOp fa) {
 124         int i = 0;
 125         try {
 126             Assert.assertEquals(c, fa.apply(a));
 127             for (; i < a.length; i += SPECIES.length()) {
 128                 Assert.assertEquals(b[i], f.apply(a, i));
 129             }
 130         } catch (AssertionError e) {
 131             Assert.assertEquals(c, fa.apply(a), "Final result is incorrect!");
 132             Assert.assertEquals(b[i], f.apply(a, i), "at index #" + i);
 133         }
 134     }
 135 
 136     interface FBoolReductionOp {
 137         boolean apply(boolean[] a, int idx);
 138     }
 139 
 140     static void assertReductionBoolArraysEquals(boolean[] a, boolean[] b, FBoolReductionOp f) {
 141         int i = 0;
 142         try {
 143             for (; i < a.length; i += SPECIES.length()) {
 144                 Assert.assertEquals(f.apply(a, i), b[i]);
 145             }
 146         } catch (AssertionError e) {
 147             Assert.assertEquals(f.apply(a, i), b[i], "at index #" + i);
 148         }
 149     }
 150 
 151     static void assertInsertArraysEquals($type$[] a, $type$[] b, $type$ element, int index) {
 152         int i = 0;
 153         try {
 154             for (; i < a.length; i += 1) {
 155                 if(i%SPECIES.length() == index) {
 156                     Assert.assertEquals(b[i], element);
 157                 } else {
 158                     Assert.assertEquals(b[i], a[i]);
 159                 }
 160             }
 161         } catch (AssertionError e) {
 162             if (i%SPECIES.length() == index) {
 163                 Assert.assertEquals(b[i], element, "at index #" + i);
 164             } else {
 165                 Assert.assertEquals(b[i], a[i], "at index #" + i);
 166             }
 167         }
 168     }
 169 
 170     static void assertRearrangeArraysEquals($type$[] a, $type$[] r, int[] order, int vector_len) {
 171         int i = 0, j = 0;
 172         try {
 173             for (; i < a.length; i += vector_len) {
 174                 for (j = 0; j < vector_len; j++) {
 175                     Assert.assertEquals(r[i+j], a[i+order[i+j]]);
 176                 }
 177             }
 178         } catch (AssertionError e) {
 179             int idx = i + j;
 180             Assert.assertEquals(r[i+j], a[i+order[i+j]], "at index #" + idx + ", input = " + a[i+order[i+j]]);
 181         }
 182     }
 183 
 184     interface FBinOp {
 185         $type$ apply($type$ a, $type$ b);
 186     }
 187 
 188     interface FBinMaskOp {
 189         $type$ apply($type$ a, $type$ b, boolean m);
 190 
 191         static FBinMaskOp lift(FBinOp f) {
 192             return (a, b, m) -> m ? f.apply(a, b) : a;
 193         }
 194     }
 195 
 196     static void assertArraysEquals($type$[] a, $type$[] b, $type$[] r, FBinOp f) {
 197         int i = 0;
 198         try {
 199             for (; i < a.length; i++) {
 200                 Assert.assertEquals(r[i], f.apply(a[i], b[i]));
 201             }
 202         } catch (AssertionError e) {
 203             Assert.assertEquals(f.apply(a[i], b[i]), r[i], "(" + a[i] + ", " + b[i] + ") at index #" + i);
 204         }
 205     }
 206 
 207     static void assertArraysEquals($type$[] a, $type$[] b, $type$[] r, boolean[] mask, FBinOp f) {
 208         assertArraysEquals(a, b, r, mask, FBinMaskOp.lift(f));
 209     }
 210 
 211     static void assertArraysEquals($type$[] a, $type$[] b, $type$[] r, boolean[] mask, FBinMaskOp f) {
 212         int i = 0;
 213         try {
 214             for (; i < a.length; i++) {
 215                 Assert.assertEquals(r[i], f.apply(a[i], b[i], mask[i % SPECIES.length()]));
 216             }
 217         } catch (AssertionError err) {
 218             Assert.assertEquals(r[i], f.apply(a[i], b[i], mask[i % SPECIES.length()]), "at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", mask = " + mask[i % SPECIES.length()]);
 219         }
 220     }
 221 
 222     static void assertShiftArraysEquals($type$[] a, $type$[] b, $type$[] r, FBinOp f) {
 223         int i = 0;
 224         int j = 0;
 225         try {
 226             for (; j < a.length; j += SPECIES.length()) {
 227                 for (i = 0; i < SPECIES.length(); i++) {
 228                     Assert.assertEquals(f.apply(a[i+j], b[j]), r[i+j]);
 229                 }
 230             }
 231         } catch (AssertionError e) {
 232             Assert.assertEquals(f.apply(a[i+j], b[j]), r[i+j], "at index #" + i + ", " + j);
 233         }
 234     }
 235 
 236     static void assertShiftArraysEquals($type$[] a, $type$[] b, $type$[] r, boolean[] mask, FBinOp f) {
 237         assertShiftArraysEquals(a, b, r, mask, FBinMaskOp.lift(f));
 238     }
 239 
 240     static void assertShiftArraysEquals($type$[] a, $type$[] b, $type$[] r, boolean[] mask, FBinMaskOp f) {
 241         int i = 0;
 242         int j = 0;
 243         try {
 244             for (; j < a.length; j += SPECIES.length()) {
 245                 for (i = 0; i < SPECIES.length(); i++) {
 246                     Assert.assertEquals(r[i+j], f.apply(a[i+j], b[j], mask[i]));
 247                 }
 248             }
 249         } catch (AssertionError err) {
 250             Assert.assertEquals(r[i+j], f.apply(a[i+j], b[j], mask[i]), "at index #" + i + ", input1 = " + a[i+j] + ", input2 = " + b[j] + ", mask = " + mask[i]);
 251         }
 252     }
 253 
 254 #if[FP]
 255     interface FTernOp {
 256         $type$ apply($type$ a, $type$ b, $type$ c);
 257     }
 258 
 259     interface FTernMaskOp {
 260         $type$ apply($type$ a, $type$ b, $type$ c, boolean m);
 261 
 262         static FTernMaskOp lift(FTernOp f) {
 263             return (a, b, c, m) -> m ? f.apply(a, b, c) : a;
 264         }
 265     }
 266 
 267     static void assertArraysEquals($type$[] a, $type$[] b, $type$[] c, $type$[] r, FTernOp f) {
 268         int i = 0;
 269         try {
 270             for (; i < a.length; i++) {
 271                 Assert.assertEquals(r[i], f.apply(a[i], b[i], c[i]));
 272             }
 273         } catch (AssertionError e) {
 274             Assert.assertEquals(r[i], f.apply(a[i], b[i], c[i]), "at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]);
 275         }
 276     }
 277 
 278     static void assertArraysEquals($type$[] a, $type$[] b, $type$[] c, $type$[] r, boolean[] mask, FTernOp f) {
 279         assertArraysEquals(a, b, c, r, mask, FTernMaskOp.lift(f));
 280     }
 281 
 282     static void assertArraysEquals($type$[] a, $type$[] b, $type$[] c, $type$[] r, boolean[] mask, FTernMaskOp f) {
 283         int i = 0;
 284         try {
 285             for (; i < a.length; i++) {
 286                 Assert.assertEquals(r[i], f.apply(a[i], b[i], c[i], mask[i % SPECIES.length()]));
 287             }
 288         } catch (AssertionError err) {
 289             Assert.assertEquals(r[i], f.apply(a[i], b[i], c[i], mask[i % SPECIES.length()]), "at index #" + i + ", input1 = " + a[i] + ", input2 = "
 290               + b[i] + ", input3 = " + c[i] + ", mask = " + mask[i % SPECIES.length()]);
 291         }
 292     }
 293 
 294     static boolean isWithin1Ulp($type$ actual, $type$ expected) {
 295         if ($Type$.isNaN(expected) && !$Type$.isNaN(actual)) {
 296             return false;
 297         } else if (!$Type$.isNaN(expected) && $Type$.isNaN(actual)) {
 298             return false;
 299         }
 300 
 301         $type$ low = Math.nextDown(expected);
 302         $type$ high = Math.nextUp(expected);
 303 
 304         if ($Type$.compare(low, expected) > 0) {
 305             return false;
 306         }
 307 
 308         if ($Type$.compare(high, expected) < 0) {
 309             return false;
 310         }
 311 
 312         return true;
 313     }
 314 
 315     static void assertArraysEqualsWithinOneUlp($type$[] a, $type$[] r, FUnOp mathf, FUnOp strictmathf) {
 316         int i = 0;
 317         try {
 318             // Check that result is within 1 ulp of strict math or equivalent to math implementation.
 319             for (; i < a.length; i++) {
 320                 Assert.assertTrue($Type$.compare(r[i], mathf.apply(a[i])) == 0 ||
 321                                     isWithin1Ulp(r[i], strictmathf.apply(a[i])));
 322             }
 323         } catch (AssertionError e) {
 324             Assert.assertTrue($Type$.compare(r[i], mathf.apply(a[i])) == 0, "at index #" + i + ", input = " + a[i] + ", actual = " + r[i] + ", expected = " + mathf.apply(a[i]));
 325             Assert.assertTrue(isWithin1Ulp(r[i], strictmathf.apply(a[i])), "at index #" + i + ", input = " + a[i] + ", actual = " + r[i] + ", expected (within 1 ulp) = " + strictmathf.apply(a[i]));
 326         }
 327     }
 328 
 329     static void assertArraysEqualsWithinOneUlp($type$[] a, $type$[] b, $type$[] r, FBinOp mathf, FBinOp strictmathf) {
 330         int i = 0;
 331         try {
 332             // Check that result is within 1 ulp of strict math or equivalent to math implementation.
 333             for (; i < a.length; i++) {
 334                 Assert.assertTrue($Type$.compare(r[i], mathf.apply(a[i], b[i])) == 0 ||
 335                                     isWithin1Ulp(r[i], strictmathf.apply(a[i], b[i])));
 336             }
 337         } catch (AssertionError e) {
 338             Assert.assertTrue($Type$.compare(r[i], mathf.apply(a[i], b[i])) == 0, "at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", actual = " + r[i] + ", expected = " + mathf.apply(a[i], b[i]));
 339             Assert.assertTrue(isWithin1Ulp(r[i], strictmathf.apply(a[i], b[i])), "at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", actual = " + r[i] + ", expected (within 1 ulp) = " + strictmathf.apply(a[i], b[i]));
 340         }
 341     }
 342 #end[FP]
 343 
 344     interface FBinArrayOp {
 345         $type$ apply($type$[] a, int b);
 346     }
 347 
 348     static void assertArraysEquals($type$[] a, $type$[] r, FBinArrayOp f) {
 349         int i = 0;
 350         try {
 351             for (; i < a.length; i++) {
 352                 Assert.assertEquals(f.apply(a, i), r[i]);
 353             }
 354         } catch (AssertionError e) {
 355             Assert.assertEquals(f.apply(a,i), r[i], "at index #" + i);
 356         }
 357     }
 358 #if[!byteOrShort]
 359     interface FGatherScatterOp {
 360         $type$[] apply($type$[] a, int ix, int[] b, int iy);
 361     }
 362 
 363     static void assertArraysEquals($type$[] a, int[] b, $type$[] r, FGatherScatterOp f) {
 364         int i = 0;
 365         try {
 366             for (; i < a.length; i += SPECIES.length()) {
 367                 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()),
 368                   f.apply(a, i, b, i));
 369             }
 370         } catch (AssertionError e) {
 371             $type$[] ref = f.apply(a, i, b, i);
 372             $type$[] res = Arrays.copyOfRange(r, i, i+SPECIES.length());
 373             Assert.assertEquals(ref, res,
 374               "(ref: " + Arrays.toString(ref) + ", res: " + Arrays.toString(res) + ", a: "
 375               + Arrays.toString(Arrays.copyOfRange(a, i, i+SPECIES.length()))
 376               + ", b: "
 377               + Arrays.toString(Arrays.copyOfRange(b, i, i+SPECIES.length()))
 378               + " at index #" + i);
 379         }
 380     }
 381 
 382 #end[!byteOrShort]
 383 
 384     static final List<IntFunction<$type$[]>> $TYPE$_GENERATORS = List.of(
 385             withToString("$type$[-i * 5]", (int s) -> {
 386                 return fill(s * 1000,
 387                             i -> ($type$)(-i * 5));
 388             }),
 389             withToString("$type$[i * 5]", (int s) -> {
 390                 return fill(s * 1000,
 391                             i -> ($type$)(i * 5));
 392             }),
 393             withToString("$type$[i + 1]", (int s) -> {
 394                 return fill(s * 1000,
 395                             i -> ((($type$)(i + 1) == 0) ? 1 : ($type$)(i + 1)));
 396             }),
 397             withToString("$type$[cornerCaseValue(i)]", (int s) -> {
 398                 return fill(s * 1000,
 399                             i -> cornerCaseValue(i));
 400             })
 401     );
 402 
 403     // Create combinations of pairs
 404     // @@@ Might be sensitive to order e.g. div by 0
 405     static final List<List<IntFunction<$type$[]>>> $TYPE$_GENERATOR_PAIRS =
 406         Stream.of($TYPE$_GENERATORS.get(0)).
 407                 flatMap(fa -> $TYPE$_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
 408                 collect(Collectors.toList());
 409 
 410     @DataProvider
 411     public Object[][] boolUnaryOpProvider() {
 412         return BOOL_ARRAY_GENERATORS.stream().
 413                 map(f -> new Object[]{f}).
 414                 toArray(Object[][]::new);
 415     }
 416 
 417 #if[FP]
 418     static final List<List<IntFunction<$type$[]>>> $TYPE$_GENERATOR_TRIPLES =
 419         $TYPE$_GENERATOR_PAIRS.stream().
 420                 flatMap(pair -> $TYPE$_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
 421                 collect(Collectors.toList());
 422 #end[FP]
 423 
 424     @DataProvider
 425     public Object[][] $type$BinaryOpProvider() {
 426         return $TYPE$_GENERATOR_PAIRS.stream().map(List::toArray).
 427                 toArray(Object[][]::new);
 428     }
 429 
 430     @DataProvider
 431     public Object[][] $type$IndexedOpProvider() {
 432         return $TYPE$_GENERATOR_PAIRS.stream().map(List::toArray).
 433                 toArray(Object[][]::new);
 434     }
 435 
 436     @DataProvider
 437     public Object[][] $type$BinaryOpMaskProvider() {
 438         return BOOLEAN_MASK_GENERATORS.stream().
 439                 flatMap(fm -> $TYPE$_GENERATOR_PAIRS.stream().map(lfa -> {
 440                     return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
 441                 })).
 442                 toArray(Object[][]::new);
 443     }
 444 
 445 #if[FP]
 446     @DataProvider
 447     public Object[][] $type$TernaryOpProvider() {
 448         return $TYPE$_GENERATOR_TRIPLES.stream().map(List::toArray).
 449                 toArray(Object[][]::new);
 450     }
 451 
 452     @DataProvider
 453     public Object[][] $type$TernaryOpMaskProvider() {
 454         return BOOLEAN_MASK_GENERATORS.stream().
 455                 flatMap(fm -> $TYPE$_GENERATOR_TRIPLES.stream().map(lfa -> {
 456                     return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
 457                 })).
 458                 toArray(Object[][]::new);
 459     }
 460 #end[FP]
 461 
 462     @DataProvider
 463     public Object[][] $type$UnaryOpProvider() {
 464         return $TYPE$_GENERATORS.stream().
 465                 map(f -> new Object[]{f}).
 466                 toArray(Object[][]::new);
 467     }
 468 
 469     @DataProvider
 470     public Object[][] $type$UnaryOpMaskProvider() {
 471         return BOOLEAN_MASK_GENERATORS.stream().
 472                 flatMap(fm -> $TYPE$_GENERATORS.stream().map(fa -> {
 473                     return new Object[] {fa, fm};
 474                 })).
 475                 toArray(Object[][]::new);
 476     }
 477 
 478     @DataProvider
 479     public Object[][] $type$UnaryOpShuffleProvider() {
 480         return INT_SHUFFLE_GENERATORS.stream().
 481                 flatMap(fs -> $TYPE$_GENERATORS.stream().map(fa -> {
 482                     return new Object[] {fa, fs};
 483                 })).
 484                 toArray(Object[][]::new);
 485     }
 486 
 487     @DataProvider
 488     public Object[][] $type$UnaryOpIndexProvider() {
 489         return INT_INDEX_GENERATORS.stream().
 490                 flatMap(fs -> $TYPE$_GENERATORS.stream().map(fa -> {
 491                     return new Object[] {fa, fs};
 492                 })).
 493                 toArray(Object[][]::new);
 494     }
 495 
 496 
 497     static final List<IntFunction<$type$[]>> $TYPE$_COMPARE_GENERATORS = List.of(
 498             withToString("$type$[i]", (int s) -> {
 499                 return fill(s * 1000,
 500                             i -> ($type$)i);
 501             }),
 502             withToString("$type$[i + 1]", (int s) -> {
 503                 return fill(s * 1000,
 504                             i -> ($type$)(i + 1));
 505             }),
 506             withToString("$type$[i - 2]", (int s) -> {
 507                 return fill(s * 1000,
 508                             i -> ($type$)(i - 2));
 509             }),
 510             withToString("$type$[zigZag(i)]", (int s) -> {
 511                 return fill(s * 1000,
 512                             i -> i%3 == 0 ? ($type$)i : (i%3 == 1 ? ($type$)(i + 1) : ($type$)(i - 2)));
 513             }),
 514             withToString("$type$[cornerCaseValue(i)]", (int s) -> {
 515                 return fill(s * 1000,
 516                             i -> cornerCaseValue(i));
 517             })
 518     );
 519 
 520     static final List<List<IntFunction<$type$[]>>> $TYPE$_COMPARE_GENERATOR_PAIRS =
 521         $TYPE$_COMPARE_GENERATORS.stream().
 522                 flatMap(fa -> $TYPE$_COMPARE_GENERATORS.stream().map(fb -> List.of(fa, fb))).
 523                 collect(Collectors.toList());
 524 
 525     @DataProvider
 526     public Object[][] $type$CompareOpProvider() {
 527         return $TYPE$_COMPARE_GENERATOR_PAIRS.stream().map(List::toArray).
 528                 toArray(Object[][]::new);
 529     }
 530 
 531     interface To$Type$F {
 532         $type$ apply(int i);
 533     }
 534 
 535     static $type$[] fill(int s , To$Type$F f) {
 536         return fill(new $type$[s], f);
 537     }
 538 
 539     static $type$[] fill($type$[] a, To$Type$F f) {
 540         for (int i = 0; i < a.length; i++) {
 541             a[i] = f.apply(i);
 542         }
 543         return a;
 544     }
 545 
 546     static $type$ cornerCaseValue(int i) {
 547 #if[FP]
 548         switch(i % 7) {
 549             case 0:
 550                 return $Wideboxtype$.MAX_VALUE;
 551             case 1:
 552                 return $Wideboxtype$.MIN_VALUE;
 553             case 2:
 554                 return $Wideboxtype$.NEGATIVE_INFINITY;
 555             case 3:
 556                 return $Wideboxtype$.POSITIVE_INFINITY;
 557             case 4:
 558                 return $Wideboxtype$.NaN;
 559             case 5:
 560                 return ($type$)0.0;
 561             default:
 562                 return ($type$)-0.0;
 563         }
 564 #else[FP]
 565         switch(i % 5) {
 566             case 0:
 567                 return $Wideboxtype$.MAX_VALUE;
 568             case 1:
 569                 return $Wideboxtype$.MIN_VALUE;
 570             case 2:
 571                 return $Wideboxtype$.MIN_VALUE;
 572             case 3:
 573                 return $Wideboxtype$.MAX_VALUE;
 574             default:
 575                 return ($type$)0;
 576         }
 577 #end[FP]
 578     }
 579    static $type$ get($type$[] a, int i) {
 580        return ($type$) a[i];
 581    }
 582 
 583    static final IntFunction<$type$[]> fr = (vl) -> {
 584         int length = 1000 * vl;
 585         return new $type$[length];
 586     };
 587 
 588     static final IntFunction<boolean[]> fmr = (vl) -> {
 589         int length = 1000 * vl;
 590         return new boolean[length];
 591     };