Commit 7761438c63e18f380979a3bf5647574243708abd

Authored by Bassam Tabbara
1 parent 87f0d439
Exists in master and in 1 other branch v3

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)
.gitignore
... ... @@ -74,4 +74,5 @@ tools/gf_poly
74 74 tools/gf_time
75 75 tools/gf_unit_w*
76 76 tools/test-suite.log
77   -
  77 +tools/.qemu/
  78 +tools/test_simd*.results
... ...
tools/test_simd.sh 0 → 100755
... ... @@ -0,0 +1,125 @@
  1 +#!/bin/bash -e
  2 +
  3 +# this scripts has a number of tests for SIMD. It can be invoked
  4 +# on the host or on a QEMU machine.
  5 +
  6 +script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
  7 +host_cpu=`uname -p`
  8 +results=${script_dir}/test_simd.results
  9 +
  10 +# runs unit tests and save the results
  11 +test_unit(){
  12 + { ./configure && make clean && make; } || { echo "Compile FAILED" >> ${results}; return 1; }
  13 + make check || { echo "gf_methods $i FAILED" >> ${results}; ((++failed)); }
  14 + cat tools/test-suite.log >> ${results} || true
  15 +}
  16 +
  17 +# build with DEBUG_FUNCTIONS and save all methods selected
  18 +# to a results file
  19 +test_functions() {
  20 + failed=0
  21 +
  22 + { ./configure && make clean && make CFLAGS="-DDEBUG_FUNCTIONS"; } || { echo "Compile FAILED" >> ${results}; return 1; }
  23 + for i in 128 64 32 16 8 4; do
  24 + { ${script_dir}/gf_methods $i -ACD -X >> ${results}; } || { echo "gf_methods $i FAILED" >> ${results}; ((++failed)); }
  25 + done
  26 +
  27 + return ${failed}
  28 +}
  29 +
  30 +compile_arm() {
  31 + failed=0
  32 +
  33 + echo -n "Compiling with NO SIMD support..." >> ${results}
  34 + { ./configure --disable-neon && make clean && make && echo "SUCCESS" >> ${results}; } || { echo "FAIL" >> ${results}; ((++failed)); }
  35 +
  36 + echo -n "Compiling with FULL SIMD support..." >> ${results}
  37 + { ./configure && make clean && make && echo "SUCCESS" >> ${results}; } || { echo "FAIL" >> ${results}; ((++failed)); }
  38 +
  39 + return ${failed}
  40 +}
  41 +
  42 +compile_intel() {
  43 + failed=0
  44 +
  45 + echo -n "Compiling with NO SIMD support..." >> ${results}
  46 + { ./configure && make clean && make && echo "SUCCESS" >> ${results}; } || { echo "FAIL" >> ${results}; ((++failed)); }
  47 +
  48 + echo -n "Compiling with SSE2 only..." >> ${results}
  49 + export ax_cv_have_sse_ext=no
  50 + export ax_cv_have_sse2_ext=yes
  51 + export ax_cv_have_sse3_ext=no
  52 + export ax_cv_have_ssse3_ext=no
  53 + export ax_cv_have_sse41_ext=no
  54 + export ax_cv_have_sse42_ext=no
  55 + export ax_cv_have_pclmuldq_ext=no
  56 + { ./configure && make clean && make && echo "SUCCESS" >> ${results}; } || { echo "FAIL" >> ${results}; ((++failed)); }
  57 +
  58 + echo -n "Compiling with SSE2,SSE3 only..." >> ${results}
  59 + export ax_cv_have_sse_ext=no
  60 + export ax_cv_have_sse2_ext=yes
  61 + export ax_cv_have_sse3_ext=yes
  62 + export ax_cv_have_ssse3_ext=no
  63 + export ax_cv_have_sse41_ext=no
  64 + export ax_cv_have_sse42_ext=no
  65 + export ax_cv_have_pclmuldq_ext=no
  66 + { ./configure && make clean && make && echo "SUCCESS" >> ${results}; } || { echo "FAIL" >> ${results}; ((++failed)); }
  67 +
  68 + echo -n "Compiling with SSE2,SSE3,SSSE3 only..." >> ${results}
  69 + export ax_cv_have_sse_ext=no
  70 + export ax_cv_have_sse2_ext=yes
  71 + export ax_cv_have_sse3_ext=yes
  72 + export ax_cv_have_ssse3_ext=yes
  73 + export ax_cv_have_sse41_ext=no
  74 + export ax_cv_have_sse42_ext=no
  75 + export ax_cv_have_pclmuldq_ext=no
  76 + { ./configure && make clean && make && echo "SUCCESS" >> ${results}; } || { echo "FAIL" >> ${results}; ((++failed)); }
  77 +
  78 + echo -n "Compiling with SSE2,SSE3,SSSE3,SSE4_1 only..." >> ${results}
  79 + export ax_cv_have_sse_ext=no
  80 + export ax_cv_have_sse2_ext=yes
  81 + export ax_cv_have_sse3_ext=yes
  82 + export ax_cv_have_ssse3_ext=yes
  83 + export ax_cv_have_sse41_ext=yes
  84 + export ax_cv_have_sse42_ext=no
  85 + export ax_cv_have_pclmuldq_ext=no
  86 + { ./configure && make clean && make && echo "SUCCESS" >> ${results}; } || { echo "FAIL" >> ${results}; ((++failed)); }
  87 +
  88 + echo -n "Compiling with SSE2,SSE3,SSSE3,SSE4_2 only..." >> ${results}
  89 + export ax_cv_have_sse_ext=no
  90 + export ax_cv_have_sse2_ext=yes
  91 + export ax_cv_have_sse3_ext=yes
  92 + export ax_cv_have_ssse3_ext=yes
  93 + export ax_cv_have_sse41_ext=no
  94 + export ax_cv_have_sse42_ext=yes
  95 + export ax_cv_have_pclmuldq_ext=no
  96 + { ./configure && make clean && make && echo "SUCCESS" >> ${results}; } || { echo "FAIL" >> ${results}; ((++failed)); }
  97 +
  98 + echo -n "Compiling with FULL SIMD support..." >> ${results}
  99 + export ax_cv_have_sse_ext=no
  100 + export ax_cv_have_sse2_ext=yes
  101 + export ax_cv_have_sse3_ext=yes
  102 + export ax_cv_have_ssse3_ext=yes
  103 + export ax_cv_have_sse41_ext=yes
  104 + export ax_cv_have_sse42_ext=yes
  105 + export ax_cv_have_pclmuldq_ext=yes
  106 + { ./configure && make clean && make && echo "SUCCESS" >> ${results}; } || { echo "FAIL" >> ${results}; ((++failed)); }
  107 +
  108 + return ${failed}
  109 +}
  110 +
  111 +# test that we can compile the source code with different
  112 +# SIMD options. We assume that we are running on processor
  113 +# full SIMD support
  114 +test_compile() {
  115 + case $host_cpu in
  116 + aarch64*|arm*) compile_arm ;;
  117 + i[[3456]]86*|x86_64*|amd64*) compile_intel ;;
  118 + esac
  119 +}
  120 +
  121 +cd ${script_dir}/..
  122 +rm -f ${results}
  123 +
  124 +test_$1
  125 +exit $?
... ...
tools/test_simd_qemu.sh 0 → 100755
... ... @@ -0,0 +1,254 @@
  1 +#!/bin/bash -e
  2 +
  3 +# This script will use QEMU to test gf-complete especially SIMD support
  4 +# on different architectures and cpus. It will boot a qemu machine
  5 +# and run an Ubuntu cloud image. All testing will happen inside the
  6 +# QEMU machine.
  7 +
  8 +# The following packages are required:
  9 +# qemu-system-aarch64
  10 +# qemu-system-arm
  11 +# qemu-system-x86_64
  12 +# genisoimage
  13 +
  14 +
  15 +script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
  16 +qemu_dir="${script_dir}/.qemu"
  17 +ssh_port=2222
  18 +ssh_pubkey_file="${qemu_dir}/qemu.pub"
  19 +ssh_key_file="${qemu_dir}/qemu"
  20 +
  21 +mkdir -p "${qemu_dir}"
  22 +
  23 +cleanup() {
  24 + if [[ -n "$(jobs -p)" ]]; then
  25 + echo killing qemu processes "$(jobs -p)"
  26 + kill $(jobs -p)
  27 + fi
  28 +}
  29 +
  30 +trap cleanup EXIT
  31 +
  32 +start_qemu() {
  33 + arch=$1
  34 + cpu=$2
  35 +
  36 + image_version="xenial"
  37 + image_url_base="http://cloud-images.ubuntu.com/${image_version}/current"
  38 +
  39 + case $arch in
  40 + i[[3456]]86*|x86_64*|amd64*)
  41 + image_kernel="${image_version}-server-cloudimg-amd64-vmlinuz-generic"
  42 + image_initrd="${image_version}-server-cloudimg-amd64-initrd-generic"
  43 + image_disk="${image_version}-server-cloudimg-amd64-disk1.img"
  44 + ;;
  45 + aarch64*)
  46 + image_kernel="${image_version}-server-cloudimg-arm64-vmlinuz-generic"
  47 + image_initrd="${image_version}-server-cloudimg-arm64-initrd-generic"
  48 + image_disk="${image_version}-server-cloudimg-arm64-disk1.img"
  49 + ;;
  50 + arm*)
  51 + image_kernel="${image_version}-server-cloudimg-armhf-vmlinuz-lpae"
  52 + image_initrd="${image_version}-server-cloudimg-armhf-initrd-generic-lpae"
  53 + image_disk="${image_version}-server-cloudimg-armhf-disk1.img"
  54 + ;;
  55 + *) die "Unsupported arch" ;;
  56 + esac
  57 +
  58 + [[ -f ${qemu_dir}/${image_kernel} ]] || wget -O ${qemu_dir}/${image_kernel} ${image_url_base}/unpacked/${image_kernel}
  59 + [[ -f ${qemu_dir}/${image_initrd} ]] || wget -O ${qemu_dir}/${image_initrd} ${image_url_base}/unpacked/${image_initrd}
  60 + [[ -f ${qemu_dir}/${image_disk} ]] || wget -O ${qemu_dir}/${image_disk} ${image_url_base}/${image_disk}
  61 +
  62 + #create a delta disk to keep the original image clean
  63 + delta_disk="${qemu_dir}/disk.img"
  64 + rm -f ${delta_disk}
  65 + qemu-img create -q -f qcow2 -b "${qemu_dir}/${image_disk}" ${delta_disk}
  66 +
  67 + # generate an ssh keys
  68 + [[ -f ${ssh_pubkey_file} ]] || ssh-keygen -q -N "" -f ${ssh_key_file}
  69 +
  70 + # create a config disk to set the SSH keys
  71 + cat > "${qemu_dir}/meta-data" <<EOF
  72 +instance-id: qemu
  73 +local-hostname: qemu
  74 +EOF
  75 + cat > "${qemu_dir}/user-data" <<EOF
  76 +#cloud-config
  77 +hostname: qemu
  78 +manage_etc_hosts: true
  79 +users:
  80 + - name: qemu
  81 + ssh-authorized-keys:
  82 + - $(cat "${ssh_pubkey_file}")
  83 + sudo: ['ALL=(ALL) NOPASSWD:ALL']
  84 + groups: sudo
  85 + shell: /bin/bash
  86 +EOF
  87 + genisoimage -quiet -output "${qemu_dir}/cloud.iso" -volid cidata -joliet -rock "${qemu_dir}/user-data" "${qemu_dir}/meta-data"
  88 +
  89 + common_args=( \
  90 + -name "qemu" \
  91 + -m 1024 \
  92 + -nodefaults \
  93 + -nographic \
  94 + -kernel ${qemu_dir}/${image_kernel} \
  95 + -initrd ${qemu_dir}/${image_initrd} \
  96 + -cdrom ${qemu_dir}/cloud.iso \
  97 + -serial file:${qemu_dir}/console.log
  98 + )
  99 +
  100 + case $arch in
  101 + i[[3456]]86*|x86_64*|amd64*)
  102 + qemu-system-x86_64 \
  103 + "${common_args[@]}" \
  104 + -machine accel=kvm -cpu $cpu \
  105 + -append "console=ttyS0 root=/dev/sda1" \
  106 + -hda "${delta_disk}" \
  107 + -net nic,vlan=0,model=virtio \
  108 + -net user,vlan=0,hostfwd=tcp::"${ssh_port}"-:22,hostname="${vm_name}" \
  109 + &
  110 + ;;
  111 + aarch64*|arm*)
  112 + qemu-system-$arch \
  113 + "${common_args[@]}" \
  114 + -machine virt -cpu $cpu -machine type=virt -smp 1 \
  115 + -drive if=none,file="${delta_disk}",id=hd0 \
  116 + -device virtio-blk-device,drive=hd0 \
  117 + -append "console=ttyAMA0 root=/dev/vda1" \
  118 + -netdev user,id=eth0,hostfwd=tcp::"${ssh_port}"-:22,hostname="${vm_name}" \
  119 + -device virtio-net-device,netdev=eth0 \
  120 + &
  121 + ;;
  122 + *) die "Unsupported arch" ;;
  123 + esac
  124 +
  125 + wait_for_ssh
  126 +}
  127 +
  128 +stop_qemu() {
  129 + run_ssh "sudo shutdown now" || true
  130 + wait $(jobs -p)
  131 +}
  132 +
  133 +shared_args=(
  134 + -i ${ssh_key_file}
  135 + -F /dev/null
  136 + -o BatchMode=yes
  137 + -o UserKnownHostsFile=/dev/null
  138 + -o StrictHostKeyChecking=no
  139 + -o IdentitiesOnly=yes
  140 +)
  141 +
  142 +ssh_args=(
  143 + ${shared_args[*]}
  144 + -p ${ssh_port}
  145 +)
  146 +
  147 +wait_for_ssh() {
  148 + retries=0
  149 + retry_count=50
  150 +
  151 + echo "waiting for machine to come up."
  152 + echo "tail -F ${qemu_dir}/console.log for progress."
  153 +
  154 + while true; do
  155 + set +e
  156 + ssh -q ${ssh_args[*]} -o ConnectTimeout=1 qemu@localhost "echo done"
  157 + error=$?
  158 + set -e
  159 + if [[ $error == 0 ]]; then
  160 + return 0
  161 + fi
  162 +
  163 + if [[ ${retries} == ${retry_count} ]]; then
  164 + echo "timeout"
  165 + return 1
  166 + fi
  167 +
  168 + echo -n "."
  169 + ((++retries))
  170 + sleep 10
  171 + done
  172 +}
  173 +
  174 +run_ssh() {
  175 + ssh -q ${ssh_args[*]} qemu@localhost "$@"
  176 +}
  177 +
  178 +run_scp() {
  179 + scp -q ${shared_args[*]} -P ${ssh_port} "$@"
  180 +}
  181 +
  182 +rsync_args=(
  183 + --exclude '.qemu'
  184 + --exclude '.git'
  185 +)
  186 +
  187 +run_rsync() {
  188 + rsync -avz -e "ssh ${ssh_args[*]}" ${rsync_args[*]} "$@"
  189 +}
  190 +
  191 +init_machine() {
  192 + run_ssh "sudo apt-get -y install --no-install-recommends make gcc autoconf libtool automake"
  193 +}
  194 +
  195 +init_machine_and_copy_source() {
  196 + init_machine
  197 + run_ssh "rm -fr ~/gf-complete; mkdir -p ~/gf-complete"
  198 + run_rsync ${script_dir}/.. qemu@localhost:gf-complete
  199 + run_ssh "cd ~/gf-complete && ./autogen.sh"
  200 +}
  201 +
  202 +run_test() {
  203 + arch=$1; shift
  204 + cpu=$1; shift
  205 + test=$1; shift
  206 +
  207 + run_ssh "~/gf-complete/tools/test_simd.sh ${test}"
  208 + run_scp qemu@localhost:gf-complete/tools/test_simd.results ${script_dir}/test_simd_${test}_${arch}_${cpu}.results
  209 +}
  210 +
  211 +# this test run the unit tests on the machine using "make check"
  212 +run_test_simd_basic() {
  213 + arch=$1; shift
  214 + cpu=$1; shift
  215 +
  216 + failed=0
  217 +
  218 + echo "=====starting qemu machine $arch $cpu"
  219 + start_qemu $arch $cpu
  220 + init_machine_and_copy_source
  221 + echo "=====running compile test"
  222 + { run_test $arch $cpu "compile" && echo "SUCCESS"; } || { echo "FAILED"; ((++failed)); }
  223 + echo "=====running unit test"
  224 + { run_test $arch $cpu "unit" && echo "SUCCESS"; } || { echo "FAILED"; ((++failed)); }
  225 + echo "=====running functions test"
  226 + { run_test $arch $cpu "functions" && echo "SUCCESS"; } || { echo "FAILED"; ((++failed)); }
  227 + stop_qemu
  228 +
  229 + return ${failed}
  230 +}
  231 +
  232 +run_all_tests() {
  233 + failed=0
  234 +
  235 + echo ============================
  236 + echo =====running x86_64 tests
  237 + # NOTE: Broadwell has all the supported SIMD instructions
  238 + { run_test_simd_basic "x86_64" "Broadwell" && echo "SUCCESS"; } || { echo "FAILED"; ((++failed)); }
  239 +
  240 + echo ============================
  241 + echo =====running aarch64 tests
  242 + # NOTE: cortex-a57 has ASIMD support
  243 + { run_test_simd_basic "aarch64" "cortex-a57" && echo "SUCCESS"; } || { echo "FAILED"; ((++failed)); }
  244 +
  245 + echo ============================
  246 + echo =====running arm tests
  247 + # NOTE: cortex-a15 has NEON support
  248 + { run_test_simd_basic "arm" "cortex-a15" && echo "SUCCESS"; } || { echo "FAILED"; ((++failed)); }
  249 +
  250 + return ${failed}
  251 +}
  252 +
  253 +run_all_tests
  254 +exit $?
... ...