1 /*
   2  * Copyright (c) 2017, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have
  23  * questions.
  24  */
  25 package jdk.incubator.vector;
  26 
  27 import jdk.internal.vm.annotation.ForceInline;
  28 
  29 import java.nio.ByteBuffer;
  30 import java.nio.ByteOrder;
  31 import java.nio.FloatBuffer;
  32 import java.util.concurrent.ThreadLocalRandom;
  33 
  34 @SuppressWarnings("cast")
  35 public abstract class FloatVector<S extends Vector.Shape> extends Vector<Float,S> {
  36 
  37     FloatVector() {}
  38 
  39     // Unary operator
  40 
  41     interface FUnOp {
  42         float apply(int i, float a);
  43     }
  44 
  45     abstract FloatVector<S> uOp(FUnOp f);
  46 
  47     abstract FloatVector<S> uOp(Mask<Float, S> m, FUnOp f);
  48 
  49     // Binary operator
  50 
  51     interface FBinOp {
  52         float apply(int i, float a, float b);
  53     }
  54 
  55     abstract FloatVector<S> bOp(Vector<Float,S> o, FBinOp f);
  56 
  57     abstract FloatVector<S> bOp(Vector<Float,S> o, Mask<Float, S> m, FBinOp f);
  58 
  59     // Trinary operator
  60 
  61     interface FTriOp {
  62         float apply(int i, float a, float b, float c);
  63     }
  64 
  65     abstract FloatVector<S> tOp(Vector<Float,S> o1, Vector<Float,S> o2, FTriOp f);
  66 
  67     abstract FloatVector<S> tOp(Vector<Float,S> o1, Vector<Float,S> o2, Mask<Float, S> m, FTriOp f);
  68 
  69     // Reduction operator
  70 
  71     abstract float rOp(float v, FBinOp f);
  72 
  73     // Binary test
  74 
  75     interface FBinTest {
  76         boolean apply(int i, float a, float b);
  77     }
  78 
  79     abstract Mask<Float, S> bTest(Vector<Float,S> o, FBinTest f);
  80 
  81     // Foreach
  82 
  83     interface FUnCon {
  84         void apply(int i, float a);
  85     }
  86 
  87     abstract void forEach(FUnCon f);
  88 
  89     abstract void forEach(Mask<Float, S> m, FUnCon f);
  90 
  91     //
  92 
  93     @Override
  94     public FloatVector<S> add(Vector<Float,S> o) {
  95         return bOp(o, (i, a, b) -> (float) (a + b));
  96     }
  97 
  98     public abstract FloatVector<S> add(float o);
  99 
 100     @Override
 101     public FloatVector<S> add(Vector<Float,S> o, Mask<Float, S> m) {
 102         return bOp(o, m, (i, a, b) -> (float) (a + b));
 103     }
 104 
 105     public abstract FloatVector<S> add(float o, Mask<Float, S> m);
 106 
 107     @Override
 108     public FloatVector<S> addSaturate(Vector<Float,S> o) {
 109         return bOp(o, (i, a, b) -> (float) ((a >= Integer.MAX_VALUE || Integer.MAX_VALUE - b > a) ? Integer.MAX_VALUE : a + b));
 110     }
 111 
 112     public abstract FloatVector<S> addSaturate(float o);
 113 
 114     @Override
 115     public FloatVector<S> addSaturate(Vector<Float,S> o, Mask<Float, S> m) {
 116         return bOp(o, m, (i, a, b) -> (float) ((a >= Integer.MAX_VALUE || Integer.MAX_VALUE - b > a) ? Integer.MAX_VALUE : a + b));
 117     }
 118 
 119     public abstract FloatVector<S> addSaturate(float o, Mask<Float, S> m);
 120 
 121     @Override
 122     public FloatVector<S> sub(Vector<Float,S> o) {
 123         return bOp(o, (i, a, b) -> (float) (a - b));
 124     }
 125 
 126     public abstract FloatVector<S> sub(float o);
 127 
 128     @Override
 129     public FloatVector<S> sub(Vector<Float,S> o, Mask<Float, S> m) {
 130         return bOp(o, m, (i, a, b) -> (float) (a - b));
 131     }
 132 
 133     public abstract FloatVector<S> sub(float o, Mask<Float, S> m);
 134 
 135     @Override
 136     public FloatVector<S> subSaturate(Vector<Float,S> o) {
 137         return bOp(o, (i, a, b) -> (float) ((a >= Float.MIN_VALUE || Float.MIN_VALUE + b > a) ? Float.MAX_VALUE : a - b));
 138     }
 139 
 140     public abstract FloatVector<S> subSaturate(float o);
 141 
 142     @Override
 143     public FloatVector<S> subSaturate(Vector<Float,S> o, Mask<Float, S> m) {
 144         return bOp(o, m, (i, a, b) -> (float) ((a >= Float.MIN_VALUE || Float.MIN_VALUE + b > a) ? Float.MAX_VALUE : a - b));
 145     }
 146 
 147     public abstract FloatVector<S> subSaturate(float o, Mask<Float, S> m);
 148 
 149     @Override
 150     public FloatVector<S> mul(Vector<Float,S> o) {
 151         return bOp(o, (i, a, b) -> (float) (a * b));
 152     }
 153 
 154     public abstract FloatVector<S> mul(float o);
 155 
 156     @Override
 157     public FloatVector<S> mul(Vector<Float,S> o, Mask<Float, S> m) {
 158         return bOp(o, m, (i, a, b) -> (float) (a * b));
 159     }
 160 
 161     public abstract FloatVector<S> mul(float o, Mask<Float, S> m);
 162 
 163     @Override
 164     public FloatVector<S> neg() {
 165         return uOp((i, a) -> (float) (-a));
 166     }
 167 
 168     @Override
 169     public FloatVector<S> neg(Mask<Float, S> m) {
 170         return uOp(m, (i, a) -> (float) (-a));
 171     }
 172 
 173     @Override
 174     public FloatVector<S> abs() {
 175         return uOp((i, a) -> (float) Math.abs(a));
 176     }
 177 
 178     @Override
 179     public FloatVector<S> abs(Mask<Float, S> m) {
 180         return uOp(m, (i, a) -> (float) Math.abs(a));
 181     }
 182 
 183     @Override
 184     public FloatVector<S> min(Vector<Float,S> o) {
 185         return bOp(o, (i, a, b) -> (a <= b) ? a : b);
 186     }
 187 
 188     public abstract FloatVector<S> min(float o);
 189 
 190     @Override
 191     public FloatVector<S> max(Vector<Float,S> o) {
 192         return bOp(o, (i, a, b) -> (a >= b) ? a : b);
 193     }
 194 
 195     public abstract FloatVector<S> max(float o);
 196 
 197     @Override
 198     public Mask<Float, S> equal(Vector<Float,S> o) {
 199         return bTest(o, (i, a, b) -> a == b);
 200     }
 201 
 202     public abstract Mask<Float, S> equal(float o);
 203 
 204     @Override
 205     public Mask<Float, S> notEqual(Vector<Float,S> o) {
 206         return bTest(o, (i, a, b) -> a != b);
 207     }
 208 
 209     public abstract Mask<Float, S> notEqual(float o);
 210 
 211     @Override
 212     public Mask<Float, S> lessThan(Vector<Float,S> o) {
 213         return bTest(o, (i, a, b) -> a < b);
 214     }
 215 
 216     public abstract Mask<Float, S> lessThan(float o);
 217 
 218     @Override
 219     public Mask<Float, S> lessThanEq(Vector<Float,S> o) {
 220         return bTest(o, (i, a, b) -> a <= b);
 221     }
 222 
 223     public abstract Mask<Float, S> lessThanEq(float o);
 224 
 225     @Override
 226     public Mask<Float, S> greaterThan(Vector<Float,S> o) {
 227         return bTest(o, (i, a, b) -> a > b);
 228     }
 229 
 230     public abstract Mask<Float, S> greaterThan(float o);
 231 
 232     @Override
 233     public Mask<Float, S> greaterThanEq(Vector<Float,S> o) {
 234         return bTest(o, (i, a, b) -> a >= b);
 235     }
 236 
 237     public abstract Mask<Float, S> greaterThanEq(float o);
 238 
 239     @Override
 240     public FloatVector<S> blend(Vector<Float,S> o, Mask<Float, S> m) {
 241         return bOp(o, (i, a, b) -> m.getElement(i) ? b : a);
 242     }
 243 
 244     public abstract FloatVector<S> blend(float o, Mask<Float, S> m);
 245 
 246     @Override
 247     public abstract FloatVector<S> shuffle(Vector<Float,S> o, Shuffle<Float, S> m);
 248 
 249     @Override
 250     public abstract FloatVector<S> swizzle(Shuffle<Float, S> m);
 251 
 252     @Override
 253     @ForceInline
 254     public <T extends Shape> FloatVector<T> resize(Species<Float, T> species) {
 255         return (FloatVector<T>) species.resize(this);
 256     }
 257 
 258     @Override
 259     public abstract FloatVector<S> rotateEL(int i);
 260 
 261     @Override
 262     public abstract FloatVector<S> rotateER(int i);
 263 
 264     @Override
 265     public abstract FloatVector<S> shiftEL(int i);
 266 
 267     @Override
 268     public abstract FloatVector<S> shiftER(int i);
 269 
 270     public FloatVector<S> div(Vector<Float,S> o) {
 271         return bOp(o, (i, a, b) -> (float) (a / b));
 272     }
 273 
 274     public abstract FloatVector<S> div(float o);
 275 
 276     public FloatVector<S> div(Vector<Float,S> o, Mask<Float, S> m) {
 277         return bOp(o, m, (i, a, b) -> (float) (a / b));
 278     }
 279 
 280     public abstract FloatVector<S> div(float o, Mask<Float, S> m);
 281 
 282     public FloatVector<S> sqrt() {
 283         return uOp((i, a) -> (float) Math.sqrt((double) a));
 284     }
 285 
 286     public FloatVector<S> sqrt(Mask<Float,S> m) {
 287         return uOp(m, (i, a) -> (float) Math.sqrt((double) a));
 288     }
 289 
 290     public FloatVector<S> tan() {
 291         return uOp((i, a) -> (float) Math.tan((double) a));
 292     }
 293 
 294     public FloatVector<S> tan(Mask<Float,S> m) {
 295         return uOp(m, (i, a) -> (float) Math.tan((double) a));
 296     }
 297 
 298     public FloatVector<S> tanh() {
 299         return uOp((i, a) -> (float) Math.tanh((double) a));
 300     }
 301 
 302     public FloatVector<S> tanh(Mask<Float,S> m) {
 303         return uOp(m, (i, a) -> (float) Math.tanh((double) a));
 304     }
 305 
 306     public FloatVector<S> sin() {
 307         return uOp((i, a) -> (float) Math.sin((double) a));
 308     }
 309 
 310     public FloatVector<S> sin(Mask<Float,S> m) {
 311         return uOp(m, (i, a) -> (float) Math.sin((double) a));
 312     }
 313 
 314     public FloatVector<S> sinh() {
 315         return uOp((i, a) -> (float) Math.sinh((double) a));
 316     }
 317 
 318     public FloatVector<S> sinh(Mask<Float,S> m) {
 319         return uOp(m, (i, a) -> (float) Math.sinh((double) a));
 320     }
 321 
 322     public FloatVector<S> cos() {
 323         return uOp((i, a) -> (float) Math.cos((double) a));
 324     }
 325 
 326     public FloatVector<S> cos(Mask<Float,S> m) {
 327         return uOp(m, (i, a) -> (float) Math.cos((double) a));
 328     }
 329 
 330     public FloatVector<S> cosh() {
 331         return uOp((i, a) -> (float) Math.cosh((double) a));
 332     }
 333 
 334     public FloatVector<S> cosh(Mask<Float,S> m) {
 335         return uOp(m, (i, a) -> (float) Math.cosh((double) a));
 336     }
 337 
 338     public FloatVector<S> asin() {
 339         return uOp((i, a) -> (float) Math.asin((double) a));
 340     }
 341 
 342     public FloatVector<S> asin(Mask<Float,S> m) {
 343         return uOp(m, (i, a) -> (float) Math.asin((double) a));
 344     }
 345 
 346     public FloatVector<S> acos() {
 347         return uOp((i, a) -> (float) Math.acos((double) a));
 348     }
 349 
 350     public FloatVector<S> acos(Mask<Float,S> m) {
 351         return uOp(m, (i, a) -> (float) Math.acos((double) a));
 352     }
 353 
 354     public FloatVector<S> atan() {
 355         return uOp((i, a) -> (float) Math.atan((double) a));
 356     }
 357 
 358     public FloatVector<S> atan(Mask<Float,S> m) {
 359         return uOp(m, (i, a) -> (float) Math.atan((double) a));
 360     }
 361 
 362     public FloatVector<S> atan2(Vector<Float,S> o) {
 363         return bOp(o, (i, a, b) -> (float) Math.atan2((double) a, (double) b));
 364     }
 365 
 366     public abstract FloatVector<S> atan2(float o);
 367 
 368     public FloatVector<S> atan2(Vector<Float,S> o, Mask<Float,S> m) {
 369         return bOp(o, m, (i, a, b) -> (float) Math.atan2((double) a, (double) b));
 370     }
 371 
 372     public abstract FloatVector<S> atan2(float o, Mask<Float,S> m);
 373 
 374     public FloatVector<S> cbrt() {
 375         return uOp((i, a) -> (float) Math.cbrt((double) a));
 376     }
 377 
 378     public FloatVector<S> cbrt(Mask<Float,S> m) {
 379         return uOp(m, (i, a) -> (float) Math.cbrt((double) a));
 380     }
 381 
 382     public FloatVector<S> log() {
 383         return uOp((i, a) -> (float) Math.log((double) a));
 384     }
 385 
 386     public FloatVector<S> log(Mask<Float,S> m) {
 387         return uOp(m, (i, a) -> (float) Math.log((double) a));
 388     }
 389 
 390     public FloatVector<S> log10() {
 391         return uOp((i, a) -> (float) Math.log10((double) a));
 392     }
 393 
 394     public FloatVector<S> log10(Mask<Float,S> m) {
 395         return uOp(m, (i, a) -> (float) Math.log10((double) a));
 396     }
 397 
 398     public FloatVector<S> log1p() {
 399         return uOp((i, a) -> (float) Math.log1p((double) a));
 400     }
 401 
 402     public FloatVector<S> log1p(Mask<Float,S> m) {
 403         return uOp(m, (i, a) -> (float) Math.log1p((double) a));
 404     }
 405 
 406     public FloatVector<S> pow(Vector<Float,S> o) {
 407         return bOp(o, (i, a, b) -> (float) Math.pow((double) a, (double) b));
 408     }
 409 
 410     public abstract FloatVector<S> pow(float o);
 411 
 412     public FloatVector<S> pow(Vector<Float,S> o, Mask<Float,S> m) {
 413         return bOp(o, m, (i, a, b) -> (float) Math.pow((double) a, (double) b));
 414     }
 415 
 416     public abstract FloatVector<S> pow(float o, Mask<Float,S> m);
 417 
 418     public FloatVector<S> exp() {
 419         return uOp((i, a) -> (float) Math.exp((double) a));
 420     }
 421 
 422     public FloatVector<S> exp(Mask<Float,S> m) {
 423         return uOp(m, (i, a) -> (float) Math.exp((double) a));
 424     }
 425 
 426     public FloatVector<S> expm1() {
 427         return uOp((i, a) -> (float) Math.expm1((double) a));
 428     }
 429 
 430     public FloatVector<S> expm1(Mask<Float,S> m) {
 431         return uOp(m, (i, a) -> (float) Math.expm1((double) a));
 432     }
 433 
 434     public FloatVector<S> fma(Vector<Float,S> o1, Vector<Float,S> o2) {
 435         return tOp(o1, o2, (i, a, b, c) -> Math.fma(a, b, c));
 436     }
 437 
 438     public abstract FloatVector<S> fma(float o1, float o2);
 439 
 440     public FloatVector<S> fma(Vector<Float,S> o1, Vector<Float,S> o2, Mask<Float,S> m) {
 441         return tOp(o1, o2, m, (i, a, b, c) -> Math.fma(a, b, c));
 442     }
 443 
 444     public abstract FloatVector<S> fma(float o1, float o2, Mask<Float,S> m);
 445 
 446     public FloatVector<S> hypot(Vector<Float,S> o) {
 447         return bOp(o, (i, a, b) -> (float) Math.hypot((double) a, (double) b));
 448     }
 449 
 450     public abstract FloatVector<S> hypot(float o);
 451 
 452     public FloatVector<S> hypot(Vector<Float,S> o, Mask<Float,S> m) {
 453         return bOp(o, m, (i, a, b) -> (float) Math.hypot((double) a, (double) b));
 454     }
 455 
 456     public abstract FloatVector<S> hypot(float o, Mask<Float,S> m);
 457 
 458 
 459     @Override
 460     public void intoByteArray(byte[] a, int ix) {
 461         ByteBuffer bb = ByteBuffer.wrap(a, ix, a.length - ix);
 462         intoByteBuffer(bb);
 463     }
 464 
 465     @Override
 466     public void intoByteArray(byte[] a, int ix, Mask<Float, S> m) {
 467         ByteBuffer bb = ByteBuffer.wrap(a, ix, a.length - ix);
 468         intoByteBuffer(bb, m);
 469     }
 470 
 471     @Override
 472     public void intoByteBuffer(ByteBuffer bb) {
 473         FloatBuffer fb = bb.asFloatBuffer();
 474         forEach((i, a) -> fb.put(a));
 475     }
 476 
 477     @Override
 478     public void intoByteBuffer(ByteBuffer bb, Mask<Float, S> m) {
 479         FloatBuffer fb = bb.asFloatBuffer();
 480         forEach((i, a) -> {
 481             if (m.getElement(i))
 482                 fb.put(a);
 483             else
 484                 fb.position(fb.position() + 1);
 485         });
 486     }
 487 
 488     @Override
 489     public void intoByteBuffer(ByteBuffer bb, int ix) {
 490         bb = bb.duplicate().position(ix);
 491         FloatBuffer fb = bb.asFloatBuffer();
 492         forEach((i, a) -> fb.put(i, a));
 493     }
 494 
 495     @Override
 496     public void intoByteBuffer(ByteBuffer bb, int ix, Mask<Float, S> m) {
 497         bb = bb.duplicate().position(ix);
 498         FloatBuffer fb = bb.asFloatBuffer();
 499         forEach(m, (i, a) -> fb.put(i, a));
 500     }
 501 
 502 
 503     // Type specific horizontal reductions
 504 
 505     public float addAll() {
 506         return rOp((float) 0, (i, a, b) -> (float) (a + b));
 507     }
 508 
 509     public float subAll() {
 510         return rOp((float) 0, (i, a, b) -> (float) (a - b));
 511     }
 512 
 513     public float mulAll() {
 514         return rOp((float) 1, (i, a, b) -> (float) (a * b));
 515     }
 516 
 517     public float minAll() {
 518         return rOp(Float.MAX_VALUE, (i, a, b) -> a > b ? b : a);
 519     }
 520 
 521     public float maxAll() {
 522         return rOp(Float.MIN_VALUE, (i, a, b) -> a < b ? b : a);
 523     }
 524 
 525 
 526     // Type specific accessors
 527 
 528     public abstract float get(int i);
 529 
 530     public abstract FloatVector<S> with(int i, float e);
 531 
 532     // Type specific extractors
 533 
 534     @ForceInline
 535     public float[] toArray() {
 536         float[] a = new float[species().length()];
 537         intoArray(a, 0);
 538         return a;
 539     }
 540 
 541     public void intoArray(float[] a, int ax) {
 542         forEach((i, a_) -> a[ax + i] = a_);
 543     }
 544 
 545     public void intoArray(float[] a, int ax, Mask<Float, S> m) {
 546         forEach(m, (i, a_) -> a[ax + i] = a_);
 547     }
 548 
 549     public void intoArray(float[] a, int ax, int[] indexMap, int mx) {
 550         forEach((i, a_) -> a[ax + indexMap[mx + i]] = a_);
 551     }
 552 
 553     public void intoArray(float[] a, int ax, Mask<Float, S> m, int[] indexMap, int mx) {
 554         forEach(m, (i, a_) -> a[ax + indexMap[mx + i]] = a_);
 555     }
 556 
 557     // Species
 558 
 559     @Override
 560     public abstract FloatSpecies<S> species();
 561 
 562     public static abstract class FloatSpecies<S extends Vector.Shape> extends Vector.Species<Float, S> {
 563         interface FOp {
 564             float apply(int i);
 565         }
 566 
 567         abstract FloatVector<S> op(FOp f);
 568 
 569         abstract FloatVector<S> op(Mask<Float, S> m, FOp f);
 570 
 571         // Factories
 572 
 573         @Override
 574         public FloatVector<S> zero() {
 575             return op(i -> 0);
 576         }
 577 
 578         public FloatVector<S> broadcast(float e) {
 579             return op(i -> e);
 580         }
 581 
 582         public FloatVector<S> single(float e) {
 583             return op(i -> i == 0 ? e : (float) 0);
 584         }
 585 
 586         public FloatVector<S> random() {
 587             ThreadLocalRandom r = ThreadLocalRandom.current();
 588             return op(i -> r.nextFloat());
 589         }
 590 
 591         public FloatVector<S> scalars(float... es) {
 592             return op(i -> es[i]);
 593         }
 594 
 595         public FloatVector<S> fromArray(float[] a, int ax) {
 596             return op(i -> a[ax + i]);
 597         }
 598 
 599         public FloatVector<S> fromArray(float[] a, int ax, Mask<Float, S> m) {
 600             return op(m, i -> a[ax + i]);
 601         }
 602 
 603         public FloatVector<S> fromArray(float[] a, int ax, int[] indexMap, int mx) {
 604             return op(i -> a[ax + indexMap[mx + i]]);
 605         }
 606 
 607         public FloatVector<S> fromArray(float[] a, int ax, Mask<Float, S> m, int[] indexMap, int mx) {
 608             return op(m, i -> a[ax + indexMap[mx + i]]);
 609         }
 610 
 611         @Override
 612         public FloatVector<S> fromByteArray(byte[] a, int ix) {
 613             ByteBuffer bb = ByteBuffer.wrap(a, ix, a.length - ix);
 614             return fromByteBuffer(bb);
 615         }
 616 
 617         @Override
 618         public FloatVector<S> fromByteArray(byte[] a, int ix, Mask<Float, S> m) {
 619             ByteBuffer bb = ByteBuffer.wrap(a, ix, a.length - ix);
 620             return fromByteBuffer(bb, m);
 621         }
 622 
 623         @Override
 624         public FloatVector<S> fromByteBuffer(ByteBuffer bb) {
 625             FloatBuffer fb = bb.asFloatBuffer();
 626             return op(i -> fb.get());
 627         }
 628 
 629         @Override
 630         public FloatVector<S> fromByteBuffer(ByteBuffer bb, Mask<Float, S> m) {
 631             FloatBuffer fb = bb.asFloatBuffer();
 632             return op(i -> {
 633                 if(m.getElement(i))
 634                     return fb.get();
 635                 else {
 636                     fb.position(fb.position() + 1);
 637                     return (float) 0;
 638                 }
 639             });
 640         }
 641 
 642         @Override
 643         public FloatVector<S> fromByteBuffer(ByteBuffer bb, int ix) {
 644             bb = bb.duplicate().position(ix);
 645             FloatBuffer fb = bb.asFloatBuffer();
 646             return op(i -> fb.get(i));
 647         }
 648 
 649         @Override
 650         public FloatVector<S> fromByteBuffer(ByteBuffer bb, int ix, Mask<Float, S> m) {
 651             bb = bb.duplicate().position(ix);
 652             FloatBuffer fb = bb.asFloatBuffer();
 653             return op(m, i -> fb.get(i));
 654         }
 655 
 656         @Override
 657         @ForceInline
 658         public <F, T extends Shape> FloatVector<S> reshape(Vector<F, T> o) {
 659             int blen = Math.max(o.species().bitSize(), bitSize()) / Byte.SIZE;
 660             ByteBuffer bb = ByteBuffer.allocate(blen).order(ByteOrder.nativeOrder());
 661             o.intoByteBuffer(bb, 0);
 662             return fromByteBuffer(bb, 0);
 663         }
 664 
 665         @Override
 666         @ForceInline
 667         public <F> FloatVector<S> rebracket(Vector<F, S> o) {
 668             return reshape(o);
 669         }
 670 
 671         @Override
 672         @ForceInline
 673         public <T extends Shape> FloatVector<S> resize(Vector<Float, T> o) {
 674             return reshape(o);
 675         }
 676 
 677         @Override
 678         @SuppressWarnings("unchecked")
 679         public <F, T extends Shape> FloatVector<S> cast(Vector<F, T> v) {
 680             // Allocate array of required size
 681             float[] a = new float[length()];
 682 
 683             Class<?> vtype = v.species().elementType();
 684             int limit = Math.min(v.species().length(), length());
 685             if (vtype == Byte.class) {
 686                 ByteVector<T> tv = (ByteVector<T>)v;
 687                 for (int i = 0; i < limit; i++) {
 688                     a[i] = (float) tv.get(i);
 689                 }
 690             } else if (vtype == Short.class) {
 691                 ShortVector<T> tv = (ShortVector<T>)v;
 692                 for (int i = 0; i < limit; i++) {
 693                     a[i] = (float) tv.get(i);
 694                 }
 695             } else if (vtype == Integer.class) {
 696                 IntVector<T> tv = (IntVector<T>)v;
 697                 for (int i = 0; i < limit; i++) {
 698                     a[i] = (float) tv.get(i);
 699                 }
 700             } else if (vtype == Long.class){
 701                 LongVector<T> tv = (LongVector<T>)v;
 702                 for (int i = 0; i < limit; i++) {
 703                     a[i] = (float) tv.get(i);
 704                 }
 705             } else if (vtype == Float.class){
 706                 FloatVector<T> tv = (FloatVector<T>)v;
 707                 for (int i = 0; i < limit; i++) {
 708                     a[i] = (float) tv.get(i);
 709                 }
 710             } else if (vtype == Double.class){
 711                 DoubleVector<T> tv = (DoubleVector<T>)v;
 712                 for (int i = 0; i < limit; i++) {
 713                     a[i] = (float) tv.get(i);
 714                 }
 715             } else {
 716                 throw new UnsupportedOperationException("Bad lane type for casting.");
 717             }
 718 
 719             return scalars(a);
 720         }
 721 
 722     }
 723 }