Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simulate file handling in qsieve #1625

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
}
77 changes: 7 additions & 70 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 All @@ -63,11 +45,6 @@
fmpz_t temp, temp2, X, Y;
slong num_facs;
fmpz * facs;
#if (defined(__WIN32) && !defined(__CYGWIN__)) || defined(_MSC_VER)
char temp_path[MAX_PATH];
#else
int fd;
#endif

if (fmpz_sgn(n) < 0)
{
Expand Down Expand Up @@ -214,41 +191,8 @@
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 +234,7 @@
{
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 +348,7 @@

_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 351 in src/qsieve/factor.c

View check run for this annotation

Codecov / codecov/patch

src/qsieve/factor.c#L351

Added line #L351 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 +426,8 @@
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