Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0524 avx512vbmi #236

Merged
merged 4 commits into from
May 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions BM/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
lkvs.log
1 change: 1 addition & 0 deletions BM/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Features
* [AMX](amx/README.md)
* [avx512vbmi](avx512vbmi/README.md)
* [cet(Control flow Enhancement Technology)](cet/README.md)
* [cstate](cstate/README.md)
* [DSA](dsa/README.md)
Expand Down
1 change: 1 addition & 0 deletions BM/avx512vbmi/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
vbmi_test
12 changes: 12 additions & 0 deletions BM/avx512vbmi/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# SPDX-License-Identifier: GPL-2.0-only
# Copyright (c) 2022 Intel Corporation.

BIN := vbmi_test

all: $(BIN)

vbmi_test: vbmi_test.c
$(CC) -o $@ $^

clean:
rm -rf $(BIN) *.o
20 changes: 20 additions & 0 deletions BM/avx512vbmi/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# avx512vbmi (avx512 Vector Byte Manipulation Instructions)

avx512vbmi is a set of instructions for Intel Tiger Lake and subsequent
platforms. Here is the test of some vbmi instructions.

You can run the cases one by one, e.g. command

```
./vbmi_func.sh -n vbmi_test -p "1 ff b"
./vbmi_func.sh -n vbmi_test -p random
```

You also can run the cases together with runtests command, e.g.
```
cd ..
./runtests -f avx512vbmi/tests -o logfile
If the platform CPU you are testing does not support avx512vbmi, it will exit
immediately and remind you to check the /tmp/lkvs_dependence log.
```
38 changes: 38 additions & 0 deletions BM/avx512vbmi/tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# This file collects the VBMI(Vector Byte Manipulation Instructions) tests on
# Intel® Architecture-based platforms.
# @hw_dep: cpuid_check 7 0 0 0 c 1 @ CPU doesn't support VBMI CPUID.(EAX=07H,ECX=0H):ECX[bit 1]
# @other_dep:
# @other_warn:

vbmi_func.sh -n vbmi_test -p "0 ff b"
vbmi_func.sh -n vbmi_test -p "1 ff b"
vbmi_func.sh -n vbmi_test -p "2 ff b"
vbmi_func.sh -n vbmi_test -p "3 ff b"
vbmi_func.sh -n vbmi_test -p "4 ff b"
vbmi_func.sh -n vbmi_test -p "5 ff b"
vbmi_func.sh -n vbmi_test -p "6 ff b"
vbmi_func.sh -n vbmi_test -p "7 ff b"
vbmi_func.sh -n vbmi_test -p "18 ff b"
vbmi_func.sh -n vbmi_test -p "19 ff b"
vbmi_func.sh -n vbmi_test -p "1F ff b"
vbmi_func.sh -n vbmi_test -p "20 ff b"
vbmi_func.sh -n vbmi_test -p "21 ff b"
vbmi_func.sh -n vbmi_test -p "30 ff b"
vbmi_func.sh -n vbmi_test -p "3A ff b"
vbmi_func.sh -n vbmi_test -p "3F ff b"
vbmi_func.sh -n vbmi_test -p "40 ff b"
vbmi_func.sh -n vbmi_test -p "41 ff b"
vbmi_func.sh -n vbmi_test -p "42 ff b"
vbmi_func.sh -n vbmi_test -p "43 ff b"
vbmi_func.sh -n vbmi_test -p "50 ff b"
vbmi_func.sh -n vbmi_test -p "60 ff b"
vbmi_func.sh -n vbmi_test -p "ff ff b"
vbmi_func.sh -n vbmi_test -p "0 0 b"
vbmi_func.sh -n vbmi_test -p "0 1 b"
vbmi_func.sh -n vbmi_test -p "0 5 b"
vbmi_func.sh -n vbmi_test -p "0 A b"
vbmi_func.sh -n vbmi_test -p "0 F b"
vbmi_func.sh -n vbmi_test -p "0 1FF b"
vbmi_func.sh -n vbmi_test -p "0 FFFF b"
vbmi_func.sh -n vbmi_test -p "0 1FFFF b"
vbmi_func.sh -n vbmi_test -p random
274 changes: 274 additions & 0 deletions BM/avx512vbmi/vbmi_func.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,274 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0-only
# Copyright (c) 2023 Intel Corporation
# Author: Pengfei Xu <[email protected]>
# Description: Test script to verify VBMI instruction

cd "$(dirname "$0")" 2>/dev/null || exit 1
# shellcheck disable=SC1091
source ../.env
# shellcheck disable=SC1091
source "ifs_common.sh"

usage() {
cat <<__EOF
usage: ./${0##*/} [-n BIN_NAME][-p parameter][-h]
-n Test cpu bin name like vpmadd and so on
-p Test bin file parameter like "2 3 b" and so on
-h show This
__EOF
}

# Check test bin results should contain "RESULTS" and no "[fail]" in it
# Input: log path
# Return: 0 for true, otherwise false or die
log_common_check() {
log=$1

grep -q -i "\[FAIL\]" "$log" && die "$log contain [FAIL]"
test_print_trc "Check $log pass, no [FAIL] in it"
}

# Show key test info in log
# Input:
# $1: log path
# $2: filter key info in log, "all" for w/o filter, other for filter key name
# Return: 0 for true, otherwise false or die
show_test_info() {
local log=$1
local key=$2
local all="all"
local key_info=""

test_print_trc "Show $key info in $log:"
if [[ "$key" == "$all" ]]; then
key_info=$(cat "$log")
else
key_info=$(grep -i "$key" "$log")
fi
test_print_trc "$key_info"
test_print_trc "$log end."
}

# Convert the number to binary and only get the low 8 bits
# Input: $1 the number which need convert
# Return low 8 bits with format "xxxx xxxx", otherwise false
convert_binary() {
num=$1
local gap=""
local bin_num=""
local bin_num_len=""
local low_num=""
local byte_num=""
local i=0
local j=0
local end_point

[ -n "$num" ] || die "Num is null:$num"
bin_num=$(echo "obase=2;$num"|bc)
bin_num_len=${#bin_num}
if [ "$bin_num_len" -lt 4 ]; then
low_num=${bin_num:0-$bin_num_len}
end_point=$((4 - bin_num_len))
for ((i=0; i<end_point; i++)); do
low_num="0"${low_num}
done
byte_num="0000 "${low_num}
elif [ "$bin_num_len" -lt 8 ]; then
low_num=${bin_num:0-4}
gap=$((bin_num_len-4))
byte_num=${bin_num:0-$bin_num_len:$gap}" ""$low_num"
end_point=$((4 - gap))
for ((j=0; j<end_point; j++)); do
byte_num="0"${byte_num}
done
else
byte_num=${bin_num:0-8:4}" "${bin_num:0-4}
fi
test_print_trc "num:$num,binary:$bin_num,length:$bin_num_len,byte_num:$byte_num"
BYTE_NUM="$byte_num"
}

# Input:
# $1: shift right num bits
# $2: the num need shift right
# Return shift right result low 8 bits with format "xxxx xxxx", otherwise false
shift_right() {
local shift_num=$1
local obj_num=$2
local k=0

for ((k=0;k<shift_num;k++));do
obj_num=$(echo "$obj_num"/2|bc)
done
convert_binary "$obj_num"
SHIFT_RIGHT_NUM=$BYTE_NUM
}

# Input:
# $1: shift left num bits
# $2: the num need shift left
# Return shift left result low 8 bits with format "xxxx xxxx", otherwise false
shift_left() {
local shift_num=$1
local obj_num=$2
local n=0

for ((n=0;n<shift_num;n++));do
obj_num=$(echo "${obj_num} * 2" | bc)
done
convert_binary "$obj_num"
SHIFT_LEFT_NUM=$BYTE_NUM
}

# Check vbmi test, instruction result is our expect.
# Input:
# $1: bin parameters
# $2: result log path
# Return: 0 for true, otherwise false or die
test_vbmi() {
local parm=$1
local log_path=$2
local par1=""
local par2=""
local bin_par2=""
local dec_par1=""
local left_par1=""
local dec_par2=""
local part1=""
local part2=""
local expect_pp0=""
local expect_pp1=""
local gap=""

par1=$(echo "$parm" | cut -d ' ' -f 1)
par2=$(echo "$parm" | cut -d ' ' -f 2)
dec_par1=$((0x$par1))
dec_par2=$((0x$par2))
convert_binary "$dec_par2"
bin_par2="$BYTE_NUM"

# part1 is checking high 3 bytes fill with 3 times bin_par2
part1="$bin_par2"' '"$bin_par2"' '"$bin_par2"

left_par1=$((dec_par1%64))
if [ "$left_par1" -le 24 ]; then
shift_right "$left_par1" "$dec_par2"
part2="$SHIFT_RIGHT_NUM"
elif [ "$left_par1" -lt 56 ]; then
part2="0000 0000"
else
gap=$((64-left_par1))
test_print_trc "shift_left gap:$gap, dec_par2:$dec_par2"
shift_left "$gap" "$dec_par2"
part2="$SHIFT_LEFT_NUM"
fi
test_print_trc "left_par1:$left_par1, dec_par1:$dec_par1, part2:$part2"
expect_pp0="$part1"' '"$part2"
test_print_trc "******expect_pp1[0](second half):$expect_pp0"
expect_pp1="$part1"' '"$bin_par2"
test_print_trc "******expect_pp1(first half):$expect_pp1"

grep "$expect_pp0" "$log_path" | grep -q "pp1\[0\]" \
|| die "Compare pp1[0] fail: not same as expect_pp0:$expect_pp0"
test_print_trc "Check $log_path pass."
}

# Execute cpu function binary program test and check success or fail
# $1: Binary program name to execute
# $2: Parameter need for binary test
# $3: Function name
# Return: 0 for true, otherwise false or die
cpu_func_parm_test() {
local bin_name=$1
local bin_parm=$2
local name=$3
local bin_parm_name=""
local log_path="/tmp/$name"
local all="all"
local log=""
local bin=""

[ -n "$bin_name" ] || die "File $bin_name was not exist"
[ -n "$bin_parm" ] || die "parameter: $bin_parm was null"
[ -d "$log_path" ] || mkdir -p "$log_path"
bin=$(which "$bin_name")
[[ -e "$bin" ]] || {
die "bin:$bin does not exist"
}

bin_parm_name=$(echo "$bin_parm" | tr ' ' '_')
if [ "$bin_parm" == "null" ]; then
log="${log_path}/${bin_name}_${bin_parm_name}.log"
eval "$bin > $log"
else
log="${log_path}/${bin_name}_${bin_parm_name}.log"
eval "$bin $bin_parm > $log"
fi

[ -e "$log" ] || die "No $log file"
case $name in
vbmi)
show_test_info "$log" "$all"
log_common_check "$log"
test_vbmi "$bin_parm" "$log"
;;
*)
show_test_info "$log" "$all"
test_print_trc "No need extra check for $name"
;;
esac
return 0
}

main() {
local func_name="vbmi"
local random_par=""
local a=""
local b=""
local ax=""
local bx=""
local times=10
local t=1

test_print_trc "Test $BIN_NAME, parameter: $PARM"

if [ "$PARM" == "random" ]; then
for((t=1;t<=times;t++)); do
test_print_trc "******* $t round test:"
((a=RANDOM%256))
((b=RANDOM%256))
ax=$(echo "obase=16;$a"|bc)
bx=$(echo "obase=16;$b"|bc)
random_par="$ax"' '"$bx"' '"b"
cpu_func_parm_test "$BIN_NAME" "$random_par" "$func_name"
done
else
cpu_func_parm_test "$BIN_NAME" "$PARM" "$func_name"
fi
}

while getopts :n:p:h arg; do
case $arg in
n)
BIN_NAME=$OPTARG
;;
p)
PARM=$OPTARG
;;
h)
usage
exit 0
;;
\?)
usage
die "Invalid Option -$OPTARG"
;;
:)
usage
die "Option -$OPTARG requires an argument."
;;
esac
done

main
Loading
Loading