aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/x86_64/fpu
diff options
context:
space:
mode:
authorJoe Ramsay <Joe.Ramsay@arm.com>2023-04-12 14:37:49 +0100
committerSzabolcs Nagy <szabolcs.nagy@arm.com>2023-05-03 12:09:49 +0100
commitcd94326a1326c4e3f1ee7a8d0a161cc0bdcaf07e (patch)
treeac23e68944f7b02293b052910aaa45604d5761c0 /sysdeps/x86_64/fpu
parentcd87e368439ce97d2a2c95894e1851f4c0ff4443 (diff)
downloadglibc-cd94326a1326c4e3f1ee7a8d0a161cc0bdcaf07e.zip
glibc-cd94326a1326c4e3f1ee7a8d0a161cc0bdcaf07e.tar.gz
glibc-cd94326a1326c4e3f1ee7a8d0a161cc0bdcaf07e.tar.bz2
Enable libmvec support for AArch64
This patch enables libmvec on AArch64. The proposed change is mainly implementing build infrastructure to add the new routines to ABI, tests and benchmarks. I have demonstrated how this all fits together by adding implementations for vector cos, in both single and double precision, targeting both Advanced SIMD and SVE. The implementations of the routines themselves are just loops over the scalar routine from libm for now, as we are more concerned with getting the plumbing right at this point. We plan to contribute vector routines from the Arm Optimized Routines repo that are compliant with requirements described in the libmvec wiki. Building libmvec requires minimum GCC 10 for SVE ACLE. To avoid raising the minimum GCC by such a big jump, we allow users to disable libmvec if their compiler is too old. Note that at this point users have to manually call the vector math functions. This seems to be acceptable to some downstream users. Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
Diffstat (limited to 'sysdeps/x86_64/fpu')
-rw-r--r--sysdeps/x86_64/fpu/Makefile2
-rw-r--r--sysdeps/x86_64/fpu/bench-libmvec-arch.h53
-rw-r--r--sysdeps/x86_64/fpu/bench-libmvec-skeleton.c103
3 files changed, 54 insertions, 104 deletions
diff --git a/sysdeps/x86_64/fpu/Makefile b/sysdeps/x86_64/fpu/Makefile
index 7233174..8eb382a 100644
--- a/sysdeps/x86_64/fpu/Makefile
+++ b/sysdeps/x86_64/fpu/Makefile
@@ -94,7 +94,7 @@ endif
$(addprefix $(objpfx)bench-,$(bench-libmvec-double)): $(libmvec-benchtests)
$(addprefix $(objpfx)bench-,$(bench-libmvec-float)): $(libmvec-benchtests)
-bench-libmvec-deps = $(..)sysdeps/x86_64/fpu/bench-libmvec-skeleton.c bench-timing.h Makefile
+bench-libmvec-deps = $(..)benchtests/bench-libmvec-skeleton.c $(..)sysdeps/x86_64/fpu/bench-libmvec-arch.h bench-timing.h Makefile
$(objpfx)bench-float-%.c: $(bench-libmvec-deps)
{ if [ -n "$($*-INCLUDE)" ]; then \
diff --git a/sysdeps/x86_64/fpu/bench-libmvec-arch.h b/sysdeps/x86_64/fpu/bench-libmvec-arch.h
new file mode 100644
index 0000000..41e8fc7
--- /dev/null
+++ b/sysdeps/x86_64/fpu/bench-libmvec-arch.h
@@ -0,0 +1,53 @@
+/* Runtime architecture check for libmvec benchtests. x86_64 version.
+ Copyright (C) 2023 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <stdio.h>
+#include <sys/platform/x86.h>
+
+#define INIT_ARCH() \
+ do \
+ { \
+ if (!supported ()) \
+ return 77; \
+ } \
+ while (0)
+
+static bool
+supported (void)
+{
+#if defined REQUIRE_AVX
+ if (!CPU_FEATURE_ACTIVE (AVX))
+ {
+ printf ("AVX not supported.");
+ return false;
+ }
+#elif defined REQUIRE_AVX2
+ if (!CPU_FEATURE_ACTIVE (AVX2))
+ {
+ printf ("AVX2 not supported.");
+ return false;
+ }
+#elif defined REQUIRE_AVX512F
+ if (!CPU_FEATURE_ACTIVE (AVX512F))
+ {
+ printf ("AVX512F not supported.");
+ return false;
+ }
+#endif
+ return true;
+}
diff --git a/sysdeps/x86_64/fpu/bench-libmvec-skeleton.c b/sysdeps/x86_64/fpu/bench-libmvec-skeleton.c
deleted file mode 100644
index cf2e9e0..0000000
--- a/sysdeps/x86_64/fpu/bench-libmvec-skeleton.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/* Skeleton for libmvec benchmark programs.
- Copyright (C) 2021-2023 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <https://www.gnu.org/licenses/>. */
-
-#include <string.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <time.h>
-#include <inttypes.h>
-#include <bench-timing.h>
-#include <json-lib.h>
-#include <bench-util.h>
-#include <math-tests-arch.h>
-
-#include <bench-util.c>
-#define D_ITERS 10000
-
-int
-main (int argc, char **argv)
-{
- unsigned long i, k;
- timing_t start, end;
- json_ctx_t json_ctx;
-
-#if defined REQUIRE_AVX
- if (!CPU_FEATURE_ACTIVE (AVX))
- {
- printf ("AVX not supported.");
- return 77;
- }
-#elif defined REQUIRE_AVX2
- if (!CPU_FEATURE_ACTIVE (AVX2))
- {
- printf ("AVX2 not supported.");
- return 77;
- }
-#elif defined REQUIRE_AVX512F
- if (!CPU_FEATURE_ACTIVE (AVX512F))
- {
- printf ("AVX512F not supported.");
- return 77;
- }
-#endif
-
- bench_start ();
-
-#ifdef BENCH_INIT
- BENCH_INIT ();
-#endif
-
- json_init (&json_ctx, 2, stdout);
-
- /* Begin function. */
- json_attr_object_begin (&json_ctx, FUNCNAME);
-
- for (int v = 0; v < NUM_VARIANTS; v++)
- {
- double d_total_time = 0;
- timing_t cur;
- for (k = 0; k < D_ITERS; k++)
- {
- TIMING_NOW (start);
- for (i = 0; i < NUM_SAMPLES (v); i++)
- BENCH_FUNC (v, i);
- TIMING_NOW (end);
-
- TIMING_DIFF (cur, start, end);
-
- TIMING_ACCUM (d_total_time, cur);
- }
- double d_total_data_set = D_ITERS * NUM_SAMPLES (v) * STRIDE;
-
- /* Begin variant. */
- json_attr_object_begin (&json_ctx, VARIANT (v));
-
- json_attr_double (&json_ctx, "duration", d_total_time);
- json_attr_double (&json_ctx, "iterations", d_total_data_set);
- json_attr_double (&json_ctx, "mean", d_total_time / d_total_data_set);
-
- /* End variant. */
- json_attr_object_end (&json_ctx);
- }
-
- /* End function. */
- json_attr_object_end (&json_ctx);
-
- return 0;
-}