flint-sys 0.9.0

Bindings to the FLINT C library
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
/*
    Copyright (C) 2009 William Hart

    This file is part of FLINT.

    FLINT 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 3 of the License, or
    (at your option) any later version.  See <https://www.gnu.org/licenses/>.
*/

#ifndef FLINT_H
#define FLINT_H

#ifndef FLINT_NOSTDIO
# include <stdio.h>
#endif

#ifndef FLINT_NOSTDARG
# include <stdarg.h>
#endif

#include <stddef.h>
#ifdef BUILDING_FLINT
# include "config.h"
#else
# include "flint-config.h"
#endif

#if FLINT_USES_GC
# include "gc.h"
#endif

#if FLINT_WANT_ASSERT
# include <assert.h>
#endif

#ifndef FLINT_DLL
# define FLINT_DLL
#endif

#ifndef alloca
# ifdef __GNUC__
#  define alloca __builtin_alloca
# else
#  ifdef _MSC_VER
#   include <malloc.h>
#   define alloca _alloca
#  else
#   include <alloca.h> /* We assume then that you have alloca.h */
#  endif
# endif
#endif

#ifdef va_start
# define FLINT_HAVE_VA_LIST 1
#endif

#if defined(FILE)       || defined(_FILE_DEFINED) || defined(__DEFINED_FILE) \
 || defined(H_STDIO)    || defined(_H_STDIO)      || defined(_STDIO_H)       \
 || defined(_STDIO_H_)  || defined(__STDIO_H)     || defined(__STDIO_H__)    \
 || defined(__STDIO__)
# define FLINT_HAVE_FILE 1
#endif

#ifdef FLINT_INLINES_C
# define FLINT_INLINE
#else
# define FLINT_INLINE static inline
#endif

#ifdef __cplusplus
extern "C" {
#endif

/* FLINT version number */

#define __FLINT_VERSION @FLINT_MAJOR@
#define __FLINT_VERSION_MINOR @FLINT_MINOR@
#define __FLINT_VERSION_PATCHLEVEL @FLINT_PATCH@
#define FLINT_VERSION "@FLINT_VERSION_FULL@"
#define __FLINT_RELEASE_NUM(a,b,c) ((a)*10000 + (b)*100 + (c))
#define __FLINT_RELEASE __FLINT_RELEASE_NUM(__FLINT_VERSION, __FLINT_VERSION_MINOR, __FLINT_VERSION_PATCHLEVEL)

FLINT_DLL extern char flint_version[];

struct __FLINT_FILE;
typedef struct __FLINT_FILE FLINT_FILE;

#if FLINT_LONG_LONG
typedef unsigned long long int ulong;
typedef long long int slong;
#else
typedef unsigned long int ulong;
typedef long int slong;
#endif

typedef ulong flint_bitcnt_t;
typedef ulong * nn_ptr;
typedef const ulong * nn_srcptr;

#if FLINT_WANT_ASSERT
# define FLINT_ASSERT(param) assert(param)
#else
# define FLINT_ASSERT(param)
#endif

#if defined(__GNUC__)
# define FLINT_FORCE_INLINE static __attribute__((always_inline)) inline
# define FLINT_STATIC_NOINLINE static __attribute__((noinline))
# if !FLINT_WANT_ASSERT
#  define FLINT_UNUSED(x) UNUSED_ ## x __attribute__((unused))
# else
   /* NOTE: This may or may not be required as some function inputs may be used
    * for assertions. */
#  define FLINT_UNUSED(x) x
# endif
# define FLINT_SET_BUT_UNUSED(x) x __attribute__((unused))
# define FLINT_CONST __attribute__ ((const))
# define FLINT_WARN_UNUSED __attribute__((warn_unused_result))
# define FLINT_UNLIKELY(x) __builtin_expect((x),0)
# define FLINT_LIKELY(x) __builtin_expect((x),1)
# define FLINT_CONSTANT_P __builtin_constant_p
# define FLINT_UNREACHABLE __builtin_unreachable()
# define FLINT_RETURNS_NONNULL __attribute__((returns_nonnull))
# define FLINT_MALLOC __attribute__((malloc))
# define FLINT_DEPRECATED __attribute__((deprecated))
#else
# define __attribute__(x)
# if defined(_MSC_VER)
#  define FLINT_FORCE_INLINE static __forceinline
#  define FLINT_UNREACHABLE __assume(0)
# else
#  define FLINT_FORCE_INLINE static inline
#  define FLINT_UNREACHABLE
# endif
# define FLINT_STATIC_NOINLINE static
# define FLINT_UNUSED(x) x
# define FLINT_SET_BUT_UNUSED(x) x
# define FLINT_WARN_UNUSED
# define FLINT_CONST
# define FLINT_UNLIKELY(x) (x)
# define FLINT_LIKELY(x) (x)
# define FLINT_CONSTANT_P(x) 0
# define FLINT_RETURNS_NONNULL
# define FLINT_MALLOC
# define FLINT_DEPRECATED
#endif

#if defined(__cplusplus) || ( __STDC_VERSION__ >= 202300L )
# define FLINT_NORETURN [[noreturn]]
#else
# define FLINT_NORETURN _Noreturn
#endif

#if FLINT_USES_TLS
# if __STDC_VERSION__ < 202300L && !defined(__cplusplus)
#  define FLINT_TLS_PREFIX _Thread_local
# else
#  define FLINT_TLS_PREFIX thread_local
# endif
#else
# define FLINT_TLS_PREFIX
#endif

#if FLINT_LONG_LONG
# define _WORD_FMT "ll"
# define WORD_FMT "%ll"
# define WORD_WIDTH_FMT "%*ll"
# define WORD(xx) (xx##LL)
# define UWORD(xx) (xx##ULL)
#else
# define _WORD_FMT "l"
# define WORD_FMT "%l"
# define WORD_WIDTH_FMT "%*l"
# define WORD(xx) (xx##L)
# define UWORD(xx) (xx##UL)
#endif

#if FLINT_BITS == 64
# define FLINT_D_BITS 53
# define FLINT64 1
# ifndef FLINT_NO_WORDMAC
#  define UWORD_MAX UWORD(18446744073709551615)
#  define UWORD_MIN UWORD(0)
#  define WORD_MAX WORD(9223372036854775807)
#  define WORD_MIN (-WORD_MAX - WORD(1))
# endif
#else
# define FLINT_D_BITS 31
# ifndef FLINT_NO_WORDMAC
#  define UWORD_MAX UWORD(4294967295)
#  define UWORD_MIN UWORD(0)
#  define WORD_MAX WORD(2147483647)
#  define WORD_MIN (-WORD_MAX - WORD(1))
# endif
#endif

/* memory ********************************************************************/

FLINT_WARN_UNUSED FLINT_MALLOC FLINT_RETURNS_NONNULL void * flint_malloc(size_t size);
FLINT_WARN_UNUSED FLINT_RETURNS_NONNULL void * flint_realloc(void * ptr, size_t size);
FLINT_WARN_UNUSED FLINT_RETURNS_NONNULL void * flint_calloc(size_t num, size_t size);
void flint_free(void * ptr);
FLINT_WARN_UNUSED FLINT_MALLOC FLINT_RETURNS_NONNULL void * flint_aligned_alloc(size_t alignment, size_t size);
void flint_aligned_free(void * ptr);

typedef void (*flint_cleanup_function_t)(void);
void flint_register_cleanup_function(flint_cleanup_function_t cleanup_function);
void flint_cleanup(void);
void flint_cleanup_master(void);

void __flint_set_all_memory_functions(
        void * (* alloc_func)(size_t),
        void * (* calloc_func)(size_t, size_t),
        void * (* realloc_func)(void *, size_t),
        void (* free_func)(void *),
        void * (* aligned_alloc_func)(size_t, size_t),
        void (* aligned_free_func)(void *));

void __flint_get_all_memory_functions(
        void * (** alloc_func)(size_t),
        void * (** calloc_func)(size_t, size_t),
        void * (** realloc_func)(void *, size_t),
        void (** free_func)(void *),
        void * (** aligned_alloc_func)(size_t, size_t),
        void (** aligned_free_func)(void *));

void __flint_set_memory_functions(
        void * (* alloc_func)(size_t),
        void * (* calloc_func)(size_t, size_t),
        void * (* realloc_func)(void *, size_t),
        void (* free_func)(void *));

void __flint_get_memory_functions(
        void * (** alloc_func)(size_t),
        void * (** calloc_func)(size_t, size_t),
        void * (** realloc_func)(void *, size_t),
        void (** free_func)(void *));

FLINT_NORETURN void flint_abort(void);

void flint_set_abort(void (*func)(void));

/* threads *******************************************************************/

int flint_get_num_threads(void);
void flint_set_num_threads(int num_threads);
void _flint_set_num_workers(int num_workers);
int flint_set_num_workers(int num_workers);
void flint_reset_num_workers(int max_workers);
int flint_set_thread_affinity(int * cpus, slong length);
int flint_restore_thread_affinity(void);

typedef int thread_pool_handle;

/* randomization and test utilities ******************************************/

FLINT_CONST double flint_test_multiplier(void);

typedef struct
{
    void * __gmp_state;
    ulong __randval;
    ulong __randval2;
}
flint_rand_struct;

typedef flint_rand_struct flint_rand_t[1];

FLINT_INLINE
void flint_rand_init(flint_rand_t state)
{
    state->__gmp_state = NULL;
#if FLINT64
    state->__randval = UWORD(13845646450878251009);
    state->__randval2 = UWORD(13142370077570254774);
#else
    state->__randval = UWORD(4187301858);
    state->__randval2 = UWORD(3721271368);
#endif
}

FLINT_INLINE
void flint_rand_set_seed(flint_rand_t state, ulong seed1, ulong seed2)
{
    state->__randval = seed1;
    state->__randval2 = seed2;
}

FLINT_INLINE
void flint_rand_get_seed(ulong * seed1, ulong * seed2, flint_rand_t state)
{
    *seed1 = state->__randval;
    *seed2 = state->__randval2;
}

/* __gmp_state is deprecated; don't clean it up */
FLINT_INLINE void flint_rand_clear(flint_rand_t FLINT_UNUSED(state)) { }

FLINT_DEPRECATED void _flint_rand_init_gmp_state(flint_rand_t state);
FLINT_DEPRECATED void _flint_rand_clear_gmp_state(flint_rand_t state);
FLINT_DEPRECATED void flint_randinit(flint_rand_t);
FLINT_DEPRECATED void flint_randclear(flint_rand_t);
FLINT_DEPRECATED void flint_randseed(flint_rand_t, ulong, ulong);
FLINT_DEPRECATED void flint_get_randseed(ulong *, ulong *, flint_rand_t);
FLINT_DEPRECATED flint_rand_struct * flint_rand_alloc(void);
FLINT_DEPRECATED void flint_rand_free(flint_rand_struct * state);

/* defined in ulong_extras, but used throughout the test code */
ulong n_randlimb(flint_rand_t);
ulong n_randtest(flint_rand_t);
ulong n_randtest_not_zero(flint_rand_t);
ulong n_randint(flint_rand_t state, ulong limit);

#if FLINT_USES_GC
# define FLINT_GC_INIT() GC_init()
#else
# define FLINT_GC_INIT()
#endif

#define FLINT_TEST_INIT(xxx) \
   flint_rand_t xxx; \
   FLINT_GC_INIT(); \
   flint_rand_init(xxx)

#define FLINT_TEST_CLEAR(xxx) \
   flint_rand_clear(xxx); \
   flint_cleanup_master();

/* comparison macros *********************************************************/

#define FLINT_MAX(x, y) ((x) > (y) ? (x) : (y))
#define FLINT_MIN(x, y) ((x) > (y) ? (y) : (x))
#define FLINT_ABS(x) ((slong)(x) < 0 ? (-(x)) : (x))
#define FLINT_UABS(x) (((slong)(x) < 0) ? (-(ulong)(x)) : ((ulong)(x)))
#define FLINT_SIGN_EXT(x) (-(ulong)((slong)(x) < 0))
#define FLINT_SGN(x) ((0 < (slong)(x)) - ((slong)(x) < 0))
#define FLINT_SWAP(T, x, y) do { T _swap_t = (x); (x) = (y); (y) = _swap_t; } while(0)

/* sorting *******************************************************************/

void flint_merge_sort(void * buf, slong len, slong size, int (* cmp) (const void *, const void *, void *), void * data);
void flint_sort(void * buf, slong len, slong size, int (* cmp) (const void *, const void *, void *), void * data);

/* allocation macros *********************************************************/

#define FLINT_ARRAY_ALLOC(n, T) (T *) flint_malloc((n)*sizeof(T))
#define FLINT_ARRAY_REALLOC(p, n, T) (T *) flint_realloc(p, (n)*sizeof(T))

#define TMP_INIT \
   typedef struct __tmp_struct { \
      void * block; \
      struct __tmp_struct * next; \
   } __tmp_t; \
   __tmp_t * __tmp_root; \
   __tmp_t * __tpx

#define TMP_START \
   __tmp_root = NULL

#ifdef FLINT_WANT_ASSERT
#define TMP_ALLOC(size) \
   (__tpx = (__tmp_t *) alloca(sizeof(__tmp_t)), \
       __tpx->next = __tmp_root, \
       __tmp_root = __tpx, \
       __tpx->block = flint_malloc(size))
#else
#define TMP_ALLOC(size) \
   (((size) > 8192) ? \
      (__tpx = (__tmp_t *) alloca(sizeof(__tmp_t)), \
       __tpx->next = __tmp_root, \
       __tmp_root = __tpx, \
       __tpx->block = flint_malloc(size)) : \
      alloca(size))
#endif

#define TMP_ARRAY_ALLOC(n, T) (T *) TMP_ALLOC((n)*sizeof(T))

#define TMP_END \
   while (__tmp_root) { \
      flint_free(__tmp_root->block); \
      __tmp_root = __tmp_root->next; \
   }

/* downstream support ********************************************************/

#ifdef FLINT_HAVE_VA_LIST
void flint_va_end(va_list vlist);
#endif

/* I/O ***********************************************************************/

int parse_fmt(int * floating, const char * fmt);

int flint_printf(const char * str, ...);
int flint_sprintf(char * s, const char * str, ...);
int flint_snprintf(char * s, size_t n, const char * str, ...);
int flint_scanf(const char * str, ...);
int flint_sscanf(const char * s, const char * str, ...);

#if FLINT_HAVE_VA_LIST
int flint_vprintf(const char * str, va_list ap);
int flint_vsprintf(char * s, const char * str, va_list ap);
int flint_vsnprintf(char * s, size_t n, const char * str, va_list ap);
#endif

#if FLINT_HAVE_FILE
int flint_fprintf(FILE * f, const char * str, ...);
int flint_fscanf(FILE * f, const char * str, ...);
#endif

#if FLINT_HAVE_VA_LIST && FLINT_HAVE_FILE
int flint_vfprintf(FILE * f, const char * str, va_list ap);
#endif

/* exceptions ****************************************************************/

typedef enum
{
   FLINT_ERROR,     /* general error */
   FLINT_OVERFLOW,  /* overflow */
   FLINT_IMPINV,    /* impossible inverse */
   FLINT_DOMERR,    /* domain error */
   FLINT_DIVZERO,   /* divide by zero */
   FLINT_EXPOF,     /* exponent overflow */
   FLINT_INEXACT,   /* inexact error */
   FLINT_TEST_FAIL  /* test fail */
} flint_err_t;

FLINT_NORETURN void flint_throw(flint_err_t exc, const char * msg, ...);

#if FLINT_HAVE_VA_LIST
void flint_set_throw(void (* func)(flint_err_t, const char *, va_list));
#endif

/* FLINT generic type definitions ********************************************/

typedef struct
{
   ulong n;
   ulong ninv;
   flint_bitcnt_t norm;
}
nmod_t;

typedef slong fmpz;
typedef fmpz fmpz_t[1];

typedef struct
{
    fmpz num;
    fmpz den;
}
fmpq;

typedef fmpq fmpq_t[1];

#define fmpq_numref(__x) (&(__x)->num)
#define fmpq_denref(__y) (&(__y)->den)

/* fmpz macros ***************************************************************/

/* The largest bit count for an fmpz to be small */
#define SMALL_FMPZ_BITCOUNT_MAX (FLINT_BITS - 2)

/* Minimum and maximum value for a small fmpz */
#define COEFF_MIN (-((WORD(1) << SMALL_FMPZ_BITCOUNT_MAX) - WORD(1)))
#define COEFF_MAX ((WORD(1) << SMALL_FMPZ_BITCOUNT_MAX) - WORD(1))

/* Conversions between mpz_ptr and fmpz_t */
#define PTR_TO_COEFF(x) (((ulong) (x) >> 2) | (WORD(1) << (FLINT_BITS - 2)))
#define COEFF_TO_PTR(x) ((mpz_ptr) ((ulong) (x) << 2))

#define COEFF_IS_MPZ(x) (((x) >> SMALL_FMPZ_BITCOUNT_MAX) == WORD(1))

/* The minimum number of limbs that the fmpz collector should spit out */
#define MPZ_MIN_ALLOC 2

/* NOTE: Never allocate less than MPZ_MIN_ALLOC */
#define FLINT_MPZ_REALLOC(ptr, sz) ((int) (sz) > ((ptr)->_mp_alloc) ? (mp_ptr) mpz_realloc(ptr, sz) : (ptr)->_mp_d)
#define FLINT_MPZ_REALLOC_TIGHT(ptr, sz) ((mp_ptr) mpz_realloc(ptr, FLINT_MAX(sz, MPZ_MIN_ALLOC)))

#ifdef __cplusplus
}
#endif

#endif