vdot

Vector BFloat16 Dot Product (A32)

VDOT<c>.BF16 <Qd>, <Qn>, <Qm>

BFloat16 dot product to float32 accumulator.

Pseudocode Operation

for i = 0 to 3 do
  acc = 0.0
  for j = 0 to 1 do
    bf16_a = Qn[4*i + 2*j : 4*i + 2*j + 1]
    bf16_b = Qm[4*i + 2*j : 4*i + 2*j + 1]
    acc = acc + BF16_to_FP32(bf16_a) * BF16_to_FP32(bf16_b)
  Qd[i] = Qd[i] + acc

Example

VDOT.BF16 q0, q1, q2

Encoding

Binary Layout
1111110
31:25
00
24:23
D
22
00
21:20
Vn
19:16
Vd
15:12
1
11
1
10
0
9
1
8
N
7
1
6
M
5
0
4
Vm
3:0
 
Format NEON BFloat16
Opcode 0xFC000D40
Extension NEON (BFloat16)

Operands

  • Qd
    Destination 128-bit SIMD register
  • Qn
    First source 128-bit SIMD register
  • Qm
    Second source 128-bit SIMD register

Related

More in NEON (BFloat16)

Reference

Instruction Forms

Encoding Instruction ISA Bit pattern
0xFC000D00 VDOT{<q>}.BF16 <Dd>, <Dn>, <Dm> A32 1111110 | 00 | D | 00 | Vn | Vd | 1 | 1 | 0 | 1 | N | 0 | M | 0 | Vm
0xFC000D40 VDOT{<q>}.BF16 <Qd>, <Qn>, <Qm> A32 1111110 | 00 | D | 00 | Vn | Vd | 1 | 1 | 0 | 1 | N | 1 | M | 0 | Vm
0xFE000D00 VDOT{<q>}.BF16 <Dd>, <Dn>, <Dm>[<index>] A32 11111110 | 0 | D | 00 | Vn | Vd | 110 | 1 | N | 0 | M | 0 | Vm
0xFE000D40 VDOT{<q>}.BF16 <Qd>, <Qn>, <Dm>[<index>] A32 11111110 | 0 | D | 00 | Vn | Vd | 110 | 1 | N | 1 | M | 0 | Vm

Description

BFloat16 floating-point (BF16) dot product (vector). This instruction delimits the source vectors into pairs of 16-bit BF16 elements. Within each pair, the elements in the first source vector are multiplied by the corresponding elements in the second source vector. The resulting single-precision products are then summed and added destructively to the single-precision element in the destination vector which aligns with the pair of BF16 values in the first source vector. The instruction does not update the FPSCR exception status.

Operation

bits(64) operand1;
bits(64) operand2;
bits(64) result;

CheckAdvSIMDEnabled();

for r = 0 to regs-1
    operand1 = Din[n+r];
    operand2 = Din[m+r];
    result = Din[d+r];
    for e = 0 to 1
        bits(16) elt1_a = Elem[operand1, 2 * e + 0, 16];
        bits(16) elt1_b = Elem[operand1, 2 * e + 1, 16];
        bits(16) elt2_a = Elem[operand2, 2 * e + 0, 16];
        bits(16) elt2_b = Elem[operand2, 2 * e + 1, 16];
        bits(32) sum = FPAdd_BF16(BFMulH(elt1_a, elt2_a), BFMulH(elt1_b, elt2_b));
        Elem[result, e, 32] = FPAdd_BF16(Elem[result, e, 32], sum);
    D[d+r] = result;