8338023: Support two vector selectFrom API

Reviewed-by: psandoz, epeter, sviswanathan
This commit is contained in:
Jatin Bhateja 2024-10-16 16:08:02 +00:00
parent c34fb2c989
commit 709914fc92
89 changed files with 2788 additions and 20 deletions

View File

@ -4738,22 +4738,6 @@ void Assembler::vpermpd(XMMRegister dst, XMMRegister src, int imm8, int vector_l
emit_int24(0x01, (0xC0 | encode), imm8);
}
void Assembler::evpermi2q(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
assert(VM_Version::supports_evex(), "");
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
attributes.set_is_evex_instruction();
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
emit_int16(0x76, (0xC0 | encode));
}
void Assembler::evpermt2b(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
assert(VM_Version::supports_avx512_vbmi(), "");
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
attributes.set_is_evex_instruction();
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
emit_int16(0x7D, (0xC0 | encode));
}
void Assembler::evpmultishiftqb(XMMRegister dst, XMMRegister ctl, XMMRegister src, int vector_len) {
assert(VM_Version::supports_avx512_vbmi(), "");
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
@ -16103,3 +16087,59 @@ void InstructionAttr::set_address_attributes(int tuple_type, int input_size_in_b
_input_size_in_bits = input_size_in_bits;
}
}
void Assembler::evpermi2b(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
assert(VM_Version::supports_avx512_vbmi() && (vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl()), "");
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
attributes.set_is_evex_instruction();
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
emit_int16(0x75, (0xC0 | encode));
}
void Assembler::evpermi2w(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
assert(VM_Version::supports_avx512bw() && (vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl()), "");
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
attributes.set_is_evex_instruction();
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
emit_int16(0x75, (0xC0 | encode));
}
void Assembler::evpermi2d(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
assert(VM_Version::supports_evex() && (vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl()), "");
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
attributes.set_is_evex_instruction();
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
emit_int16(0x76, (0xC0 | encode));
}
void Assembler::evpermi2q(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
assert(VM_Version::supports_evex() && (vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl()), "");
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
attributes.set_is_evex_instruction();
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
emit_int16(0x76, (0xC0 | encode));
}
void Assembler::evpermi2ps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
assert(VM_Version::supports_evex() && (vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl()), "");
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
attributes.set_is_evex_instruction();
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
emit_int16(0x77, (0xC0 | encode));
}
void Assembler::evpermi2pd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
assert(VM_Version::supports_evex() && (vector_len == Assembler::AVX_512bit || VM_Version::supports_avx512vl()), "");
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
attributes.set_is_evex_instruction();
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
emit_int16(0x77, (0xC0 | encode));
}
void Assembler::evpermt2b(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
assert(VM_Version::supports_avx512_vbmi(), "");
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
attributes.set_is_evex_instruction();
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
emit_int16(0x7D, (0xC0 | encode));
}

View File

@ -1962,9 +1962,14 @@ private:
void vpermilps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
void vpermilpd(XMMRegister dst, XMMRegister src, int imm8, int vector_len);
void vpermpd(XMMRegister dst, XMMRegister src, int imm8, int vector_len);
void evpermi2q(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
void evpermt2b(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
void evpmultishiftqb(XMMRegister dst, XMMRegister ctl, XMMRegister src, int vector_len);
void evpermi2b(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
void evpermi2w(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
void evpermi2d(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
void evpermi2q(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
void evpermi2ps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
void evpermi2pd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
void evpermt2b(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
void pause();

View File

@ -6475,3 +6475,30 @@ void C2_MacroAssembler::vector_rearrange_int_float(BasicType bt, XMMRegister dst
vpermps(dst, shuffle, src, vlen_enc);
}
}
void C2_MacroAssembler::select_from_two_vectors_evex(BasicType elem_bt, XMMRegister dst, XMMRegister src1,
XMMRegister src2, int vlen_enc) {
switch(elem_bt) {
case T_BYTE:
evpermi2b(dst, src1, src2, vlen_enc);
break;
case T_SHORT:
evpermi2w(dst, src1, src2, vlen_enc);
break;
case T_INT:
evpermi2d(dst, src1, src2, vlen_enc);
break;
case T_LONG:
evpermi2q(dst, src1, src2, vlen_enc);
break;
case T_FLOAT:
evpermi2ps(dst, src1, src2, vlen_enc);
break;
case T_DOUBLE:
evpermi2pd(dst, src1, src2, vlen_enc);
break;
default:
fatal("Unsupported type %s", type2name(elem_bt));
break;
}
}

View File

@ -505,4 +505,6 @@ public:
void vgather8b_offset(BasicType elem_bt, XMMRegister dst, Register base, Register idx_base,
Register offset, Register rtmp, int vlen_enc);
void select_from_two_vectors_evex(BasicType elem_bt, XMMRegister dst, XMMRegister src1, XMMRegister src2, int vlen_enc);
#endif // CPU_X86_C2_MACROASSEMBLER_X86_HPP

View File

@ -1935,6 +1935,20 @@ bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) {
return false;
}
break;
case Op_SelectFromTwoVector:
if (size_in_bits < 128 || (size_in_bits < 512 && !VM_Version::supports_avx512vl())) {
return false;
}
if (bt == T_SHORT && !VM_Version::supports_avx512bw()) {
return false;
}
if (bt == T_BYTE && !VM_Version::supports_avx512_vbmi()) {
return false;
}
if ((bt == T_INT || bt == T_FLOAT || bt == T_DOUBLE) && !VM_Version::supports_evex()) {
return false;
}
break;
case Op_MaskAll:
if (!VM_Version::supports_evex()) {
return false;
@ -10468,3 +10482,16 @@ instruct DoubleClassCheck_reg_reg_vfpclass(rRegI dst, regD src, kReg ktmp, rFlag
%}
ins_pipe(pipe_slow);
%}
instruct vector_selectfrom_twovectors_reg_evex(vec index, vec src1, vec src2)
%{
match(Set index (SelectFromTwoVector (Binary index src1) src2));
format %{ "select_from_two_vector $index, $src1, $src2 \t!" %}
ins_encode %{
int vlen_enc = vector_length_encoding(this);
BasicType bt = Matcher::vector_element_basic_type(this);
__ select_from_two_vectors_evex(bt, $index$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vlen_enc);
%}
ins_pipe(pipe_slow);
%}

View File

@ -4355,7 +4355,7 @@ bool MatchRule::is_vector() const {
"Replicate","ReverseV","ReverseBytesV",
"RoundDoubleModeV","RotateLeftV" , "RotateRightV", "LoadVector","StoreVector",
"LoadVectorGather", "StoreVectorScatter", "LoadVectorGatherMasked", "StoreVectorScatterMasked",
"VectorTest", "VectorLoadMask", "VectorStoreMask", "VectorBlend", "VectorInsert",
"SelectFromTwoVector", "VectorTest", "VectorLoadMask", "VectorStoreMask", "VectorBlend", "VectorInsert",
"VectorRearrange", "VectorLoadShuffle", "VectorLoadConst",
"VectorCastB2X", "VectorCastS2X", "VectorCastI2X",
"VectorCastL2X", "VectorCastF2X", "VectorCastD2X", "VectorCastF2HF", "VectorCastHF2F",

View File

@ -981,6 +981,17 @@ class methodHandle;
"Ljdk/internal/vm/vector/VectorSupport$Vector;") \
do_name(vector_ternary_op_name, "ternaryOp") \
\
do_intrinsic(_VectorSelectFromTwoVectorOp, jdk_internal_vm_vector_VectorSupport, vector_select_from_op_name, vector_select_from_op_sig, F_S) \
do_signature(vector_select_from_op_sig, "(Ljava/lang/Class;" \
"Ljava/lang/Class;" \
"I" \
"Ljdk/internal/vm/vector/VectorSupport$Vector;" \
"Ljdk/internal/vm/vector/VectorSupport$Vector;" \
"Ljdk/internal/vm/vector/VectorSupport$Vector;" \
"Ljdk/internal/vm/vector/VectorSupport$SelectFromTwoVector;)" \
"Ljdk/internal/vm/vector/VectorSupport$Vector;") \
do_name(vector_select_from_op_name, "selectFromTwoVectorOp") \
\
do_intrinsic(_VectorFromBitsCoerced, jdk_internal_vm_vector_VectorSupport, vector_frombits_coerced_name, vector_frombits_coerced_sig, F_S) \
do_signature(vector_frombits_coerced_sig, "(Ljava/lang/Class;" \
"Ljava/lang/Class;" \

View File

@ -818,6 +818,7 @@ bool C2Compiler::is_intrinsic_supported(vmIntrinsics::ID id) {
case vmIntrinsics::_VectorLoadMaskedOp:
case vmIntrinsics::_VectorStoreOp:
case vmIntrinsics::_VectorStoreMaskedOp:
case vmIntrinsics::_VectorSelectFromTwoVectorOp:
case vmIntrinsics::_VectorGatherOp:
case vmIntrinsics::_VectorScatterOp:
case vmIntrinsics::_VectorReductionCoerced:

View File

@ -482,6 +482,7 @@ macro(Digit)
macro(LowerCase)
macro(UpperCase)
macro(Whitespace)
macro(SelectFromTwoVector)
macro(VectorBox)
macro(VectorBoxAllocate)
macro(VectorUnbox)

View File

@ -755,6 +755,8 @@ bool LibraryCallKit::try_to_inline(int predicate) {
return inline_vector_extract();
case vmIntrinsics::_VectorCompressExpand:
return inline_vector_compress_expand();
case vmIntrinsics::_VectorSelectFromTwoVectorOp:
return inline_vector_select_from_two_vectors();
case vmIntrinsics::_IndexVector:
return inline_index_vector();
case vmIntrinsics::_IndexPartiallyInUpperRange:

View File

@ -374,6 +374,7 @@ class LibraryCallKit : public GraphKit {
bool inline_vector_compress_expand();
bool inline_index_vector();
bool inline_index_partially_in_upper_range();
bool inline_vector_select_from_two_vectors();
Node* gen_call_to_vector_math(int vector_api_op_id, BasicType bt, int num_elem, Node* opd1, Node* opd2);

View File

@ -2436,6 +2436,7 @@ void Matcher::find_shared_post_visit(Node* n, uint opcode) {
n->del_req(4);
break;
}
case Op_SelectFromTwoVector:
case Op_LoopLimit: {
Node* pair1 = new BinaryNode(n->in(1), n->in(2));
n->set_req(1, pair1);

View File

@ -2356,9 +2356,10 @@ bool LibraryCallKit::inline_vector_broadcast_int() {
}
Node* cnt = argument(6);
const TypeInt* cnt_type = cnt->bottom_type()->isa_int();
ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass();
const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass);
const TypeInt* cnt_type = cnt->bottom_type()->isa_int();
// If CPU supports vector constant rotate instructions pass it directly
bool is_const_rotate = is_rotate && cnt_type && cnt_type->is_con() &&
@ -2841,6 +2842,188 @@ bool LibraryCallKit::inline_vector_extract() {
return true;
}
static Node* LowerSelectFromTwoVectorOperation(PhaseGVN& phase, Node* index_vec, Node* src1, Node* src2, const TypeVect* vt) {
int num_elem = vt->length();
BasicType elem_bt = vt->element_basic_type();
// Lower selectFrom operation into its constituent operations.
// SelectFromTwoVectorNode =
// (VectorBlend
// (VectorRearrange SRC1 (WRAPED_INDEX AND (VLEN-1))
// (VectorRearrange SRC2 (WRAPED_INDEX AND (VLEN-1))
// MASK)
// Where
// WRAPED_INDEX are computed by wrapping incoming indexes
// to two vector index range [0, VLEN*2) and
// MASK = WRAPED_INDEX < VLEN
//
// IR lowering prevents intrinsification failure and associated argument
// boxing penalties.
//
const TypeVect* index_vect_type = index_vec->bottom_type()->is_vect();
BasicType index_elem_bt = index_vect_type->element_basic_type();
// Downcast index vector to a type agnostic shuffle representation, shuffle
// indices are held in a byte vector which are later transformed to target
// specific permutation index format by subsequent VectorLoadShuffle.
int cast_vopc = VectorCastNode::opcode(0, index_elem_bt, true);
Node* index_byte_vec = phase.transform(VectorCastNode::make(cast_vopc, index_vec, T_BYTE, num_elem));
// Wrap indexes into two vector index range [0, VLEN * 2)
Node* two_vect_lane_cnt_m1 = phase.makecon(TypeInt::make(2 * num_elem - 1));
Node* bcast_two_vect_lane_cnt_m1_vec = phase.transform(VectorNode::scalar2vector(two_vect_lane_cnt_m1, num_elem,
Type::get_const_basic_type(T_BYTE), false));
index_byte_vec = phase.transform(VectorNode::make(Op_AndV, index_byte_vec, bcast_two_vect_lane_cnt_m1_vec,
index_byte_vec->bottom_type()->is_vect()));
// Compute the blend mask for merging two independently permitted vectors
// using shuffle index in two vector index range [0, VLEN * 2).
BoolTest::mask pred = BoolTest::le;
ConINode* pred_node = phase.makecon(TypeInt::make(pred))->as_ConI();
const TypeVect* vmask_type = TypeVect::makemask(T_BYTE, num_elem);
Node* lane_cnt_m1 = phase.makecon(TypeInt::make(num_elem - 1));
Node* bcast_lane_cnt_m1_vec = phase.transform(VectorNode::scalar2vector(lane_cnt_m1, num_elem,
Type::get_const_basic_type(T_BYTE), false));
Node* mask = phase.transform(new VectorMaskCmpNode(pred, index_byte_vec, bcast_lane_cnt_m1_vec, pred_node, vmask_type));
// Rearrange expects the indexes to lie within single vector index range [0, VLEN).
index_byte_vec = phase.transform(VectorNode::make(Op_AndV, index_byte_vec, bcast_lane_cnt_m1_vec,
index_byte_vec->bottom_type()->is_vect()));
// Load indexes from byte vector and appropriately transform them to target
// specific permutation index format.
index_vec = phase.transform(new VectorLoadShuffleNode(index_byte_vec, index_vect_type));
vmask_type = TypeVect::makemask(elem_bt, num_elem);
mask = phase.transform(new VectorMaskCastNode(mask, vmask_type));
Node* p1 = phase.transform(new VectorRearrangeNode(src1, index_vec));
Node* p2 = phase.transform(new VectorRearrangeNode(src2, index_vec));
return new VectorBlendNode(p2, p1, mask);
}
// public static
// <V extends Vector<E>,
// E>
// V selectFromTwoVectorOp(Class<? extends V> vClass, Class<E> eClass, int length,
// V v1, V v2, V v3,
// SelectFromTwoVector<V> defaultImpl)
bool LibraryCallKit::inline_vector_select_from_two_vectors() {
const TypeInstPtr* vector_klass = gvn().type(argument(0))->isa_instptr();
const TypeInstPtr* elem_klass = gvn().type(argument(1))->isa_instptr();
const TypeInt* vlen = gvn().type(argument(2))->isa_int();
if (vector_klass == nullptr || elem_klass == nullptr || vlen == nullptr || vector_klass->const_oop() == nullptr ||
elem_klass->const_oop() == nullptr ||!vlen->is_con()) {
log_if_needed(" ** missing constant: vclass=%s etype=%s vlen=%s",
NodeClassNames[argument(0)->Opcode()],
NodeClassNames[argument(1)->Opcode()],
NodeClassNames[argument(2)->Opcode()]);
return false; // not enough info for intrinsification
}
if (!is_klass_initialized(vector_klass)) {
log_if_needed(" ** klass argument not initialized");
return false;
}
ciType* elem_type = elem_klass->const_oop()->as_instance()->java_mirror_type();
if (!elem_type->is_primitive_type()) {
log_if_needed(" ** not a primitive bt=%d", elem_type->basic_type());
return false; // should be primitive type
}
int num_elem = vlen->get_con();
if (!is_power_of_2(num_elem)) {
log_if_needed(" ** vlen is not power of two=%d", num_elem);
return false;
}
BasicType elem_bt = elem_type->basic_type();
BasicType index_elem_bt = elem_bt;
if (elem_bt == T_FLOAT) {
index_elem_bt = T_INT;
} else if (elem_bt == T_DOUBLE) {
index_elem_bt = T_LONG;
}
bool lowerSelectFromOp = false;
if (!arch_supports_vector(Op_SelectFromTwoVector, num_elem, elem_bt, VecMaskNotUsed)) {
int cast_vopc = VectorCastNode::opcode(-1, elem_bt, true);
if (!arch_supports_vector(Op_VectorMaskCmp, num_elem, T_BYTE, VecMaskNotUsed) ||
!arch_supports_vector(Op_AndV, num_elem, T_BYTE, VecMaskNotUsed) ||
!arch_supports_vector(Op_VectorMaskCast, num_elem, elem_bt, VecMaskNotUsed) ||
!arch_supports_vector(Op_VectorBlend, num_elem, elem_bt, VecMaskUseLoad) ||
!arch_supports_vector(Op_VectorRearrange, num_elem, elem_bt, VecMaskNotUsed) ||
!arch_supports_vector(cast_vopc, num_elem, T_BYTE, VecMaskNotUsed) ||
!arch_supports_vector(Op_VectorLoadShuffle, num_elem, index_elem_bt, VecMaskNotUsed) ||
!arch_supports_vector(Op_Replicate, num_elem, T_BYTE, VecMaskNotUsed)) {
log_if_needed(" ** not supported: opc=%d vlen=%d etype=%s ismask=useload",
Op_SelectFromTwoVector, num_elem, type2name(elem_bt));
return false; // not supported
}
lowerSelectFromOp = true;
}
int cast_vopc = VectorCastNode::opcode(-1, elem_bt, true);
if (!lowerSelectFromOp) {
if (!arch_supports_vector(Op_AndV, num_elem, index_elem_bt, VecMaskNotUsed) ||
!arch_supports_vector(Op_Replicate, num_elem, index_elem_bt, VecMaskNotUsed) ||
(is_floating_point_type(elem_bt) &&
!arch_supports_vector(cast_vopc, num_elem, index_elem_bt, VecMaskNotUsed))) {
log_if_needed(" ** index wrapping not supported: vlen=%d etype=%s" ,
num_elem, type2name(elem_bt));
return false; // not supported
}
}
ciKlass* vbox_klass = vector_klass->const_oop()->as_instance()->java_lang_Class_klass();
const TypeInstPtr* vbox_type = TypeInstPtr::make_exact(TypePtr::NotNull, vbox_klass);
Node* opd1 = unbox_vector(argument(3), vbox_type, elem_bt, num_elem);
if (opd1 == nullptr) {
log_if_needed(" ** unbox failed v1=%s",
NodeClassNames[argument(3)->Opcode()]);
return false;
}
Node* opd2 = unbox_vector(argument(4), vbox_type, elem_bt, num_elem);
if (opd2 == nullptr) {
log_if_needed(" ** unbox failed v2=%s",
NodeClassNames[argument(4)->Opcode()]);
return false;
}
Node* opd3 = unbox_vector(argument(5), vbox_type, elem_bt, num_elem);
if (opd3 == nullptr) {
log_if_needed(" ** unbox failed v3=%s",
NodeClassNames[argument(5)->Opcode()]);
return false;
}
const TypeVect* vt = TypeVect::make(elem_bt, num_elem);
Node* operation = nullptr;
if (lowerSelectFromOp) {
operation = gvn().transform(LowerSelectFromTwoVectorOperation(gvn(), opd1, opd2, opd3, vt));
} else {
if (index_elem_bt != elem_bt) {
opd1 = gvn().transform(VectorCastNode::make(cast_vopc, opd1, index_elem_bt, num_elem));
}
int indexRangeMask = 2 * num_elem - 1;
Node* wrap_mask = gvn().makecon(TypeInteger::make(indexRangeMask, indexRangeMask, Type::WidenMin, index_elem_bt != T_LONG ? T_INT : index_elem_bt));
Node* wrap_mask_vec = gvn().transform(VectorNode::scalar2vector(wrap_mask, num_elem, Type::get_const_basic_type(index_elem_bt), false));
opd1 = gvn().transform(VectorNode::make(Op_AndV, opd1, wrap_mask_vec, opd1->bottom_type()->is_vect()));
operation = gvn().transform(VectorNode::make(Op_SelectFromTwoVector, opd1, opd2, opd3, vt));
}
// Wrap it up in VectorBox to keep object type information.
Node* vbox = box_vector(operation, vbox_type, elem_bt, num_elem);
set_result(vbox);
C->set_max_vector_size(MAX2(C->max_vector_size(), (uint)(num_elem * type2aelembytes(elem_bt))));
return true;
}
// public static
// <V extends Vector<E>,
// M extends VectorMask<E>,

View File

@ -781,6 +781,7 @@ VectorNode* VectorNode::make(int vopc, Node* n1, Node* n2, Node* n3, const TypeV
switch (vopc) {
case Op_FmaVD: return new FmaVDNode(n1, n2, n3, vt);
case Op_FmaVF: return new FmaVFNode(n1, n2, n3, vt);
case Op_SelectFromTwoVector: return new SelectFromTwoVectorNode(n1, n2, n3, vt);
case Op_SignumVD: return new SignumVDNode(n1, n2, n3, vt);
case Op_SignumVF: return new SignumVFNode(n1, n2, n3, vt);
default:
@ -2078,6 +2079,7 @@ Node* VectorBlendNode::Identity(PhaseGVN* phase) {
return this;
}
#ifndef PRODUCT
void VectorBoxAllocateNode::dump_spec(outputStream *st) const {
CallStaticJavaNode::dump_spec(st);

View File

@ -1612,6 +1612,21 @@ class VectorRearrangeNode : public VectorNode {
Node* vec_shuffle() const { return in(2); }
};
// Select elements from two source vectors based on the wrapped indexes held in
// the first vector.
class SelectFromTwoVectorNode : public VectorNode {
public:
SelectFromTwoVectorNode(Node* indexes, Node* src1, Node* src2, const TypeVect* vt)
: VectorNode(indexes, src1, src2, vt) {
assert(is_integral_type(indexes->bottom_type()->is_vect()->element_basic_type()),
"indexes must be an integral vector");
}
virtual int Opcode() const;
};
class VectorLoadShuffleNode : public VectorNode {
public:
VectorLoadShuffleNode(Node* in, const TypeVect* vt)

View File

@ -395,6 +395,24 @@ public class VectorSupport {
assert isNonCapturingLambda(defaultImpl) : defaultImpl;
return defaultImpl.apply(v1, v2, m);
}
/* ============================================================================ */
public interface SelectFromTwoVector<V extends Vector<?>> {
V apply(V v1, V v2, V v3);
}
@IntrinsicCandidate
public static
<V extends Vector<E>,
E>
V selectFromTwoVectorOp(Class<? extends V> vClass, Class<E> eClass, int length,
V v1, V v2, V v3,
SelectFromTwoVector<V> defaultImpl) {
assert isNonCapturingLambda(defaultImpl) : defaultImpl;
return defaultImpl.apply(v1, v2, v3);
}
/* ============================================================================ */
/* ============================================================================ */

View File

@ -506,6 +506,13 @@ final class Byte128Vector extends ByteVector {
Byte128Mask.class, (Byte128Mask) m); // specialize
}
@Override
@ForceInline
public Byte128Vector selectFrom(Vector<Byte> v1,
Vector<Byte> v2) {
return (Byte128Vector)
super.selectFromTemplate((Byte128Vector) v1, (Byte128Vector) v2); // specialize
}
@ForceInline
@Override

View File

@ -506,6 +506,13 @@ final class Byte256Vector extends ByteVector {
Byte256Mask.class, (Byte256Mask) m); // specialize
}
@Override
@ForceInline
public Byte256Vector selectFrom(Vector<Byte> v1,
Vector<Byte> v2) {
return (Byte256Vector)
super.selectFromTemplate((Byte256Vector) v1, (Byte256Vector) v2); // specialize
}
@ForceInline
@Override

View File

@ -506,6 +506,13 @@ final class Byte512Vector extends ByteVector {
Byte512Mask.class, (Byte512Mask) m); // specialize
}
@Override
@ForceInline
public Byte512Vector selectFrom(Vector<Byte> v1,
Vector<Byte> v2) {
return (Byte512Vector)
super.selectFromTemplate((Byte512Vector) v1, (Byte512Vector) v2); // specialize
}
@ForceInline
@Override

View File

@ -506,6 +506,13 @@ final class Byte64Vector extends ByteVector {
Byte64Mask.class, (Byte64Mask) m); // specialize
}
@Override
@ForceInline
public Byte64Vector selectFrom(Vector<Byte> v1,
Vector<Byte> v2) {
return (Byte64Vector)
super.selectFromTemplate((Byte64Vector) v1, (Byte64Vector) v2); // specialize
}
@ForceInline
@Override

View File

@ -506,6 +506,13 @@ final class ByteMaxVector extends ByteVector {
ByteMaxMask.class, (ByteMaxMask) m); // specialize
}
@Override
@ForceInline
public ByteMaxVector selectFrom(Vector<Byte> v1,
Vector<Byte> v2) {
return (ByteMaxVector)
super.selectFromTemplate((ByteMaxVector) v1, (ByteMaxVector) v2); // specialize
}
@ForceInline
@Override

View File

@ -536,6 +536,19 @@ public abstract class ByteVector extends AbstractVector<Byte> {
return r;
}
static ByteVector selectFromTwoVectorHelper(Vector<Byte> indexes, Vector<Byte> src1, Vector<Byte> src2) {
int vlen = indexes.length();
byte[] res = new byte[vlen];
byte[] vecPayload1 = ((ByteVector)indexes).vec();
byte[] vecPayload2 = ((ByteVector)src1).vec();
byte[] vecPayload3 = ((ByteVector)src2).vec();
for (int i = 0; i < vlen; i++) {
int wrapped_index = VectorIntrinsics.wrapToRange((int)vecPayload1[i], 2 * vlen);
res[i] = wrapped_index >= vlen ? vecPayload3[wrapped_index - vlen] : vecPayload2[wrapped_index];
}
return ((ByteVector)src1).vectorFactory(res);
}
// Static factories (other than memory operations)
// Note: A surprising behavior in javadoc
@ -2575,6 +2588,22 @@ public abstract class ByteVector extends AbstractVector<Byte> {
v2.rearrange(v1.toShuffle(), _m));
}
/**
* {@inheritDoc} <!--workaround-->
*/
@Override
public abstract
ByteVector selectFrom(Vector<Byte> v1, Vector<Byte> v2);
/*package-private*/
@ForceInline
final ByteVector selectFromTemplate(ByteVector v1, ByteVector v2) {
return VectorSupport.selectFromTwoVectorOp(getClass(), byte.class, length(), this, v1, v2,
(vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3));
}
/// Ternary operations
/**

View File

@ -493,6 +493,13 @@ final class Double128Vector extends DoubleVector {
Double128Mask.class, (Double128Mask) m); // specialize
}
@Override
@ForceInline
public Double128Vector selectFrom(Vector<Double> v1,
Vector<Double> v2) {
return (Double128Vector)
super.selectFromTemplate((Double128Vector) v1, (Double128Vector) v2); // specialize
}
@ForceInline
@Override

View File

@ -493,6 +493,13 @@ final class Double256Vector extends DoubleVector {
Double256Mask.class, (Double256Mask) m); // specialize
}
@Override
@ForceInline
public Double256Vector selectFrom(Vector<Double> v1,
Vector<Double> v2) {
return (Double256Vector)
super.selectFromTemplate((Double256Vector) v1, (Double256Vector) v2); // specialize
}
@ForceInline
@Override

View File

@ -493,6 +493,13 @@ final class Double512Vector extends DoubleVector {
Double512Mask.class, (Double512Mask) m); // specialize
}
@Override
@ForceInline
public Double512Vector selectFrom(Vector<Double> v1,
Vector<Double> v2) {
return (Double512Vector)
super.selectFromTemplate((Double512Vector) v1, (Double512Vector) v2); // specialize
}
@ForceInline
@Override

View File

@ -493,6 +493,13 @@ final class Double64Vector extends DoubleVector {
Double64Mask.class, (Double64Mask) m); // specialize
}
@Override
@ForceInline
public Double64Vector selectFrom(Vector<Double> v1,
Vector<Double> v2) {
return (Double64Vector)
super.selectFromTemplate((Double64Vector) v1, (Double64Vector) v2); // specialize
}
@ForceInline
@Override

View File

@ -493,6 +493,13 @@ final class DoubleMaxVector extends DoubleVector {
DoubleMaxMask.class, (DoubleMaxMask) m); // specialize
}
@Override
@ForceInline
public DoubleMaxVector selectFrom(Vector<Double> v1,
Vector<Double> v2) {
return (DoubleMaxVector)
super.selectFromTemplate((DoubleMaxVector) v1, (DoubleMaxVector) v2); // specialize
}
@ForceInline
@Override

View File

@ -525,6 +525,19 @@ public abstract class DoubleVector extends AbstractVector<Double> {
return r;
}
static DoubleVector selectFromTwoVectorHelper(Vector<Double> indexes, Vector<Double> src1, Vector<Double> src2) {
int vlen = indexes.length();
double[] res = new double[vlen];
double[] vecPayload1 = ((DoubleVector)indexes).vec();
double[] vecPayload2 = ((DoubleVector)src1).vec();
double[] vecPayload3 = ((DoubleVector)src2).vec();
for (int i = 0; i < vlen; i++) {
int wrapped_index = VectorIntrinsics.wrapToRange((int)vecPayload1[i], 2 * vlen);
res[i] = wrapped_index >= vlen ? vecPayload3[wrapped_index - vlen] : vecPayload2[wrapped_index];
}
return ((DoubleVector)src1).vectorFactory(res);
}
// Static factories (other than memory operations)
// Note: A surprising behavior in javadoc
@ -2417,6 +2430,22 @@ public abstract class DoubleVector extends AbstractVector<Double> {
v2.rearrange(v1.toShuffle(), _m));
}
/**
* {@inheritDoc} <!--workaround-->
*/
@Override
public abstract
DoubleVector selectFrom(Vector<Double> v1, Vector<Double> v2);
/*package-private*/
@ForceInline
final DoubleVector selectFromTemplate(DoubleVector v1, DoubleVector v2) {
return VectorSupport.selectFromTwoVectorOp(getClass(), double.class, length(), this, v1, v2,
(vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3));
}
/// Ternary operations

View File

@ -493,6 +493,13 @@ final class Float128Vector extends FloatVector {
Float128Mask.class, (Float128Mask) m); // specialize
}
@Override
@ForceInline
public Float128Vector selectFrom(Vector<Float> v1,
Vector<Float> v2) {
return (Float128Vector)
super.selectFromTemplate((Float128Vector) v1, (Float128Vector) v2); // specialize
}
@ForceInline
@Override

View File

@ -493,6 +493,13 @@ final class Float256Vector extends FloatVector {
Float256Mask.class, (Float256Mask) m); // specialize
}
@Override
@ForceInline
public Float256Vector selectFrom(Vector<Float> v1,
Vector<Float> v2) {
return (Float256Vector)
super.selectFromTemplate((Float256Vector) v1, (Float256Vector) v2); // specialize
}
@ForceInline
@Override

View File

@ -493,6 +493,13 @@ final class Float512Vector extends FloatVector {
Float512Mask.class, (Float512Mask) m); // specialize
}
@Override
@ForceInline
public Float512Vector selectFrom(Vector<Float> v1,
Vector<Float> v2) {
return (Float512Vector)
super.selectFromTemplate((Float512Vector) v1, (Float512Vector) v2); // specialize
}
@ForceInline
@Override

View File

@ -493,6 +493,13 @@ final class Float64Vector extends FloatVector {
Float64Mask.class, (Float64Mask) m); // specialize
}
@Override
@ForceInline
public Float64Vector selectFrom(Vector<Float> v1,
Vector<Float> v2) {
return (Float64Vector)
super.selectFromTemplate((Float64Vector) v1, (Float64Vector) v2); // specialize
}
@ForceInline
@Override

View File

@ -493,6 +493,13 @@ final class FloatMaxVector extends FloatVector {
FloatMaxMask.class, (FloatMaxMask) m); // specialize
}
@Override
@ForceInline
public FloatMaxVector selectFrom(Vector<Float> v1,
Vector<Float> v2) {
return (FloatMaxVector)
super.selectFromTemplate((FloatMaxVector) v1, (FloatMaxVector) v2); // specialize
}
@ForceInline
@Override

View File

@ -525,6 +525,19 @@ public abstract class FloatVector extends AbstractVector<Float> {
return r;
}
static FloatVector selectFromTwoVectorHelper(Vector<Float> indexes, Vector<Float> src1, Vector<Float> src2) {
int vlen = indexes.length();
float[] res = new float[vlen];
float[] vecPayload1 = ((FloatVector)indexes).vec();
float[] vecPayload2 = ((FloatVector)src1).vec();
float[] vecPayload3 = ((FloatVector)src2).vec();
for (int i = 0; i < vlen; i++) {
int wrapped_index = VectorIntrinsics.wrapToRange((int)vecPayload1[i], 2 * vlen);
res[i] = wrapped_index >= vlen ? vecPayload3[wrapped_index - vlen] : vecPayload2[wrapped_index];
}
return ((FloatVector)src1).vectorFactory(res);
}
// Static factories (other than memory operations)
// Note: A surprising behavior in javadoc
@ -2429,6 +2442,22 @@ public abstract class FloatVector extends AbstractVector<Float> {
v2.rearrange(v1.toShuffle(), _m));
}
/**
* {@inheritDoc} <!--workaround-->
*/
@Override
public abstract
FloatVector selectFrom(Vector<Float> v1, Vector<Float> v2);
/*package-private*/
@ForceInline
final FloatVector selectFromTemplate(FloatVector v1, FloatVector v2) {
return VectorSupport.selectFromTwoVectorOp(getClass(), float.class, length(), this, v1, v2,
(vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3));
}
/// Ternary operations

View File

@ -506,6 +506,13 @@ final class Int128Vector extends IntVector {
Int128Mask.class, (Int128Mask) m); // specialize
}
@Override
@ForceInline
public Int128Vector selectFrom(Vector<Integer> v1,
Vector<Integer> v2) {
return (Int128Vector)
super.selectFromTemplate((Int128Vector) v1, (Int128Vector) v2); // specialize
}
@ForceInline
@Override

View File

@ -506,6 +506,13 @@ final class Int256Vector extends IntVector {
Int256Mask.class, (Int256Mask) m); // specialize
}
@Override
@ForceInline
public Int256Vector selectFrom(Vector<Integer> v1,
Vector<Integer> v2) {
return (Int256Vector)
super.selectFromTemplate((Int256Vector) v1, (Int256Vector) v2); // specialize
}
@ForceInline
@Override

View File

@ -506,6 +506,13 @@ final class Int512Vector extends IntVector {
Int512Mask.class, (Int512Mask) m); // specialize
}
@Override
@ForceInline
public Int512Vector selectFrom(Vector<Integer> v1,
Vector<Integer> v2) {
return (Int512Vector)
super.selectFromTemplate((Int512Vector) v1, (Int512Vector) v2); // specialize
}
@ForceInline
@Override

View File

@ -506,6 +506,13 @@ final class Int64Vector extends IntVector {
Int64Mask.class, (Int64Mask) m); // specialize
}
@Override
@ForceInline
public Int64Vector selectFrom(Vector<Integer> v1,
Vector<Integer> v2) {
return (Int64Vector)
super.selectFromTemplate((Int64Vector) v1, (Int64Vector) v2); // specialize
}
@ForceInline
@Override

View File

@ -506,6 +506,13 @@ final class IntMaxVector extends IntVector {
IntMaxMask.class, (IntMaxMask) m); // specialize
}
@Override
@ForceInline
public IntMaxVector selectFrom(Vector<Integer> v1,
Vector<Integer> v2) {
return (IntMaxVector)
super.selectFromTemplate((IntMaxVector) v1, (IntMaxVector) v2); // specialize
}
@ForceInline
@Override

View File

@ -536,6 +536,19 @@ public abstract class IntVector extends AbstractVector<Integer> {
return r;
}
static IntVector selectFromTwoVectorHelper(Vector<Integer> indexes, Vector<Integer> src1, Vector<Integer> src2) {
int vlen = indexes.length();
int[] res = new int[vlen];
int[] vecPayload1 = ((IntVector)indexes).vec();
int[] vecPayload2 = ((IntVector)src1).vec();
int[] vecPayload3 = ((IntVector)src2).vec();
for (int i = 0; i < vlen; i++) {
int wrapped_index = VectorIntrinsics.wrapToRange((int)vecPayload1[i], 2 * vlen);
res[i] = wrapped_index >= vlen ? vecPayload3[wrapped_index - vlen] : vecPayload2[wrapped_index];
}
return ((IntVector)src1).vectorFactory(res);
}
// Static factories (other than memory operations)
// Note: A surprising behavior in javadoc
@ -2560,6 +2573,22 @@ public abstract class IntVector extends AbstractVector<Integer> {
v2.rearrange(v1.toShuffle(), _m));
}
/**
* {@inheritDoc} <!--workaround-->
*/
@Override
public abstract
IntVector selectFrom(Vector<Integer> v1, Vector<Integer> v2);
/*package-private*/
@ForceInline
final IntVector selectFromTemplate(IntVector v1, IntVector v2) {
return VectorSupport.selectFromTwoVectorOp(getClass(), int.class, length(), this, v1, v2,
(vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3));
}
/// Ternary operations
/**

View File

@ -496,6 +496,13 @@ final class Long128Vector extends LongVector {
Long128Mask.class, (Long128Mask) m); // specialize
}
@Override
@ForceInline
public Long128Vector selectFrom(Vector<Long> v1,
Vector<Long> v2) {
return (Long128Vector)
super.selectFromTemplate((Long128Vector) v1, (Long128Vector) v2); // specialize
}
@ForceInline
@Override

View File

@ -496,6 +496,13 @@ final class Long256Vector extends LongVector {
Long256Mask.class, (Long256Mask) m); // specialize
}
@Override
@ForceInline
public Long256Vector selectFrom(Vector<Long> v1,
Vector<Long> v2) {
return (Long256Vector)
super.selectFromTemplate((Long256Vector) v1, (Long256Vector) v2); // specialize
}
@ForceInline
@Override

View File

@ -496,6 +496,13 @@ final class Long512Vector extends LongVector {
Long512Mask.class, (Long512Mask) m); // specialize
}
@Override
@ForceInline
public Long512Vector selectFrom(Vector<Long> v1,
Vector<Long> v2) {
return (Long512Vector)
super.selectFromTemplate((Long512Vector) v1, (Long512Vector) v2); // specialize
}
@ForceInline
@Override

View File

@ -496,6 +496,13 @@ final class Long64Vector extends LongVector {
Long64Mask.class, (Long64Mask) m); // specialize
}
@Override
@ForceInline
public Long64Vector selectFrom(Vector<Long> v1,
Vector<Long> v2) {
return (Long64Vector)
super.selectFromTemplate((Long64Vector) v1, (Long64Vector) v2); // specialize
}
@ForceInline
@Override

View File

@ -496,6 +496,13 @@ final class LongMaxVector extends LongVector {
LongMaxMask.class, (LongMaxMask) m); // specialize
}
@Override
@ForceInline
public LongMaxVector selectFrom(Vector<Long> v1,
Vector<Long> v2) {
return (LongMaxVector)
super.selectFromTemplate((LongMaxVector) v1, (LongMaxVector) v2); // specialize
}
@ForceInline
@Override

View File

@ -536,6 +536,19 @@ public abstract class LongVector extends AbstractVector<Long> {
return r;
}
static LongVector selectFromTwoVectorHelper(Vector<Long> indexes, Vector<Long> src1, Vector<Long> src2) {
int vlen = indexes.length();
long[] res = new long[vlen];
long[] vecPayload1 = ((LongVector)indexes).vec();
long[] vecPayload2 = ((LongVector)src1).vec();
long[] vecPayload3 = ((LongVector)src2).vec();
for (int i = 0; i < vlen; i++) {
int wrapped_index = VectorIntrinsics.wrapToRange((int)vecPayload1[i], 2 * vlen);
res[i] = wrapped_index >= vlen ? vecPayload3[wrapped_index - vlen] : vecPayload2[wrapped_index];
}
return ((LongVector)src1).vectorFactory(res);
}
// Static factories (other than memory operations)
// Note: A surprising behavior in javadoc
@ -2426,6 +2439,22 @@ public abstract class LongVector extends AbstractVector<Long> {
v2.rearrange(v1.toShuffle(), _m));
}
/**
* {@inheritDoc} <!--workaround-->
*/
@Override
public abstract
LongVector selectFrom(Vector<Long> v1, Vector<Long> v2);
/*package-private*/
@ForceInline
final LongVector selectFromTemplate(LongVector v1, LongVector v2) {
return VectorSupport.selectFromTwoVectorOp(getClass(), long.class, length(), this, v1, v2,
(vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3));
}
/// Ternary operations
/**

View File

@ -506,6 +506,13 @@ final class Short128Vector extends ShortVector {
Short128Mask.class, (Short128Mask) m); // specialize
}
@Override
@ForceInline
public Short128Vector selectFrom(Vector<Short> v1,
Vector<Short> v2) {
return (Short128Vector)
super.selectFromTemplate((Short128Vector) v1, (Short128Vector) v2); // specialize
}
@ForceInline
@Override

View File

@ -506,6 +506,13 @@ final class Short256Vector extends ShortVector {
Short256Mask.class, (Short256Mask) m); // specialize
}
@Override
@ForceInline
public Short256Vector selectFrom(Vector<Short> v1,
Vector<Short> v2) {
return (Short256Vector)
super.selectFromTemplate((Short256Vector) v1, (Short256Vector) v2); // specialize
}
@ForceInline
@Override

View File

@ -506,6 +506,13 @@ final class Short512Vector extends ShortVector {
Short512Mask.class, (Short512Mask) m); // specialize
}
@Override
@ForceInline
public Short512Vector selectFrom(Vector<Short> v1,
Vector<Short> v2) {
return (Short512Vector)
super.selectFromTemplate((Short512Vector) v1, (Short512Vector) v2); // specialize
}
@ForceInline
@Override

View File

@ -506,6 +506,13 @@ final class Short64Vector extends ShortVector {
Short64Mask.class, (Short64Mask) m); // specialize
}
@Override
@ForceInline
public Short64Vector selectFrom(Vector<Short> v1,
Vector<Short> v2) {
return (Short64Vector)
super.selectFromTemplate((Short64Vector) v1, (Short64Vector) v2); // specialize
}
@ForceInline
@Override

View File

@ -506,6 +506,13 @@ final class ShortMaxVector extends ShortVector {
ShortMaxMask.class, (ShortMaxMask) m); // specialize
}
@Override
@ForceInline
public ShortMaxVector selectFrom(Vector<Short> v1,
Vector<Short> v2) {
return (ShortMaxVector)
super.selectFromTemplate((ShortMaxVector) v1, (ShortMaxVector) v2); // specialize
}
@ForceInline
@Override

View File

@ -536,6 +536,19 @@ public abstract class ShortVector extends AbstractVector<Short> {
return r;
}
static ShortVector selectFromTwoVectorHelper(Vector<Short> indexes, Vector<Short> src1, Vector<Short> src2) {
int vlen = indexes.length();
short[] res = new short[vlen];
short[] vecPayload1 = ((ShortVector)indexes).vec();
short[] vecPayload2 = ((ShortVector)src1).vec();
short[] vecPayload3 = ((ShortVector)src2).vec();
for (int i = 0; i < vlen; i++) {
int wrapped_index = VectorIntrinsics.wrapToRange((int)vecPayload1[i], 2 * vlen);
res[i] = wrapped_index >= vlen ? vecPayload3[wrapped_index - vlen] : vecPayload2[wrapped_index];
}
return ((ShortVector)src1).vectorFactory(res);
}
// Static factories (other than memory operations)
// Note: A surprising behavior in javadoc
@ -2576,6 +2589,22 @@ public abstract class ShortVector extends AbstractVector<Short> {
v2.rearrange(v1.toShuffle(), _m));
}
/**
* {@inheritDoc} <!--workaround-->
*/
@Override
public abstract
ShortVector selectFrom(Vector<Short> v1, Vector<Short> v2);
/*package-private*/
@ForceInline
final ShortVector selectFromTemplate(ShortVector v1, ShortVector v2) {
return VectorSupport.selectFromTwoVectorOp(getClass(), short.class, length(), this, v1, v2,
(vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3));
}
/// Ternary operations
/**

View File

@ -2756,6 +2756,61 @@ public abstract class Vector<E> extends jdk.internal.vm.vector.VectorSupport.Vec
*/
public abstract Vector<E> selectFrom(Vector<E> v);
/**
* Using values stored in the lanes of this vector,
* assemble values stored in the second vector {@code v1}
* and third vector {@code v2}. The second and third vectors thus
* serve as a table, whose elements are selected by indexes
* in this vector.
*
* This is a cross-lane operation that rearranges the lane
* elements of the argument vectors, under the control of
* this vector.
*
* For each lane {@code N} of this vector, and for each lane
* value {@code I=wrapIndex(this.lane(N)} in this vector,
* the output lane {@code N} obtains the value from
* the second vector at lane {@code I} if {@code I < VLENGTH}.
* Otherwise, the output lane {@code N} obtains the value from
* the third vector at lane {@code I - VLENGTH}.
*
* Here, {@code VLENGTH} is the result of {@code this.length()},
* and for integral values {@code wrapIndex} computes the result of
* {@code Math.floorMod(E, 2 * VLENGTH)}, where {@code E} is the index
* to be wrapped. As long as {@code VLENGTH} is a power of two, then the
* result is also equal to {@code E & (2 * VLENGTH - 1)}.
*
* For floating point values {@code wrapIndex} computes
* {@code Math.floorMod(convert(E), 2 * VLENGTH)}, where {@code convert}
* converts the floating point value to an integral value with the same
* number of representational bits - as in converting a double value to
* a long value ({@code (long)doubleVal}), or a float value to an int value
* ({@code (int)floatVal}).
*
* In this way, the result contains only values stored in the
* argument vectors {@code v1} and {@code v2}, but presented in
* an order which depends on the index values in {@code this}.
*
* The result for integral values is the same as the expression
* {@snippet lang=java :
* v1.rearrange(
* this.lanewise(VectorOperators.AND, 2 * VLENGTH - 1).toShuffle(),
* v2)
* }
* when {@code VLENGTH} is a power of two.
* The lane-wise {@code AND} operation results in a vector whose
* elements are in the range {@code [0, 2 * VLENGTH - 1])}. The shuffle
* conversion results in a partially wrapped shuffle whose indexes are
* in the range {@code [-VLENGTH, VLENGTH - 1])}, where exceptional
* indexes are used to select elements in the third vector.
*
* @param v1 the first input vector
* @param v2 the second input vector
* @return the rearrangement of lane elements of {@code v1} and {@code v2}
* @see #rearrange(VectorShuffle,Vector)
*/
public abstract Vector<E> selectFrom(Vector<E> v1, Vector<E> v2);
/**
* Using index values stored in the lanes of this vector,
* assemble values stored in second vector, under the control

View File

@ -563,6 +563,7 @@ public abstract class VectorOperators {
public static final /*bitwise*/ Associative OR = assoc("OR", "|", VectorSupport.VECTOR_OP_OR, VO_NOFP+VO_ASSOC);
/*package-private*/ /** Version of OR which works on float and double too. */
static final Associative OR_UNCHECKED = assoc("OR_UNCHECKED", "|", VectorSupport.VECTOR_OP_OR, VO_ASSOC+VO_PRIVATE);
/** Produce {@code a^b}. Integral only. */
public static final /*bitwise*/ Associative XOR = assoc("XOR", "^", VectorSupport.VECTOR_OP_XOR, VO_NOFP+VO_ASSOC);

View File

@ -550,6 +550,19 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
return r;
}
static $abstractvectortype$ selectFromTwoVectorHelper(Vector<$Boxtype$> indexes, Vector<$Boxtype$> src1, Vector<$Boxtype$> src2) {
int vlen = indexes.length();
$type$[] res = new $type$[vlen];
$type$[] vecPayload1 = (($abstractvectortype$)indexes).vec();
$type$[] vecPayload2 = (($abstractvectortype$)src1).vec();
$type$[] vecPayload3 = (($abstractvectortype$)src2).vec();
for (int i = 0; i < vlen; i++) {
int wrapped_index = VectorIntrinsics.wrapToRange((int)vecPayload1[i], 2 * vlen);
res[i] = wrapped_index >= vlen ? vecPayload3[wrapped_index - vlen] : vecPayload2[wrapped_index];
}
return (($abstractvectortype$)src1).vectorFactory(res);
}
// Static factories (other than memory operations)
// Note: A surprising behavior in javadoc
@ -2952,6 +2965,22 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
v2.rearrange(v1.toShuffle(), _m));
}
/**
* {@inheritDoc} <!--workaround-->
*/
@Override
public abstract
$abstractvectortype$ selectFrom(Vector<$Boxtype$> v1, Vector<$Boxtype$> v2);
/*package-private*/
@ForceInline
final $abstractvectortype$ selectFromTemplate($abstractvectortype$ v1, $abstractvectortype$ v2) {
return VectorSupport.selectFromTwoVectorOp(getClass(), $type$.class, length(), this, v1, v2,
(vec1, vec2, vec3) -> selectFromTwoVectorHelper(vec1, vec2, vec3));
}
/// Ternary operations
#if[BITWISE]

View File

@ -512,6 +512,13 @@ final class $vectortype$ extends $abstractvectortype$ {
$masktype$.class, ($masktype$) m); // specialize
}
@Override
@ForceInline
public $vectortype$ selectFrom(Vector<$Boxtype$> v1,
Vector<$Boxtype$> v2) {
return ($vectortype$)
super.selectFromTemplate(($vectortype$) v1, ($vectortype$) v2); // specialize
}
#if[FP]
@ForceInline

View File

@ -302,6 +302,25 @@ public class Byte128VectorTests extends AbstractVectorTest {
}
}
static void assertSelectFromTwoVectorEquals(byte[] r, byte[] order, byte[] a, byte[] b, int vector_len) {
int i = 0, j = 0;
boolean is_exceptional_idx = false;
int idx = 0, wrapped_index = 0, oidx = 0;
try {
for (; i < a.length; i += vector_len) {
for (j = 0; j < vector_len; j++) {
idx = i + j;
wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len);
is_exceptional_idx = wrapped_index >= vector_len;
oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
}
}
} catch (AssertionError e) {
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
}
}
static void assertSelectFromArraysEquals(byte[] r, byte[] a, byte[] order, int vector_len) {
int i = 0, j = 0;
try {
@ -962,6 +981,18 @@ public class Byte128VectorTests extends AbstractVectorTest {
flatMap(pair -> BYTE_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
static final List<IntFunction<byte[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
withToString("byte[0..VECLEN*2)", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (byte)(RAND.nextInt()));
})
);
static final List<List<IntFunction<byte[]>>> BYTE_GENERATOR_SELECT_FROM_TRIPLES =
BYTE_GENERATOR_PAIRS.stream().
flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
@DataProvider
public Object[][] byteBinaryOpProvider() {
return BYTE_GENERATOR_PAIRS.stream().map(List::toArray).
@ -989,6 +1020,12 @@ public class Byte128VectorTests extends AbstractVectorTest {
toArray(Object[][]::new);
}
@DataProvider
public Object[][] byteSelectFromTwoVectorOpProvider() {
return BYTE_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] byteTernaryOpMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
@ -5746,6 +5783,24 @@ public class Byte128VectorTests extends AbstractVectorTest {
assertSelectFromArraysEquals(r, a, order, SPECIES.length());
}
@Test(dataProvider = "byteSelectFromTwoVectorOpProvider")
static void SelectFromTwoVectorByte128VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb, IntFunction<byte[]> fc) {
byte[] a = fa.apply(SPECIES.length());
byte[] b = fb.apply(SPECIES.length());
byte[] idx = fc.apply(SPECIES.length());
byte[] r = fr.apply(SPECIES.length());
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < idx.length; i += SPECIES.length()) {
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
ByteVector idxv = ByteVector.fromArray(SPECIES, idx, i);
idxv.selectFrom(av, bv).intoArray(r, i);
}
}
assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length());
}
@Test(dataProvider = "byteUnaryOpSelectFromMaskProvider")
static void SelectFromByte128VectorTestsMaskedSmokeTest(IntFunction<byte[]> fa,
BiFunction<Integer,Integer,byte[]> fs,

View File

@ -302,6 +302,25 @@ public class Byte256VectorTests extends AbstractVectorTest {
}
}
static void assertSelectFromTwoVectorEquals(byte[] r, byte[] order, byte[] a, byte[] b, int vector_len) {
int i = 0, j = 0;
boolean is_exceptional_idx = false;
int idx = 0, wrapped_index = 0, oidx = 0;
try {
for (; i < a.length; i += vector_len) {
for (j = 0; j < vector_len; j++) {
idx = i + j;
wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len);
is_exceptional_idx = wrapped_index >= vector_len;
oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
}
}
} catch (AssertionError e) {
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
}
}
static void assertSelectFromArraysEquals(byte[] r, byte[] a, byte[] order, int vector_len) {
int i = 0, j = 0;
try {
@ -962,6 +981,18 @@ public class Byte256VectorTests extends AbstractVectorTest {
flatMap(pair -> BYTE_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
static final List<IntFunction<byte[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
withToString("byte[0..VECLEN*2)", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (byte)(RAND.nextInt()));
})
);
static final List<List<IntFunction<byte[]>>> BYTE_GENERATOR_SELECT_FROM_TRIPLES =
BYTE_GENERATOR_PAIRS.stream().
flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
@DataProvider
public Object[][] byteBinaryOpProvider() {
return BYTE_GENERATOR_PAIRS.stream().map(List::toArray).
@ -989,6 +1020,12 @@ public class Byte256VectorTests extends AbstractVectorTest {
toArray(Object[][]::new);
}
@DataProvider
public Object[][] byteSelectFromTwoVectorOpProvider() {
return BYTE_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] byteTernaryOpMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
@ -5746,6 +5783,24 @@ public class Byte256VectorTests extends AbstractVectorTest {
assertSelectFromArraysEquals(r, a, order, SPECIES.length());
}
@Test(dataProvider = "byteSelectFromTwoVectorOpProvider")
static void SelectFromTwoVectorByte256VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb, IntFunction<byte[]> fc) {
byte[] a = fa.apply(SPECIES.length());
byte[] b = fb.apply(SPECIES.length());
byte[] idx = fc.apply(SPECIES.length());
byte[] r = fr.apply(SPECIES.length());
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < idx.length; i += SPECIES.length()) {
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
ByteVector idxv = ByteVector.fromArray(SPECIES, idx, i);
idxv.selectFrom(av, bv).intoArray(r, i);
}
}
assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length());
}
@Test(dataProvider = "byteUnaryOpSelectFromMaskProvider")
static void SelectFromByte256VectorTestsMaskedSmokeTest(IntFunction<byte[]> fa,
BiFunction<Integer,Integer,byte[]> fs,

View File

@ -302,6 +302,25 @@ public class Byte512VectorTests extends AbstractVectorTest {
}
}
static void assertSelectFromTwoVectorEquals(byte[] r, byte[] order, byte[] a, byte[] b, int vector_len) {
int i = 0, j = 0;
boolean is_exceptional_idx = false;
int idx = 0, wrapped_index = 0, oidx = 0;
try {
for (; i < a.length; i += vector_len) {
for (j = 0; j < vector_len; j++) {
idx = i + j;
wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len);
is_exceptional_idx = wrapped_index >= vector_len;
oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
}
}
} catch (AssertionError e) {
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
}
}
static void assertSelectFromArraysEquals(byte[] r, byte[] a, byte[] order, int vector_len) {
int i = 0, j = 0;
try {
@ -962,6 +981,18 @@ public class Byte512VectorTests extends AbstractVectorTest {
flatMap(pair -> BYTE_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
static final List<IntFunction<byte[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
withToString("byte[0..VECLEN*2)", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (byte)(RAND.nextInt()));
})
);
static final List<List<IntFunction<byte[]>>> BYTE_GENERATOR_SELECT_FROM_TRIPLES =
BYTE_GENERATOR_PAIRS.stream().
flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
@DataProvider
public Object[][] byteBinaryOpProvider() {
return BYTE_GENERATOR_PAIRS.stream().map(List::toArray).
@ -989,6 +1020,12 @@ public class Byte512VectorTests extends AbstractVectorTest {
toArray(Object[][]::new);
}
@DataProvider
public Object[][] byteSelectFromTwoVectorOpProvider() {
return BYTE_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] byteTernaryOpMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
@ -5746,6 +5783,24 @@ public class Byte512VectorTests extends AbstractVectorTest {
assertSelectFromArraysEquals(r, a, order, SPECIES.length());
}
@Test(dataProvider = "byteSelectFromTwoVectorOpProvider")
static void SelectFromTwoVectorByte512VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb, IntFunction<byte[]> fc) {
byte[] a = fa.apply(SPECIES.length());
byte[] b = fb.apply(SPECIES.length());
byte[] idx = fc.apply(SPECIES.length());
byte[] r = fr.apply(SPECIES.length());
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < idx.length; i += SPECIES.length()) {
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
ByteVector idxv = ByteVector.fromArray(SPECIES, idx, i);
idxv.selectFrom(av, bv).intoArray(r, i);
}
}
assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length());
}
@Test(dataProvider = "byteUnaryOpSelectFromMaskProvider")
static void SelectFromByte512VectorTestsMaskedSmokeTest(IntFunction<byte[]> fa,
BiFunction<Integer,Integer,byte[]> fs,

View File

@ -302,6 +302,25 @@ public class Byte64VectorTests extends AbstractVectorTest {
}
}
static void assertSelectFromTwoVectorEquals(byte[] r, byte[] order, byte[] a, byte[] b, int vector_len) {
int i = 0, j = 0;
boolean is_exceptional_idx = false;
int idx = 0, wrapped_index = 0, oidx = 0;
try {
for (; i < a.length; i += vector_len) {
for (j = 0; j < vector_len; j++) {
idx = i + j;
wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len);
is_exceptional_idx = wrapped_index >= vector_len;
oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
}
}
} catch (AssertionError e) {
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
}
}
static void assertSelectFromArraysEquals(byte[] r, byte[] a, byte[] order, int vector_len) {
int i = 0, j = 0;
try {
@ -962,6 +981,18 @@ public class Byte64VectorTests extends AbstractVectorTest {
flatMap(pair -> BYTE_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
static final List<IntFunction<byte[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
withToString("byte[0..VECLEN*2)", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (byte)(RAND.nextInt()));
})
);
static final List<List<IntFunction<byte[]>>> BYTE_GENERATOR_SELECT_FROM_TRIPLES =
BYTE_GENERATOR_PAIRS.stream().
flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
@DataProvider
public Object[][] byteBinaryOpProvider() {
return BYTE_GENERATOR_PAIRS.stream().map(List::toArray).
@ -989,6 +1020,12 @@ public class Byte64VectorTests extends AbstractVectorTest {
toArray(Object[][]::new);
}
@DataProvider
public Object[][] byteSelectFromTwoVectorOpProvider() {
return BYTE_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] byteTernaryOpMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
@ -5746,6 +5783,24 @@ public class Byte64VectorTests extends AbstractVectorTest {
assertSelectFromArraysEquals(r, a, order, SPECIES.length());
}
@Test(dataProvider = "byteSelectFromTwoVectorOpProvider")
static void SelectFromTwoVectorByte64VectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb, IntFunction<byte[]> fc) {
byte[] a = fa.apply(SPECIES.length());
byte[] b = fb.apply(SPECIES.length());
byte[] idx = fc.apply(SPECIES.length());
byte[] r = fr.apply(SPECIES.length());
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < idx.length; i += SPECIES.length()) {
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
ByteVector idxv = ByteVector.fromArray(SPECIES, idx, i);
idxv.selectFrom(av, bv).intoArray(r, i);
}
}
assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length());
}
@Test(dataProvider = "byteUnaryOpSelectFromMaskProvider")
static void SelectFromByte64VectorTestsMaskedSmokeTest(IntFunction<byte[]> fa,
BiFunction<Integer,Integer,byte[]> fs,

View File

@ -307,6 +307,25 @@ public class ByteMaxVectorTests extends AbstractVectorTest {
}
}
static void assertSelectFromTwoVectorEquals(byte[] r, byte[] order, byte[] a, byte[] b, int vector_len) {
int i = 0, j = 0;
boolean is_exceptional_idx = false;
int idx = 0, wrapped_index = 0, oidx = 0;
try {
for (; i < a.length; i += vector_len) {
for (j = 0; j < vector_len; j++) {
idx = i + j;
wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len);
is_exceptional_idx = wrapped_index >= vector_len;
oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
}
}
} catch (AssertionError e) {
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
}
}
static void assertSelectFromArraysEquals(byte[] r, byte[] a, byte[] order, int vector_len) {
int i = 0, j = 0;
try {
@ -967,6 +986,18 @@ public class ByteMaxVectorTests extends AbstractVectorTest {
flatMap(pair -> BYTE_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
static final List<IntFunction<byte[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
withToString("byte[0..VECLEN*2)", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (byte)(RAND.nextInt()));
})
);
static final List<List<IntFunction<byte[]>>> BYTE_GENERATOR_SELECT_FROM_TRIPLES =
BYTE_GENERATOR_PAIRS.stream().
flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
@DataProvider
public Object[][] byteBinaryOpProvider() {
return BYTE_GENERATOR_PAIRS.stream().map(List::toArray).
@ -994,6 +1025,12 @@ public class ByteMaxVectorTests extends AbstractVectorTest {
toArray(Object[][]::new);
}
@DataProvider
public Object[][] byteSelectFromTwoVectorOpProvider() {
return BYTE_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] byteTernaryOpMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
@ -5751,6 +5788,24 @@ public class ByteMaxVectorTests extends AbstractVectorTest {
assertSelectFromArraysEquals(r, a, order, SPECIES.length());
}
@Test(dataProvider = "byteSelectFromTwoVectorOpProvider")
static void SelectFromTwoVectorByteMaxVectorTests(IntFunction<byte[]> fa, IntFunction<byte[]> fb, IntFunction<byte[]> fc) {
byte[] a = fa.apply(SPECIES.length());
byte[] b = fb.apply(SPECIES.length());
byte[] idx = fc.apply(SPECIES.length());
byte[] r = fr.apply(SPECIES.length());
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < idx.length; i += SPECIES.length()) {
ByteVector av = ByteVector.fromArray(SPECIES, a, i);
ByteVector bv = ByteVector.fromArray(SPECIES, b, i);
ByteVector idxv = ByteVector.fromArray(SPECIES, idx, i);
idxv.selectFrom(av, bv).intoArray(r, i);
}
}
assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length());
}
@Test(dataProvider = "byteUnaryOpSelectFromMaskProvider")
static void SelectFromByteMaxVectorTestsMaskedSmokeTest(IntFunction<byte[]> fa,
BiFunction<Integer,Integer,byte[]> fs,

View File

@ -321,6 +321,25 @@ relativeError));
}
}
static void assertSelectFromTwoVectorEquals(double[] r, double[] order, double[] a, double[] b, int vector_len) {
int i = 0, j = 0;
boolean is_exceptional_idx = false;
int idx = 0, wrapped_index = 0, oidx = 0;
try {
for (; i < a.length; i += vector_len) {
for (j = 0; j < vector_len; j++) {
idx = i + j;
wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len);
is_exceptional_idx = wrapped_index >= vector_len;
oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
}
}
} catch (AssertionError e) {
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
}
}
static void assertSelectFromArraysEquals(double[] r, double[] a, double[] order, int vector_len) {
int i = 0, j = 0;
try {
@ -1108,6 +1127,18 @@ relativeError));
flatMap(pair -> DOUBLE_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
static final List<IntFunction<double[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
withToString("double[0..VECLEN*2)", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (double)(RAND.nextInt()));
})
);
static final List<List<IntFunction<double[]>>> DOUBLE_GENERATOR_SELECT_FROM_TRIPLES =
DOUBLE_GENERATOR_PAIRS.stream().
flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
@DataProvider
public Object[][] doubleBinaryOpProvider() {
return DOUBLE_GENERATOR_PAIRS.stream().map(List::toArray).
@ -1135,6 +1166,12 @@ relativeError));
toArray(Object[][]::new);
}
@DataProvider
public Object[][] doubleSelectFromTwoVectorOpProvider() {
return DOUBLE_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] doubleTernaryOpMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
@ -4799,6 +4836,24 @@ relativeError));
assertSelectFromArraysEquals(r, a, order, SPECIES.length());
}
@Test(dataProvider = "doubleSelectFromTwoVectorOpProvider")
static void SelectFromTwoVectorDouble128VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb, IntFunction<double[]> fc) {
double[] a = fa.apply(SPECIES.length());
double[] b = fb.apply(SPECIES.length());
double[] idx = fc.apply(SPECIES.length());
double[] r = fr.apply(SPECIES.length());
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < idx.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
DoubleVector idxv = DoubleVector.fromArray(SPECIES, idx, i);
idxv.selectFrom(av, bv).intoArray(r, i);
}
}
assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length());
}
@Test(dataProvider = "doubleUnaryOpSelectFromMaskProvider")
static void SelectFromDouble128VectorTestsMaskedSmokeTest(IntFunction<double[]> fa,
BiFunction<Integer,Integer,double[]> fs,

View File

@ -321,6 +321,25 @@ relativeError));
}
}
static void assertSelectFromTwoVectorEquals(double[] r, double[] order, double[] a, double[] b, int vector_len) {
int i = 0, j = 0;
boolean is_exceptional_idx = false;
int idx = 0, wrapped_index = 0, oidx = 0;
try {
for (; i < a.length; i += vector_len) {
for (j = 0; j < vector_len; j++) {
idx = i + j;
wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len);
is_exceptional_idx = wrapped_index >= vector_len;
oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
}
}
} catch (AssertionError e) {
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
}
}
static void assertSelectFromArraysEquals(double[] r, double[] a, double[] order, int vector_len) {
int i = 0, j = 0;
try {
@ -1108,6 +1127,18 @@ relativeError));
flatMap(pair -> DOUBLE_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
static final List<IntFunction<double[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
withToString("double[0..VECLEN*2)", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (double)(RAND.nextInt()));
})
);
static final List<List<IntFunction<double[]>>> DOUBLE_GENERATOR_SELECT_FROM_TRIPLES =
DOUBLE_GENERATOR_PAIRS.stream().
flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
@DataProvider
public Object[][] doubleBinaryOpProvider() {
return DOUBLE_GENERATOR_PAIRS.stream().map(List::toArray).
@ -1135,6 +1166,12 @@ relativeError));
toArray(Object[][]::new);
}
@DataProvider
public Object[][] doubleSelectFromTwoVectorOpProvider() {
return DOUBLE_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] doubleTernaryOpMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
@ -4799,6 +4836,24 @@ relativeError));
assertSelectFromArraysEquals(r, a, order, SPECIES.length());
}
@Test(dataProvider = "doubleSelectFromTwoVectorOpProvider")
static void SelectFromTwoVectorDouble256VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb, IntFunction<double[]> fc) {
double[] a = fa.apply(SPECIES.length());
double[] b = fb.apply(SPECIES.length());
double[] idx = fc.apply(SPECIES.length());
double[] r = fr.apply(SPECIES.length());
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < idx.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
DoubleVector idxv = DoubleVector.fromArray(SPECIES, idx, i);
idxv.selectFrom(av, bv).intoArray(r, i);
}
}
assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length());
}
@Test(dataProvider = "doubleUnaryOpSelectFromMaskProvider")
static void SelectFromDouble256VectorTestsMaskedSmokeTest(IntFunction<double[]> fa,
BiFunction<Integer,Integer,double[]> fs,

View File

@ -321,6 +321,25 @@ relativeError));
}
}
static void assertSelectFromTwoVectorEquals(double[] r, double[] order, double[] a, double[] b, int vector_len) {
int i = 0, j = 0;
boolean is_exceptional_idx = false;
int idx = 0, wrapped_index = 0, oidx = 0;
try {
for (; i < a.length; i += vector_len) {
for (j = 0; j < vector_len; j++) {
idx = i + j;
wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len);
is_exceptional_idx = wrapped_index >= vector_len;
oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
}
}
} catch (AssertionError e) {
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
}
}
static void assertSelectFromArraysEquals(double[] r, double[] a, double[] order, int vector_len) {
int i = 0, j = 0;
try {
@ -1108,6 +1127,18 @@ relativeError));
flatMap(pair -> DOUBLE_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
static final List<IntFunction<double[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
withToString("double[0..VECLEN*2)", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (double)(RAND.nextInt()));
})
);
static final List<List<IntFunction<double[]>>> DOUBLE_GENERATOR_SELECT_FROM_TRIPLES =
DOUBLE_GENERATOR_PAIRS.stream().
flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
@DataProvider
public Object[][] doubleBinaryOpProvider() {
return DOUBLE_GENERATOR_PAIRS.stream().map(List::toArray).
@ -1135,6 +1166,12 @@ relativeError));
toArray(Object[][]::new);
}
@DataProvider
public Object[][] doubleSelectFromTwoVectorOpProvider() {
return DOUBLE_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] doubleTernaryOpMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
@ -4799,6 +4836,24 @@ relativeError));
assertSelectFromArraysEquals(r, a, order, SPECIES.length());
}
@Test(dataProvider = "doubleSelectFromTwoVectorOpProvider")
static void SelectFromTwoVectorDouble512VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb, IntFunction<double[]> fc) {
double[] a = fa.apply(SPECIES.length());
double[] b = fb.apply(SPECIES.length());
double[] idx = fc.apply(SPECIES.length());
double[] r = fr.apply(SPECIES.length());
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < idx.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
DoubleVector idxv = DoubleVector.fromArray(SPECIES, idx, i);
idxv.selectFrom(av, bv).intoArray(r, i);
}
}
assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length());
}
@Test(dataProvider = "doubleUnaryOpSelectFromMaskProvider")
static void SelectFromDouble512VectorTestsMaskedSmokeTest(IntFunction<double[]> fa,
BiFunction<Integer,Integer,double[]> fs,

View File

@ -321,6 +321,25 @@ relativeError));
}
}
static void assertSelectFromTwoVectorEquals(double[] r, double[] order, double[] a, double[] b, int vector_len) {
int i = 0, j = 0;
boolean is_exceptional_idx = false;
int idx = 0, wrapped_index = 0, oidx = 0;
try {
for (; i < a.length; i += vector_len) {
for (j = 0; j < vector_len; j++) {
idx = i + j;
wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len);
is_exceptional_idx = wrapped_index >= vector_len;
oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
}
}
} catch (AssertionError e) {
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
}
}
static void assertSelectFromArraysEquals(double[] r, double[] a, double[] order, int vector_len) {
int i = 0, j = 0;
try {
@ -1108,6 +1127,18 @@ relativeError));
flatMap(pair -> DOUBLE_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
static final List<IntFunction<double[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
withToString("double[0..VECLEN*2)", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (double)(RAND.nextInt()));
})
);
static final List<List<IntFunction<double[]>>> DOUBLE_GENERATOR_SELECT_FROM_TRIPLES =
DOUBLE_GENERATOR_PAIRS.stream().
flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
@DataProvider
public Object[][] doubleBinaryOpProvider() {
return DOUBLE_GENERATOR_PAIRS.stream().map(List::toArray).
@ -1135,6 +1166,12 @@ relativeError));
toArray(Object[][]::new);
}
@DataProvider
public Object[][] doubleSelectFromTwoVectorOpProvider() {
return DOUBLE_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] doubleTernaryOpMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
@ -4799,6 +4836,24 @@ relativeError));
assertSelectFromArraysEquals(r, a, order, SPECIES.length());
}
@Test(dataProvider = "doubleSelectFromTwoVectorOpProvider")
static void SelectFromTwoVectorDouble64VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb, IntFunction<double[]> fc) {
double[] a = fa.apply(SPECIES.length());
double[] b = fb.apply(SPECIES.length());
double[] idx = fc.apply(SPECIES.length());
double[] r = fr.apply(SPECIES.length());
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < idx.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
DoubleVector idxv = DoubleVector.fromArray(SPECIES, idx, i);
idxv.selectFrom(av, bv).intoArray(r, i);
}
}
assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length());
}
@Test(dataProvider = "doubleUnaryOpSelectFromMaskProvider")
static void SelectFromDouble64VectorTestsMaskedSmokeTest(IntFunction<double[]> fa,
BiFunction<Integer,Integer,double[]> fs,

View File

@ -326,6 +326,25 @@ relativeError));
}
}
static void assertSelectFromTwoVectorEquals(double[] r, double[] order, double[] a, double[] b, int vector_len) {
int i = 0, j = 0;
boolean is_exceptional_idx = false;
int idx = 0, wrapped_index = 0, oidx = 0;
try {
for (; i < a.length; i += vector_len) {
for (j = 0; j < vector_len; j++) {
idx = i + j;
wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len);
is_exceptional_idx = wrapped_index >= vector_len;
oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
}
}
} catch (AssertionError e) {
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
}
}
static void assertSelectFromArraysEquals(double[] r, double[] a, double[] order, int vector_len) {
int i = 0, j = 0;
try {
@ -1113,6 +1132,18 @@ relativeError));
flatMap(pair -> DOUBLE_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
static final List<IntFunction<double[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
withToString("double[0..VECLEN*2)", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (double)(RAND.nextInt()));
})
);
static final List<List<IntFunction<double[]>>> DOUBLE_GENERATOR_SELECT_FROM_TRIPLES =
DOUBLE_GENERATOR_PAIRS.stream().
flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
@DataProvider
public Object[][] doubleBinaryOpProvider() {
return DOUBLE_GENERATOR_PAIRS.stream().map(List::toArray).
@ -1140,6 +1171,12 @@ relativeError));
toArray(Object[][]::new);
}
@DataProvider
public Object[][] doubleSelectFromTwoVectorOpProvider() {
return DOUBLE_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] doubleTernaryOpMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
@ -4804,6 +4841,24 @@ relativeError));
assertSelectFromArraysEquals(r, a, order, SPECIES.length());
}
@Test(dataProvider = "doubleSelectFromTwoVectorOpProvider")
static void SelectFromTwoVectorDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb, IntFunction<double[]> fc) {
double[] a = fa.apply(SPECIES.length());
double[] b = fb.apply(SPECIES.length());
double[] idx = fc.apply(SPECIES.length());
double[] r = fr.apply(SPECIES.length());
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < idx.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
DoubleVector idxv = DoubleVector.fromArray(SPECIES, idx, i);
idxv.selectFrom(av, bv).intoArray(r, i);
}
}
assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length());
}
@Test(dataProvider = "doubleUnaryOpSelectFromMaskProvider")
static void SelectFromDoubleMaxVectorTestsMaskedSmokeTest(IntFunction<double[]> fa,
BiFunction<Integer,Integer,double[]> fs,

View File

@ -321,6 +321,25 @@ relativeError));
}
}
static void assertSelectFromTwoVectorEquals(float[] r, float[] order, float[] a, float[] b, int vector_len) {
int i = 0, j = 0;
boolean is_exceptional_idx = false;
int idx = 0, wrapped_index = 0, oidx = 0;
try {
for (; i < a.length; i += vector_len) {
for (j = 0; j < vector_len; j++) {
idx = i + j;
wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len);
is_exceptional_idx = wrapped_index >= vector_len;
oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
}
}
} catch (AssertionError e) {
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
}
}
static void assertSelectFromArraysEquals(float[] r, float[] a, float[] order, int vector_len) {
int i = 0, j = 0;
try {
@ -1119,6 +1138,18 @@ relativeError));
flatMap(pair -> FLOAT_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
static final List<IntFunction<float[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
withToString("float[0..VECLEN*2)", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (float)(RAND.nextInt()));
})
);
static final List<List<IntFunction<float[]>>> FLOAT_GENERATOR_SELECT_FROM_TRIPLES =
FLOAT_GENERATOR_PAIRS.stream().
flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
@DataProvider
public Object[][] floatBinaryOpProvider() {
return FLOAT_GENERATOR_PAIRS.stream().map(List::toArray).
@ -1146,6 +1177,12 @@ relativeError));
toArray(Object[][]::new);
}
@DataProvider
public Object[][] floatSelectFromTwoVectorOpProvider() {
return FLOAT_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] floatTernaryOpMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
@ -4778,6 +4815,24 @@ relativeError));
assertSelectFromArraysEquals(r, a, order, SPECIES.length());
}
@Test(dataProvider = "floatSelectFromTwoVectorOpProvider")
static void SelectFromTwoVectorFloat128VectorTests(IntFunction<float[]> fa, IntFunction<float[]> fb, IntFunction<float[]> fc) {
float[] a = fa.apply(SPECIES.length());
float[] b = fb.apply(SPECIES.length());
float[] idx = fc.apply(SPECIES.length());
float[] r = fr.apply(SPECIES.length());
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < idx.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
FloatVector bv = FloatVector.fromArray(SPECIES, b, i);
FloatVector idxv = FloatVector.fromArray(SPECIES, idx, i);
idxv.selectFrom(av, bv).intoArray(r, i);
}
}
assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length());
}
@Test(dataProvider = "floatUnaryOpSelectFromMaskProvider")
static void SelectFromFloat128VectorTestsMaskedSmokeTest(IntFunction<float[]> fa,
BiFunction<Integer,Integer,float[]> fs,

View File

@ -321,6 +321,25 @@ relativeError));
}
}
static void assertSelectFromTwoVectorEquals(float[] r, float[] order, float[] a, float[] b, int vector_len) {
int i = 0, j = 0;
boolean is_exceptional_idx = false;
int idx = 0, wrapped_index = 0, oidx = 0;
try {
for (; i < a.length; i += vector_len) {
for (j = 0; j < vector_len; j++) {
idx = i + j;
wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len);
is_exceptional_idx = wrapped_index >= vector_len;
oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
}
}
} catch (AssertionError e) {
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
}
}
static void assertSelectFromArraysEquals(float[] r, float[] a, float[] order, int vector_len) {
int i = 0, j = 0;
try {
@ -1119,6 +1138,18 @@ relativeError));
flatMap(pair -> FLOAT_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
static final List<IntFunction<float[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
withToString("float[0..VECLEN*2)", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (float)(RAND.nextInt()));
})
);
static final List<List<IntFunction<float[]>>> FLOAT_GENERATOR_SELECT_FROM_TRIPLES =
FLOAT_GENERATOR_PAIRS.stream().
flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
@DataProvider
public Object[][] floatBinaryOpProvider() {
return FLOAT_GENERATOR_PAIRS.stream().map(List::toArray).
@ -1146,6 +1177,12 @@ relativeError));
toArray(Object[][]::new);
}
@DataProvider
public Object[][] floatSelectFromTwoVectorOpProvider() {
return FLOAT_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] floatTernaryOpMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
@ -4778,6 +4815,24 @@ relativeError));
assertSelectFromArraysEquals(r, a, order, SPECIES.length());
}
@Test(dataProvider = "floatSelectFromTwoVectorOpProvider")
static void SelectFromTwoVectorFloat256VectorTests(IntFunction<float[]> fa, IntFunction<float[]> fb, IntFunction<float[]> fc) {
float[] a = fa.apply(SPECIES.length());
float[] b = fb.apply(SPECIES.length());
float[] idx = fc.apply(SPECIES.length());
float[] r = fr.apply(SPECIES.length());
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < idx.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
FloatVector bv = FloatVector.fromArray(SPECIES, b, i);
FloatVector idxv = FloatVector.fromArray(SPECIES, idx, i);
idxv.selectFrom(av, bv).intoArray(r, i);
}
}
assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length());
}
@Test(dataProvider = "floatUnaryOpSelectFromMaskProvider")
static void SelectFromFloat256VectorTestsMaskedSmokeTest(IntFunction<float[]> fa,
BiFunction<Integer,Integer,float[]> fs,

View File

@ -321,6 +321,25 @@ relativeError));
}
}
static void assertSelectFromTwoVectorEquals(float[] r, float[] order, float[] a, float[] b, int vector_len) {
int i = 0, j = 0;
boolean is_exceptional_idx = false;
int idx = 0, wrapped_index = 0, oidx = 0;
try {
for (; i < a.length; i += vector_len) {
for (j = 0; j < vector_len; j++) {
idx = i + j;
wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len);
is_exceptional_idx = wrapped_index >= vector_len;
oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
}
}
} catch (AssertionError e) {
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
}
}
static void assertSelectFromArraysEquals(float[] r, float[] a, float[] order, int vector_len) {
int i = 0, j = 0;
try {
@ -1119,6 +1138,18 @@ relativeError));
flatMap(pair -> FLOAT_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
static final List<IntFunction<float[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
withToString("float[0..VECLEN*2)", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (float)(RAND.nextInt()));
})
);
static final List<List<IntFunction<float[]>>> FLOAT_GENERATOR_SELECT_FROM_TRIPLES =
FLOAT_GENERATOR_PAIRS.stream().
flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
@DataProvider
public Object[][] floatBinaryOpProvider() {
return FLOAT_GENERATOR_PAIRS.stream().map(List::toArray).
@ -1146,6 +1177,12 @@ relativeError));
toArray(Object[][]::new);
}
@DataProvider
public Object[][] floatSelectFromTwoVectorOpProvider() {
return FLOAT_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] floatTernaryOpMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
@ -4778,6 +4815,24 @@ relativeError));
assertSelectFromArraysEquals(r, a, order, SPECIES.length());
}
@Test(dataProvider = "floatSelectFromTwoVectorOpProvider")
static void SelectFromTwoVectorFloat512VectorTests(IntFunction<float[]> fa, IntFunction<float[]> fb, IntFunction<float[]> fc) {
float[] a = fa.apply(SPECIES.length());
float[] b = fb.apply(SPECIES.length());
float[] idx = fc.apply(SPECIES.length());
float[] r = fr.apply(SPECIES.length());
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < idx.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
FloatVector bv = FloatVector.fromArray(SPECIES, b, i);
FloatVector idxv = FloatVector.fromArray(SPECIES, idx, i);
idxv.selectFrom(av, bv).intoArray(r, i);
}
}
assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length());
}
@Test(dataProvider = "floatUnaryOpSelectFromMaskProvider")
static void SelectFromFloat512VectorTestsMaskedSmokeTest(IntFunction<float[]> fa,
BiFunction<Integer,Integer,float[]> fs,

View File

@ -321,6 +321,25 @@ relativeError));
}
}
static void assertSelectFromTwoVectorEquals(float[] r, float[] order, float[] a, float[] b, int vector_len) {
int i = 0, j = 0;
boolean is_exceptional_idx = false;
int idx = 0, wrapped_index = 0, oidx = 0;
try {
for (; i < a.length; i += vector_len) {
for (j = 0; j < vector_len; j++) {
idx = i + j;
wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len);
is_exceptional_idx = wrapped_index >= vector_len;
oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
}
}
} catch (AssertionError e) {
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
}
}
static void assertSelectFromArraysEquals(float[] r, float[] a, float[] order, int vector_len) {
int i = 0, j = 0;
try {
@ -1119,6 +1138,18 @@ relativeError));
flatMap(pair -> FLOAT_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
static final List<IntFunction<float[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
withToString("float[0..VECLEN*2)", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (float)(RAND.nextInt()));
})
);
static final List<List<IntFunction<float[]>>> FLOAT_GENERATOR_SELECT_FROM_TRIPLES =
FLOAT_GENERATOR_PAIRS.stream().
flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
@DataProvider
public Object[][] floatBinaryOpProvider() {
return FLOAT_GENERATOR_PAIRS.stream().map(List::toArray).
@ -1146,6 +1177,12 @@ relativeError));
toArray(Object[][]::new);
}
@DataProvider
public Object[][] floatSelectFromTwoVectorOpProvider() {
return FLOAT_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] floatTernaryOpMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
@ -4778,6 +4815,24 @@ relativeError));
assertSelectFromArraysEquals(r, a, order, SPECIES.length());
}
@Test(dataProvider = "floatSelectFromTwoVectorOpProvider")
static void SelectFromTwoVectorFloat64VectorTests(IntFunction<float[]> fa, IntFunction<float[]> fb, IntFunction<float[]> fc) {
float[] a = fa.apply(SPECIES.length());
float[] b = fb.apply(SPECIES.length());
float[] idx = fc.apply(SPECIES.length());
float[] r = fr.apply(SPECIES.length());
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < idx.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
FloatVector bv = FloatVector.fromArray(SPECIES, b, i);
FloatVector idxv = FloatVector.fromArray(SPECIES, idx, i);
idxv.selectFrom(av, bv).intoArray(r, i);
}
}
assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length());
}
@Test(dataProvider = "floatUnaryOpSelectFromMaskProvider")
static void SelectFromFloat64VectorTestsMaskedSmokeTest(IntFunction<float[]> fa,
BiFunction<Integer,Integer,float[]> fs,

View File

@ -326,6 +326,25 @@ relativeError));
}
}
static void assertSelectFromTwoVectorEquals(float[] r, float[] order, float[] a, float[] b, int vector_len) {
int i = 0, j = 0;
boolean is_exceptional_idx = false;
int idx = 0, wrapped_index = 0, oidx = 0;
try {
for (; i < a.length; i += vector_len) {
for (j = 0; j < vector_len; j++) {
idx = i + j;
wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len);
is_exceptional_idx = wrapped_index >= vector_len;
oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
}
}
} catch (AssertionError e) {
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
}
}
static void assertSelectFromArraysEquals(float[] r, float[] a, float[] order, int vector_len) {
int i = 0, j = 0;
try {
@ -1124,6 +1143,18 @@ relativeError));
flatMap(pair -> FLOAT_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
static final List<IntFunction<float[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
withToString("float[0..VECLEN*2)", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (float)(RAND.nextInt()));
})
);
static final List<List<IntFunction<float[]>>> FLOAT_GENERATOR_SELECT_FROM_TRIPLES =
FLOAT_GENERATOR_PAIRS.stream().
flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
@DataProvider
public Object[][] floatBinaryOpProvider() {
return FLOAT_GENERATOR_PAIRS.stream().map(List::toArray).
@ -1151,6 +1182,12 @@ relativeError));
toArray(Object[][]::new);
}
@DataProvider
public Object[][] floatSelectFromTwoVectorOpProvider() {
return FLOAT_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] floatTernaryOpMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
@ -4783,6 +4820,24 @@ relativeError));
assertSelectFromArraysEquals(r, a, order, SPECIES.length());
}
@Test(dataProvider = "floatSelectFromTwoVectorOpProvider")
static void SelectFromTwoVectorFloatMaxVectorTests(IntFunction<float[]> fa, IntFunction<float[]> fb, IntFunction<float[]> fc) {
float[] a = fa.apply(SPECIES.length());
float[] b = fb.apply(SPECIES.length());
float[] idx = fc.apply(SPECIES.length());
float[] r = fr.apply(SPECIES.length());
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < idx.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
FloatVector bv = FloatVector.fromArray(SPECIES, b, i);
FloatVector idxv = FloatVector.fromArray(SPECIES, idx, i);
idxv.selectFrom(av, bv).intoArray(r, i);
}
}
assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length());
}
@Test(dataProvider = "floatUnaryOpSelectFromMaskProvider")
static void SelectFromFloatMaxVectorTestsMaskedSmokeTest(IntFunction<float[]> fa,
BiFunction<Integer,Integer,float[]> fs,

View File

@ -302,6 +302,25 @@ public class Int128VectorTests extends AbstractVectorTest {
}
}
static void assertSelectFromTwoVectorEquals(int[] r, int[] order, int[] a, int[] b, int vector_len) {
int i = 0, j = 0;
boolean is_exceptional_idx = false;
int idx = 0, wrapped_index = 0, oidx = 0;
try {
for (; i < a.length; i += vector_len) {
for (j = 0; j < vector_len; j++) {
idx = i + j;
wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len);
is_exceptional_idx = wrapped_index >= vector_len;
oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
}
}
} catch (AssertionError e) {
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
}
}
static void assertSelectFromArraysEquals(int[] r, int[] a, int[] order, int vector_len) {
int i = 0, j = 0;
try {
@ -952,6 +971,18 @@ public class Int128VectorTests extends AbstractVectorTest {
flatMap(pair -> INT_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
static final List<IntFunction<int[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
withToString("int[0..VECLEN*2)", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (int)(RAND.nextInt()));
})
);
static final List<List<IntFunction<int[]>>> INT_GENERATOR_SELECT_FROM_TRIPLES =
INT_GENERATOR_PAIRS.stream().
flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
@DataProvider
public Object[][] intBinaryOpProvider() {
return INT_GENERATOR_PAIRS.stream().map(List::toArray).
@ -979,6 +1010,12 @@ public class Int128VectorTests extends AbstractVectorTest {
toArray(Object[][]::new);
}
@DataProvider
public Object[][] intSelectFromTwoVectorOpProvider() {
return INT_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] intTernaryOpMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
@ -5779,6 +5816,24 @@ public class Int128VectorTests extends AbstractVectorTest {
assertSelectFromArraysEquals(r, a, order, SPECIES.length());
}
@Test(dataProvider = "intSelectFromTwoVectorOpProvider")
static void SelectFromTwoVectorInt128VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb, IntFunction<int[]> fc) {
int[] a = fa.apply(SPECIES.length());
int[] b = fb.apply(SPECIES.length());
int[] idx = fc.apply(SPECIES.length());
int[] r = fr.apply(SPECIES.length());
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < idx.length; i += SPECIES.length()) {
IntVector av = IntVector.fromArray(SPECIES, a, i);
IntVector bv = IntVector.fromArray(SPECIES, b, i);
IntVector idxv = IntVector.fromArray(SPECIES, idx, i);
idxv.selectFrom(av, bv).intoArray(r, i);
}
}
assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length());
}
@Test(dataProvider = "intUnaryOpShuffleMaskProvider")
static void SelectFromInt128VectorTestsMaskedSmokeTest(IntFunction<int[]> fa,
BiFunction<Integer,Integer,int[]> fs,

View File

@ -302,6 +302,25 @@ public class Int256VectorTests extends AbstractVectorTest {
}
}
static void assertSelectFromTwoVectorEquals(int[] r, int[] order, int[] a, int[] b, int vector_len) {
int i = 0, j = 0;
boolean is_exceptional_idx = false;
int idx = 0, wrapped_index = 0, oidx = 0;
try {
for (; i < a.length; i += vector_len) {
for (j = 0; j < vector_len; j++) {
idx = i + j;
wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len);
is_exceptional_idx = wrapped_index >= vector_len;
oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
}
}
} catch (AssertionError e) {
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
}
}
static void assertSelectFromArraysEquals(int[] r, int[] a, int[] order, int vector_len) {
int i = 0, j = 0;
try {
@ -952,6 +971,18 @@ public class Int256VectorTests extends AbstractVectorTest {
flatMap(pair -> INT_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
static final List<IntFunction<int[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
withToString("int[0..VECLEN*2)", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (int)(RAND.nextInt()));
})
);
static final List<List<IntFunction<int[]>>> INT_GENERATOR_SELECT_FROM_TRIPLES =
INT_GENERATOR_PAIRS.stream().
flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
@DataProvider
public Object[][] intBinaryOpProvider() {
return INT_GENERATOR_PAIRS.stream().map(List::toArray).
@ -979,6 +1010,12 @@ public class Int256VectorTests extends AbstractVectorTest {
toArray(Object[][]::new);
}
@DataProvider
public Object[][] intSelectFromTwoVectorOpProvider() {
return INT_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] intTernaryOpMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
@ -5779,6 +5816,24 @@ public class Int256VectorTests extends AbstractVectorTest {
assertSelectFromArraysEquals(r, a, order, SPECIES.length());
}
@Test(dataProvider = "intSelectFromTwoVectorOpProvider")
static void SelectFromTwoVectorInt256VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb, IntFunction<int[]> fc) {
int[] a = fa.apply(SPECIES.length());
int[] b = fb.apply(SPECIES.length());
int[] idx = fc.apply(SPECIES.length());
int[] r = fr.apply(SPECIES.length());
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < idx.length; i += SPECIES.length()) {
IntVector av = IntVector.fromArray(SPECIES, a, i);
IntVector bv = IntVector.fromArray(SPECIES, b, i);
IntVector idxv = IntVector.fromArray(SPECIES, idx, i);
idxv.selectFrom(av, bv).intoArray(r, i);
}
}
assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length());
}
@Test(dataProvider = "intUnaryOpShuffleMaskProvider")
static void SelectFromInt256VectorTestsMaskedSmokeTest(IntFunction<int[]> fa,
BiFunction<Integer,Integer,int[]> fs,

View File

@ -302,6 +302,25 @@ public class Int512VectorTests extends AbstractVectorTest {
}
}
static void assertSelectFromTwoVectorEquals(int[] r, int[] order, int[] a, int[] b, int vector_len) {
int i = 0, j = 0;
boolean is_exceptional_idx = false;
int idx = 0, wrapped_index = 0, oidx = 0;
try {
for (; i < a.length; i += vector_len) {
for (j = 0; j < vector_len; j++) {
idx = i + j;
wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len);
is_exceptional_idx = wrapped_index >= vector_len;
oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
}
}
} catch (AssertionError e) {
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
}
}
static void assertSelectFromArraysEquals(int[] r, int[] a, int[] order, int vector_len) {
int i = 0, j = 0;
try {
@ -952,6 +971,18 @@ public class Int512VectorTests extends AbstractVectorTest {
flatMap(pair -> INT_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
static final List<IntFunction<int[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
withToString("int[0..VECLEN*2)", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (int)(RAND.nextInt()));
})
);
static final List<List<IntFunction<int[]>>> INT_GENERATOR_SELECT_FROM_TRIPLES =
INT_GENERATOR_PAIRS.stream().
flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
@DataProvider
public Object[][] intBinaryOpProvider() {
return INT_GENERATOR_PAIRS.stream().map(List::toArray).
@ -979,6 +1010,12 @@ public class Int512VectorTests extends AbstractVectorTest {
toArray(Object[][]::new);
}
@DataProvider
public Object[][] intSelectFromTwoVectorOpProvider() {
return INT_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] intTernaryOpMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
@ -5779,6 +5816,24 @@ public class Int512VectorTests extends AbstractVectorTest {
assertSelectFromArraysEquals(r, a, order, SPECIES.length());
}
@Test(dataProvider = "intSelectFromTwoVectorOpProvider")
static void SelectFromTwoVectorInt512VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb, IntFunction<int[]> fc) {
int[] a = fa.apply(SPECIES.length());
int[] b = fb.apply(SPECIES.length());
int[] idx = fc.apply(SPECIES.length());
int[] r = fr.apply(SPECIES.length());
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < idx.length; i += SPECIES.length()) {
IntVector av = IntVector.fromArray(SPECIES, a, i);
IntVector bv = IntVector.fromArray(SPECIES, b, i);
IntVector idxv = IntVector.fromArray(SPECIES, idx, i);
idxv.selectFrom(av, bv).intoArray(r, i);
}
}
assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length());
}
@Test(dataProvider = "intUnaryOpShuffleMaskProvider")
static void SelectFromInt512VectorTestsMaskedSmokeTest(IntFunction<int[]> fa,
BiFunction<Integer,Integer,int[]> fs,

View File

@ -302,6 +302,25 @@ public class Int64VectorTests extends AbstractVectorTest {
}
}
static void assertSelectFromTwoVectorEquals(int[] r, int[] order, int[] a, int[] b, int vector_len) {
int i = 0, j = 0;
boolean is_exceptional_idx = false;
int idx = 0, wrapped_index = 0, oidx = 0;
try {
for (; i < a.length; i += vector_len) {
for (j = 0; j < vector_len; j++) {
idx = i + j;
wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len);
is_exceptional_idx = wrapped_index >= vector_len;
oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
}
}
} catch (AssertionError e) {
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
}
}
static void assertSelectFromArraysEquals(int[] r, int[] a, int[] order, int vector_len) {
int i = 0, j = 0;
try {
@ -952,6 +971,18 @@ public class Int64VectorTests extends AbstractVectorTest {
flatMap(pair -> INT_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
static final List<IntFunction<int[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
withToString("int[0..VECLEN*2)", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (int)(RAND.nextInt()));
})
);
static final List<List<IntFunction<int[]>>> INT_GENERATOR_SELECT_FROM_TRIPLES =
INT_GENERATOR_PAIRS.stream().
flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
@DataProvider
public Object[][] intBinaryOpProvider() {
return INT_GENERATOR_PAIRS.stream().map(List::toArray).
@ -979,6 +1010,12 @@ public class Int64VectorTests extends AbstractVectorTest {
toArray(Object[][]::new);
}
@DataProvider
public Object[][] intSelectFromTwoVectorOpProvider() {
return INT_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] intTernaryOpMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
@ -5779,6 +5816,24 @@ public class Int64VectorTests extends AbstractVectorTest {
assertSelectFromArraysEquals(r, a, order, SPECIES.length());
}
@Test(dataProvider = "intSelectFromTwoVectorOpProvider")
static void SelectFromTwoVectorInt64VectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb, IntFunction<int[]> fc) {
int[] a = fa.apply(SPECIES.length());
int[] b = fb.apply(SPECIES.length());
int[] idx = fc.apply(SPECIES.length());
int[] r = fr.apply(SPECIES.length());
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < idx.length; i += SPECIES.length()) {
IntVector av = IntVector.fromArray(SPECIES, a, i);
IntVector bv = IntVector.fromArray(SPECIES, b, i);
IntVector idxv = IntVector.fromArray(SPECIES, idx, i);
idxv.selectFrom(av, bv).intoArray(r, i);
}
}
assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length());
}
@Test(dataProvider = "intUnaryOpShuffleMaskProvider")
static void SelectFromInt64VectorTestsMaskedSmokeTest(IntFunction<int[]> fa,
BiFunction<Integer,Integer,int[]> fs,

View File

@ -307,6 +307,25 @@ public class IntMaxVectorTests extends AbstractVectorTest {
}
}
static void assertSelectFromTwoVectorEquals(int[] r, int[] order, int[] a, int[] b, int vector_len) {
int i = 0, j = 0;
boolean is_exceptional_idx = false;
int idx = 0, wrapped_index = 0, oidx = 0;
try {
for (; i < a.length; i += vector_len) {
for (j = 0; j < vector_len; j++) {
idx = i + j;
wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len);
is_exceptional_idx = wrapped_index >= vector_len;
oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
}
}
} catch (AssertionError e) {
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
}
}
static void assertSelectFromArraysEquals(int[] r, int[] a, int[] order, int vector_len) {
int i = 0, j = 0;
try {
@ -957,6 +976,18 @@ public class IntMaxVectorTests extends AbstractVectorTest {
flatMap(pair -> INT_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
static final List<IntFunction<int[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
withToString("int[0..VECLEN*2)", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (int)(RAND.nextInt()));
})
);
static final List<List<IntFunction<int[]>>> INT_GENERATOR_SELECT_FROM_TRIPLES =
INT_GENERATOR_PAIRS.stream().
flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
@DataProvider
public Object[][] intBinaryOpProvider() {
return INT_GENERATOR_PAIRS.stream().map(List::toArray).
@ -984,6 +1015,12 @@ public class IntMaxVectorTests extends AbstractVectorTest {
toArray(Object[][]::new);
}
@DataProvider
public Object[][] intSelectFromTwoVectorOpProvider() {
return INT_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] intTernaryOpMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
@ -5784,6 +5821,24 @@ public class IntMaxVectorTests extends AbstractVectorTest {
assertSelectFromArraysEquals(r, a, order, SPECIES.length());
}
@Test(dataProvider = "intSelectFromTwoVectorOpProvider")
static void SelectFromTwoVectorIntMaxVectorTests(IntFunction<int[]> fa, IntFunction<int[]> fb, IntFunction<int[]> fc) {
int[] a = fa.apply(SPECIES.length());
int[] b = fb.apply(SPECIES.length());
int[] idx = fc.apply(SPECIES.length());
int[] r = fr.apply(SPECIES.length());
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < idx.length; i += SPECIES.length()) {
IntVector av = IntVector.fromArray(SPECIES, a, i);
IntVector bv = IntVector.fromArray(SPECIES, b, i);
IntVector idxv = IntVector.fromArray(SPECIES, idx, i);
idxv.selectFrom(av, bv).intoArray(r, i);
}
}
assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length());
}
@Test(dataProvider = "intUnaryOpShuffleMaskProvider")
static void SelectFromIntMaxVectorTestsMaskedSmokeTest(IntFunction<int[]> fa,
BiFunction<Integer,Integer,int[]> fs,

View File

@ -259,6 +259,25 @@ public class Long128VectorTests extends AbstractVectorTest {
}
}
static void assertSelectFromTwoVectorEquals(long[] r, long[] order, long[] a, long[] b, int vector_len) {
int i = 0, j = 0;
boolean is_exceptional_idx = false;
int idx = 0, wrapped_index = 0, oidx = 0;
try {
for (; i < a.length; i += vector_len) {
for (j = 0; j < vector_len; j++) {
idx = i + j;
wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len);
is_exceptional_idx = wrapped_index >= vector_len;
oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
}
}
} catch (AssertionError e) {
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
}
}
static void assertSelectFromArraysEquals(long[] r, long[] a, long[] order, int vector_len) {
int i = 0, j = 0;
try {
@ -942,6 +961,18 @@ public class Long128VectorTests extends AbstractVectorTest {
flatMap(pair -> LONG_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
static final List<IntFunction<long[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
withToString("long[0..VECLEN*2)", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (long)(RAND.nextInt()));
})
);
static final List<List<IntFunction<long[]>>> LONG_GENERATOR_SELECT_FROM_TRIPLES =
LONG_GENERATOR_PAIRS.stream().
flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
@DataProvider
public Object[][] longBinaryOpProvider() {
return LONG_GENERATOR_PAIRS.stream().map(List::toArray).
@ -969,6 +1000,12 @@ public class Long128VectorTests extends AbstractVectorTest {
toArray(Object[][]::new);
}
@DataProvider
public Object[][] longSelectFromTwoVectorOpProvider() {
return LONG_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] longTernaryOpMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
@ -5665,6 +5702,24 @@ public class Long128VectorTests extends AbstractVectorTest {
assertSelectFromArraysEquals(r, a, order, SPECIES.length());
}
@Test(dataProvider = "longSelectFromTwoVectorOpProvider")
static void SelectFromTwoVectorLong128VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb, IntFunction<long[]> fc) {
long[] a = fa.apply(SPECIES.length());
long[] b = fb.apply(SPECIES.length());
long[] idx = fc.apply(SPECIES.length());
long[] r = fr.apply(SPECIES.length());
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < idx.length; i += SPECIES.length()) {
LongVector av = LongVector.fromArray(SPECIES, a, i);
LongVector bv = LongVector.fromArray(SPECIES, b, i);
LongVector idxv = LongVector.fromArray(SPECIES, idx, i);
idxv.selectFrom(av, bv).intoArray(r, i);
}
}
assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length());
}
@Test(dataProvider = "longUnaryOpSelectFromMaskProvider")
static void SelectFromLong128VectorTestsMaskedSmokeTest(IntFunction<long[]> fa,
BiFunction<Integer,Integer,long[]> fs,

View File

@ -259,6 +259,25 @@ public class Long256VectorTests extends AbstractVectorTest {
}
}
static void assertSelectFromTwoVectorEquals(long[] r, long[] order, long[] a, long[] b, int vector_len) {
int i = 0, j = 0;
boolean is_exceptional_idx = false;
int idx = 0, wrapped_index = 0, oidx = 0;
try {
for (; i < a.length; i += vector_len) {
for (j = 0; j < vector_len; j++) {
idx = i + j;
wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len);
is_exceptional_idx = wrapped_index >= vector_len;
oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
}
}
} catch (AssertionError e) {
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
}
}
static void assertSelectFromArraysEquals(long[] r, long[] a, long[] order, int vector_len) {
int i = 0, j = 0;
try {
@ -942,6 +961,18 @@ public class Long256VectorTests extends AbstractVectorTest {
flatMap(pair -> LONG_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
static final List<IntFunction<long[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
withToString("long[0..VECLEN*2)", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (long)(RAND.nextInt()));
})
);
static final List<List<IntFunction<long[]>>> LONG_GENERATOR_SELECT_FROM_TRIPLES =
LONG_GENERATOR_PAIRS.stream().
flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
@DataProvider
public Object[][] longBinaryOpProvider() {
return LONG_GENERATOR_PAIRS.stream().map(List::toArray).
@ -969,6 +1000,12 @@ public class Long256VectorTests extends AbstractVectorTest {
toArray(Object[][]::new);
}
@DataProvider
public Object[][] longSelectFromTwoVectorOpProvider() {
return LONG_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] longTernaryOpMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
@ -5665,6 +5702,24 @@ public class Long256VectorTests extends AbstractVectorTest {
assertSelectFromArraysEquals(r, a, order, SPECIES.length());
}
@Test(dataProvider = "longSelectFromTwoVectorOpProvider")
static void SelectFromTwoVectorLong256VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb, IntFunction<long[]> fc) {
long[] a = fa.apply(SPECIES.length());
long[] b = fb.apply(SPECIES.length());
long[] idx = fc.apply(SPECIES.length());
long[] r = fr.apply(SPECIES.length());
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < idx.length; i += SPECIES.length()) {
LongVector av = LongVector.fromArray(SPECIES, a, i);
LongVector bv = LongVector.fromArray(SPECIES, b, i);
LongVector idxv = LongVector.fromArray(SPECIES, idx, i);
idxv.selectFrom(av, bv).intoArray(r, i);
}
}
assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length());
}
@Test(dataProvider = "longUnaryOpSelectFromMaskProvider")
static void SelectFromLong256VectorTestsMaskedSmokeTest(IntFunction<long[]> fa,
BiFunction<Integer,Integer,long[]> fs,

View File

@ -259,6 +259,25 @@ public class Long512VectorTests extends AbstractVectorTest {
}
}
static void assertSelectFromTwoVectorEquals(long[] r, long[] order, long[] a, long[] b, int vector_len) {
int i = 0, j = 0;
boolean is_exceptional_idx = false;
int idx = 0, wrapped_index = 0, oidx = 0;
try {
for (; i < a.length; i += vector_len) {
for (j = 0; j < vector_len; j++) {
idx = i + j;
wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len);
is_exceptional_idx = wrapped_index >= vector_len;
oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
}
}
} catch (AssertionError e) {
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
}
}
static void assertSelectFromArraysEquals(long[] r, long[] a, long[] order, int vector_len) {
int i = 0, j = 0;
try {
@ -942,6 +961,18 @@ public class Long512VectorTests extends AbstractVectorTest {
flatMap(pair -> LONG_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
static final List<IntFunction<long[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
withToString("long[0..VECLEN*2)", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (long)(RAND.nextInt()));
})
);
static final List<List<IntFunction<long[]>>> LONG_GENERATOR_SELECT_FROM_TRIPLES =
LONG_GENERATOR_PAIRS.stream().
flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
@DataProvider
public Object[][] longBinaryOpProvider() {
return LONG_GENERATOR_PAIRS.stream().map(List::toArray).
@ -969,6 +1000,12 @@ public class Long512VectorTests extends AbstractVectorTest {
toArray(Object[][]::new);
}
@DataProvider
public Object[][] longSelectFromTwoVectorOpProvider() {
return LONG_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] longTernaryOpMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
@ -5665,6 +5702,24 @@ public class Long512VectorTests extends AbstractVectorTest {
assertSelectFromArraysEquals(r, a, order, SPECIES.length());
}
@Test(dataProvider = "longSelectFromTwoVectorOpProvider")
static void SelectFromTwoVectorLong512VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb, IntFunction<long[]> fc) {
long[] a = fa.apply(SPECIES.length());
long[] b = fb.apply(SPECIES.length());
long[] idx = fc.apply(SPECIES.length());
long[] r = fr.apply(SPECIES.length());
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < idx.length; i += SPECIES.length()) {
LongVector av = LongVector.fromArray(SPECIES, a, i);
LongVector bv = LongVector.fromArray(SPECIES, b, i);
LongVector idxv = LongVector.fromArray(SPECIES, idx, i);
idxv.selectFrom(av, bv).intoArray(r, i);
}
}
assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length());
}
@Test(dataProvider = "longUnaryOpSelectFromMaskProvider")
static void SelectFromLong512VectorTestsMaskedSmokeTest(IntFunction<long[]> fa,
BiFunction<Integer,Integer,long[]> fs,

View File

@ -259,6 +259,25 @@ public class Long64VectorTests extends AbstractVectorTest {
}
}
static void assertSelectFromTwoVectorEquals(long[] r, long[] order, long[] a, long[] b, int vector_len) {
int i = 0, j = 0;
boolean is_exceptional_idx = false;
int idx = 0, wrapped_index = 0, oidx = 0;
try {
for (; i < a.length; i += vector_len) {
for (j = 0; j < vector_len; j++) {
idx = i + j;
wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len);
is_exceptional_idx = wrapped_index >= vector_len;
oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
}
}
} catch (AssertionError e) {
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
}
}
static void assertSelectFromArraysEquals(long[] r, long[] a, long[] order, int vector_len) {
int i = 0, j = 0;
try {
@ -942,6 +961,18 @@ public class Long64VectorTests extends AbstractVectorTest {
flatMap(pair -> LONG_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
static final List<IntFunction<long[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
withToString("long[0..VECLEN*2)", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (long)(RAND.nextInt()));
})
);
static final List<List<IntFunction<long[]>>> LONG_GENERATOR_SELECT_FROM_TRIPLES =
LONG_GENERATOR_PAIRS.stream().
flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
@DataProvider
public Object[][] longBinaryOpProvider() {
return LONG_GENERATOR_PAIRS.stream().map(List::toArray).
@ -969,6 +1000,12 @@ public class Long64VectorTests extends AbstractVectorTest {
toArray(Object[][]::new);
}
@DataProvider
public Object[][] longSelectFromTwoVectorOpProvider() {
return LONG_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] longTernaryOpMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
@ -5665,6 +5702,24 @@ public class Long64VectorTests extends AbstractVectorTest {
assertSelectFromArraysEquals(r, a, order, SPECIES.length());
}
@Test(dataProvider = "longSelectFromTwoVectorOpProvider")
static void SelectFromTwoVectorLong64VectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb, IntFunction<long[]> fc) {
long[] a = fa.apply(SPECIES.length());
long[] b = fb.apply(SPECIES.length());
long[] idx = fc.apply(SPECIES.length());
long[] r = fr.apply(SPECIES.length());
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < idx.length; i += SPECIES.length()) {
LongVector av = LongVector.fromArray(SPECIES, a, i);
LongVector bv = LongVector.fromArray(SPECIES, b, i);
LongVector idxv = LongVector.fromArray(SPECIES, idx, i);
idxv.selectFrom(av, bv).intoArray(r, i);
}
}
assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length());
}
@Test(dataProvider = "longUnaryOpSelectFromMaskProvider")
static void SelectFromLong64VectorTestsMaskedSmokeTest(IntFunction<long[]> fa,
BiFunction<Integer,Integer,long[]> fs,

View File

@ -264,6 +264,25 @@ public class LongMaxVectorTests extends AbstractVectorTest {
}
}
static void assertSelectFromTwoVectorEquals(long[] r, long[] order, long[] a, long[] b, int vector_len) {
int i = 0, j = 0;
boolean is_exceptional_idx = false;
int idx = 0, wrapped_index = 0, oidx = 0;
try {
for (; i < a.length; i += vector_len) {
for (j = 0; j < vector_len; j++) {
idx = i + j;
wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len);
is_exceptional_idx = wrapped_index >= vector_len;
oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
}
}
} catch (AssertionError e) {
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
}
}
static void assertSelectFromArraysEquals(long[] r, long[] a, long[] order, int vector_len) {
int i = 0, j = 0;
try {
@ -947,6 +966,18 @@ public class LongMaxVectorTests extends AbstractVectorTest {
flatMap(pair -> LONG_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
static final List<IntFunction<long[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
withToString("long[0..VECLEN*2)", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (long)(RAND.nextInt()));
})
);
static final List<List<IntFunction<long[]>>> LONG_GENERATOR_SELECT_FROM_TRIPLES =
LONG_GENERATOR_PAIRS.stream().
flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
@DataProvider
public Object[][] longBinaryOpProvider() {
return LONG_GENERATOR_PAIRS.stream().map(List::toArray).
@ -974,6 +1005,12 @@ public class LongMaxVectorTests extends AbstractVectorTest {
toArray(Object[][]::new);
}
@DataProvider
public Object[][] longSelectFromTwoVectorOpProvider() {
return LONG_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] longTernaryOpMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
@ -5670,6 +5707,24 @@ public class LongMaxVectorTests extends AbstractVectorTest {
assertSelectFromArraysEquals(r, a, order, SPECIES.length());
}
@Test(dataProvider = "longSelectFromTwoVectorOpProvider")
static void SelectFromTwoVectorLongMaxVectorTests(IntFunction<long[]> fa, IntFunction<long[]> fb, IntFunction<long[]> fc) {
long[] a = fa.apply(SPECIES.length());
long[] b = fb.apply(SPECIES.length());
long[] idx = fc.apply(SPECIES.length());
long[] r = fr.apply(SPECIES.length());
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < idx.length; i += SPECIES.length()) {
LongVector av = LongVector.fromArray(SPECIES, a, i);
LongVector bv = LongVector.fromArray(SPECIES, b, i);
LongVector idxv = LongVector.fromArray(SPECIES, idx, i);
idxv.selectFrom(av, bv).intoArray(r, i);
}
}
assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length());
}
@Test(dataProvider = "longUnaryOpSelectFromMaskProvider")
static void SelectFromLongMaxVectorTestsMaskedSmokeTest(IntFunction<long[]> fa,
BiFunction<Integer,Integer,long[]> fs,

View File

@ -302,6 +302,25 @@ public class Short128VectorTests extends AbstractVectorTest {
}
}
static void assertSelectFromTwoVectorEquals(short[] r, short[] order, short[] a, short[] b, int vector_len) {
int i = 0, j = 0;
boolean is_exceptional_idx = false;
int idx = 0, wrapped_index = 0, oidx = 0;
try {
for (; i < a.length; i += vector_len) {
for (j = 0; j < vector_len; j++) {
idx = i + j;
wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len);
is_exceptional_idx = wrapped_index >= vector_len;
oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
}
}
} catch (AssertionError e) {
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
}
}
static void assertSelectFromArraysEquals(short[] r, short[] a, short[] order, int vector_len) {
int i = 0, j = 0;
try {
@ -952,6 +971,18 @@ public class Short128VectorTests extends AbstractVectorTest {
flatMap(pair -> SHORT_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
static final List<IntFunction<short[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
withToString("short[0..VECLEN*2)", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (short)(RAND.nextInt()));
})
);
static final List<List<IntFunction<short[]>>> SHORT_GENERATOR_SELECT_FROM_TRIPLES =
SHORT_GENERATOR_PAIRS.stream().
flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
@DataProvider
public Object[][] shortBinaryOpProvider() {
return SHORT_GENERATOR_PAIRS.stream().map(List::toArray).
@ -979,6 +1010,12 @@ public class Short128VectorTests extends AbstractVectorTest {
toArray(Object[][]::new);
}
@DataProvider
public Object[][] shortSelectFromTwoVectorOpProvider() {
return SHORT_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] shortTernaryOpMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
@ -5726,6 +5763,24 @@ public class Short128VectorTests extends AbstractVectorTest {
assertSelectFromArraysEquals(r, a, order, SPECIES.length());
}
@Test(dataProvider = "shortSelectFromTwoVectorOpProvider")
static void SelectFromTwoVectorShort128VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb, IntFunction<short[]> fc) {
short[] a = fa.apply(SPECIES.length());
short[] b = fb.apply(SPECIES.length());
short[] idx = fc.apply(SPECIES.length());
short[] r = fr.apply(SPECIES.length());
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < idx.length; i += SPECIES.length()) {
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
ShortVector idxv = ShortVector.fromArray(SPECIES, idx, i);
idxv.selectFrom(av, bv).intoArray(r, i);
}
}
assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length());
}
@Test(dataProvider = "shortUnaryOpSelectFromMaskProvider")
static void SelectFromShort128VectorTestsMaskedSmokeTest(IntFunction<short[]> fa,
BiFunction<Integer,Integer,short[]> fs,

View File

@ -302,6 +302,25 @@ public class Short256VectorTests extends AbstractVectorTest {
}
}
static void assertSelectFromTwoVectorEquals(short[] r, short[] order, short[] a, short[] b, int vector_len) {
int i = 0, j = 0;
boolean is_exceptional_idx = false;
int idx = 0, wrapped_index = 0, oidx = 0;
try {
for (; i < a.length; i += vector_len) {
for (j = 0; j < vector_len; j++) {
idx = i + j;
wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len);
is_exceptional_idx = wrapped_index >= vector_len;
oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
}
}
} catch (AssertionError e) {
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
}
}
static void assertSelectFromArraysEquals(short[] r, short[] a, short[] order, int vector_len) {
int i = 0, j = 0;
try {
@ -952,6 +971,18 @@ public class Short256VectorTests extends AbstractVectorTest {
flatMap(pair -> SHORT_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
static final List<IntFunction<short[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
withToString("short[0..VECLEN*2)", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (short)(RAND.nextInt()));
})
);
static final List<List<IntFunction<short[]>>> SHORT_GENERATOR_SELECT_FROM_TRIPLES =
SHORT_GENERATOR_PAIRS.stream().
flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
@DataProvider
public Object[][] shortBinaryOpProvider() {
return SHORT_GENERATOR_PAIRS.stream().map(List::toArray).
@ -979,6 +1010,12 @@ public class Short256VectorTests extends AbstractVectorTest {
toArray(Object[][]::new);
}
@DataProvider
public Object[][] shortSelectFromTwoVectorOpProvider() {
return SHORT_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] shortTernaryOpMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
@ -5726,6 +5763,24 @@ public class Short256VectorTests extends AbstractVectorTest {
assertSelectFromArraysEquals(r, a, order, SPECIES.length());
}
@Test(dataProvider = "shortSelectFromTwoVectorOpProvider")
static void SelectFromTwoVectorShort256VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb, IntFunction<short[]> fc) {
short[] a = fa.apply(SPECIES.length());
short[] b = fb.apply(SPECIES.length());
short[] idx = fc.apply(SPECIES.length());
short[] r = fr.apply(SPECIES.length());
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < idx.length; i += SPECIES.length()) {
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
ShortVector idxv = ShortVector.fromArray(SPECIES, idx, i);
idxv.selectFrom(av, bv).intoArray(r, i);
}
}
assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length());
}
@Test(dataProvider = "shortUnaryOpSelectFromMaskProvider")
static void SelectFromShort256VectorTestsMaskedSmokeTest(IntFunction<short[]> fa,
BiFunction<Integer,Integer,short[]> fs,

View File

@ -302,6 +302,25 @@ public class Short512VectorTests extends AbstractVectorTest {
}
}
static void assertSelectFromTwoVectorEquals(short[] r, short[] order, short[] a, short[] b, int vector_len) {
int i = 0, j = 0;
boolean is_exceptional_idx = false;
int idx = 0, wrapped_index = 0, oidx = 0;
try {
for (; i < a.length; i += vector_len) {
for (j = 0; j < vector_len; j++) {
idx = i + j;
wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len);
is_exceptional_idx = wrapped_index >= vector_len;
oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
}
}
} catch (AssertionError e) {
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
}
}
static void assertSelectFromArraysEquals(short[] r, short[] a, short[] order, int vector_len) {
int i = 0, j = 0;
try {
@ -952,6 +971,18 @@ public class Short512VectorTests extends AbstractVectorTest {
flatMap(pair -> SHORT_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
static final List<IntFunction<short[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
withToString("short[0..VECLEN*2)", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (short)(RAND.nextInt()));
})
);
static final List<List<IntFunction<short[]>>> SHORT_GENERATOR_SELECT_FROM_TRIPLES =
SHORT_GENERATOR_PAIRS.stream().
flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
@DataProvider
public Object[][] shortBinaryOpProvider() {
return SHORT_GENERATOR_PAIRS.stream().map(List::toArray).
@ -979,6 +1010,12 @@ public class Short512VectorTests extends AbstractVectorTest {
toArray(Object[][]::new);
}
@DataProvider
public Object[][] shortSelectFromTwoVectorOpProvider() {
return SHORT_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] shortTernaryOpMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
@ -5726,6 +5763,24 @@ public class Short512VectorTests extends AbstractVectorTest {
assertSelectFromArraysEquals(r, a, order, SPECIES.length());
}
@Test(dataProvider = "shortSelectFromTwoVectorOpProvider")
static void SelectFromTwoVectorShort512VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb, IntFunction<short[]> fc) {
short[] a = fa.apply(SPECIES.length());
short[] b = fb.apply(SPECIES.length());
short[] idx = fc.apply(SPECIES.length());
short[] r = fr.apply(SPECIES.length());
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < idx.length; i += SPECIES.length()) {
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
ShortVector idxv = ShortVector.fromArray(SPECIES, idx, i);
idxv.selectFrom(av, bv).intoArray(r, i);
}
}
assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length());
}
@Test(dataProvider = "shortUnaryOpSelectFromMaskProvider")
static void SelectFromShort512VectorTestsMaskedSmokeTest(IntFunction<short[]> fa,
BiFunction<Integer,Integer,short[]> fs,

View File

@ -302,6 +302,25 @@ public class Short64VectorTests extends AbstractVectorTest {
}
}
static void assertSelectFromTwoVectorEquals(short[] r, short[] order, short[] a, short[] b, int vector_len) {
int i = 0, j = 0;
boolean is_exceptional_idx = false;
int idx = 0, wrapped_index = 0, oidx = 0;
try {
for (; i < a.length; i += vector_len) {
for (j = 0; j < vector_len; j++) {
idx = i + j;
wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len);
is_exceptional_idx = wrapped_index >= vector_len;
oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
}
}
} catch (AssertionError e) {
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
}
}
static void assertSelectFromArraysEquals(short[] r, short[] a, short[] order, int vector_len) {
int i = 0, j = 0;
try {
@ -952,6 +971,18 @@ public class Short64VectorTests extends AbstractVectorTest {
flatMap(pair -> SHORT_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
static final List<IntFunction<short[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
withToString("short[0..VECLEN*2)", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (short)(RAND.nextInt()));
})
);
static final List<List<IntFunction<short[]>>> SHORT_GENERATOR_SELECT_FROM_TRIPLES =
SHORT_GENERATOR_PAIRS.stream().
flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
@DataProvider
public Object[][] shortBinaryOpProvider() {
return SHORT_GENERATOR_PAIRS.stream().map(List::toArray).
@ -979,6 +1010,12 @@ public class Short64VectorTests extends AbstractVectorTest {
toArray(Object[][]::new);
}
@DataProvider
public Object[][] shortSelectFromTwoVectorOpProvider() {
return SHORT_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] shortTernaryOpMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
@ -5726,6 +5763,24 @@ public class Short64VectorTests extends AbstractVectorTest {
assertSelectFromArraysEquals(r, a, order, SPECIES.length());
}
@Test(dataProvider = "shortSelectFromTwoVectorOpProvider")
static void SelectFromTwoVectorShort64VectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb, IntFunction<short[]> fc) {
short[] a = fa.apply(SPECIES.length());
short[] b = fb.apply(SPECIES.length());
short[] idx = fc.apply(SPECIES.length());
short[] r = fr.apply(SPECIES.length());
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < idx.length; i += SPECIES.length()) {
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
ShortVector idxv = ShortVector.fromArray(SPECIES, idx, i);
idxv.selectFrom(av, bv).intoArray(r, i);
}
}
assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length());
}
@Test(dataProvider = "shortUnaryOpSelectFromMaskProvider")
static void SelectFromShort64VectorTestsMaskedSmokeTest(IntFunction<short[]> fa,
BiFunction<Integer,Integer,short[]> fs,

View File

@ -307,6 +307,25 @@ public class ShortMaxVectorTests extends AbstractVectorTest {
}
}
static void assertSelectFromTwoVectorEquals(short[] r, short[] order, short[] a, short[] b, int vector_len) {
int i = 0, j = 0;
boolean is_exceptional_idx = false;
int idx = 0, wrapped_index = 0, oidx = 0;
try {
for (; i < a.length; i += vector_len) {
for (j = 0; j < vector_len; j++) {
idx = i + j;
wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len);
is_exceptional_idx = wrapped_index >= vector_len;
oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
}
}
} catch (AssertionError e) {
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
}
}
static void assertSelectFromArraysEquals(short[] r, short[] a, short[] order, int vector_len) {
int i = 0, j = 0;
try {
@ -957,6 +976,18 @@ public class ShortMaxVectorTests extends AbstractVectorTest {
flatMap(pair -> SHORT_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
static final List<IntFunction<short[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
withToString("short[0..VECLEN*2)", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (short)(RAND.nextInt()));
})
);
static final List<List<IntFunction<short[]>>> SHORT_GENERATOR_SELECT_FROM_TRIPLES =
SHORT_GENERATOR_PAIRS.stream().
flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
@DataProvider
public Object[][] shortBinaryOpProvider() {
return SHORT_GENERATOR_PAIRS.stream().map(List::toArray).
@ -984,6 +1015,12 @@ public class ShortMaxVectorTests extends AbstractVectorTest {
toArray(Object[][]::new);
}
@DataProvider
public Object[][] shortSelectFromTwoVectorOpProvider() {
return SHORT_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] shortTernaryOpMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
@ -5731,6 +5768,24 @@ public class ShortMaxVectorTests extends AbstractVectorTest {
assertSelectFromArraysEquals(r, a, order, SPECIES.length());
}
@Test(dataProvider = "shortSelectFromTwoVectorOpProvider")
static void SelectFromTwoVectorShortMaxVectorTests(IntFunction<short[]> fa, IntFunction<short[]> fb, IntFunction<short[]> fc) {
short[] a = fa.apply(SPECIES.length());
short[] b = fb.apply(SPECIES.length());
short[] idx = fc.apply(SPECIES.length());
short[] r = fr.apply(SPECIES.length());
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < idx.length; i += SPECIES.length()) {
ShortVector av = ShortVector.fromArray(SPECIES, a, i);
ShortVector bv = ShortVector.fromArray(SPECIES, b, i);
ShortVector idxv = ShortVector.fromArray(SPECIES, idx, i);
idxv.selectFrom(av, bv).intoArray(r, i);
}
}
assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length());
}
@Test(dataProvider = "shortUnaryOpSelectFromMaskProvider")
static void SelectFromShortMaxVectorTestsMaskedSmokeTest(IntFunction<short[]> fa,
BiFunction<Integer,Integer,short[]> fs,

View File

@ -297,6 +297,24 @@
assertSelectFromArraysEquals(r, a, order, SPECIES.length());
}
@Test(dataProvider = "$type$SelectFromTwoVectorOpProvider")
static void SelectFromTwoVector$vectorteststype$(IntFunction<$type$[]> fa, IntFunction<$type$[]> fb, IntFunction<$type$[]> fc) {
$type$[] a = fa.apply(SPECIES.length());
$type$[] b = fb.apply(SPECIES.length());
$type$[] idx = fc.apply(SPECIES.length());
$type$[] r = fr.apply(SPECIES.length());
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < idx.length; i += SPECIES.length()) {
$abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i);
$abstractvectortype$ bv = $abstractvectortype$.fromArray(SPECIES, b, i);
$abstractvectortype$ idxv = $abstractvectortype$.fromArray(SPECIES, idx, i);
idxv.selectFrom(av, bv).intoArray(r, i);
}
}
assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length());
}
#if[Int]
@Test(dataProvider = "$type$UnaryOpShuffleMaskProvider")
#else[Int]

View File

@ -397,6 +397,25 @@ relativeError));
}
}
static void assertSelectFromTwoVectorEquals($type$[] r, $type$[] order, $type$[] a, $type$[] b, int vector_len) {
int i = 0, j = 0;
boolean is_exceptional_idx = false;
int idx = 0, wrapped_index = 0, oidx = 0;
try {
for (; i < a.length; i += vector_len) {
for (j = 0; j < vector_len; j++) {
idx = i + j;
wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len);
is_exceptional_idx = wrapped_index >= vector_len;
oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
}
}
} catch (AssertionError e) {
Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
}
}
static void assertSelectFromArraysEquals($type$[] r, $type$[] a, $type$[] order, int vector_len) {
int i = 0, j = 0;
try {
@ -1221,6 +1240,18 @@ relativeError));
flatMap(pair -> $TYPE$_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
static final List<IntFunction<$type$[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
withToString("$type$[0..VECLEN*2)", (int s) -> {
return fill(s * BUFFER_REPS,
i -> ($type$)(RAND.nextInt()));
})
);
static final List<List<IntFunction<$type$[]>>> $TYPE$_GENERATOR_SELECT_FROM_TRIPLES =
$TYPE$_GENERATOR_PAIRS.stream().
flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
collect(Collectors.toList());
@DataProvider
public Object[][] $type$BinaryOpProvider() {
return $TYPE$_GENERATOR_PAIRS.stream().map(List::toArray).
@ -1248,6 +1279,12 @@ relativeError));
toArray(Object[][]::new);
}
@DataProvider
public Object[][] $type$SelectFromTwoVectorOpProvider() {
return $TYPE$_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] $type$TernaryOpMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().

View File

@ -0,0 +1,251 @@
/*
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package org.openjdk.bench.jdk.incubator.vector;
import java.util.Random;
import java.util.Arrays;
import jdk.incubator.vector.*;
import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.infra.Blackhole;
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Thread)
@Fork(jvmArgsPrepend = {"--add-modules=jdk.incubator.vector"})
public class SelectFromBenchmark {
@Param({"1024","2048"})
int size;
byte[] byteindex;
byte[] bytesrc1;
byte[] bytesrc2;
byte[] byteres;
short[] shortindex;
short[] shortsrc1;
short[] shortsrc2;
short[] shortres;
int[] intindex;
int[] intsrc1;
int[] intsrc2;
int[] intres;
long[] longindex;
long[] longsrc1;
long[] longsrc2;
long[] longres;
float[] floatindex;
float[] floatsrc1;
float[] floatsrc2;
float[] floatres;
double[] doubleindex;
double[] doublesrc1;
double[] doublesrc2;
double[] doubleres;
@Setup(Level.Trial)
public void BmSetup() {
Random r = new Random(1024);
byteindex = new byte[size];
bytesrc1 = new byte[size];
bytesrc2 = new byte[size];
byteres = new byte[size];
shortindex = new short[size];
shortsrc1 = new short[size];
shortsrc2 = new short[size];
shortres = new short[size];
intindex = new int[size];
intsrc1 = new int[size];
intsrc2 = new int[size];
intres = new int[size];
longindex = new long[size];
longsrc1 = new long[size];
longsrc2 = new long[size];
longres = new long[size];
floatindex = new float[size];
floatsrc1 = new float[size];
floatsrc2 = new float[size];
floatres = new float[size];
doubleindex = new double[size];
doublesrc1 = new double[size];
doublesrc2 = new double[size];
doubleres = new double[size];
Arrays.fill(bytesrc1, (byte)1);
Arrays.fill(bytesrc2, (byte)2);
Arrays.fill(shortsrc1, (short)1);
Arrays.fill(shortsrc2, (short)2);
Arrays.fill(intsrc1, 1);
Arrays.fill(intsrc2, 2);
Arrays.fill(longsrc1, 1);
Arrays.fill(longsrc2, 2);
Arrays.fill(floatsrc1, 1.0f);
Arrays.fill(floatsrc2, 2.0f);
Arrays.fill(doublesrc1, 1.0);
Arrays.fill(doublesrc2, 2.0);
for (int i = 0; i < size; i++) {
byteindex[i] = (byte)((ByteVector.SPECIES_PREFERRED.length() - 1) & i);
shortindex[i] = (short)((ShortVector.SPECIES_PREFERRED.length() - 1) & i);
intindex[i] = (int)((IntVector.SPECIES_PREFERRED.length() - 1) & i);
longindex[i] = (long)((LongVector.SPECIES_PREFERRED.length() - 1) & i);
floatindex[i] = (float)((FloatVector.SPECIES_PREFERRED.length() - 1) & i);
doubleindex[i] = (double)((DoubleVector.SPECIES_PREFERRED.length() - 1) & i);
}
}
@Benchmark
public void selectFromByteVector() {
for (int j = 0; j < size; j += ByteVector.SPECIES_PREFERRED.length()) {
ByteVector.fromArray(ByteVector.SPECIES_PREFERRED, byteindex, j)
.selectFrom(ByteVector.fromArray(ByteVector.SPECIES_PREFERRED, bytesrc1, j),
ByteVector.fromArray(ByteVector.SPECIES_PREFERRED, bytesrc2, j))
.intoArray(byteres, j);
}
}
@Benchmark
public void rearrangeFromByteVector() {
for (int j = 0; j < size; j += ByteVector.SPECIES_PREFERRED.length()) {
ByteVector.fromArray(ByteVector.SPECIES_PREFERRED, bytesrc1, j)
.rearrange(ByteVector.fromArray(ByteVector.SPECIES_PREFERRED, byteindex, j).toShuffle(),
ByteVector.fromArray(ByteVector.SPECIES_PREFERRED, bytesrc2, j))
.intoArray(byteres, j);
}
}
@Benchmark
public void selectFromShortVector() {
for (int j = 0; j < size; j += ShortVector.SPECIES_PREFERRED.length()) {
ShortVector.fromArray(ShortVector.SPECIES_PREFERRED, shortindex, j)
.selectFrom(ShortVector.fromArray(ShortVector.SPECIES_PREFERRED, shortsrc1, j),
ShortVector.fromArray(ShortVector.SPECIES_PREFERRED, shortsrc2, j))
.intoArray(shortres, j);
}
}
@Benchmark
public void rearrangeFromShortVector() {
for (int j = 0; j < size; j += ShortVector.SPECIES_PREFERRED.length()) {
ShortVector.fromArray(ShortVector.SPECIES_PREFERRED, shortsrc1, j)
.rearrange(ShortVector.fromArray(ShortVector.SPECIES_PREFERRED, shortindex, j).toShuffle(),
ShortVector.fromArray(ShortVector.SPECIES_PREFERRED, shortsrc2, j))
.intoArray(shortres, j);
}
}
@Benchmark
public void selectFromIntVector() {
for (int j = 0; j < size; j += IntVector.SPECIES_PREFERRED.length()) {
IntVector.fromArray(IntVector.SPECIES_PREFERRED, intindex, j)
.selectFrom(IntVector.fromArray(IntVector.SPECIES_PREFERRED, intsrc1, j),
IntVector.fromArray(IntVector.SPECIES_PREFERRED, intsrc2, j))
.intoArray(intres, j);
}
}
@Benchmark
public void rearrangeFromIntVector() {
for (int j = 0; j < size; j += IntVector.SPECIES_PREFERRED.length()) {
IntVector.fromArray(IntVector.SPECIES_PREFERRED, intsrc1, j)
.rearrange(IntVector.fromArray(IntVector.SPECIES_PREFERRED, intindex, j).toShuffle(),
IntVector.fromArray(IntVector.SPECIES_PREFERRED, intsrc2, j))
.intoArray(intres, j);
}
}
@Benchmark
public void selectFromLongVector() {
for (int j = 0; j < size; j += LongVector.SPECIES_PREFERRED.length()) {
LongVector.fromArray(LongVector.SPECIES_PREFERRED, longindex, j)
.selectFrom(LongVector.fromArray(LongVector.SPECIES_PREFERRED, longsrc1, j),
LongVector.fromArray(LongVector.SPECIES_PREFERRED, longsrc2, j))
.intoArray(longres, j);
}
}
@Benchmark
public void rearrangeFromLongVector() {
for (int j = 0; j < size; j += LongVector.SPECIES_PREFERRED.length()) {
LongVector.fromArray(LongVector.SPECIES_PREFERRED, longsrc1, j)
.rearrange(LongVector.fromArray(LongVector.SPECIES_PREFERRED, longindex, j).toShuffle(),
LongVector.fromArray(LongVector.SPECIES_PREFERRED, longsrc2, j))
.intoArray(longres, j);
}
}
@Benchmark
public void selectFromFloatVector() {
for (int j = 0; j < size; j += FloatVector.SPECIES_PREFERRED.length()) {
FloatVector.fromArray(FloatVector.SPECIES_PREFERRED, floatindex, j)
.selectFrom(FloatVector.fromArray(FloatVector.SPECIES_PREFERRED, floatsrc1, j),
FloatVector.fromArray(FloatVector.SPECIES_PREFERRED, floatsrc2, j))
.intoArray(floatres, j);
}
}
@Benchmark
public void rearrangeFromFloatVector() {
for (int j = 0; j < size; j += FloatVector.SPECIES_PREFERRED.length()) {
FloatVector.fromArray(FloatVector.SPECIES_PREFERRED, floatsrc1, j)
.rearrange(FloatVector.fromArray(FloatVector.SPECIES_PREFERRED, floatindex, j).toShuffle(),
FloatVector.fromArray(FloatVector.SPECIES_PREFERRED, floatsrc2, j))
.intoArray(floatres, j);
}
}
@Benchmark
public void selectFromDoubleVector() {
for (int j = 0; j < size; j += DoubleVector.SPECIES_PREFERRED.length()) {
DoubleVector.fromArray(DoubleVector.SPECIES_PREFERRED, doubleindex, j)
.selectFrom(DoubleVector.fromArray(DoubleVector.SPECIES_PREFERRED, doublesrc1, j),
DoubleVector.fromArray(DoubleVector.SPECIES_PREFERRED, doublesrc2, j))
.intoArray(doubleres, j);
}
}
@Benchmark
public void rearrangeFromDoubleVector() {
for (int j = 0; j < size; j += DoubleVector.SPECIES_PREFERRED.length()) {
DoubleVector.fromArray(DoubleVector.SPECIES_PREFERRED, doublesrc1, j)
.rearrange(DoubleVector.fromArray(DoubleVector.SPECIES_PREFERRED, doubleindex, j).toShuffle(),
DoubleVector.fromArray(DoubleVector.SPECIES_PREFERRED, doublesrc2, j))
.intoArray(doubleres, j);
}
}
}