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 #if[!byte] 32 import java.nio.$Type$Buffer; 33 #end[!byte] 34 import java.util.Objects; 35 import java.util.concurrent.ThreadLocalRandom; 36 37 38 /** 39 * A specialized {@link Vector} representing an ordered immutable sequence of 40 * {@code $type$} values. 41 * 42 * @param <S> the type of shape of this vector 43 */ 44 @SuppressWarnings("cast") 45 public abstract class $abstractvectortype$<S extends Vector.Shape> extends Vector<$Boxtype$,S> { 46 47 $abstractvectortype$() {} 48 49 // Unary operator 50 51 interface FUnOp { 52 $type$ apply(int i, $type$ a); 53 } 54 55 abstract $abstractvectortype$<S> uOp(FUnOp f); 56 57 abstract $abstractvectortype$<S> uOp(Mask<$Boxtype$, S> m, FUnOp f); 58 59 // Binary operator 60 61 interface FBinOp { 62 $type$ apply(int i, $type$ a, $type$ b); 63 } 64 65 abstract $abstractvectortype$<S> bOp(Vector<$Boxtype$,S> o, FBinOp f); 66 67 abstract $abstractvectortype$<S> bOp(Vector<$Boxtype$,S> o, Mask<$Boxtype$, S> m, FBinOp f); 68 69 // Trinary operator 70 71 interface FTriOp { 72 $type$ apply(int i, $type$ a, $type$ b, $type$ c); 73 } 74 75 abstract $abstractvectortype$<S> tOp(Vector<$Boxtype$,S> o1, Vector<$Boxtype$,S> o2, FTriOp f); 76 77 abstract $abstractvectortype$<S> tOp(Vector<$Boxtype$,S> o1, Vector<$Boxtype$,S> o2, Mask<$Boxtype$, S> m, FTriOp f); 78 79 // Reduction operator 80 81 abstract $type$ rOp($type$ v, FBinOp f); 82 83 // Binary test 84 85 interface FBinTest { 86 boolean apply(int i, $type$ a, $type$ b); 87 } 88 89 abstract Mask<$Boxtype$, S> bTest(Vector<$Boxtype$,S> o, FBinTest f); 90 91 // Foreach 92 93 interface FUnCon { 94 void apply(int i, $type$ a); 95 } 96 97 abstract void forEach(FUnCon f); 98 99 abstract void forEach(Mask<$Boxtype$, S> m, FUnCon f); 100 101 // 102 103 @Override 104 public $abstractvectortype$<S> add(Vector<$Boxtype$,S> o) { 105 return bOp(o, (i, a, b) -> ($type$) (a + b)); 106 } 107 108 /** 109 * Adds this vector to the result of broadcasting an input scalar. 110 * <p> 111 * This is a vector binary operation where the primitive addition operation 112 * ({@code +}) is applied to lane elements. 113 * 114 * @param b the input scalar 115 * @return the result of adding this vector to the broadcast of an input 116 * scalar 117 */ 118 public abstract $abstractvectortype$<S> add($type$ b); 119 120 @Override 121 public $abstractvectortype$<S> add(Vector<$Boxtype$,S> o, Mask<$Boxtype$, S> m) { 122 return bOp(o, m, (i, a, b) -> ($type$) (a + b)); 123 } 124 125 /** 126 * Adds this vector to the result of broadcasting an input scalar, 127 * selecting lane elements controlled by a mask. 128 * <p> 129 * This is a vector binary operation where the primitive addition operation 130 * ({@code +}) is applied to lane elements. 131 * 132 * @param b the input vector 133 * @param m the mask controlling lane selection 134 * @return the result of adding this vector to the broadcast of an input 135 * scalar 136 */ 137 public abstract $abstractvectortype$<S> add($type$ b, Mask<$Boxtype$, S> m); 138 139 @Override 140 public $abstractvectortype$<S> addSaturate(Vector<$Boxtype$,S> o) { 141 return bOp(o, (i, a, b) -> ($type$) ((a >= Integer.MAX_VALUE || Integer.MAX_VALUE - b > a) ? Integer.MAX_VALUE : a + b)); 142 } 143 144 public abstract $abstractvectortype$<S> addSaturate($type$ o); 145 146 @Override 147 public $abstractvectortype$<S> addSaturate(Vector<$Boxtype$,S> o, Mask<$Boxtype$, S> m) { 148 return bOp(o, m, (i, a, b) -> ($type$) ((a >= Integer.MAX_VALUE || Integer.MAX_VALUE - b > a) ? Integer.MAX_VALUE : a + b)); 149 } 150 151 public abstract $abstractvectortype$<S> addSaturate($type$ o, Mask<$Boxtype$, S> m); 152 153 @Override 154 public $abstractvectortype$<S> sub(Vector<$Boxtype$,S> o) { 155 return bOp(o, (i, a, b) -> ($type$) (a - b)); 156 } 157 158 public abstract $abstractvectortype$<S> sub($type$ o); 159 160 @Override 161 public $abstractvectortype$<S> sub(Vector<$Boxtype$,S> o, Mask<$Boxtype$, S> m) { 162 return bOp(o, m, (i, a, b) -> ($type$) (a - b)); 163 } 164 165 public abstract $abstractvectortype$<S> sub($type$ o, Mask<$Boxtype$, S> m); 166 167 @Override 168 public $abstractvectortype$<S> subSaturate(Vector<$Boxtype$,S> o) { 169 return bOp(o, (i, a, b) -> ($type$) ((a >= $Wideboxtype$.MIN_VALUE || $Wideboxtype$.MIN_VALUE + b > a) ? $Wideboxtype$.MAX_VALUE : a - b)); 170 } 171 172 public abstract $abstractvectortype$<S> subSaturate($type$ o); 173 174 @Override 175 public $abstractvectortype$<S> subSaturate(Vector<$Boxtype$,S> o, Mask<$Boxtype$, S> m) { 176 return bOp(o, m, (i, a, b) -> ($type$) ((a >= $Wideboxtype$.MIN_VALUE || $Wideboxtype$.MIN_VALUE + b > a) ? $Wideboxtype$.MAX_VALUE : a - b)); 177 } 178 179 public abstract $abstractvectortype$<S> subSaturate($type$ o, Mask<$Boxtype$, S> m); 180 181 @Override 182 public $abstractvectortype$<S> mul(Vector<$Boxtype$,S> o) { 183 return bOp(o, (i, a, b) -> ($type$) (a * b)); 184 } 185 186 public abstract $abstractvectortype$<S> mul($type$ o); 187 188 @Override 189 public $abstractvectortype$<S> mul(Vector<$Boxtype$,S> o, Mask<$Boxtype$, S> m) { 190 return bOp(o, m, (i, a, b) -> ($type$) (a * b)); 191 } 192 193 public abstract $abstractvectortype$<S> mul($type$ o, Mask<$Boxtype$, S> m); 194 195 @Override 196 public $abstractvectortype$<S> neg() { 197 return uOp((i, a) -> ($type$) (-a)); 198 } 199 200 @Override 201 public $abstractvectortype$<S> neg(Mask<$Boxtype$, S> m) { 202 return uOp(m, (i, a) -> ($type$) (-a)); 203 } 204 205 @Override 206 public $abstractvectortype$<S> abs() { 207 return uOp((i, a) -> ($type$) Math.abs(a)); 208 } 209 210 @Override 211 public $abstractvectortype$<S> abs(Mask<$Boxtype$, S> m) { 212 return uOp(m, (i, a) -> ($type$) Math.abs(a)); 213 } 214 215 @Override 216 public $abstractvectortype$<S> min(Vector<$Boxtype$,S> o) { 217 return bOp(o, (i, a, b) -> (a <= b) ? a : b); 218 } 219 220 public abstract $abstractvectortype$<S> min($type$ o); 221 222 @Override 223 public $abstractvectortype$<S> max(Vector<$Boxtype$,S> o) { 224 return bOp(o, (i, a, b) -> (a >= b) ? a : b); 225 } 226 227 public abstract $abstractvectortype$<S> max($type$ o); 228 229 @Override 230 public Mask<$Boxtype$, S> equal(Vector<$Boxtype$,S> o) { 231 return bTest(o, (i, a, b) -> a == b); 232 } 233 234 public abstract Mask<$Boxtype$, S> equal($type$ o); 235 236 @Override 237 public Mask<$Boxtype$, S> notEqual(Vector<$Boxtype$,S> o) { 238 return bTest(o, (i, a, b) -> a != b); 239 } 240 241 public abstract Mask<$Boxtype$, S> notEqual($type$ o); 242 243 @Override 244 public Mask<$Boxtype$, S> lessThan(Vector<$Boxtype$,S> o) { 245 return bTest(o, (i, a, b) -> a < b); 246 } 247 248 public abstract Mask<$Boxtype$, S> lessThan($type$ o); 249 250 @Override 251 public Mask<$Boxtype$, S> lessThanEq(Vector<$Boxtype$,S> o) { 252 return bTest(o, (i, a, b) -> a <= b); 253 } 254 255 public abstract Mask<$Boxtype$, S> lessThanEq($type$ o); 256 257 @Override 258 public Mask<$Boxtype$, S> greaterThan(Vector<$Boxtype$,S> o) { 259 return bTest(o, (i, a, b) -> a > b); 260 } 261 262 public abstract Mask<$Boxtype$, S> greaterThan($type$ o); 263 264 @Override 265 public Mask<$Boxtype$, S> greaterThanEq(Vector<$Boxtype$,S> o) { 266 return bTest(o, (i, a, b) -> a >= b); 267 } 268 269 public abstract Mask<$Boxtype$, S> greaterThanEq($type$ o); 270 271 @Override 272 public $abstractvectortype$<S> blend(Vector<$Boxtype$,S> o, Mask<$Boxtype$, S> m) { 273 return bOp(o, (i, a, b) -> m.getElement(i) ? b : a); 274 } 275 276 public abstract $abstractvectortype$<S> blend($type$ o, Mask<$Boxtype$, S> m); 277 278 @Override 279 public abstract $abstractvectortype$<S> shuffle(Vector<$Boxtype$,S> o, Shuffle<$Boxtype$, S> m); 280 281 @Override 282 public abstract $abstractvectortype$<S> swizzle(Shuffle<$Boxtype$, S> m); 283 284 @Override 285 @ForceInline 286 public <T extends Shape> $abstractvectortype$<T> resize(Species<$Boxtype$, T> species) { 287 return ($abstractvectortype$<T>) species.reshape(this); 288 } 289 290 @Override 291 public abstract $abstractvectortype$<S> rotateEL(int i); 292 293 @Override 294 public abstract $abstractvectortype$<S> rotateER(int i); 295 296 @Override 297 public abstract $abstractvectortype$<S> shiftEL(int i); 298 299 @Override 300 public abstract $abstractvectortype$<S> shiftER(int i); 301 302 #if[FP] 303 public $abstractvectortype$<S> div(Vector<$Boxtype$,S> o) { 304 return bOp(o, (i, a, b) -> ($type$) (a / b)); 305 } 306 307 public abstract $abstractvectortype$<S> div($type$ o); 308 309 public $abstractvectortype$<S> div(Vector<$Boxtype$,S> o, Mask<$Boxtype$, S> m) { 310 return bOp(o, m, (i, a, b) -> ($type$) (a / b)); 311 } 312 313 public abstract $abstractvectortype$<S> div($type$ o, Mask<$Boxtype$, S> m); 314 315 public $abstractvectortype$<S> sqrt() { 316 return uOp((i, a) -> ($type$) Math.sqrt((double) a)); 317 } 318 319 public $abstractvectortype$<S> sqrt(Mask<$Boxtype$,S> m) { 320 return uOp(m, (i, a) -> ($type$) Math.sqrt((double) a)); 321 } 322 323 public $abstractvectortype$<S> tan() { 324 return uOp((i, a) -> ($type$) Math.tan((double) a)); 325 } 326 327 public $abstractvectortype$<S> tan(Mask<$Boxtype$,S> m) { 328 return uOp(m, (i, a) -> ($type$) Math.tan((double) a)); 329 } 330 331 public $abstractvectortype$<S> tanh() { 332 return uOp((i, a) -> ($type$) Math.tanh((double) a)); 333 } 334 335 public $abstractvectortype$<S> tanh(Mask<$Boxtype$,S> m) { 336 return uOp(m, (i, a) -> ($type$) Math.tanh((double) a)); 337 } 338 339 public $abstractvectortype$<S> sin() { 340 return uOp((i, a) -> ($type$) Math.sin((double) a)); 341 } 342 343 public $abstractvectortype$<S> sin(Mask<$Boxtype$,S> m) { 344 return uOp(m, (i, a) -> ($type$) Math.sin((double) a)); 345 } 346 347 public $abstractvectortype$<S> sinh() { 348 return uOp((i, a) -> ($type$) Math.sinh((double) a)); 349 } 350 351 public $abstractvectortype$<S> sinh(Mask<$Boxtype$,S> m) { 352 return uOp(m, (i, a) -> ($type$) Math.sinh((double) a)); 353 } 354 355 public $abstractvectortype$<S> cos() { 356 return uOp((i, a) -> ($type$) Math.cos((double) a)); 357 } 358 359 public $abstractvectortype$<S> cos(Mask<$Boxtype$,S> m) { 360 return uOp(m, (i, a) -> ($type$) Math.cos((double) a)); 361 } 362 363 public $abstractvectortype$<S> cosh() { 364 return uOp((i, a) -> ($type$) Math.cosh((double) a)); 365 } 366 367 public $abstractvectortype$<S> cosh(Mask<$Boxtype$,S> m) { 368 return uOp(m, (i, a) -> ($type$) Math.cosh((double) a)); 369 } 370 371 public $abstractvectortype$<S> asin() { 372 return uOp((i, a) -> ($type$) Math.asin((double) a)); 373 } 374 375 public $abstractvectortype$<S> asin(Mask<$Boxtype$,S> m) { 376 return uOp(m, (i, a) -> ($type$) Math.asin((double) a)); 377 } 378 379 public $abstractvectortype$<S> acos() { 380 return uOp((i, a) -> ($type$) Math.acos((double) a)); 381 } 382 383 public $abstractvectortype$<S> acos(Mask<$Boxtype$,S> m) { 384 return uOp(m, (i, a) -> ($type$) Math.acos((double) a)); 385 } 386 387 public $abstractvectortype$<S> atan() { 388 return uOp((i, a) -> ($type$) Math.atan((double) a)); 389 } 390 391 public $abstractvectortype$<S> atan(Mask<$Boxtype$,S> m) { 392 return uOp(m, (i, a) -> ($type$) Math.atan((double) a)); 393 } 394 395 public $abstractvectortype$<S> atan2(Vector<$Boxtype$,S> o) { 396 return bOp(o, (i, a, b) -> ($type$) Math.atan2((double) a, (double) b)); 397 } 398 399 public abstract $abstractvectortype$<S> atan2($type$ o); 400 401 public $abstractvectortype$<S> atan2(Vector<$Boxtype$,S> o, Mask<$Boxtype$,S> m) { 402 return bOp(o, m, (i, a, b) -> ($type$) Math.atan2((double) a, (double) b)); 403 } 404 405 public abstract $abstractvectortype$<S> atan2($type$ o, Mask<$Boxtype$,S> m); 406 407 public $abstractvectortype$<S> cbrt() { 408 return uOp((i, a) -> ($type$) Math.cbrt((double) a)); 409 } 410 411 public $abstractvectortype$<S> cbrt(Mask<$Boxtype$,S> m) { 412 return uOp(m, (i, a) -> ($type$) Math.cbrt((double) a)); 413 } 414 415 public $abstractvectortype$<S> log() { 416 return uOp((i, a) -> ($type$) Math.log((double) a)); 417 } 418 419 public $abstractvectortype$<S> log(Mask<$Boxtype$,S> m) { 420 return uOp(m, (i, a) -> ($type$) Math.log((double) a)); 421 } 422 423 public $abstractvectortype$<S> log10() { 424 return uOp((i, a) -> ($type$) Math.log10((double) a)); 425 } 426 427 public $abstractvectortype$<S> log10(Mask<$Boxtype$,S> m) { 428 return uOp(m, (i, a) -> ($type$) Math.log10((double) a)); 429 } 430 431 public $abstractvectortype$<S> log1p() { 432 return uOp((i, a) -> ($type$) Math.log1p((double) a)); 433 } 434 435 public $abstractvectortype$<S> log1p(Mask<$Boxtype$,S> m) { 436 return uOp(m, (i, a) -> ($type$) Math.log1p((double) a)); 437 } 438 439 public $abstractvectortype$<S> pow(Vector<$Boxtype$,S> o) { 440 return bOp(o, (i, a, b) -> ($type$) Math.pow((double) a, (double) b)); 441 } 442 443 public abstract $abstractvectortype$<S> pow($type$ o); 444 445 public $abstractvectortype$<S> pow(Vector<$Boxtype$,S> o, Mask<$Boxtype$,S> m) { 446 return bOp(o, m, (i, a, b) -> ($type$) Math.pow((double) a, (double) b)); 447 } 448 449 public abstract $abstractvectortype$<S> pow($type$ o, Mask<$Boxtype$,S> m); 450 451 public $abstractvectortype$<S> exp() { 452 return uOp((i, a) -> ($type$) Math.exp((double) a)); 453 } 454 455 public $abstractvectortype$<S> exp(Mask<$Boxtype$,S> m) { 456 return uOp(m, (i, a) -> ($type$) Math.exp((double) a)); 457 } 458 459 public $abstractvectortype$<S> expm1() { 460 return uOp((i, a) -> ($type$) Math.expm1((double) a)); 461 } 462 463 public $abstractvectortype$<S> expm1(Mask<$Boxtype$,S> m) { 464 return uOp(m, (i, a) -> ($type$) Math.expm1((double) a)); 465 } 466 467 public $abstractvectortype$<S> fma(Vector<$Boxtype$,S> o1, Vector<$Boxtype$,S> o2) { 468 return tOp(o1, o2, (i, a, b, c) -> Math.fma(a, b, c)); 469 } 470 471 public abstract $abstractvectortype$<S> fma($type$ o1, $type$ o2); 472 473 public $abstractvectortype$<S> fma(Vector<$Boxtype$,S> o1, Vector<$Boxtype$,S> o2, Mask<$Boxtype$,S> m) { 474 return tOp(o1, o2, m, (i, a, b, c) -> Math.fma(a, b, c)); 475 } 476 477 public abstract $abstractvectortype$<S> fma($type$ o1, $type$ o2, Mask<$Boxtype$,S> m); 478 479 public $abstractvectortype$<S> hypot(Vector<$Boxtype$,S> o) { 480 return bOp(o, (i, a, b) -> ($type$) Math.hypot((double) a, (double) b)); 481 } 482 483 public abstract $abstractvectortype$<S> hypot($type$ o); 484 485 public $abstractvectortype$<S> hypot(Vector<$Boxtype$,S> o, Mask<$Boxtype$,S> m) { 486 return bOp(o, m, (i, a, b) -> ($type$) Math.hypot((double) a, (double) b)); 487 } 488 489 public abstract $abstractvectortype$<S> hypot($type$ o, Mask<$Boxtype$,S> m); 490 #end[FP] 491 492 #if[BITWISE] 493 public $abstractvectortype$<S> and(Vector<$Boxtype$,S> o) { 494 return bOp(o, (i, a, b) -> ($type$) (a & b)); 495 } 496 497 public abstract $abstractvectortype$<S> and($type$ o); 498 499 public $abstractvectortype$<S> and(Vector<$Boxtype$,S> o, Mask<$Boxtype$, S> m) { 500 return bOp(o, m, (i, a, b) -> ($type$) (a & b)); 501 } 502 503 public abstract $abstractvectortype$<S> and($type$ o, Mask<$Boxtype$, S> m); 504 505 public $abstractvectortype$<S> or(Vector<$Boxtype$,S> o) { 506 return bOp(o, (i, a, b) -> ($type$) (a | b)); 507 } 508 509 public abstract $abstractvectortype$<S> or($type$ o); 510 511 public $abstractvectortype$<S> or(Vector<$Boxtype$,S> o, Mask<$Boxtype$, S> m) { 512 return bOp(o, m, (i, a, b) -> ($type$) (a | b)); 513 } 514 515 public abstract $abstractvectortype$<S> or($type$ o, Mask<$Boxtype$, S> m); 516 517 public $abstractvectortype$<S> xor(Vector<$Boxtype$,S> o) { 518 return bOp(o, (i, a, b) -> ($type$) (a ^ b)); 519 } 520 521 public abstract $abstractvectortype$<S> xor($type$ o); 522 523 public $abstractvectortype$<S> xor(Vector<$Boxtype$,S> o, Mask<$Boxtype$, S> m) { 524 return bOp(o, m, (i, a, b) -> ($type$) (a ^ b)); 525 } 526 527 public abstract $abstractvectortype$<S> xor($type$ o, Mask<$Boxtype$, S> m); 528 529 public $abstractvectortype$<S> not() { 530 return uOp((i, a) -> ($type$) (~a)); 531 } 532 533 public $abstractvectortype$<S> not(Mask<$Boxtype$, S> m) { 534 return uOp(m, (i, a) -> ($type$) (~a)); 535 } 536 537 // logical shift left 538 public $abstractvectortype$<S> shiftL(int s) { 539 return uOp((i, a) -> ($type$) (a << s)); 540 } 541 542 public $abstractvectortype$<S> shiftL(int s, Mask<$Boxtype$, S> m) { 543 return uOp(m, (i, a) -> ($type$) (a << s)); 544 } 545 546 #if[intOrLong] 547 public $abstractvectortype$<S> shiftL(Vector<$Boxtype$,S> o) { 548 return bOp(o, (i, a, b) -> ($type$) (a << b)); 549 } 550 551 public $abstractvectortype$<S> shiftL(Vector<$Boxtype$,S> o, Mask<$Boxtype$, S> m) { 552 return bOp(o, m, (i, a, b) -> ($type$) (a << b)); 553 } 554 #end[intOrLong] 555 556 // logical, or unsigned, shift right 557 public $abstractvectortype$<S> shiftR(int s) { 558 return uOp((i, a) -> ($type$) (a >>> s)); 559 } 560 561 public $abstractvectortype$<S> shiftR(int s, Mask<$Boxtype$, S> m) { 562 return uOp(m, (i, a) -> ($type$) (a >>> s)); 563 } 564 565 #if[intOrLong] 566 public $abstractvectortype$<S> shiftR(Vector<$Boxtype$,S> o) { 567 return bOp(o, (i, a, b) -> ($type$) (a >>> b)); 568 } 569 570 public $abstractvectortype$<S> shiftR(Vector<$Boxtype$,S> o, Mask<$Boxtype$, S> m) { 571 return bOp(o, m, (i, a, b) -> ($type$) (a >>> b)); 572 } 573 #end[intOrLong] 574 575 // arithmetic, or signed, shift right 576 public $abstractvectortype$<S> aShiftR(int s) { 577 return uOp((i, a) -> ($type$) (a >> s)); 578 } 579 580 public $abstractvectortype$<S> aShiftR(int s, Mask<$Boxtype$, S> m) { 581 return uOp(m, (i, a) -> ($type$) (a >> s)); 582 } 583 584 #if[intOrLong] 585 public $abstractvectortype$<S> ashiftR(Vector<$Boxtype$,S> o) { 586 return bOp(o, (i, a, b) -> ($type$) (a >> b)); 587 } 588 589 public $abstractvectortype$<S> ashiftR(Vector<$Boxtype$,S> o, Mask<$Boxtype$, S> m) { 590 return bOp(o, m, (i, a, b) -> ($type$) (a >> b)); 591 } 592 #end[intOrLong] 593 594 public $abstractvectortype$<S> rotateL(int j) { 595 return uOp((i, a) -> ($type$) $Wideboxtype$.rotateLeft(a, j)); 596 } 597 598 public $abstractvectortype$<S> rotateR(int j) { 599 return uOp((i, a) -> ($type$) $Wideboxtype$.rotateRight(a, j)); 600 } 601 #end[BITWISE] 602 603 @Override 604 public void intoByteArray(byte[] a, int ix) { 605 ByteBuffer bb = ByteBuffer.wrap(a, ix, a.length - ix).order(ByteOrder.nativeOrder()); 606 intoByteBuffer(bb); 607 } 608 609 @Override 610 public void intoByteArray(byte[] a, int ix, Mask<$Boxtype$, S> m) { 611 ByteBuffer bb = ByteBuffer.wrap(a, ix, a.length - ix).order(ByteOrder.nativeOrder()); 612 intoByteBuffer(bb, m); 613 } 614 615 @Override 616 public void intoByteBuffer(ByteBuffer bb) { 617 $Type$Buffer fb = bb{#if[byte]?;:.as$Type$Buffer();} 618 forEach((i, a) -> fb.put(a)); 619 } 620 621 @Override 622 public void intoByteBuffer(ByteBuffer bb, Mask<$Boxtype$, S> m) { 623 $Type$Buffer fb = bb{#if[byte]?;:.as$Type$Buffer();} 624 forEach((i, a) -> { 625 if (m.getElement(i)) 626 fb.put(a); 627 else 628 fb.position(fb.position() + 1); 629 }); 630 } 631 632 @Override 633 public void intoByteBuffer(ByteBuffer bb, int ix) { 634 bb = bb.duplicate().position(ix); 635 $Type$Buffer fb = bb{#if[byte]?;:.as$Type$Buffer();} 636 forEach((i, a) -> fb.put(i, a)); 637 } 638 639 @Override 640 public void intoByteBuffer(ByteBuffer bb, int ix, Mask<$Boxtype$, S> m) { 641 bb = bb.duplicate().position(ix); 642 $Type$Buffer fb = bb{#if[byte]?;:.as$Type$Buffer();} 643 forEach(m, (i, a) -> fb.put(i, a)); 644 } 645 646 647 // Type specific horizontal reductions 648 649 #if[BITWISE] 650 /** 651 * Sums all lane elements of this vector. 652 * <p> 653 * This is an associative vector reduction operation where the addition 654 * operation ({@code +}) is applied to lane elements, and the identity value 655 * is {@code 0}. 656 * 657 * @return the sum of all the lane elements of this vector 658 */ 659 #end[BITWISE] 660 public $type$ addAll() { 661 return rOp(($type$) 0, (i, a, b) -> ($type$) (a + b)); 662 } 663 664 public $type$ subAll() { 665 return rOp(($type$) 0, (i, a, b) -> ($type$) (a - b)); 666 } 667 668 public $type$ mulAll() { 669 return rOp(($type$) 1, (i, a, b) -> ($type$) (a * b)); 670 } 671 672 public $type$ minAll() { 673 return rOp($Boxtype$.MAX_VALUE, (i, a, b) -> a > b ? b : a); 674 } 675 676 public $type$ maxAll() { 677 return rOp($Boxtype$.MIN_VALUE, (i, a, b) -> a < b ? b : a); 678 } 679 680 #if[BITWISE] 681 public $type$ orAll() { 682 return rOp(($type$) 0, (i, a, b) -> ($type$) (a | b)); 683 } 684 685 public $type$ andAll() { 686 return rOp(($type$) -1, (i, a, b) -> ($type$) (a & b)); 687 } 688 689 public $type$ xorAll() { 690 return rOp(($type$) 0, (i, a, b) -> ($type$) (a ^ b)); 691 } 692 #end[BITWISE] 693 694 // Type specific accessors 695 696 /** 697 * Gets the lane element at lane index {@code i} 698 * 699 * @param i the lane index 700 * @return the lane element at lane index {@code i} 701 */ 702 public abstract $type$ get(int i); 703 704 /** 705 * Replaces the lane element of this vector at lane index {@code i} with 706 * value {@code e}. 707 * <p> 708 * This is a cross-lane operation and behaves it returns the result of 709 * blending this vector with an input vector that is the result of 710 * broadcasting {@code e} and a mask that has only one lane set at lane 711 * index {@code i}. 712 * 713 * @param i the lane index of the lane element to be replaced 714 * @param e the value to be placed 715 * @return the result of replacing the lane element of this vector at lane 716 * index {@code i} with value {@code e}. 717 */ 718 public abstract $abstractvectortype$<S> with(int i, $type$ e); 719 720 // Type specific extractors 721 722 /** 723 * Returns an array containing the lane elements of this vector. 724 * <p> 725 * This method behaves as if it {@link #intoArray($type$[], int)} stores} 726 * this vector into an allocated array and returns the array as follows: 727 * <pre>{@code 728 * $type$[] a = new $type$[this.length()]; 729 * this.intoArray(a, 0); 730 * return a; 731 * }</pre> 732 * 733 * @return an array containing the the lane elements of this vector 734 */ 735 @ForceInline 736 public $type$[] toArray() { 737 $type$[] a = new $type$[species().length()]; 738 intoArray(a, 0); 739 return a; 740 } 741 742 /** 743 * Stores this vector into an array starting at offset. 744 * <p> 745 * For each vector lane, where {@code N} is the vector lane index, 746 * the lane element at index {@code N} is stored into the array at index 747 * {@code i + N}. 748 * 749 * @param a the array 750 * @param i the offset into the array 751 * @throws IndexOutOfBoundsException if {@code i < 0}, or 752 * {@code i > a.length - this.length()} 753 */ 754 public void intoArray($type$[] a, int i) { 755 forEach((n, e) -> a[i + n] = e); 756 } 757 758 /** 759 * Stores this vector into an array starting at offset and using a mask. 760 * <p> 761 * For each vector lane, where {@code N} is the vector lane index, 762 * if the mask lane at index {@code N} is set then the lane element at 763 * index {@code N} is stored into the array index {@code i + N}. 764 * 765 * @param a the array 766 * @param i the offset into the array 767 * @param m the mask 768 * @throws IndexOutOfBoundsException if {@code i < 0}, or 769 * for any vector lane index {@code N} where the mask at lane {@code N} 770 * is set {@code i >= a.length - N} 771 */ 772 public void intoArray($type$[] a, int i, Mask<$Boxtype$, S> m) { 773 forEach(m, (n, e) -> a[i + n] = e); 774 } 775 776 /** 777 * Stores this vector into an array using indexes obtained from an index 778 * map. 779 * <p> 780 * For each vector lane, where {@code N} is the vector lane index, the 781 * lane element at index {@code N} is stored into the array at index 782 * {@code i + indexMap[j + N]}. 783 * 784 * @param a the array 785 * @param i the offset into the array, may be negative if relative 786 * indexes in the index map compensate to produce a value within the 787 * array bounds 788 * @param indexMap the index map 789 * @param j the offset into the index map 790 * @throws IndexOutOfBoundsException if {@code j < 0}, or 791 * {@code j > indexMap.length - this.length()}, 792 * or for any vector lane index {@code N} the result of 793 * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length} 794 */ 795 public void intoArray($type$[] a, int i, int[] indexMap, int j) { 796 forEach((n, e) -> a[i + indexMap[j + n]] = e); 797 } 798 799 /** 800 * Stores this vector into an array using indexes obtained from an index 801 * map and using a mask. 802 * <p> 803 * For each vector lane, where {@code N} is the vector lane index, 804 * if the mask lane at index {@code N} is set then the lane element at 805 * index {@code N} is stored into the array at index 806 * {@code i + indexMap[j + N]}. 807 * 808 * @param a the array 809 * @param i the offset into the array, may be negative if relative 810 * indexes in the index map compensate to produce a value within the 811 * array bounds 812 * @param m the mask 813 * @param indexMap the index map 814 * @param j the offset into the index map 815 * @throws IndexOutOfBoundsException if {@code j < 0}, or 816 * {@code j > indexMap.length - this.length()}, 817 * or for any vector lane index {@code N} where the mask at lane 818 * {@code N} is set the result of {@code i + indexMap[j + N]} is 819 * {@code < 0} or {@code >= a.length} 820 */ 821 public void intoArray($type$[] a, int i, Mask<$Boxtype$, S> m, int[] indexMap, int j) { 822 forEach(m, (n, e) -> a[i + indexMap[j + n]] = e); 823 } 824 825 // Species 826 827 @Override 828 public abstract $Type$Species<S> species(); 829 830 /** 831 * A specialized factory for creating {@link $Type$Vector} value of the same 832 * shape, and a {@link Mask} and {@link Shuffle} values of the same shape 833 * and {@code int} element type. 834 * 835 * @param <S> the type of shape of this species 836 */ 837 public static abstract class $Type$Species<S extends Vector.Shape> extends Vector.Species<$Boxtype$, S> { 838 interface FOp { 839 $type$ apply(int i); 840 } 841 842 abstract $abstractvectortype$<S> op(FOp f); 843 844 abstract $abstractvectortype$<S> op(Mask<$Boxtype$, S> m, FOp f); 845 846 // Factories 847 848 @Override 849 public $abstractvectortype$<S> zero() { 850 return op(i -> 0); 851 } 852 853 /** 854 * Returns a vector where all lane elements are set to the primitive 855 * value {@code e}. 856 * 857 * @param e the value 858 * @return a vector of vector where all lane elements are set to 859 * the primitive value {@code e} 860 */ 861 public $abstractvectortype$<S> broadcast($type$ e) { 862 return op(i -> e); 863 } 864 865 /** 866 * Returns a vector where the first lane element is set to the primtive 867 * value {@code e}, all other lane elements are set to the default 868 * value. 869 * 870 * @param e the value 871 * @return a vector where the first lane element is set to the primitive 872 * value {@code e} 873 */ 874 public $abstractvectortype$<S> single($type$ e) { 875 return op(i -> i == 0 ? e : ($type$) 0); 876 } 877 878 /** 879 * Returns a vector where each lane element is set to a randomly 880 * generated primitive value. 881 * @@@ what are the properties of the random number generator? 882 * 883 * @return a vector where each lane elements is set to a randomly 884 * generated primitive value 885 */ 886 #if[intOrLong] 887 public $abstractvectortype$<S> random() { 888 ThreadLocalRandom r = ThreadLocalRandom.current(); 889 return op(i -> r.next$Type$()); 890 } 891 #else[intOrLong] 892 #if[FP] 893 public $abstractvectortype$<S> random() { 894 ThreadLocalRandom r = ThreadLocalRandom.current(); 895 return op(i -> r.next$Type$()); 896 } 897 #else[FP] 898 public $abstractvectortype$<S> random() { 899 ThreadLocalRandom r = ThreadLocalRandom.current(); 900 return op(i -> ($type$) r.nextInt()); 901 } 902 #end[FP] 903 #end[intOrLong] 904 905 /** 906 * Returns a vector where each lane element is set to a given 907 * primitive value. 908 * <p> 909 * For each vector lane, where {@code N} is the vector lane index, the 910 * the primitive value at index {@code N} is placed into the resulting 911 * vector at lane index {@code N}. 912 * 913 * @@@ What should happen if es.length < this.length() ? use the default 914 * value or throw IndexOutOfBoundsException 915 * 916 * @param es the given primitive values 917 * @return a vector where each lane element is set to a given primitive 918 * value 919 */ 920 public $abstractvectortype$<S> scalars($type$... es) { 921 return op(i -> es[i]); 922 } 923 924 /** 925 * Loads a vector from an array starting at offset. 926 * <p> 927 * For each vector lane, where {@code N} is the vector lane index, the 928 * array element at index {@code i + N} is placed into the 929 * resulting vector at lane index {@code N}. 930 * 931 * @param a the array 932 * @param i the offset into the array 933 * @return the vector loaded from an array 934 * @throws IndexOutOfBoundsException if {@code i < 0}, or 935 * {@code i > a.length - this.length()} 936 */ 937 public $abstractvectortype$<S> fromArray($type$[] a, int i) { 938 return op(n -> a[i + n]); 939 } 940 941 /** 942 * Loads a vector from an array starting at offset and using a mask. 943 * <p> 944 * For each vector lane, where {@code N} is the vector lane index, 945 * if the mask lane at index {@code N} is set then the array element at 946 * index {@code i + N} is placed into the resulting vector at lane index 947 * {@code N}, otherwise the default element value is placed into the 948 * resulting vector at lane index {@code N}. 949 * 950 * @param a the array 951 * @param i the offset into the array 952 * @param m the mask 953 * @return the vector loaded from an array 954 * @throws IndexOutOfBoundsException if {@code i < 0}, or 955 * for any vector lane index {@code N} where the mask at lane {@code N} 956 * is set {@code i > a.length - N} 957 */ 958 public $abstractvectortype$<S> fromArray($type$[] a, int i, Mask<$Boxtype$, S> m) { 959 return op(m, n -> a[i + n]); 960 } 961 962 /** 963 * Loads a vector from an array using indexes obtained from an index 964 * map. 965 * <p> 966 * For each vector lane, where {@code N} is the vector lane index, the 967 * array element at index {@code i + indexMap[j + N]} is placed into the 968 * resulting vector at lane index {@code N}. 969 * 970 * @param a the array 971 * @param i the offset into the array, may be negative if relative 972 * indexes in the index map compensate to produce a value within the 973 * array bounds 974 * @param indexMap the index map 975 * @param j the offset into the index map 976 * @return the vector loaded from an array 977 * @throws IndexOutOfBoundsException if {@code j < 0}, or 978 * {@code j > indexMap.length - this.length()}, 979 * or for any vector lane index {@code N} the result of 980 * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length} 981 */ 982 public $abstractvectortype$<S> fromArray($type$[] a, int i, int[] indexMap, int j) { 983 return op(n -> a[i + indexMap[j + n]]); 984 } 985 986 /** 987 * Loads a vector from an array using indexes obtained from an index 988 * map and using a mask. 989 * <p> 990 * For each vector lane, where {@code N} is the vector lane index, 991 * if the mask lane at index {@code N} is set then the array element at 992 * index {@code i + indexMap[j + N]} is placed into the resulting vector 993 * at lane index {@code N}. 994 * 995 * @param a the array 996 * @param i the offset into the array, may be negative if relative 997 * indexes in the index map compensate to produce a value within the 998 * array bounds 999 * @param indexMap the index map 1000 * @param j the offset into the index map 1001 * @return the vector loaded from an array 1002 * @throws IndexOutOfBoundsException if {@code j < 0}, or 1003 * {@code j > indexMap.length - this.length()}, 1004 * or for any vector lane index {@code N} where the mask at lane 1005 * {@code N} is set the result of {@code i + indexMap[j + N]} is 1006 * {@code < 0} or {@code >= a.length} 1007 */ 1008 public $abstractvectortype$<S> fromArray($type$[] a, int i, Mask<$Boxtype$, S> m, int[] indexMap, int j) { 1009 return op(m, n -> a[i + indexMap[j + n]]); 1010 } 1011 1012 @Override 1013 public $abstractvectortype$<S> fromByteArray(byte[] a, int ix) { 1014 ByteBuffer bb = ByteBuffer.wrap(a, ix, a.length - ix).order(ByteOrder.nativeOrder()); 1015 return fromByteBuffer(bb); 1016 } 1017 1018 @Override 1019 public $abstractvectortype$<S> fromByteArray(byte[] a, int ix, Mask<$Boxtype$, S> m) { 1020 ByteBuffer bb = ByteBuffer.wrap(a, ix, a.length - ix).order(ByteOrder.nativeOrder()); 1021 return fromByteBuffer(bb, m); 1022 } 1023 1024 @Override 1025 public $abstractvectortype$<S> fromByteBuffer(ByteBuffer bb) { 1026 $Type$Buffer fb = bb{#if[byte]?;:.as$Type$Buffer();} 1027 return op(i -> fb.get()); 1028 } 1029 1030 @Override 1031 public $abstractvectortype$<S> fromByteBuffer(ByteBuffer bb, Mask<$Boxtype$, S> m) { 1032 $Type$Buffer fb = bb{#if[byte]?;:.as$Type$Buffer();} 1033 return op(i -> { 1034 if(m.getElement(i)) 1035 return fb.get(); 1036 else { 1037 fb.position(fb.position() + 1); 1038 return ($type$) 0; 1039 } 1040 }); 1041 } 1042 1043 @Override 1044 public $abstractvectortype$<S> fromByteBuffer(ByteBuffer bb, int ix) { 1045 bb = bb.duplicate().order(ByteOrder.nativeOrder()).position(ix); 1046 $Type$Buffer fb = bb{#if[byte]?;:.as$Type$Buffer();} 1047 return op(i -> fb.get(i)); 1048 } 1049 1050 @Override 1051 public $abstractvectortype$<S> fromByteBuffer(ByteBuffer bb, int ix, Mask<$Boxtype$, S> m) { 1052 bb = bb.duplicate().order(ByteOrder.nativeOrder()).position(ix); 1053 $Type$Buffer fb = bb{#if[byte]?;:.as$Type$Buffer();} 1054 return op(m, i -> fb.get(i)); 1055 } 1056 1057 @Override 1058 public <F, T extends Shape> $abstractvectortype$<S> reshape(Vector<F, T> o) { 1059 int blen = Math.max(o.species().bitSize(), bitSize()) / Byte.SIZE; 1060 ByteBuffer bb = ByteBuffer.allocate(blen).order(ByteOrder.nativeOrder()); 1061 o.intoByteBuffer(bb, 0); 1062 return fromByteBuffer(bb, 0); 1063 } 1064 1065 @Override 1066 @ForceInline 1067 public <F> $abstractvectortype$<S> rebracket(Vector<F, S> o) { 1068 return reshape(o); 1069 } 1070 1071 @Override 1072 @ForceInline 1073 public <T extends Shape> $abstractvectortype$<S> resize(Vector<$Boxtype$, T> o) { 1074 return reshape(o); 1075 } 1076 1077 @Override 1078 @SuppressWarnings("unchecked") 1079 public <F, T extends Shape> $abstractvectortype$<S> cast(Vector<F, T> v) { 1080 // Allocate array of required size 1081 $type$[] a = new $type$[length()]; 1082 1083 Class<?> vtype = v.species().elementType(); 1084 int limit = Math.min(v.species().length(), length()); 1085 if (vtype == byte.class) { 1086 ByteVector<T> tv = (ByteVector<T>)v; 1087 for (int i = 0; i < limit; i++) { 1088 a[i] = ($type$) tv.get(i); 1089 } 1090 } else if (vtype == short.class) { 1091 ShortVector<T> tv = (ShortVector<T>)v; 1092 for (int i = 0; i < limit; i++) { 1093 a[i] = ($type$) tv.get(i); 1094 } 1095 } else if (vtype == int.class) { 1096 IntVector<T> tv = (IntVector<T>)v; 1097 for (int i = 0; i < limit; i++) { 1098 a[i] = ($type$) tv.get(i); 1099 } 1100 } else if (vtype == long.class){ 1101 LongVector<T> tv = (LongVector<T>)v; 1102 for (int i = 0; i < limit; i++) { 1103 a[i] = ($type$) tv.get(i); 1104 } 1105 } else if (vtype == float.class){ 1106 FloatVector<T> tv = (FloatVector<T>)v; 1107 for (int i = 0; i < limit; i++) { 1108 a[i] = ($type$) tv.get(i); 1109 } 1110 } else if (vtype == double.class){ 1111 DoubleVector<T> tv = (DoubleVector<T>)v; 1112 for (int i = 0; i < limit; i++) { 1113 a[i] = ($type$) tv.get(i); 1114 } 1115 } else { 1116 throw new UnsupportedOperationException("Bad lane type for casting."); 1117 } 1118 1119 return scalars(a); 1120 } 1121 1122 } 1123 1124 /** 1125 * Finds the preferred species for an element type of {@code $type$}. 1126 * <p> 1127 * A preferred species is a species chosen by the platform that has a 1128 * shape of maximal bit size. A preferred species for different element 1129 * types will have the same shape, and therefore vectors, masks, and 1130 * shuffles created from such species will be shape compatible. 1131 * 1132 * @return the preferred species for an element type of {@code $type$} 1133 */ 1134 @SuppressWarnings("unchecked") 1135 public static $Type$Species<?> preferredSpeciesInstance() { 1136 return ($Type$Species<?>) Vector.preferredSpeciesInstance($type$.class); 1137 } 1138 1139 /** 1140 * Finds a species for an element type of {@code $type$} and shape. 1141 * 1142 * @param s the shape 1143 * @param <S> the type of shape 1144 * @return a species for an element type of {@code $type$} and shape 1145 * @throws IllegalArgumentException if no such species exists for the shape 1146 */ 1147 @SuppressWarnings("unchecked") 1148 public static <S extends Shape> $Type$Species<S> speciesInstance(S s) { 1149 Objects.requireNonNull(s); 1150 if (s == Shapes.S_64_BIT) { 1151 return ($Type$Species<S>) $Type$64Vector.SPECIES; 1152 } else if (s == Shapes.S_128_BIT) { 1153 return ($Type$Species<S>) $Type$128Vector.SPECIES; 1154 } else if (s == Shapes.S_256_BIT) { 1155 return ($Type$Species<S>) $Type$256Vector.SPECIES; 1156 } else if (s == Shapes.S_512_BIT) { 1157 return ($Type$Species<S>) $Type$512Vector.SPECIES; 1158 } else { 1159 throw new IllegalArgumentException("Bad shape: " + s); 1160 } 1161 } 1162 }