xref: /freebsd/contrib/arm-optimized-routines/math/test/runulp.sh (revision dd21556857e8d40f66bf5ad54754d9d52669ebf7)
1#!/bin/bash
2
3# ULP error check script.
4#
5# Copyright (c) 2019-2024, Arm Limited.
6# SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception
7
8#set -x
9set -eu
10
11# cd to bin directory.
12cd "${0%/*}"
13
14rmodes='n u d z'
15#rmodes=n
16flags="${ULPFLAGS:--q}"
17emu="$@"
18
19FAIL=0
20PASS=0
21
22t() {
23    # First argument: routine name
24    routine=$1; shift
25    # Second and third argument: lo and hi bounds
26    # Extra processing needed for bivariate routines
27    IFS=',' read -ra LO <<< "$1"; shift
28    IFS=',' read -ra HI <<< "$1"; shift
29    ITV="${LO[0]} ${HI[0]}"
30    for i in "${!LO[@]}"; do
31	[[ "$i" -eq "0" ]] || ITV="$ITV x ${LO[$i]} ${HI[$i]}"
32    done
33    # Fourth argument: number of test points
34    n=$1; shift
35    # Any remaining arguments forwards directly to ulp tool
36    extra_flags="$@"
37
38    # Read ULP limits, fenv expectation and control values from autogenerated files
39    limits_file=$LIMITS
40    [ $r == "n" ] || limits_file=${limits_file}_nn
41    L=$(grep "^$routine " $limits_file | awk '{print $2}')
42    [ -n "$L" ] || { echo ERROR: Could not determine ULP limit for $routine in $limits_file && false; }
43    cvals=($(grep "^$routine " $CVALS | awk '{print $2}'))
44
45    if grep -q "^$routine$" $DISABLE_FENV; then extra_flags="$extra_flags -f"; fi
46    # Emulate a do-while loop to loop over cvals, but still execute once if it is empty
47    while : ; do
48	# Empty string if we are at the end of cvals array
49	c_arg=""
50	[ -z "${cvals[0]:-}" ] || c_arg="-c ${cvals[0]}"
51	$emu ./ulp -e $L $flags $extra_flags -r $r $c_arg $routine $ITV $n && PASS=$((PASS+1)) || FAIL=$((FAIL+1))
52	# Shift cvals by 1, and break if it is now empty
53	cvals=("${cvals[@]:1}")
54	[ -n "${cvals[0]:-}" ] || break
55    done
56
57    # Run ULP tool
58
59}
60
61check() {
62	$emu ./ulp -f -q "$@"
63}
64
65if [[ $WANT_EXPERIMENTAL_MATH -eq 1 ]] && [[ $WANT_SVE_TESTS -eq 1 ]] && [[ $USE_MPFR -eq 0 ]]; then
66    # No guarantees about powi accuracy, so regression-test for exactness
67    # w.r.t. the custom reference impl in ulp_wrappers.h
68    if [ -z "$FUNC" ] || [ "$FUNC" == "_ZGVsMxvv_powi" ]; then
69	check -q -f -e 0 _ZGVsMxvv_powi  0  inf x  0  1000 100000
70	check -q -f -e 0 _ZGVsMxvv_powi -0 -inf x  0  1000 100000
71	check -q -f -e 0 _ZGVsMxvv_powi  0  inf x -0 -1000 100000
72	check -q -f -e 0 _ZGVsMxvv_powi -0 -inf x -0 -1000 100000
73    fi
74    if [ -z "$FUNC" ] || [ "$FUNC" == "_ZGVsMxvv_powk" ]; then
75	check -q -f -e 0 _ZGVsMxvv_powk  0  inf x  0  1000 100000
76	check -q -f -e 0 _ZGVsMxvv_powk -0 -inf x  0  1000 100000
77	check -q -f -e 0 _ZGVsMxvv_powk  0  inf x -0 -1000 100000
78	check -q -f -e 0 _ZGVsMxvv_powk -0 -inf x -0 -1000 100000
79    fi
80fi
81
82# Test generic routines in all rounding modes
83for r in $rmodes
84do
85  while read F LO HI N
86  do
87	[[ -z $F ]] || t $F $LO $HI $N
88  done << EOF
89$(grep "\b$FUNC\b" $GEN_ITVS)
90EOF
91done
92
93# Only test arch-specific routines in round-to-nearest, with sign of zero ignored (-z flag)
94r=n
95while read F LO HI N
96do
97	[[ -z $F ]] || t $F $LO $HI $N -z
98done << EOF
99$(grep "\b$FUNC\b" $ARCH_ITVS)
100EOF
101
102[ 0 -eq $FAIL ] || {
103	echo "FAILED $FAIL PASSED $PASS"
104	exit 1
105}
106