From a9ac126d8d8e4defb450bc8d9374aca4b85f85ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albin=20Ahlb=C3=A4ck?= Date: Sat, 9 Apr 2022 03:27:38 +0200 Subject: [PATCH 1/3] Introduce header arb-defs.h The header is meant to include macros, functions and constants used throughout the whole library. --- Makefile.in | 2 +- arb-defs.h | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++ arb.h | 11 ---- arb_poly.h | 43 --------------- arf.h | 30 ---------- bool_mat.h | 10 +--- dlog.h | 8 +-- fmpr.h | 23 +------- fmpz_extras.h | 14 +---- mag.h | 11 ---- 10 files changed, 153 insertions(+), 147 deletions(-) create mode 100644 arb-defs.h diff --git a/Makefile.in b/Makefile.in index 89d52a08e..07cc1505e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -25,7 +25,7 @@ export SOURCES = LIB_SOURCES = $(wildcard $(patsubst %, %/*.c, $(BUILD_DIRS))) $(patsubst %, %/*.c, $(TEMPLATE_DIRS)) -HEADERS = $(patsubst %, %.h, $(BUILD_DIRS)) +HEADERS = $(patsubst %, %.h, $(BUILD_DIRS)) arb-defs.h OBJS = $(patsubst %.c, build/%.o, $(SOURCES)) LIB_OBJS = $(patsubst %, build/%/*.o, $(BUILD_DIRS)) diff --git a/arb-defs.h b/arb-defs.h new file mode 100644 index 000000000..a4bfbdb3e --- /dev/null +++ b/arb-defs.h @@ -0,0 +1,148 @@ +/* + Copyright (C) 2022 Albin Ahlbäck + Copyright (C) 2022 Fredrik Johansson + + This file is part of Arb. + + Arb is free software: you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License (LGPL) as published + by the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. See . +*/ + +#include "flint/flint.h" + +#ifndef ARB_DEFS_H +#define ARB_DEFS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define __ARB_VERSION 2 +#define __ARB_VERSION_MINOR 22 +#define __ARB_VERSION_PATCHLEVEL 1 + +#define ARB_VERSION "2.22.1" + +#define __ARB_RELEASE (__ARB_VERSION * 10000 + \ + __ARB_VERSION_MINOR * 100 + \ + __ARB_VERSION_PATCHLEVEL) + + +#define TLS_PREFIX FLINT_TLS_PREFIX + +#if defined(_MSC_VER) && defined(ARB_BUILD_DLL) +#define ARB_DLL __declspec(dllexport) +#else +#define ARB_DLL FLINT_DLL +#endif + + +#ifndef flint_abort +#if __FLINT_RELEASE <= 20502 +#define flint_abort abort +#endif +#endif + +#if __FLINT_RELEASE < 20600 +#define flint_bitcnt_t ulong +#endif + + +#define LIMB_ONE ((mp_limb_t) 1) +#define LIMB_ONES (-(mp_limb_t) 1) +#define LIMB_TOP (((mp_limb_t) 1) << (FLINT_BITS - 1)) +#define MASK_LIMB(n, c) ((n) & (LIMB_ONES << (c))) + + +/* FLINT_ABS is unsafe for x = WORD_MIN */ +#define UI_ABS_SI(x) (((slong)(x) < 0) ? (-(ulong)(x)) : ((ulong)(x))) + + +#define nn_mul_2x1(r2, r1, r0, a1, a0, b0) \ + do { \ + mp_limb_t t1; \ + umul_ppmm(r1, r0, a0, b0); \ + umul_ppmm(r2, t1, a1, b0); \ + add_ssaaaa(r2, r1, r2, r1, 0, t1); \ + } while (0) + +#define nn_mul_2x2(r3, r2, r1, r0, a1, a0, b1, b0) \ + do { \ + mp_limb_t t1, t2, t3; \ + umul_ppmm(r1, r0, a0, b0); \ + umul_ppmm(r2, t1, a1, b0); \ + add_ssaaaa(r2, r1, r2, r1, 0, t1); \ + umul_ppmm(t1, t2, a0, b1); \ + umul_ppmm(r3, t3, a1, b1); \ + add_ssaaaa(r3, t1, r3, t1, 0, t3); \ + add_ssaaaa(r2, r1, r2, r1, t1, t2); \ + r3 += r2 < t1; \ + } while (0) + + +#ifndef NEWTON_INIT + +#define NEWTON_INIT(from, to) \ + { \ + slong __steps[FLINT_BITS], __i, __from, __to; \ + __steps[__i = 0] = __to = (to); \ + __from = (from); \ + while (__to > __from) \ + __steps[++__i] = (__to = (__to + 1) / 2); \ + +#define NEWTON_BASECASE(bc_to) { slong bc_to = __to; + +#define NEWTON_END_BASECASE } + +#define NEWTON_LOOP(step_from, step_to) \ + { \ + for (__i--; __i >= 0; __i--) \ + { \ + slong step_from = __steps[__i+1]; \ + slong step_to = __steps[__i]; \ + +#define NEWTON_END_LOOP }} + +#define NEWTON_END } + +#endif + + +ARB_DLL extern const char * arb_version; + +double arb_test_multiplier(void); + +/* counts zero bits in the binary representation of e */ +static __inline__ +int +n_zerobits(mp_limb_t e) +{ + int zeros = 0; + + while (e > 1) + { + zeros += !(e & 1); + e >>= 1; + } + + return zeros; + /* FIXME: Why doesn't the following work? */ +/* #ifdef __GMP_SHORT_LIMB */ +/* return (FLINT_BITS - 1) - __builtin_popcount(e); */ +/* #else */ +/* # ifdef _LONG_LONG_LIMB */ +/* return (FLINT_BITS - 1) - __builtin_popcountll(e); */ +/* # else */ +/* return (FLINT_BITS - 1) - __builtin_popcountl(e); */ +/* # endif */ +/* #endif */ +} + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/arb.h b/arb.h index be5bf85ff..903c239bd 100644 --- a/arb.h +++ b/arb.h @@ -26,17 +26,6 @@ extern "C" { #endif -#define __ARB_VERSION 2 -#define __ARB_VERSION_MINOR 22 -#define __ARB_VERSION_PATCHLEVEL 1 -#define ARB_VERSION "2.22.1" -#define __ARB_RELEASE (__ARB_VERSION * 10000 + \ - __ARB_VERSION_MINOR * 100 + \ - __ARB_VERSION_PATCHLEVEL) - -ARB_DLL extern const char * arb_version; -double arb_test_multiplier(void); - typedef struct { arf_struct mid; diff --git a/arb_poly.h b/arb_poly.h index 1fa2940b2..3d00dae92 100644 --- a/arb_poly.h +++ b/arb_poly.h @@ -730,22 +730,6 @@ arb_poly_allocated_bytes(const arb_poly_t x) /* Macros */ - -/* counts zero bits in the binary representation of e */ -ARB_POLY_INLINE int -n_zerobits(mp_limb_t e) -{ - int zeros = 0; - - while (e > 1) - { - zeros += !(e & 1); - e >>= 1; - } - - return zeros; -} - /* Computes the length of the result when raising a polynomial of length *len* to the power *exp* and truncating to length *trunc*, without overflow. Assumes poly_len >= 1. */ @@ -760,33 +744,6 @@ poly_pow_length(slong poly_len, ulong exp, slong trunc) return FLINT_MIN((slong) lo, trunc); } -#ifndef NEWTON_INIT - -#define NEWTON_INIT(from, to) \ - { \ - slong __steps[FLINT_BITS], __i, __from, __to; \ - __steps[__i = 0] = __to = (to); \ - __from = (from); \ - while (__to > __from) \ - __steps[++__i] = (__to = (__to + 1) / 2); \ - -#define NEWTON_BASECASE(bc_to) { slong bc_to = __to; - -#define NEWTON_END_BASECASE } - -#define NEWTON_LOOP(step_from, step_to) \ - { \ - for (__i--; __i >= 0; __i--) \ - { \ - slong step_from = __steps[__i+1]; \ - slong step_to = __steps[__i]; \ - -#define NEWTON_END_LOOP }} - -#define NEWTON_END } - -#endif - #ifdef __cplusplus } #endif diff --git a/arf.h b/arf.h index 2c193f520..3ab1f74b4 100644 --- a/arf.h +++ b/arf.h @@ -27,12 +27,6 @@ #include "fmpr.h" #include "mag.h" -#ifndef flint_abort -#if __FLINT_RELEASE <= 20502 -#define flint_abort abort -#endif -#endif - #ifdef __cplusplus extern "C" { #endif @@ -439,9 +433,6 @@ arf_init_set_ui(arf_t x, ulong v) } } -/* FLINT_ABS is unsafe for x = WORD_MIN */ -#define UI_ABS_SI(x) (((slong)(x) < 0) ? (-(ulong)(x)) : ((ulong)(x))) - ARF_INLINE void arf_init_set_si(arf_t x, slong v) { @@ -805,27 +796,6 @@ void arf_urandom(arf_t x, flint_rand_t state, slong bits, arf_rnd_t rnd); #define MUL_MPFR_MIN_LIMBS 25 #define MUL_MPFR_MAX_LIMBS 10000 -#define nn_mul_2x1(r2, r1, r0, a1, a0, b0) \ - do { \ - mp_limb_t t1; \ - umul_ppmm(r1, r0, a0, b0); \ - umul_ppmm(r2, t1, a1, b0); \ - add_ssaaaa(r2, r1, r2, r1, 0, t1); \ - } while (0) - -#define nn_mul_2x2(r3, r2, r1, r0, a1, a0, b1, b0) \ - do { \ - mp_limb_t t1, t2, t3; \ - umul_ppmm(r1, r0, a0, b0); \ - umul_ppmm(r2, t1, a1, b0); \ - add_ssaaaa(r2, r1, r2, r1, 0, t1); \ - umul_ppmm(t1, t2, a0, b1); \ - umul_ppmm(r3, t3, a1, b1); \ - add_ssaaaa(r3, t1, r3, t1, 0, t3); \ - add_ssaaaa(r2, r1, r2, r1, t1, t2); \ - r3 += r2 < t1; \ - } while (0) - #define ARF_MPN_MUL(_z, _x, _xn, _y, _yn) \ if ((_xn) == (_yn)) \ { \ diff --git a/bool_mat.h b/bool_mat.h index e35940b6c..3b45fa1e4 100644 --- a/bool_mat.h +++ b/bool_mat.h @@ -21,20 +21,12 @@ #include #include "flint/flint.h" #include "flint/fmpz_mat.h" - -#ifndef flint_abort -#if __FLINT_RELEASE <= 20502 -#define flint_abort abort -#endif -#endif +#include "arb-defs.h" #ifdef __cplusplus extern "C" { #endif -/* currently defined in the arb module, but global to the library */ -double arb_test_multiplier(void); - typedef struct { int *entries; diff --git a/dlog.h b/dlog.h index a00f017e0..0d580d1a7 100644 --- a/dlog.h +++ b/dlog.h @@ -19,15 +19,9 @@ #endif #include "flint/flint.h" - -#ifndef flint_abort -#if __FLINT_RELEASE <= 20502 -#define flint_abort abort -#endif -#endif - #include "flint/ulong_extras.h" #include "flint/nmod_vec.h" +#include "arb-defs.h" #ifdef __cplusplus extern "C" { diff --git a/fmpr.h b/fmpr.h index c6a8c3425..c03edf50a 100644 --- a/fmpr.h +++ b/fmpr.h @@ -22,26 +22,8 @@ #include "flint/flint.h" #include "flint/fmpz.h" #include "flint/fmpq.h" -#if __FLINT_RELEASE < 20600 -#include "flint/config.h" -#else -#include "flint/flint-config.h" -#endif #include "fmpz_extras.h" - -#ifndef flint_abort -#if __FLINT_RELEASE <= 20502 -#define flint_abort abort -#endif -#endif - -#define TLS_PREFIX FLINT_TLS_PREFIX - -#if defined(_MSC_VER) && defined(ARB_BUILD_DLL) -#define ARB_DLL __declspec(dllexport) -#else -#define ARB_DLL FLINT_DLL -#endif +#include "arb-defs.h" #define fmpr_rnd_t int #define FMPR_RND_DOWN 0 @@ -54,9 +36,6 @@ extern "C" { #endif -/* currently defined in the arb module, but global to the library */ -double arb_test_multiplier(void); - static __inline__ int rounds_up(fmpr_rnd_t rnd, int negative) { diff --git a/fmpz_extras.h b/fmpz_extras.h index 0c55f7f6a..168752840 100644 --- a/fmpz_extras.h +++ b/fmpz_extras.h @@ -15,24 +15,12 @@ #include #include "flint/flint.h" #include "flint/fmpz.h" +#include "arb-defs.h" #ifdef __cplusplus extern "C" { #endif -#ifndef flint_abort -#if __FLINT_RELEASE <= 20502 -#define flint_abort abort -#endif -#endif - -#if __FLINT_RELEASE < 20600 -#define flint_bitcnt_t ulong -#endif - -/* currently defined in the arb module, but global to the library */ -double arb_test_multiplier(void); - static __inline__ void fmpz_add_inline(fmpz_t z, const fmpz_t x, const fmpz_t y) { diff --git a/mag.h b/mag.h index 00eb44fa9..3e2991125 100644 --- a/mag.h +++ b/mag.h @@ -24,21 +24,10 @@ #include "flint/fmpz.h" #include "fmpz_extras.h" -#ifndef flint_abort -#if __FLINT_RELEASE <= 20502 -#define flint_abort abort -#endif -#endif - #ifdef __cplusplus extern "C" { #endif -#define LIMB_ONE ((mp_limb_t) 1) -#define LIMB_ONES (-(mp_limb_t) 1) -#define LIMB_TOP (((mp_limb_t) 1) << (FLINT_BITS - 1)) -#define MASK_LIMB(n, c) ((n) & (LIMB_ONES << (c))) - #define MAG_MAX_LAGOM_EXP (COEFF_MAX / 4) #define MAG_MIN_LAGOM_EXP (-MAG_MAX_LAGOM_EXP) From 95007f0c65f653b4df462866ff1de7d4f6646661 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albin=20Ahlb=C3=A4ck?= Date: Sun, 10 Apr 2022 02:57:40 +0200 Subject: [PATCH 2/3] Use popcnt and clz for n_zerobits --- arb-defs.h | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/arb-defs.h b/arb-defs.h index a4bfbdb3e..8748d8c4b 100644 --- a/arb-defs.h +++ b/arb-defs.h @@ -119,25 +119,15 @@ static __inline__ int n_zerobits(mp_limb_t e) { - int zeros = 0; - - while (e > 1) - { - zeros += !(e & 1); - e >>= 1; - } - - return zeros; - /* FIXME: Why doesn't the following work? */ -/* #ifdef __GMP_SHORT_LIMB */ -/* return (FLINT_BITS - 1) - __builtin_popcount(e); */ -/* #else */ -/* # ifdef _LONG_LONG_LIMB */ -/* return (FLINT_BITS - 1) - __builtin_popcountll(e); */ -/* # else */ -/* return (FLINT_BITS - 1) - __builtin_popcountl(e); */ -/* # endif */ -/* #endif */ +#ifdef __GMP_SHORT_LIMB + return FLINT_BITS - __builtin_popcount(e) - __builtin_clz(e); +#else +# ifdef _LONG_LONG_LIMB + return FLINT_BITS - __builtin_popcountll(e) - __builtin_clzll(e); +# else + return FLINT_BITS - __builtin_popcountl(e) - __builtin_clzl(e); +# endif +#endif } From 2e533d2d3e6fc88141c88af0ba485d69db6036af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albin=20Ahlb=C3=A4ck?= Date: Sun, 10 Apr 2022 03:05:36 +0200 Subject: [PATCH 3/3] Document arb-defs.h --- doc/source/arb-defs.rst | 91 +++++++++++++++++++++++++++++++++++++++++ doc/source/index.rst | 10 +++++ 2 files changed, 101 insertions(+) create mode 100644 doc/source/arb-defs.rst diff --git a/doc/source/arb-defs.rst b/doc/source/arb-defs.rst new file mode 100644 index 000000000..36d1272d4 --- /dev/null +++ b/doc/source/arb-defs.rst @@ -0,0 +1,91 @@ +.. _arb-defs: + +**arb-defs.h** -- global definitions for the Arb library +================================================================================ + +The header ``arb-defs.h`` provides macros and functions used throughout the +Arb-library that are not specific for any Arb-types. + + +Types, macros and constants +-------------------------------------------------------------------------------- + +.. macro:: __ARB_VERSION + +.. macro:: __ARB_VERSION_MINOR + +.. macro:: __ARB_VERSION_PATCHLEVEL + + A macro for the major, minor and patch version of Arb, respectively, + represented as an integer. In other words, it gives you the first, second or + third number in the version number. + +.. macro:: ARB_VERSION + + A macro for the version of Arb, represented as a string. + +.. var:: const char * arb_version + + A constant variable equivalence to :macro:`ARB_VERSION`. + +.. macro:: __ARB_RELEASE + + A macro aimed for easily parsing the version number of Arb. It is represented + as an integer defined by + + .. math :: + \mathtt{\_\_ARB\_RELEASE} + = + 10000 \cdot \mathtt{\_\_ARB\_VERSION} + + + 100 \cdot \mathtt{\_\_ARB\_VERSION\_MINOR} + + + \mathtt{\_\_ARB\_VERSION\_PATCHLEVEL} + +.. macro:: LIMB_ONE + + The limb with binary representation `(0 0 \cdots 0 1)_{2}`. + +.. macro:: LIMB_ONES + + The limb with binary representation `(1 1 \cdots 1 1)_{2}`. + +.. macro:: LIMB_TOP + + The limb with binary representation `(1 0 \cdots 0 0)_{2}`. + +.. macro:: MASK_LIMB(n, c) + + A macro for removing the `c` lower ones in the bit representation of `n`. + +.. macro:: UI_ABS_SI(x) + + Returns the absolute value of `x`. + +.. macro:: nn_mul_2x1(r2, r1, r0, a1, a0, b0) + + Given `a = \{a_0, a_1\}` and `b = \{b_0\}`, it sets `r = \{r_0, r_1, r_2\}` + to the product `a \cdot b`. + +.. macro:: nn_mul_2x2(r3, r2, r1, r0, a1, a0, b1, b0) + + Given `a = \{a_0, a_1\}` and `b = \{b_0, b_1\}`, it sets + `r = \{r_0, r_1, r_2, r_3\}` to the product `a \cdot b`. + + +Functions +-------------------------------------------------------------------------------- + +.. function:: double arb_test_multiplier(void) + + Returns the test multiplier. This function is used to determine how many + tests are going to be performed during ``make check``. + +.. function:: int n_zerobits(mp_limb_t e) + + Returns the number of zero bits in the binary representation of `e` *up to + its most significant bit*. + + +.. + vim:spell spelllang=en_us:ts=3:sw=3:tw=80:expandtab: diff --git a/doc/source/index.rst b/doc/source/index.rst index 3b94791ac..a37d6743f 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -100,6 +100,14 @@ Example programs examples.rst +General utilities +:::::::::::::::::::::::::::::::::::: + +.. toctree:: + :maxdepth: 2 + + arb-defs.rst + Floating-point numbers :::::::::::::::::::::::::::::::::::: @@ -248,3 +256,5 @@ Version history history.rst +.. + vim:spell spelllang=en_us:ts=3:sw=3:tw=80:expandtab: