530 lines
21 KiB
C
530 lines
21 KiB
C
/*++
|
|
|
|
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
Licensed under the MIT License.
|
|
|
|
Module Name:
|
|
|
|
FgemmKernelAvx512FCommon.h
|
|
|
|
Abstract:
|
|
|
|
This module implements the kernels for the floating point matrix/matrix
|
|
multiply operation (SGEMM and DGEMM).
|
|
|
|
This implementation uses AVX512F instructions.
|
|
|
|
--*/
|
|
|
|
/*++
|
|
|
|
Macro Description:
|
|
|
|
This macro multiplies and accumulates for 2 ZMMWORDs by N rows of the output
|
|
matrix.
|
|
|
|
Arguments:
|
|
|
|
RowCount - Supplies the number of rows to process.
|
|
|
|
VectorOffset - Supplies the byte offset from matrix B to fetch elements.
|
|
|
|
BroadcastOffset - Supplies the byte offset from matrix A to fetch elements.
|
|
|
|
PrefetchOffset - Optionally supplies the byte offset from matrix B to
|
|
prefetch elements.
|
|
|
|
Implicit Arguments:
|
|
|
|
rdi - Supplies the address into the matrix A data.
|
|
|
|
rbx - Supplies the address into the matrix A data plus 3 rows.
|
|
|
|
r13 - Supplies the address into the matrix A data plus 6 rows.
|
|
|
|
r14 - Supplies the address into the matrix A data plus 9 rows.
|
|
|
|
rsi - Supplies the address into the matrix B data.
|
|
|
|
r10 - Supplies the length in bytes of a row from matrix A.
|
|
|
|
zmm4-zmm27 - Supplies the block accumulators.
|
|
|
|
--*/
|
|
|
|
.macro ComputeBlockAvx512FBy2 RowCount, VectorOffset, BroadcastOffset, PrefetchOffset
|
|
|
|
.ifnb \PrefetchOffset\()
|
|
prefetcht0 [rsi+\VectorOffset\()+\PrefetchOffset\()]
|
|
prefetcht0 [rsi+r12+\VectorOffset\()+\PrefetchOffset\()]
|
|
.endif
|
|
.if \RowCount\() == 1
|
|
vbroadcastsf zmm3,[rdi+\BroadcastOffset\()]
|
|
vfmadd231pf zmm4,zmm3,ZMMWORD PTR [rsi+\VectorOffset\()]
|
|
vfmadd231pf zmm5,zmm3,ZMMWORD PTR [rsi+r12+\VectorOffset\()]
|
|
.else
|
|
vmovapf zmm0,ZMMWORD PTR [rsi+\VectorOffset\()]
|
|
vmovapf zmm1,ZMMWORD PTR [rsi+r12+\VectorOffset\()]
|
|
EmitIfCountGE \RowCount\(), 1, "vbroadcastsf zmm3,[rdi+\BroadcastOffset\()]"
|
|
EmitIfCountGE \RowCount\(), 1, "vfmadd231pf zmm4,zmm3,zmm0"
|
|
EmitIfCountGE \RowCount\(), 1, "vfmadd231pf zmm5,zmm3,zmm1"
|
|
EmitIfCountGE \RowCount\(), 2, "vbroadcastsf zmm3,[rdi+r10+\BroadcastOffset\()]"
|
|
EmitIfCountGE \RowCount\(), 2, "vfmadd231pf zmm6,zmm3,zmm0"
|
|
EmitIfCountGE \RowCount\(), 2, "vfmadd231pf zmm7,zmm3,zmm1"
|
|
EmitIfCountGE \RowCount\(), 3, "vbroadcastsf zmm3,[rdi+r10*2+\BroadcastOffset\()]"
|
|
EmitIfCountGE \RowCount\(), 3, "vfmadd231pf zmm8,zmm3,zmm0"
|
|
EmitIfCountGE \RowCount\(), 3, "vfmadd231pf zmm9,zmm3,zmm1"
|
|
EmitIfCountGE \RowCount\(), 4, "vbroadcastsf zmm3,[rbx+\BroadcastOffset\()]"
|
|
EmitIfCountGE \RowCount\(), 4, "vfmadd231pf zmm10,zmm3,zmm0"
|
|
EmitIfCountGE \RowCount\(), 4, "vfmadd231pf zmm11,zmm3,zmm1"
|
|
EmitIfCountGE \RowCount\(), 5, "vbroadcastsf zmm3,[rbx+r10+\BroadcastOffset\()]"
|
|
EmitIfCountGE \RowCount\(), 5, "vfmadd231pf zmm12,zmm3,zmm0"
|
|
EmitIfCountGE \RowCount\(), 5, "vfmadd231pf zmm13,zmm3,zmm1"
|
|
EmitIfCountGE \RowCount\(), 6, "vbroadcastsf zmm3,[rbx+r10*2+\BroadcastOffset\()]"
|
|
EmitIfCountGE \RowCount\(), 6, "vfmadd231pf zmm14,zmm3,zmm0"
|
|
EmitIfCountGE \RowCount\(), 6, "vfmadd231pf zmm15,zmm3,zmm1"
|
|
EmitIfCountGE \RowCount\(), 12, "vbroadcastsf zmm3,[r13+\BroadcastOffset\()]"
|
|
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf zmm16,zmm3,zmm0"
|
|
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf zmm17,zmm3,zmm1"
|
|
EmitIfCountGE \RowCount\(), 12, "vbroadcastsf zmm3,[r13+r10+\BroadcastOffset\()]"
|
|
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf zmm18,zmm3,zmm0"
|
|
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf zmm19,zmm3,zmm1"
|
|
EmitIfCountGE \RowCount\(), 12, "vbroadcastsf zmm3,[r13+r10*2+\BroadcastOffset\()]"
|
|
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf zmm20,zmm3,zmm0"
|
|
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf zmm21,zmm3,zmm1"
|
|
EmitIfCountGE \RowCount\(), 12, "vbroadcastsf zmm3,[r14+\BroadcastOffset\()]"
|
|
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf zmm22,zmm3,zmm0"
|
|
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf zmm23,zmm3,zmm1"
|
|
EmitIfCountGE \RowCount\(), 12, "vbroadcastsf zmm3,[r14+r10+\BroadcastOffset\()]"
|
|
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf zmm24,zmm3,zmm0"
|
|
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf zmm25,zmm3,zmm1"
|
|
EmitIfCountGE \RowCount\(), 12, "vbroadcastsf zmm3,[r14+r10*2+\BroadcastOffset\()]"
|
|
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf zmm26,zmm3,zmm0"
|
|
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf zmm27,zmm3,zmm1"
|
|
.endif
|
|
|
|
.endm
|
|
|
|
/*++
|
|
|
|
Macro Description:
|
|
|
|
This macro multiplies and accumulates for 1 ZMMWORD by N rows of the output
|
|
matrix.
|
|
|
|
Arguments:
|
|
|
|
RowCount - Supplies the number of rows to process.
|
|
|
|
VectorOffset - Supplies the byte offset from matrix B to fetch elements.
|
|
|
|
BroadcastOffset - Supplies the byte offset from matrix A to fetch elements.
|
|
|
|
PrefetchOffset - Optionally supplies the byte offset from matrix B to
|
|
prefetch elements.
|
|
|
|
Implicit Arguments:
|
|
|
|
rdi - Supplies the address into the matrix A data.
|
|
|
|
rbx - Supplies the address into the matrix A data plus 3 rows.
|
|
|
|
r13 - Supplies the address into the matrix A data plus 6 rows.
|
|
|
|
r14 - Supplies the address into the matrix A data plus 9 rows.
|
|
|
|
rsi - Supplies the address into the matrix B data.
|
|
|
|
r10 - Supplies the length in bytes of a row from matrix A.
|
|
|
|
zmm4-zmm27 - Supplies the block accumulators.
|
|
|
|
--*/
|
|
|
|
.macro ComputeBlockAvx512FBy1 RowCount, VectorOffset, BroadcastOffset, PrefetchOffset
|
|
|
|
.ifnb \PrefetchOffset\()
|
|
prefetcht0 [rsi+\VectorOffset\()+\PrefetchOffset\()]
|
|
.endif
|
|
vmovapf zmm0,ZMMWORD PTR [rsi+\VectorOffset\()]
|
|
EmitIfCountGE \RowCount\(), 1, "vfmadd231pf_bcst zmm5,zmm0,[rdi+\BroadcastOffset\()]"
|
|
EmitIfCountGE \RowCount\(), 2, "vfmadd231pf_bcst zmm7,zmm0,[rdi+r10+\BroadcastOffset\()]"
|
|
EmitIfCountGE \RowCount\(), 3, "vfmadd231pf_bcst zmm9,zmm0,[rdi+r10*2+\BroadcastOffset\()]"
|
|
EmitIfCountGE \RowCount\(), 4, "vfmadd231pf_bcst zmm11,zmm0,[rbx+\BroadcastOffset\()]"
|
|
EmitIfCountGE \RowCount\(), 5, "vfmadd231pf_bcst zmm13,zmm0,[rbx+r10+\BroadcastOffset\()]"
|
|
EmitIfCountGE \RowCount\(), 6, "vfmadd231pf_bcst zmm15,zmm0,[rbx+r10*2+\BroadcastOffset\()]"
|
|
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf_bcst zmm17,zmm0,[r13+\BroadcastOffset\()]"
|
|
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf_bcst zmm19,zmm0,[r13+r10+\BroadcastOffset\()]"
|
|
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf_bcst zmm21,zmm0,[r13+r10*2+\BroadcastOffset\()]"
|
|
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf_bcst zmm23,zmm0,[r14+\BroadcastOffset\()]"
|
|
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf_bcst zmm25,zmm0,[r14+r10+\BroadcastOffset\()]"
|
|
EmitIfCountGE \RowCount\(), 12, "vfmadd231pf_bcst zmm27,zmm0,[r14+r10*2+\BroadcastOffset\()]"
|
|
|
|
.endm
|
|
|
|
/*++
|
|
|
|
Macro Description:
|
|
|
|
This macro generates code to execute the block compute macro multiple
|
|
times and advancing the matrix A and matrix B data pointers.
|
|
|
|
Arguments:
|
|
|
|
ComputeBlock - Supplies the macro to compute a single block.
|
|
|
|
RowCount - Supplies the number of rows to process.
|
|
|
|
Implicit Arguments:
|
|
|
|
rdi - Supplies the address into the matrix A data.
|
|
|
|
rsi - Supplies the address into the matrix B data.
|
|
|
|
rcx - Supplies the number of columns from matrix A and the number of rows
|
|
from matrix B to iterate over.
|
|
|
|
r10 - Supplies the length in bytes of a row from matrix A.
|
|
|
|
zmm4-zmm27 - Supplies the block accumulators.
|
|
|
|
--*/
|
|
|
|
.macro ComputeBlockAvx512FLoop ComputeBlock, RowCount
|
|
|
|
.if \RowCount\() > 3
|
|
lea rbx,[r10*2+r10]
|
|
.if \RowCount\() == 12
|
|
lea r13,[rdi+rbx*2] # compute matrix A plus 6 rows
|
|
lea r14,[r13+rbx] # compute matrix A plus 9 rows
|
|
.endif
|
|
add rbx,rdi # compute matrix A plus 3 rows
|
|
.endif
|
|
ComputeBlockLoop \ComputeBlock\(), \RowCount\(), \RowCount\() > 3
|
|
.if \RowCount\() > 3
|
|
lea rbx,[rax*2+rax]
|
|
.if \RowCount\() == 12
|
|
lea r13,[rdx+rbx*2] # compute matrix C plus 6 rows
|
|
lea r14,[r13+rbx] # compute matrix C plus 9 rows
|
|
.endif
|
|
add rbx,rdx # compute matrix C plus 3 rows
|
|
.endif
|
|
|
|
.endm
|
|
|
|
/*++
|
|
|
|
Macro Description:
|
|
|
|
This macro generates code to compute matrix multiplication for a fixed set
|
|
of rows.
|
|
|
|
Arguments:
|
|
|
|
RowCount - Supplies the number of rows to process.
|
|
|
|
Implicit Arguments:
|
|
|
|
rdi - Supplies the address of matrix A.
|
|
|
|
rsi - Supplies the address of matrix B.
|
|
|
|
r11 - Supplies the address of matrix A.
|
|
|
|
r9 - Supplies the number of columns from matrix B and matrix C to iterate
|
|
over.
|
|
|
|
rdx - Supplies the address of matrix C.
|
|
|
|
rcx - Supplies the number of columns from matrix A and the number of rows
|
|
from matrix B to iterate over.
|
|
|
|
r10 - Supplies the length in bytes of a row from matrix A.
|
|
|
|
rax - Supplies the length in bytes of a row from matrix C.
|
|
|
|
r15 - Stores the ZeroMode argument from the stack frame.
|
|
|
|
--*/
|
|
|
|
.macro ProcessCountM RowCount
|
|
|
|
cmp r9,.LFgemmZmmElementCount
|
|
jbe .LProcessRemainingCountN\@
|
|
|
|
.LProcessNextColumnLoop2xN\@:
|
|
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm16,zmm4"
|
|
# clear upper block accumulators
|
|
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm17,zmm5"
|
|
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm18,zmm4"
|
|
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm19,zmm5"
|
|
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm20,zmm4"
|
|
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm21,zmm5"
|
|
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm22,zmm4"
|
|
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm23,zmm5"
|
|
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm24,zmm4"
|
|
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm25,zmm5"
|
|
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm26,zmm4"
|
|
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm27,zmm5"
|
|
ComputeBlockAvx512FLoop ComputeBlockAvx512FBy2, \RowCount\()
|
|
add rsi,r12 # advance matrix B by 64*CountK bytes
|
|
test r15b,r15b # ZeroMode?
|
|
jnz .LMultiplyAlpha2xNBlock\@
|
|
EmitIfCountGE \RowCount\(), 1, "vfmadd213pf zmm4,zmm31,ZMMWORD PTR [rdx]"
|
|
EmitIfCountGE \RowCount\(), 2, "vfmadd213pf zmm6,zmm31,ZMMWORD PTR [rdx+rax]"
|
|
EmitIfCountGE \RowCount\(), 3, "vfmadd213pf zmm8,zmm31,ZMMWORD PTR [rdx+rax*2]"
|
|
EmitIfCountGE \RowCount\(), 4, "vfmadd213pf zmm10,zmm31,ZMMWORD PTR [rbx]"
|
|
EmitIfCountGE \RowCount\(), 5, "vfmadd213pf zmm12,zmm31,ZMMWORD PTR [rbx+rax]"
|
|
EmitIfCountGE \RowCount\(), 6, "vfmadd213pf zmm14,zmm31,ZMMWORD PTR [rbx+rax*2]"
|
|
EmitIfCountGE \RowCount\(), 12, "vfmadd213pf zmm16,zmm31,ZMMWORD PTR [r13]"
|
|
EmitIfCountGE \RowCount\(), 12, "vfmadd213pf zmm18,zmm31,ZMMWORD PTR [r13+rax]"
|
|
EmitIfCountGE \RowCount\(), 12, "vfmadd213pf zmm20,zmm31,ZMMWORD PTR [r13+rax*2]"
|
|
EmitIfCountGE \RowCount\(), 12, "vfmadd213pf zmm22,zmm31,ZMMWORD PTR [r14]"
|
|
EmitIfCountGE \RowCount\(), 12, "vfmadd213pf zmm24,zmm31,ZMMWORD PTR [r14+rax]"
|
|
EmitIfCountGE \RowCount\(), 12, "vfmadd213pf zmm26,zmm31,ZMMWORD PTR [r14+rax*2]"
|
|
jmp .LStore2xNBlock\@
|
|
|
|
.LMultiplyAlpha2xNBlock\@:
|
|
EmitIfCountGE \RowCount\(), 1, "vmulpf zmm4,zmm4,zmm31"
|
|
EmitIfCountGE \RowCount\(), 2, "vmulpf zmm6,zmm6,zmm31"
|
|
EmitIfCountGE \RowCount\(), 3, "vmulpf zmm8,zmm8,zmm31"
|
|
EmitIfCountGE \RowCount\(), 4, "vmulpf zmm10,zmm10,zmm31"
|
|
EmitIfCountGE \RowCount\(), 5, "vmulpf zmm12,zmm12,zmm31"
|
|
EmitIfCountGE \RowCount\(), 6, "vmulpf zmm14,zmm14,zmm31"
|
|
EmitIfCountGE \RowCount\(), 12, "vmulpf zmm16,zmm16,zmm31"
|
|
EmitIfCountGE \RowCount\(), 12, "vmulpf zmm18,zmm18,zmm31"
|
|
EmitIfCountGE \RowCount\(), 12, "vmulpf zmm20,zmm20,zmm31"
|
|
EmitIfCountGE \RowCount\(), 12, "vmulpf zmm22,zmm22,zmm31"
|
|
EmitIfCountGE \RowCount\(), 12, "vmulpf zmm24,zmm24,zmm31"
|
|
EmitIfCountGE \RowCount\(), 12, "vmulpf zmm26,zmm26,zmm31"
|
|
|
|
.LStore2xNBlock\@:
|
|
EmitIfCountGE \RowCount\(), 1, "vmovupf ZMMWORD PTR [rdx],zmm4"
|
|
EmitIfCountGE \RowCount\(), 2, "vmovupf ZMMWORD PTR [rdx+rax],zmm6"
|
|
EmitIfCountGE \RowCount\(), 3, "vmovupf ZMMWORD PTR [rdx+rax*2],zmm8"
|
|
EmitIfCountGE \RowCount\(), 4, "vmovupf ZMMWORD PTR [rbx],zmm10"
|
|
EmitIfCountGE \RowCount\(), 5, "vmovupf ZMMWORD PTR [rbx+rax],zmm12"
|
|
EmitIfCountGE \RowCount\(), 6, "vmovupf ZMMWORD PTR [rbx+rax*2],zmm14"
|
|
EmitIfCountGE \RowCount\(), 12, "vmovupf ZMMWORD PTR [r13],zmm16"
|
|
EmitIfCountGE \RowCount\(), 12, "vmovupf ZMMWORD PTR [r13+rax],zmm18"
|
|
EmitIfCountGE \RowCount\(), 12, "vmovupf ZMMWORD PTR [r13+rax*2],zmm20"
|
|
EmitIfCountGE \RowCount\(), 12, "vmovupf ZMMWORD PTR [r14],zmm22"
|
|
EmitIfCountGE \RowCount\(), 12, "vmovupf ZMMWORD PTR [r14+rax],zmm24"
|
|
EmitIfCountGE \RowCount\(), 12, "vmovupf ZMMWORD PTR [r14+rax*2],zmm26"
|
|
add rdx,64 # advance matrix C by ZMMWORD
|
|
.if \RowCount\() > 3
|
|
add rbx,64 # advance matrix C plus 3 rows by ZMMWORD
|
|
.if \RowCount\() == 12
|
|
add r13,64 # advance matrix C plus 6 rows by ZMMWORD
|
|
add r14,64 # advance matrix C plus 9 rows by ZMMWORD
|
|
.endif
|
|
.endif
|
|
sub r9,.LFgemmZmmElementCount
|
|
|
|
.LOutput1xNBlock\@:
|
|
sub r9,.LFgemmZmmElementCount
|
|
jae .LOutput1xNBlockWithMask\@
|
|
lea rcx,[r9+.LFgemmZmmElementCount]
|
|
# correct for over-subtract above
|
|
mov ebp,1
|
|
shl ebp,cl
|
|
dec ebp
|
|
kmovw k1,ebp # update mask for remaining columns
|
|
xor r9,r9 # no more columns remaining
|
|
|
|
.LOutput1xNBlockWithMask\@:
|
|
test r15b,r15b # ZeroMode?
|
|
jnz .LMultiplyAlpha1xNBlockWithMask\@
|
|
EmitIfCountGE \RowCount\(), 1, "vfmadd213pf zmm5{k1},zmm31,ZMMWORD PTR [rdx]"
|
|
EmitIfCountGE \RowCount\(), 2, "vfmadd213pf zmm7{k1},zmm31,ZMMWORD PTR [rdx+rax]"
|
|
EmitIfCountGE \RowCount\(), 3, "vfmadd213pf zmm9{k1},zmm31,ZMMWORD PTR [rdx+rax*2]"
|
|
EmitIfCountGE \RowCount\(), 4, "vfmadd213pf zmm11{k1},zmm31,ZMMWORD PTR [rbx]"
|
|
EmitIfCountGE \RowCount\(), 5, "vfmadd213pf zmm13{k1},zmm31,ZMMWORD PTR [rbx+rax]"
|
|
EmitIfCountGE \RowCount\(), 6, "vfmadd213pf zmm15{k1},zmm31,ZMMWORD PTR [rbx+rax*2]"
|
|
EmitIfCountGE \RowCount\(), 12, "vfmadd213pf zmm17{k1},zmm31,ZMMWORD PTR [r13]"
|
|
EmitIfCountGE \RowCount\(), 12, "vfmadd213pf zmm19{k1},zmm31,ZMMWORD PTR [r13+rax]"
|
|
EmitIfCountGE \RowCount\(), 12, "vfmadd213pf zmm21{k1},zmm31,ZMMWORD PTR [r13+rax*2]"
|
|
EmitIfCountGE \RowCount\(), 12, "vfmadd213pf zmm23{k1},zmm31,ZMMWORD PTR [r14]"
|
|
EmitIfCountGE \RowCount\(), 12, "vfmadd213pf zmm25{k1},zmm31,ZMMWORD PTR [r14+rax]"
|
|
EmitIfCountGE \RowCount\(), 12, "vfmadd213pf zmm27{k1},zmm31,ZMMWORD PTR [r14+rax*2]"
|
|
jmp .LStore1xNBlockWithMask\@
|
|
|
|
.LMultiplyAlpha1xNBlockWithMask\@:
|
|
EmitIfCountGE \RowCount\(), 1, "vmulpf zmm5,zmm5,zmm31"
|
|
EmitIfCountGE \RowCount\(), 2, "vmulpf zmm7,zmm7,zmm31"
|
|
EmitIfCountGE \RowCount\(), 3, "vmulpf zmm9,zmm9,zmm31"
|
|
EmitIfCountGE \RowCount\(), 4, "vmulpf zmm11,zmm11,zmm31"
|
|
EmitIfCountGE \RowCount\(), 5, "vmulpf zmm13,zmm13,zmm31"
|
|
EmitIfCountGE \RowCount\(), 6, "vmulpf zmm15,zmm15,zmm31"
|
|
EmitIfCountGE \RowCount\(), 12, "vmulpf zmm17,zmm17,zmm31"
|
|
EmitIfCountGE \RowCount\(), 12, "vmulpf zmm19,zmm19,zmm31"
|
|
EmitIfCountGE \RowCount\(), 12, "vmulpf zmm21,zmm21,zmm31"
|
|
EmitIfCountGE \RowCount\(), 12, "vmulpf zmm23,zmm23,zmm31"
|
|
EmitIfCountGE \RowCount\(), 12, "vmulpf zmm25,zmm25,zmm31"
|
|
EmitIfCountGE \RowCount\(), 12, "vmulpf zmm27,zmm27,zmm31"
|
|
|
|
.LStore1xNBlockWithMask\@:
|
|
EmitIfCountGE \RowCount\(), 1, "vmovupf ZMMWORD PTR [rdx]{k1},zmm5"
|
|
EmitIfCountGE \RowCount\(), 2, "vmovupf ZMMWORD PTR [rdx+rax]{k1},zmm7"
|
|
EmitIfCountGE \RowCount\(), 3, "vmovupf ZMMWORD PTR [rdx+rax*2]{k1},zmm9"
|
|
EmitIfCountGE \RowCount\(), 4, "vmovupf ZMMWORD PTR [rbx]{k1},zmm11"
|
|
EmitIfCountGE \RowCount\(), 5, "vmovupf ZMMWORD PTR [rbx+rax]{k1},zmm13"
|
|
EmitIfCountGE \RowCount\(), 6, "vmovupf ZMMWORD PTR [rbx+rax*2]{k1},zmm15"
|
|
EmitIfCountGE \RowCount\(), 12, "vmovupf ZMMWORD PTR [r13]{k1},zmm17"
|
|
EmitIfCountGE \RowCount\(), 12, "vmovupf ZMMWORD PTR [r13+rax]{k1},zmm19"
|
|
EmitIfCountGE \RowCount\(), 12, "vmovupf ZMMWORD PTR [r13+rax*2]{k1},zmm21"
|
|
EmitIfCountGE \RowCount\(), 12, "vmovupf ZMMWORD PTR [r14]{k1},zmm23"
|
|
EmitIfCountGE \RowCount\(), 12, "vmovupf ZMMWORD PTR [r14+rax]{k1},zmm25"
|
|
EmitIfCountGE \RowCount\(), 12, "vmovupf ZMMWORD PTR [r14+rax*2]{k1},zmm27"
|
|
add rdx,64 # advance matrix C by ZMMWORD
|
|
mov rdi,r11 # reload matrix A
|
|
vzeroall
|
|
cmp r9,.LFgemmZmmElementCount
|
|
ja .LProcessNextColumnLoop2xN\@
|
|
test r9,r9
|
|
jz .LExitKernel
|
|
|
|
.LProcessRemainingCountN\@:
|
|
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm17,zmm5"
|
|
# clear upper block accumulators
|
|
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm19,zmm5"
|
|
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm21,zmm5"
|
|
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm23,zmm5"
|
|
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm25,zmm5"
|
|
EmitIfCountGE \RowCount\(), 12, "vmovapf zmm27,zmm5"
|
|
ComputeBlockAvx512FLoop ComputeBlockAvx512FBy1, \RowCount\()
|
|
jmp .LOutput1xNBlock\@
|
|
|
|
.endm
|
|
|
|
/*++
|
|
|
|
Macro Description:
|
|
|
|
This macro generates the inner kernel to compute matrix multiplication.
|
|
|
|
Arguments:
|
|
|
|
FunctionName - Supplies the name for the generated function.
|
|
|
|
--*/
|
|
|
|
.macro FgemmKernelAvx512FFunction FunctionName
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is an inner kernel to compute matrix multiplication for a
|
|
set of rows.
|
|
|
|
Arguments:
|
|
|
|
A (rdi) - Supplies the address of matrix A.
|
|
|
|
B (rsi) - Supplies the address of matrix B. The matrix data has been packed
|
|
using MlasSgemmCopyPackB or MlasSgemmTransposePackB.
|
|
|
|
C (rdx) - Supplies the address of matrix C.
|
|
|
|
CountK (rcx) - Supplies the number of columns from matrix A and the number
|
|
of rows from matrix B to iterate over.
|
|
|
|
CountM (r8) - Supplies the maximum number of rows that can be processed for
|
|
matrix A and matrix C. The actual number of rows handled for this
|
|
invocation depends on the kernel implementation.
|
|
|
|
CountN (r9) - Supplies the number of columns from matrix B and matrix C to
|
|
iterate over.
|
|
|
|
lda - Supplies the first dimension of matrix A.
|
|
|
|
ldc - Supplies the first dimension of matrix C.
|
|
|
|
Alpha (xmm0) - Supplies the scalar alpha multiplier (see GEMM definition).
|
|
|
|
ZeroMode - Supplies true if the output matrix must be zero initialized,
|
|
else false if the output matrix is accumulated into.
|
|
|
|
Return Value:
|
|
|
|
Returns the number of rows handled.
|
|
|
|
--*/
|
|
|
|
FUNCTION_ENTRY \FunctionName\()
|
|
|
|
push rbp
|
|
push rbx
|
|
push r15
|
|
mov .LFgemmKernelFrame_SavedR12[rsp],r12
|
|
mov .LFgemmKernelFrame_SavedR13[rsp],r13
|
|
mov .LFgemmKernelFrame_SavedR14[rsp],r14
|
|
mov r11,rdi
|
|
mov r10,.LFgemmKernelFrame_lda[rsp]
|
|
shl r10,.LFgemmElementShift # convert lda to bytes
|
|
mov rax,.LFgemmKernelFrame_ldc[rsp]
|
|
shl rax,.LFgemmElementShift # convert ldc to bytes
|
|
mov r12,rcx
|
|
shl r12,6 # compute 64*CountK bytes
|
|
mov ebp,-1
|
|
kmovw k1,ebp # update mask to write all columns
|
|
movzx r15,BYTE PTR .LFgemmKernelFrame_ZeroMode[rsp]
|
|
vbroadcastsf zmm31,xmm0
|
|
vzeroall
|
|
|
|
//
|
|
// Process CountM rows of the matrices.
|
|
//
|
|
|
|
cmp r8,12
|
|
jb .LProcessCountMLessThan12
|
|
mov r8d,12 # return 12 rows handled
|
|
ProcessCountM 12
|
|
|
|
.LProcessCountMLessThan12:
|
|
cmp r8,5
|
|
ja .LProcessCountM6
|
|
je .LProcessCountM5
|
|
cmp r8,3
|
|
ja .LProcessCountM4
|
|
je .LProcessCountM3
|
|
cmp r8,1
|
|
je .LProcessCountM1
|
|
|
|
.LProcessCountM2:
|
|
ProcessCountM 2
|
|
|
|
.LProcessCountM4:
|
|
ProcessCountM 4
|
|
|
|
.LProcessCountM6:
|
|
mov r8d,6 # return 6 rows handled
|
|
ProcessCountM 6
|
|
|
|
//
|
|
// Restore non-volatile registers and return.
|
|
//
|
|
|
|
.LExitKernel:
|
|
mov eax,r8d
|
|
mov r12,.LFgemmKernelFrame_SavedR12[rsp]
|
|
mov r13,.LFgemmKernelFrame_SavedR13[rsp]
|
|
mov r14,.LFgemmKernelFrame_SavedR14[rsp]
|
|
pop r15
|
|
pop rbx
|
|
pop rbp
|
|
ret
|
|
|
|
.LProcessCountM1:
|
|
ProcessCountM 1
|
|
|
|
.LProcessCountM3:
|
|
ProcessCountM 3
|
|
|
|
.LProcessCountM5:
|
|
ProcessCountM 5
|
|
|
|
.endm
|