Skip to content

Commit 3e3cf40

Browse files
committed
Simulate file handling in qsieve
1 parent 32740ea commit 3e3cf40

File tree

5 files changed

+133
-128
lines changed

5 files changed

+133
-128
lines changed

src/qsieve.h

+98-2
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,10 @@ typedef struct
167167
RELATION DATA
168168
***************************************************************************/
169169

170-
FLINT_FILE * siqs; /* pointer to file for storing relations */
171-
char * fname; /* name of file used for relations */
170+
char * siqs; /* pointer to storage */
171+
char * siqs_cur; /* pointer to current position in storage */
172+
slong siqs_alloc; /* number of bytes allocated */
173+
slong siqs_size; /* number of bytes used */
172174

173175
slong full_relation; /* number of full relations */
174176
slong num_cycles; /* number of possible full relations from partials */
@@ -420,6 +422,100 @@ uint64_t * block_lanczos(flint_rand_t state, slong nrows,
420422
void qsieve_square_root(fmpz_t X, fmpz_t Y, qs_t qs_inf,
421423
uint64_t * nullrows, slong ncols, slong l, fmpz_t N);
422424

425+
#define QS_SIQS_SIZE_LEFT(qs_inf) ((slong) ((qs_inf)->siqs + (qs_inf)->siqs_size - (qs_inf)->siqs_cur))
426+
#define QS_SIQS_ALLOC_LEFT(qs_inf) ((slong) ((qs_inf)->siqs + (qs_inf)->siqs_alloc - (qs_inf)->siqs_cur))
427+
428+
#define QS_SIQS_INIT_ALLOC_SIZE (sizeof(char) * (WORD(1) << 25)) /* 32 MB */
429+
430+
#define QS_SIQS_INIT(qs_inf) \
431+
do \
432+
{ \
433+
(qs_inf)->siqs = flint_malloc(QS_SIQS_INIT_ALLOC_SIZE); \
434+
/* Do not set (qs_inf)->siqs_cur */ \
435+
(qs_inf)->siqs_alloc = QS_SIQS_INIT_ALLOC_SIZE; \
436+
(qs_inf)->siqs_size = 0; \
437+
} while (0)
438+
#define QS_SIQS_REALLOC(qs_inf, size) \
439+
do \
440+
{ \
441+
char * __tmp = flint_realloc((qs_inf)->siqs, size); \
442+
(qs_inf)->siqs_cur = __tmp + ((qs_inf)->siqs_cur - (qs_inf)->siqs); \
443+
(qs_inf)->siqs = __tmp; \
444+
(qs_inf)->siqs_alloc = (size); \
445+
} while (0)
446+
#define QS_SIQS_CLEAR(qs_inf) \
447+
do \
448+
{ \
449+
flint_free((qs_inf)->siqs); \
450+
(qs_inf)->siqs = NULL; \
451+
/* Do not clear (qs_inf)->siqs_cur */ \
452+
(qs_inf)->siqs_alloc = 0; \
453+
(qs_inf)->siqs_size = 0; \
454+
} while (0)
455+
456+
#define QS_SIQS_FCLOSE(qs_inf) \
457+
do \
458+
{ \
459+
(qs_inf)->siqs_cur = NULL; \
460+
} while (0)
461+
#define QS_SIQS_FOPEN_R(qs_inf) \
462+
do \
463+
{ \
464+
(qs_inf)->siqs_cur = (qs_inf)->siqs; \
465+
} while (0)
466+
#define QS_SIQS_FOPEN_W(qs_inf) \
467+
do \
468+
{ \
469+
(qs_inf)->siqs_cur = (qs_inf)->siqs; \
470+
(qs_inf)->siqs_size = 0; \
471+
} while (0)
472+
#define QS_SIQS_FOPEN_A(qs_inf) \
473+
do \
474+
{ \
475+
(qs_inf)->siqs_cur = (qs_inf)->siqs + (qs_inf)->siqs_size; \
476+
} while (0)
477+
478+
#define QS_SIQS_FREAD(res, ptr, size, count, qs_inf) \
479+
do \
480+
{ \
481+
slong _max_read \
482+
= FLINT_MIN((slong) (size) * (slong) (count), \
483+
QS_SIQS_SIZE_LEFT(qs_inf)); \
484+
\
485+
memcpy(ptr, (qs_inf)->siqs_cur, _max_read); \
486+
(qs_inf)->siqs_cur += _max_read; \
487+
(res) = _max_read; \
488+
} while (0)
489+
#define QS_SIQS_FREAD_NORES(ptr, size, count, qs_inf) \
490+
do \
491+
{ \
492+
slong __useless; \
493+
QS_SIQS_FREAD(__useless, ptr, size, count, qs_inf); \
494+
} while (0)
495+
#define QS_SIQS_FWRITE(ptr, size, count, qs_inf) \
496+
do \
497+
{ \
498+
slong _write_size = (slong) (size) * (slong) (count); \
499+
\
500+
/* Here we assume that the relation size is always */ \
501+
/* less than QS_SIQS_INIT_ALLOC_SIZE */ \
502+
if (_write_size > QS_SIQS_ALLOC_LEFT(qs_inf)) \
503+
QS_SIQS_REALLOC(qs_inf, 2 * (qs_inf)->siqs_alloc); \
504+
\
505+
memcpy((qs_inf)->siqs_cur, ptr, _write_size); \
506+
(qs_inf)->siqs_cur += _write_size; \
507+
(qs_inf)->siqs_size += _write_size; \
508+
} while (0)
509+
510+
#define QS_SIQS_FSEEK_SEEK_CUR(qs_inf, offset) \
511+
do \
512+
{ \
513+
slong _jump_size \
514+
= FLINT_MIN((slong) (offset), QS_SIQS_SIZE_LEFT(qs_inf)); \
515+
\
516+
(qs_inf)->siqs_cur += _jump_size; \
517+
} while (0)
518+
423519
#ifdef __cplusplus
424520
}
425521
#endif

src/qsieve/clear.c

-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,4 @@ void qsieve_clear(qs_t qs_inf)
2323

2424
qs_inf->factor_base = NULL;
2525
qs_inf->sqrts = NULL;
26-
27-
flint_free(qs_inf->fname);
2826
}

src/qsieve/factor.c

+7-70
Original file line numberDiff line numberDiff line change
@@ -11,32 +11,14 @@
1111
(at your option) any later version. See <https://www.gnu.org/licenses/>.
1212
*/
1313

14-
#define _STDC_FORMAT_MACROS
15-
16-
#ifdef __GNUC__
17-
# define strcpy __builtin_strcpy
18-
#else
19-
# include <math.h>
20-
#endif
21-
22-
/* try to get fdopen, mkstemp declared */
23-
#if defined __STRICT_ANSI__
24-
#undef __STRICT_ANSI__
25-
#endif
26-
27-
#include <stdio.h>
2814
#include <stdlib.h>
15+
#include <string.h>
2916
#include "thread_support.h"
3017
#include "fmpz.h"
3118
#include "fmpz_factor.h"
3219
#include "fmpz_vec.h"
3320
#include "qsieve.h"
3421

35-
/* Use Windows API for temporary files under MSVC and MinGW */
36-
#if (defined(__WIN32) && !defined(__CYGWIN__)) || defined(_MSC_VER)
37-
#include <windows.h>
38-
#endif
39-
4022
int compare_facs(const void * a, const void * b)
4123
{
4224
fmpz * x = (fmpz *) a;
@@ -63,11 +45,6 @@ void qsieve_factor(fmpz_factor_t factors, const fmpz_t n)
6345
fmpz_t temp, temp2, X, Y;
6446
slong num_facs;
6547
fmpz * facs;
66-
#if (defined(__WIN32) && !defined(__CYGWIN__)) || defined(_MSC_VER)
67-
char temp_path[MAX_PATH];
68-
#else
69-
int fd;
70-
#endif
7148

7249
if (fmpz_sgn(n) < 0)
7350
{
@@ -214,41 +191,8 @@ void qsieve_factor(fmpz_factor_t factors, const fmpz_t n)
214191
pthread_mutex_init(&qs_inf->mutex, NULL);
215192
#endif
216193

217-
#if (defined(__WIN32) && !defined(__CYGWIN__)) || defined(_MSC_VER)
218-
if (GetTempPathA(MAX_PATH, temp_path) == 0)
219-
{
220-
flint_printf("Exception (qsieve_factor). GetTempPathA() failed.\n");
221-
flint_abort();
222-
}
223-
/* uUnique = 0 means the we *do* want a unique filename (obviously!). */
224-
if (GetTempFileNameA(temp_path, "siq", /*uUnique*/ 0, qs_inf->fname) == 0)
225-
{
226-
flint_printf("Exception (qsieve_factor). GetTempFileNameA() failed.\n");
227-
flint_abort();
228-
}
229-
qs_inf->siqs = (FLINT_FILE *) fopen(qs_inf->fname, "wb");
230-
if (qs_inf->siqs == NULL)
231-
flint_throw(FLINT_ERROR, "fopen failed\n");
232-
#else
233-
strcpy(qs_inf->fname, "/tmp/siqsXXXXXX"); /* must be shorter than fname_alloc_size in init.c */
234-
fd = mkstemp(qs_inf->fname);
235-
if (fd == -1)
236-
flint_throw(FLINT_ERROR, "mkstemp failed\n");
237-
238-
qs_inf->siqs = (FLINT_FILE *) fdopen(fd, "wb");
239-
if (qs_inf->siqs == NULL)
240-
flint_throw(FLINT_ERROR, "fdopen failed\n");
241-
#endif
242-
/*
243-
* The code here and in large_prime_variant.c opens and closes the file
244-
* qs_inf->fname in several different places. On Windows all file handles
245-
* need to be closed before the file can be removed in cleanup at function
246-
* exit. The invariant that needs to be preserved at each open/close is
247-
* that either
248-
* qs_inf->siqs is NULL and there are no open handles to the file,
249-
* or
250-
* qs_inf->siqs is not NULL and is the *only* open handle to the file.
251-
*/
194+
QS_SIQS_INIT(qs_inf);
195+
QS_SIQS_FOPEN_W(qs_inf);
252196

253197
for (j = qs_inf->small_primes; j < qs_inf->num_primes; j++)
254198
{
@@ -290,9 +234,7 @@ void qsieve_factor(fmpz_factor_t factors, const fmpz_t n)
290234
{
291235
int ok;
292236

293-
if (fclose((FILE *) qs_inf->siqs))
294-
flint_throw(FLINT_ERROR, "fclose fail\n");
295-
qs_inf->siqs = NULL;
237+
QS_SIQS_FCLOSE(qs_inf);
296238

297239
ok = qsieve_process_relation(qs_inf);
298240

@@ -406,9 +348,7 @@ void qsieve_factor(fmpz_factor_t factors, const fmpz_t n)
406348

407349
_fmpz_vec_clear(facs, 100);
408350

409-
qs_inf->siqs = (FLINT_FILE *) fopen(qs_inf->fname, "wb");
410-
if (qs_inf->siqs == NULL)
411-
flint_throw(FLINT_ERROR, "fopen fail\n");
351+
QS_SIQS_FOPEN_W(qs_inf);
412352
qs_inf->num_primes = num_primes; /* linear algebra adjusts this */
413353
goto more_primes; /* factoring failed, may need more primes */
414354
}
@@ -486,11 +426,8 @@ void qsieve_factor(fmpz_factor_t factors, const fmpz_t n)
486426
flint_give_back_threads(qs_inf->handles, qs_inf->num_handles);
487427

488428
flint_free(sieve);
489-
if (qs_inf->siqs != NULL && fclose((FILE *) qs_inf->siqs))
490-
flint_throw(FLINT_ERROR, "fclose fail\n");
491-
if (remove(qs_inf->fname)) {
492-
flint_throw(FLINT_ERROR, "remove fail\n");
493-
}
429+
QS_SIQS_FCLOSE(qs_inf);
430+
QS_SIQS_CLEAR(qs_inf);
494431
qsieve_clear(qs_inf);
495432
qsieve_linalg_clear(qs_inf);
496433
qsieve_poly_clear(qs_inf);

src/qsieve/init.c

-12
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,10 @@
1313
#include "fmpz.h"
1414
#include "qsieve.h"
1515

16-
#if (defined(__WIN32) && !defined(__CYGWIN__)) || defined(_MSC_VER)
17-
#include <windows.h>
18-
#endif
19-
2016
void qsieve_init(qs_t qs_inf, const fmpz_t n)
2117
{
22-
size_t fname_alloc_size;
2318
slong i;
2419

25-
#if (defined(__WIN32) && !defined(__CYGWIN__)) || defined(_MSC_VER)
26-
fname_alloc_size = MAX_PATH;
27-
#else
28-
fname_alloc_size = 20;
29-
#endif
30-
qs_inf->fname = (char *) flint_malloc(fname_alloc_size); /* space for filename */
31-
3220
/* store n in struct */
3321
fmpz_init_set(qs_inf->n, n);
3422

0 commit comments

Comments
 (0)