Add SIMD test helpers
This commit adds a couple of scripts that help test SIMD functionality on different machines through QEMU. tools/test_simd_qemu.sh will automatically start qemu, run tests and stop it. it uses the Ubuntu cloud images which are built for x86_64, arm and arm64. tools/test_simd.sh run a number of tests including compiling with different flags, unit tests, and gathering the functions selected in gf_init (and when compiling with DEBUG_FUNCTIONS)master
parent
87f0d4395d
commit
7761438c63
|
@ -74,4 +74,5 @@ tools/gf_poly
|
||||||
tools/gf_time
|
tools/gf_time
|
||||||
tools/gf_unit_w*
|
tools/gf_unit_w*
|
||||||
tools/test-suite.log
|
tools/test-suite.log
|
||||||
|
tools/.qemu/
|
||||||
|
tools/test_simd*.results
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
#!/bin/bash -e
|
||||||
|
|
||||||
|
# this scripts has a number of tests for SIMD. It can be invoked
|
||||||
|
# on the host or on a QEMU machine.
|
||||||
|
|
||||||
|
script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
host_cpu=`uname -p`
|
||||||
|
results=${script_dir}/test_simd.results
|
||||||
|
|
||||||
|
# runs unit tests and save the results
|
||||||
|
test_unit(){
|
||||||
|
{ ./configure && make clean && make; } || { echo "Compile FAILED" >> ${results}; return 1; }
|
||||||
|
make check || { echo "gf_methods $i FAILED" >> ${results}; ((++failed)); }
|
||||||
|
cat tools/test-suite.log >> ${results} || true
|
||||||
|
}
|
||||||
|
|
||||||
|
# build with DEBUG_FUNCTIONS and save all methods selected
|
||||||
|
# to a results file
|
||||||
|
test_functions() {
|
||||||
|
failed=0
|
||||||
|
|
||||||
|
{ ./configure && make clean && make CFLAGS="-DDEBUG_FUNCTIONS"; } || { echo "Compile FAILED" >> ${results}; return 1; }
|
||||||
|
for i in 128 64 32 16 8 4; do
|
||||||
|
{ ${script_dir}/gf_methods $i -ACD -X >> ${results}; } || { echo "gf_methods $i FAILED" >> ${results}; ((++failed)); }
|
||||||
|
done
|
||||||
|
|
||||||
|
return ${failed}
|
||||||
|
}
|
||||||
|
|
||||||
|
compile_arm() {
|
||||||
|
failed=0
|
||||||
|
|
||||||
|
echo -n "Compiling with NO SIMD support..." >> ${results}
|
||||||
|
{ ./configure --disable-neon && make clean && make && echo "SUCCESS" >> ${results}; } || { echo "FAIL" >> ${results}; ((++failed)); }
|
||||||
|
|
||||||
|
echo -n "Compiling with FULL SIMD support..." >> ${results}
|
||||||
|
{ ./configure && make clean && make && echo "SUCCESS" >> ${results}; } || { echo "FAIL" >> ${results}; ((++failed)); }
|
||||||
|
|
||||||
|
return ${failed}
|
||||||
|
}
|
||||||
|
|
||||||
|
compile_intel() {
|
||||||
|
failed=0
|
||||||
|
|
||||||
|
echo -n "Compiling with NO SIMD support..." >> ${results}
|
||||||
|
{ ./configure && make clean && make && echo "SUCCESS" >> ${results}; } || { echo "FAIL" >> ${results}; ((++failed)); }
|
||||||
|
|
||||||
|
echo -n "Compiling with SSE2 only..." >> ${results}
|
||||||
|
export ax_cv_have_sse_ext=no
|
||||||
|
export ax_cv_have_sse2_ext=yes
|
||||||
|
export ax_cv_have_sse3_ext=no
|
||||||
|
export ax_cv_have_ssse3_ext=no
|
||||||
|
export ax_cv_have_sse41_ext=no
|
||||||
|
export ax_cv_have_sse42_ext=no
|
||||||
|
export ax_cv_have_pclmuldq_ext=no
|
||||||
|
{ ./configure && make clean && make && echo "SUCCESS" >> ${results}; } || { echo "FAIL" >> ${results}; ((++failed)); }
|
||||||
|
|
||||||
|
echo -n "Compiling with SSE2,SSE3 only..." >> ${results}
|
||||||
|
export ax_cv_have_sse_ext=no
|
||||||
|
export ax_cv_have_sse2_ext=yes
|
||||||
|
export ax_cv_have_sse3_ext=yes
|
||||||
|
export ax_cv_have_ssse3_ext=no
|
||||||
|
export ax_cv_have_sse41_ext=no
|
||||||
|
export ax_cv_have_sse42_ext=no
|
||||||
|
export ax_cv_have_pclmuldq_ext=no
|
||||||
|
{ ./configure && make clean && make && echo "SUCCESS" >> ${results}; } || { echo "FAIL" >> ${results}; ((++failed)); }
|
||||||
|
|
||||||
|
echo -n "Compiling with SSE2,SSE3,SSSE3 only..." >> ${results}
|
||||||
|
export ax_cv_have_sse_ext=no
|
||||||
|
export ax_cv_have_sse2_ext=yes
|
||||||
|
export ax_cv_have_sse3_ext=yes
|
||||||
|
export ax_cv_have_ssse3_ext=yes
|
||||||
|
export ax_cv_have_sse41_ext=no
|
||||||
|
export ax_cv_have_sse42_ext=no
|
||||||
|
export ax_cv_have_pclmuldq_ext=no
|
||||||
|
{ ./configure && make clean && make && echo "SUCCESS" >> ${results}; } || { echo "FAIL" >> ${results}; ((++failed)); }
|
||||||
|
|
||||||
|
echo -n "Compiling with SSE2,SSE3,SSSE3,SSE4_1 only..." >> ${results}
|
||||||
|
export ax_cv_have_sse_ext=no
|
||||||
|
export ax_cv_have_sse2_ext=yes
|
||||||
|
export ax_cv_have_sse3_ext=yes
|
||||||
|
export ax_cv_have_ssse3_ext=yes
|
||||||
|
export ax_cv_have_sse41_ext=yes
|
||||||
|
export ax_cv_have_sse42_ext=no
|
||||||
|
export ax_cv_have_pclmuldq_ext=no
|
||||||
|
{ ./configure && make clean && make && echo "SUCCESS" >> ${results}; } || { echo "FAIL" >> ${results}; ((++failed)); }
|
||||||
|
|
||||||
|
echo -n "Compiling with SSE2,SSE3,SSSE3,SSE4_2 only..." >> ${results}
|
||||||
|
export ax_cv_have_sse_ext=no
|
||||||
|
export ax_cv_have_sse2_ext=yes
|
||||||
|
export ax_cv_have_sse3_ext=yes
|
||||||
|
export ax_cv_have_ssse3_ext=yes
|
||||||
|
export ax_cv_have_sse41_ext=no
|
||||||
|
export ax_cv_have_sse42_ext=yes
|
||||||
|
export ax_cv_have_pclmuldq_ext=no
|
||||||
|
{ ./configure && make clean && make && echo "SUCCESS" >> ${results}; } || { echo "FAIL" >> ${results}; ((++failed)); }
|
||||||
|
|
||||||
|
echo -n "Compiling with FULL SIMD support..." >> ${results}
|
||||||
|
export ax_cv_have_sse_ext=no
|
||||||
|
export ax_cv_have_sse2_ext=yes
|
||||||
|
export ax_cv_have_sse3_ext=yes
|
||||||
|
export ax_cv_have_ssse3_ext=yes
|
||||||
|
export ax_cv_have_sse41_ext=yes
|
||||||
|
export ax_cv_have_sse42_ext=yes
|
||||||
|
export ax_cv_have_pclmuldq_ext=yes
|
||||||
|
{ ./configure && make clean && make && echo "SUCCESS" >> ${results}; } || { echo "FAIL" >> ${results}; ((++failed)); }
|
||||||
|
|
||||||
|
return ${failed}
|
||||||
|
}
|
||||||
|
|
||||||
|
# test that we can compile the source code with different
|
||||||
|
# SIMD options. We assume that we are running on processor
|
||||||
|
# full SIMD support
|
||||||
|
test_compile() {
|
||||||
|
case $host_cpu in
|
||||||
|
aarch64*|arm*) compile_arm ;;
|
||||||
|
i[[3456]]86*|x86_64*|amd64*) compile_intel ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
cd ${script_dir}/..
|
||||||
|
rm -f ${results}
|
||||||
|
|
||||||
|
test_$1
|
||||||
|
exit $?
|
|
@ -0,0 +1,254 @@
|
||||||
|
#!/bin/bash -e
|
||||||
|
|
||||||
|
# This script will use QEMU to test gf-complete especially SIMD support
|
||||||
|
# on different architectures and cpus. It will boot a qemu machine
|
||||||
|
# and run an Ubuntu cloud image. All testing will happen inside the
|
||||||
|
# QEMU machine.
|
||||||
|
|
||||||
|
# The following packages are required:
|
||||||
|
# qemu-system-aarch64
|
||||||
|
# qemu-system-arm
|
||||||
|
# qemu-system-x86_64
|
||||||
|
# genisoimage
|
||||||
|
|
||||||
|
|
||||||
|
script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
qemu_dir="${script_dir}/.qemu"
|
||||||
|
ssh_port=2222
|
||||||
|
ssh_pubkey_file="${qemu_dir}/qemu.pub"
|
||||||
|
ssh_key_file="${qemu_dir}/qemu"
|
||||||
|
|
||||||
|
mkdir -p "${qemu_dir}"
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
if [[ -n "$(jobs -p)" ]]; then
|
||||||
|
echo killing qemu processes "$(jobs -p)"
|
||||||
|
kill $(jobs -p)
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
trap cleanup EXIT
|
||||||
|
|
||||||
|
start_qemu() {
|
||||||
|
arch=$1
|
||||||
|
cpu=$2
|
||||||
|
|
||||||
|
image_version="xenial"
|
||||||
|
image_url_base="http://cloud-images.ubuntu.com/${image_version}/current"
|
||||||
|
|
||||||
|
case $arch in
|
||||||
|
i[[3456]]86*|x86_64*|amd64*)
|
||||||
|
image_kernel="${image_version}-server-cloudimg-amd64-vmlinuz-generic"
|
||||||
|
image_initrd="${image_version}-server-cloudimg-amd64-initrd-generic"
|
||||||
|
image_disk="${image_version}-server-cloudimg-amd64-disk1.img"
|
||||||
|
;;
|
||||||
|
aarch64*)
|
||||||
|
image_kernel="${image_version}-server-cloudimg-arm64-vmlinuz-generic"
|
||||||
|
image_initrd="${image_version}-server-cloudimg-arm64-initrd-generic"
|
||||||
|
image_disk="${image_version}-server-cloudimg-arm64-disk1.img"
|
||||||
|
;;
|
||||||
|
arm*)
|
||||||
|
image_kernel="${image_version}-server-cloudimg-armhf-vmlinuz-lpae"
|
||||||
|
image_initrd="${image_version}-server-cloudimg-armhf-initrd-generic-lpae"
|
||||||
|
image_disk="${image_version}-server-cloudimg-armhf-disk1.img"
|
||||||
|
;;
|
||||||
|
*) die "Unsupported arch" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
[[ -f ${qemu_dir}/${image_kernel} ]] || wget -O ${qemu_dir}/${image_kernel} ${image_url_base}/unpacked/${image_kernel}
|
||||||
|
[[ -f ${qemu_dir}/${image_initrd} ]] || wget -O ${qemu_dir}/${image_initrd} ${image_url_base}/unpacked/${image_initrd}
|
||||||
|
[[ -f ${qemu_dir}/${image_disk} ]] || wget -O ${qemu_dir}/${image_disk} ${image_url_base}/${image_disk}
|
||||||
|
|
||||||
|
#create a delta disk to keep the original image clean
|
||||||
|
delta_disk="${qemu_dir}/disk.img"
|
||||||
|
rm -f ${delta_disk}
|
||||||
|
qemu-img create -q -f qcow2 -b "${qemu_dir}/${image_disk}" ${delta_disk}
|
||||||
|
|
||||||
|
# generate an ssh keys
|
||||||
|
[[ -f ${ssh_pubkey_file} ]] || ssh-keygen -q -N "" -f ${ssh_key_file}
|
||||||
|
|
||||||
|
# create a config disk to set the SSH keys
|
||||||
|
cat > "${qemu_dir}/meta-data" <<EOF
|
||||||
|
instance-id: qemu
|
||||||
|
local-hostname: qemu
|
||||||
|
EOF
|
||||||
|
cat > "${qemu_dir}/user-data" <<EOF
|
||||||
|
#cloud-config
|
||||||
|
hostname: qemu
|
||||||
|
manage_etc_hosts: true
|
||||||
|
users:
|
||||||
|
- name: qemu
|
||||||
|
ssh-authorized-keys:
|
||||||
|
- $(cat "${ssh_pubkey_file}")
|
||||||
|
sudo: ['ALL=(ALL) NOPASSWD:ALL']
|
||||||
|
groups: sudo
|
||||||
|
shell: /bin/bash
|
||||||
|
EOF
|
||||||
|
genisoimage -quiet -output "${qemu_dir}/cloud.iso" -volid cidata -joliet -rock "${qemu_dir}/user-data" "${qemu_dir}/meta-data"
|
||||||
|
|
||||||
|
common_args=( \
|
||||||
|
-name "qemu" \
|
||||||
|
-m 1024 \
|
||||||
|
-nodefaults \
|
||||||
|
-nographic \
|
||||||
|
-kernel ${qemu_dir}/${image_kernel} \
|
||||||
|
-initrd ${qemu_dir}/${image_initrd} \
|
||||||
|
-cdrom ${qemu_dir}/cloud.iso \
|
||||||
|
-serial file:${qemu_dir}/console.log
|
||||||
|
)
|
||||||
|
|
||||||
|
case $arch in
|
||||||
|
i[[3456]]86*|x86_64*|amd64*)
|
||||||
|
qemu-system-x86_64 \
|
||||||
|
"${common_args[@]}" \
|
||||||
|
-machine accel=kvm -cpu $cpu \
|
||||||
|
-append "console=ttyS0 root=/dev/sda1" \
|
||||||
|
-hda "${delta_disk}" \
|
||||||
|
-net nic,vlan=0,model=virtio \
|
||||||
|
-net user,vlan=0,hostfwd=tcp::"${ssh_port}"-:22,hostname="${vm_name}" \
|
||||||
|
&
|
||||||
|
;;
|
||||||
|
aarch64*|arm*)
|
||||||
|
qemu-system-$arch \
|
||||||
|
"${common_args[@]}" \
|
||||||
|
-machine virt -cpu $cpu -machine type=virt -smp 1 \
|
||||||
|
-drive if=none,file="${delta_disk}",id=hd0 \
|
||||||
|
-device virtio-blk-device,drive=hd0 \
|
||||||
|
-append "console=ttyAMA0 root=/dev/vda1" \
|
||||||
|
-netdev user,id=eth0,hostfwd=tcp::"${ssh_port}"-:22,hostname="${vm_name}" \
|
||||||
|
-device virtio-net-device,netdev=eth0 \
|
||||||
|
&
|
||||||
|
;;
|
||||||
|
*) die "Unsupported arch" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
wait_for_ssh
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_qemu() {
|
||||||
|
run_ssh "sudo shutdown now" || true
|
||||||
|
wait $(jobs -p)
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_args=(
|
||||||
|
-i ${ssh_key_file}
|
||||||
|
-F /dev/null
|
||||||
|
-o BatchMode=yes
|
||||||
|
-o UserKnownHostsFile=/dev/null
|
||||||
|
-o StrictHostKeyChecking=no
|
||||||
|
-o IdentitiesOnly=yes
|
||||||
|
)
|
||||||
|
|
||||||
|
ssh_args=(
|
||||||
|
${shared_args[*]}
|
||||||
|
-p ${ssh_port}
|
||||||
|
)
|
||||||
|
|
||||||
|
wait_for_ssh() {
|
||||||
|
retries=0
|
||||||
|
retry_count=50
|
||||||
|
|
||||||
|
echo "waiting for machine to come up."
|
||||||
|
echo "tail -F ${qemu_dir}/console.log for progress."
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
set +e
|
||||||
|
ssh -q ${ssh_args[*]} -o ConnectTimeout=1 qemu@localhost "echo done"
|
||||||
|
error=$?
|
||||||
|
set -e
|
||||||
|
if [[ $error == 0 ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ${retries} == ${retry_count} ]]; then
|
||||||
|
echo "timeout"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -n "."
|
||||||
|
((++retries))
|
||||||
|
sleep 10
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
run_ssh() {
|
||||||
|
ssh -q ${ssh_args[*]} qemu@localhost "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
run_scp() {
|
||||||
|
scp -q ${shared_args[*]} -P ${ssh_port} "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
rsync_args=(
|
||||||
|
--exclude '.qemu'
|
||||||
|
--exclude '.git'
|
||||||
|
)
|
||||||
|
|
||||||
|
run_rsync() {
|
||||||
|
rsync -avz -e "ssh ${ssh_args[*]}" ${rsync_args[*]} "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
init_machine() {
|
||||||
|
run_ssh "sudo apt-get -y install --no-install-recommends make gcc autoconf libtool automake"
|
||||||
|
}
|
||||||
|
|
||||||
|
init_machine_and_copy_source() {
|
||||||
|
init_machine
|
||||||
|
run_ssh "rm -fr ~/gf-complete; mkdir -p ~/gf-complete"
|
||||||
|
run_rsync ${script_dir}/.. qemu@localhost:gf-complete
|
||||||
|
run_ssh "cd ~/gf-complete && ./autogen.sh"
|
||||||
|
}
|
||||||
|
|
||||||
|
run_test() {
|
||||||
|
arch=$1; shift
|
||||||
|
cpu=$1; shift
|
||||||
|
test=$1; shift
|
||||||
|
|
||||||
|
run_ssh "~/gf-complete/tools/test_simd.sh ${test}"
|
||||||
|
run_scp qemu@localhost:gf-complete/tools/test_simd.results ${script_dir}/test_simd_${test}_${arch}_${cpu}.results
|
||||||
|
}
|
||||||
|
|
||||||
|
# this test run the unit tests on the machine using "make check"
|
||||||
|
run_test_simd_basic() {
|
||||||
|
arch=$1; shift
|
||||||
|
cpu=$1; shift
|
||||||
|
|
||||||
|
failed=0
|
||||||
|
|
||||||
|
echo "=====starting qemu machine $arch $cpu"
|
||||||
|
start_qemu $arch $cpu
|
||||||
|
init_machine_and_copy_source
|
||||||
|
echo "=====running compile test"
|
||||||
|
{ run_test $arch $cpu "compile" && echo "SUCCESS"; } || { echo "FAILED"; ((++failed)); }
|
||||||
|
echo "=====running unit test"
|
||||||
|
{ run_test $arch $cpu "unit" && echo "SUCCESS"; } || { echo "FAILED"; ((++failed)); }
|
||||||
|
echo "=====running functions test"
|
||||||
|
{ run_test $arch $cpu "functions" && echo "SUCCESS"; } || { echo "FAILED"; ((++failed)); }
|
||||||
|
stop_qemu
|
||||||
|
|
||||||
|
return ${failed}
|
||||||
|
}
|
||||||
|
|
||||||
|
run_all_tests() {
|
||||||
|
failed=0
|
||||||
|
|
||||||
|
echo ============================
|
||||||
|
echo =====running x86_64 tests
|
||||||
|
# NOTE: Broadwell has all the supported SIMD instructions
|
||||||
|
{ run_test_simd_basic "x86_64" "Broadwell" && echo "SUCCESS"; } || { echo "FAILED"; ((++failed)); }
|
||||||
|
|
||||||
|
echo ============================
|
||||||
|
echo =====running aarch64 tests
|
||||||
|
# NOTE: cortex-a57 has ASIMD support
|
||||||
|
{ run_test_simd_basic "aarch64" "cortex-a57" && echo "SUCCESS"; } || { echo "FAILED"; ((++failed)); }
|
||||||
|
|
||||||
|
echo ============================
|
||||||
|
echo =====running arm tests
|
||||||
|
# NOTE: cortex-a15 has NEON support
|
||||||
|
{ run_test_simd_basic "arm" "cortex-a15" && echo "SUCCESS"; } || { echo "FAILED"; ((++failed)); }
|
||||||
|
|
||||||
|
return ${failed}
|
||||||
|
}
|
||||||
|
|
||||||
|
run_all_tests
|
||||||
|
exit $?
|
Loading…
Reference in New Issue