Skip to content

Commit

Permalink
Simulate file handling in qsieve
Browse files Browse the repository at this point in the history
  • Loading branch information
albinahlback committed Nov 16, 2023
1 parent 32740ea commit 3be9cf7
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 123 deletions.
100 changes: 98 additions & 2 deletions src/qsieve.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,10 @@ typedef struct
RELATION DATA
***************************************************************************/

FLINT_FILE * siqs; /* pointer to file for storing relations */
char * fname; /* name of file used for relations */
char * siqs; /* pointer to storage */
char * siqs_cur; /* pointer to current position in storage */
slong siqs_alloc; /* number of bytes allocated */
slong siqs_size; /* number of bytes used */

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

#define QS_SIQS_SIZE_LEFT(qs_inf) ((slong) ((qs_inf)->siqs + (qs_inf)->siqs_size - (qs_inf)->siqs_cur))
#define QS_SIQS_ALLOC_LEFT(qs_inf) ((slong) ((qs_inf)->siqs + (qs_inf)->siqs_alloc - (qs_inf)->siqs_cur))

#define QS_SIQS_INIT_ALLOC_SIZE (sizeof(char) * (WORD(1) << 25)) /* 32 MB */

#define QS_SIQS_INIT(qs_inf) \
do \
{ \
(qs_inf)->siqs = flint_malloc(QS_SIQS_INIT_ALLOC_SIZE); \
/* Do not set (qs_inf)->siqs_cur */ \
(qs_inf)->siqs_alloc = QS_SIQS_INIT_ALLOC_SIZE; \
(qs_inf)->siqs_size = 0; \
} while (0)
#define QS_SIQS_REALLOC(qs_inf, size) \
do \
{ \
char * __tmp = flint_realloc((qs_inf)->siqs, size); \
(qs_inf)->siqs_cur = __tmp + ((qs_inf)->siqs_cur - (qs_inf)->siqs); \
(qs_inf)->siqs = __tmp; \
(qs_inf)->siqs_alloc = (size); \
} while (0)
#define QS_SIQS_CLEAR(qs_inf) \
do \
{ \
flint_free((qs_inf)->siqs); \
(qs_inf)->siqs = NULL; \
/* Do not clear (qs_inf)->siqs_cur */ \
(qs_inf)->siqs_alloc = 0; \
(qs_inf)->siqs_size = 0; \
} while (0)

#define QS_SIQS_FCLOSE(qs_inf) \
do \
{ \
(qs_inf)->siqs_cur = NULL; \
} while (0)
#define QS_SIQS_FOPEN_R(qs_inf) \
do \
{ \
(qs_inf)->siqs_cur = (qs_inf)->siqs; \
} while (0)
#define QS_SIQS_FOPEN_W(qs_inf) \
do \
{ \
(qs_inf)->siqs_cur = (qs_inf)->siqs; \
(qs_inf)->siqs_size = 0; \
} while (0)
#define QS_SIQS_FOPEN_A(qs_inf) \
do \
{ \
(qs_inf)->siqs_cur = (qs_inf)->siqs + (qs_inf)->siqs_size; \
} while (0)

#define QS_SIQS_FREAD(res, ptr, size, count, qs_inf) \
do \
{ \
slong _max_read \
= FLINT_MIN((slong) (size) * (slong) (count), \
QS_SIQS_SIZE_LEFT(qs_inf)); \
\
memcpy(ptr, (qs_inf)->siqs_cur, _max_read); \
(qs_inf)->siqs_cur += _max_read; \
(res) = _max_read; \
} while (0)
#define QS_SIQS_FREAD_NORES(ptr, size, count, qs_inf) \
do \
{ \
slong __useless; \
QS_SIQS_FREAD(__useless, ptr, size, count, qs_inf); \
} while (0)
#define QS_SIQS_FWRITE(ptr, size, count, qs_inf) \
do \
{ \
slong _write_size = (slong) (size) * (slong) (count); \
\
/* Here we assume that the relation size is always */ \
/* less than QS_SIQS_INIT_ALLOC_SIZE */ \
if (_write_size > QS_SIQS_ALLOC_LEFT(qs_inf)) \
QS_SIQS_REALLOC(qs_inf, 2 * (qs_inf)->siqs_alloc); \
\
memcpy((qs_inf)->siqs_cur, ptr, _write_size); \
(qs_inf)->siqs_cur += _write_size; \
(qs_inf)->siqs_size += _write_size; \
} while (0)

#define QS_SIQS_FSEEK_SEEK_CUR(qs_inf, offset) \
do \
{ \
slong _jump_size \
= FLINT_MIN((slong) (offset), QS_SIQS_SIZE_LEFT(qs_inf)); \
\
(qs_inf)->siqs_cur += _jump_size; \
} while (0)

#ifdef __cplusplus
}
#endif
Expand Down
2 changes: 0 additions & 2 deletions src/qsieve/clear.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,4 @@ void qsieve_clear(qs_t qs_inf)

qs_inf->factor_base = NULL;
qs_inf->sqrts = NULL;

flint_free(qs_inf->fname);
}
72 changes: 7 additions & 65 deletions src/qsieve/factor.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,32 +11,14 @@
(at your option) any later version. See <https://www.gnu.org/licenses/>.
*/

#define _STDC_FORMAT_MACROS

#ifdef __GNUC__
# define strcpy __builtin_strcpy
#else
# include <math.h>
#endif

/* try to get fdopen, mkstemp declared */
#if defined __STRICT_ANSI__
#undef __STRICT_ANSI__
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "thread_support.h"
#include "fmpz.h"
#include "fmpz_factor.h"
#include "fmpz_vec.h"
#include "qsieve.h"

/* Use Windows API for temporary files under MSVC and MinGW */
#if (defined(__WIN32) && !defined(__CYGWIN__)) || defined(_MSC_VER)
#include <windows.h>
#endif

int compare_facs(const void * a, const void * b)
{
fmpz * x = (fmpz *) a;
Expand Down Expand Up @@ -214,41 +196,8 @@ void qsieve_factor(fmpz_factor_t factors, const fmpz_t n)
pthread_mutex_init(&qs_inf->mutex, NULL);
#endif

#if (defined(__WIN32) && !defined(__CYGWIN__)) || defined(_MSC_VER)
if (GetTempPathA(MAX_PATH, temp_path) == 0)
{
flint_printf("Exception (qsieve_factor). GetTempPathA() failed.\n");
flint_abort();
}
/* uUnique = 0 means the we *do* want a unique filename (obviously!). */
if (GetTempFileNameA(temp_path, "siq", /*uUnique*/ 0, qs_inf->fname) == 0)
{
flint_printf("Exception (qsieve_factor). GetTempFileNameA() failed.\n");
flint_abort();
}
qs_inf->siqs = (FLINT_FILE *) fopen(qs_inf->fname, "wb");
if (qs_inf->siqs == NULL)
flint_throw(FLINT_ERROR, "fopen failed\n");
#else
strcpy(qs_inf->fname, "/tmp/siqsXXXXXX"); /* must be shorter than fname_alloc_size in init.c */
fd = mkstemp(qs_inf->fname);
if (fd == -1)
flint_throw(FLINT_ERROR, "mkstemp failed\n");

qs_inf->siqs = (FLINT_FILE *) fdopen(fd, "wb");
if (qs_inf->siqs == NULL)
flint_throw(FLINT_ERROR, "fdopen failed\n");
#endif
/*
* The code here and in large_prime_variant.c opens and closes the file
* qs_inf->fname in several different places. On Windows all file handles
* need to be closed before the file can be removed in cleanup at function
* exit. The invariant that needs to be preserved at each open/close is
* that either
* qs_inf->siqs is NULL and there are no open handles to the file,
* or
* qs_inf->siqs is not NULL and is the *only* open handle to the file.
*/
QS_SIQS_INIT(qs_inf);
QS_SIQS_FOPEN_W(qs_inf);

for (j = qs_inf->small_primes; j < qs_inf->num_primes; j++)
{
Expand Down Expand Up @@ -290,9 +239,7 @@ void qsieve_factor(fmpz_factor_t factors, const fmpz_t n)
{
int ok;

if (fclose((FILE *) qs_inf->siqs))
flint_throw(FLINT_ERROR, "fclose fail\n");
qs_inf->siqs = NULL;
QS_SIQS_FCLOSE(qs_inf);

ok = qsieve_process_relation(qs_inf);

Expand Down Expand Up @@ -406,9 +353,7 @@ void qsieve_factor(fmpz_factor_t factors, const fmpz_t n)

_fmpz_vec_clear(facs, 100);

qs_inf->siqs = (FLINT_FILE *) fopen(qs_inf->fname, "wb");
if (qs_inf->siqs == NULL)
flint_throw(FLINT_ERROR, "fopen fail\n");
QS_SIQS_FOPEN_W(qs_inf);

Check warning on line 356 in src/qsieve/factor.c

View check run for this annotation

Codecov / codecov/patch

src/qsieve/factor.c#L356

Added line #L356 was not covered by tests
qs_inf->num_primes = num_primes; /* linear algebra adjusts this */
goto more_primes; /* factoring failed, may need more primes */
}
Expand Down Expand Up @@ -486,11 +431,8 @@ void qsieve_factor(fmpz_factor_t factors, const fmpz_t n)
flint_give_back_threads(qs_inf->handles, qs_inf->num_handles);

flint_free(sieve);
if (qs_inf->siqs != NULL && fclose((FILE *) qs_inf->siqs))
flint_throw(FLINT_ERROR, "fclose fail\n");
if (remove(qs_inf->fname)) {
flint_throw(FLINT_ERROR, "remove fail\n");
}
QS_SIQS_FCLOSE(qs_inf);
QS_SIQS_CLEAR(qs_inf);
qsieve_clear(qs_inf);
qsieve_linalg_clear(qs_inf);
qsieve_poly_clear(qs_inf);
Expand Down
12 changes: 0 additions & 12 deletions src/qsieve/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,10 @@
#include "fmpz.h"
#include "qsieve.h"

#if (defined(__WIN32) && !defined(__CYGWIN__)) || defined(_MSC_VER)
#include <windows.h>
#endif

void qsieve_init(qs_t qs_inf, const fmpz_t n)
{
size_t fname_alloc_size;
slong i;

#if (defined(__WIN32) && !defined(__CYGWIN__)) || defined(_MSC_VER)
fname_alloc_size = MAX_PATH;
#else
fname_alloc_size = 20;
#endif
qs_inf->fname = (char *) flint_malloc(fname_alloc_size); /* space for filename */

/* store n in struct */
fmpz_init_set(qs_inf->n, n);

Expand Down
Loading

0 comments on commit 3be9cf7

Please sign in to comment.