git clone https://github.com/linedot/ukrgen
cd ukrgen
pip install . "asmgen @ git+https://github.com/linedot/asmgen"
Generate a complete BLIS source specifying microkernel configuration files
Usage:
usage: blisgen [-h] [--debug [DEBUG ...]] --sgemm-config SGEMM_CONFIG --dgemm-config DGEMM_CONFIG
[--config-name CONFIG_NAME] (--from-dir FROM_DIR | --from-git FROM_GIT) [--temp-dir TEMP_DIR]
--out-dir OUT_DIR [--overwrite] --author AUTHOR
options:
-h, --help show this help message and exit
--debug [DEBUG ...] Enables debug output for a specific subsystem; without any arguments, all debug output is enabled
--sgemm-config SGEMM_CONFIG
file containing the configuration for sgemm
--dgemm-config DGEMM_CONFIG
file containing the configuration for dgemm
--config-name CONFIG_NAME
name of the blis config (default: ukrgen_<isa>)
--from-dir FROM_DIR generate blis using the source in the specified directory
--from-git FROM_GIT generate blis using the source in the specified git repository URL
--temp-dir TEMP_DIR Directory to put temporary files in (default: autogenerated)
--out-dir OUT_DIR directory to output the generated source to
--overwrite overwrite the output directory if it exists
--author AUTHOR Author to insert in the copyright string
Example:
# generate BLIS source with RVV kernels
blisgen --sgemm-config ukrconfig/sgemm_rvv_2vx12x8.yaml --dgemm-config ukrconfig/dgemm_rvv_2vx12x8.yaml --author "Stepan Nassyr" --from-dir /path/to/vanilla/blis --out-dir /some/path/generated-blis-rvv --overwrite
# configure blis (crosscompilation on x86 machine)
cd /some/path/generated-blis-rvv
CC=riscv64-linux-gnu-gcc CXX=riscv64-linux-gnu-g++ AS=riscv64-linux-gnu-as ./configure --prefix=/some/path/riscv64/blis-generated --enable-cblas --enable-shared --enable-static -t openmp ukrgen_rvv
# build library, testsuite executable and level 3 benchmarks
make -j$(nproc)
make -j$(nproc) test_libblis.x
make -j$(nproc) -C test/3/ blis-mt# Run the testsuite with qemu:
cd testsuite
$ qemu-riscv64-static -cpu max,vlen=256 -L /usr/riscv64-linux-gnu/ ../test_libblis.x
[...]
% blis_<dt><op>_<stor> m n k gflops resid result
blis_sgemm_ukr_r 16 12 100 0.04 6.47e-09 PASS
blis_sgemm_ukr_r 16 12 200 0.30 6.91e-09 PASS
blis_sgemm_ukr_r 16 12 300 0.50 6.54e-09 PASS
blis_sgemm_ukr_r 16 12 400 0.50 1.19e-08 PASS
blis_sgemm_ukr_r 16 12 500 0.50 7.12e-09 PASS
% blis_<dt><op>_<stor> m n k gflops resid result
blis_dgemm_ukr_r 8 12 100 0.02 2.49e-17 PASS
blis_dgemm_ukr_r 8 12 200 0.21 4.14e-17 PASS
blis_dgemm_ukr_r 8 12 300 0.39 1.50e-17 PASS
blis_dgemm_ukr_r 8 12 400 0.39 3.66e-17 PASS
blis_dgemm_ukr_r 8 12 500 0.39 3.61e-17 PASS
[...]
% blis_<dt><op>_<params>_<stor> m n k gflops resid result
blis_sgemm_nn_ccc 100 100 100 0.19 2.30e-08 PASS
blis_sgemm_nn_ccc 200 200 200 0.29 1.61e-08 PASS
blis_sgemm_nn_ccc 300 300 300 0.34 1.09e-08 PASS
blis_sgemm_nn_ccc 400 400 400 0.37 2.25e-08 PASS
blis_sgemm_nn_ccc 500 500 500 0.38 1.43e-08 PASS
[...]
% blis_<dt><op>_<params>_<stor> m n k gflops resid result
blis_dgemm_nn_ccc 100 100 100 0.17 4.26e-17 PASS
blis_dgemm_nn_ccc 200 200 200 0.25 5.33e-17 PASS
blis_dgemm_nn_ccc 300 300 300 0.28 2.57e-17 PASS
blis_dgemm_nn_ccc 400 400 400 0.30 4.06e-17 PASS
blis_dgemm_nn_ccc 500 500 500 0.32 2.40e-17 PASS
[...]
Inspect the generated ASM function for given parameters directly or debug the generator for 1 kernel specifically
Usage:
usage: ukrgen [--debug [DEBUG ...]] --isa {avx128,avx256,avx512,rvv,rvv071,neon,sve,sme} --op {fma,dota,fopa,mma}
[--ukr {gemm,mm}] --rvv-LMUL RVV_LMUL
--AB-data-type {HALF,FP32,UINT32,SINT64,UINT8,SINT8,DOUBLE,FP16,SINT32,UINT16,FP64,SINT16,SINGLE}
--C-data-type {HALF,FP32,UINT32,SINT64,SINT8,DOUBLE,FP16,SINT32,UINT16,FP64,SINT16,UINT64,SINGLE}
[--variant {0,1}] --m M --n N --k K [--vecdir {M,N}] [--order ORDER] [--column-strides COLUMN_STRIDES]
[--row-strides ROW_STRIDES] --A-data-regs A_DATA_REGS [--A-addr-regs A_ADDR_REGS]
[--A-multiaddr-strat {interleave,split,phase}] [--A-preload A_PRELOAD] --B-data-regs B_DATA_REGS
[--B-addr-regs B_ADDR_REGS] [--B-multiaddr-strat {interleave,split,phase}] [--B-preload B_PRELOAD]
--AB-data-regs AB_DATA_REGS [--AB-addr-regs AB_ADDR_REGS] [--AB-multiaddr-strat {interleave,split,phase}]
--C-data-regs C_DATA_REGS [--C-addr-regs C_ADDR_REGS] [--C-multiaddr-strat {interleave,split,phase}]
[--sched-distance-specs SCHED_DISTANCE_SPECS [SCHED_DISTANCE_SPECS ...]] [--function-name FUNCTION_NAME]
options:
--debug [DEBUG ...] Enables debug output for a specific subsystem; without any arguments, all debug output is enabled
--isa {avx128,avx256,avx512,rvv,rvv071,neon,sve,sme}
Instruction set to use
--op {fma,dota,fopa,mma}
Arithmentic instruction to base the kernel on
--ukr {gemm,mm} Type of Microkernel to generate
--rvv-LMUL RVV_LMUL rvv parameter: LMUL
--AB-data-type {HALF,FP32,UINT32,SINT64,UINT8,SINT8,DOUBLE,FP16,SINT32,UINT16,FP64,SINT16,SINGLE}
Data type for component AB
--C-data-type {HALF,FP32,UINT32,SINT64,SINT8,DOUBLE,FP16,SINT32,UINT16,FP64,SINT16,UINT64,SINGLE}
Data type for component C
--variant {0,1} Variant of the supported instruction. 0 ==> A: HALF with 1vx1 B: HALF with 1x1 C: SINGLE with 1vx1 ;
1 ==> A: HALF with 1vx1 B: HALF with 1vx1 C: SINGLE with 1vx1
--m M Microkernel dimension m
--n N Microkernel dimension n
--k K Microkernel dimension k
--vecdir {M,N} Microkernel dimension along which to vectorize
--order ORDER Order in which to tile the kernel
--column-strides COLUMN_STRIDES
Components with general column strides
--row-strides ROW_STRIDES
Components with general row strides
--A-data-regs A_DATA_REGS
Number of data registers to use for component A
--A-addr-regs A_ADDR_REGS
Number of address register to use for component A
--A-multiaddr-strat {interleave,split,phase}
Strategy for using multiple address registers for component A
--A-preload A_PRELOAD
How many registers for A data to preload before the main loop
--B-data-regs B_DATA_REGS
Number of data registers to use for component B
--B-addr-regs B_ADDR_REGS
Number of address register to use for component B
--B-multiaddr-strat {interleave,split,phase}
Strategy for using multiple address registers for component B
--B-preload B_PRELOAD
How many registers for B data to preload before the main loop
--AB-data-regs AB_DATA_REGS
Number of data registers to use for component AB
--AB-addr-regs AB_ADDR_REGS
Number of address register to use for component AB
--AB-multiaddr-strat {interleave,split,phase}
Strategy for using multiple address registers for component AB
--C-data-regs C_DATA_REGS
Number of data registers to use for component C
--C-addr-regs C_ADDR_REGS
Number of address register to use for component C
--C-multiaddr-strat {interleave,split,phase}
Strategy for using multiple address registers for component C
--sched-distance-specs SCHED_DISTANCE_SPECS [SCHED_DISTANCE_SPECS ...]
distance specifications for the scheduler in "dep:regt:rtag:op1:op2:dist" format
--function-name FUNCTION_NAME
Override ASM Symbol/function name with a custom one
(available arguments and argument choices change depending on other arguments)
- RVV GEMM kernel
- based on FMA vf-form instruction
- dimensions: 2Vx12
- unroll 8x
- FP32 (sgemm)
- use 4 vregs for A
- use 24 fregs for B
- preload all A regs and 12 B regs
- 2 address regs for each component
- general column strides for C matrix
- ensure 11 instructions of distance between raw dependencies of vector registers
- ensure 5 instructions of distance between war dependencies of vector registers
- ensure 11 instructions of distance between raw dependencies of FP registers
$ ukrgen --ukr gemm --isa rvv --rvv-LMUL 1 \
--op fma --AB-data-type SINGLE --C-data-type SINGLE \
--variant 0 --m 2 --n 12 --k 8 --column-strides C \
--A-data-regs 4 --B-data-regs 24 --C-data-regs 24 --AB-data-regs 24 \
--A-addr-regs 2 --B-addr-regs 2 --C-addr-regs 2 \
--B-multiaddr-strat interleave --A-preload 4 --B-preload 12 \
--sched-distance-specs "raw::vreg:::11" "war::vreg:::5" "raw::freg:::11"
[...]
vfmacc.vf v13,f16,v26
vse32.v v13, (s4)
add s4,s4,s1
add a7,a7,s1
vle32.v v1, (a7)
vfmul.vf v1,v1,f6
vfmacc.vf v1,f16,v27
vse32.v v1, (s4)
# END STOREBLOCK -----------------------------
# FINALIZE -----------------------------------
# FUNC OUTRO ---------------------------------
ld s1,0(sp)
ld s2,8(sp)
ld s3,16(sp)
ld s4,24(sp)
ld s5,32(sp)
ld s6,40(sp)
fld f8, 48(sp)
fld f9, 56(sp)
fld f18, 64(sp)
fld f19, 72(sp)
fld f20, 80(sp)
fld f21, 88(sp)
fld f22, 96(sp)
fld f23, 104(sp)
add sp,sp,112
ret
see asmgen-gemm
ukrgen is distributed under the terms of both the MIT license and the GNU General Public License v3.0. Users may choose either license, at their option.
All new contributions must be made under both the MIT and GNU General Public License v3.0.
See LICENSE-GPL-3.0, LICENSE-MIT for details.
SPDX-License-Identifier: MIT OR GPL-3.0-or-later