#include "thread_pool.h"
#include "thread_support.h"
#include "fmpz.h"
#include "fmpz_vec.h"
#include "fmpz_mod_vec.h"
#include "fmpz_mod_mat.h"
typedef struct {
fmpz ** Mrows;
fmpz * const * Arows;
slong c;
const fmpz_mod_ctx_struct * ctx;
} _worker_arg;
static void _red_worker(slong i, void * varg)
{
_worker_arg * arg = (_worker_arg *) varg;
_fmpz_mod_vec_set_fmpz_vec(arg->Mrows[i], arg->Arows[i], arg->c, arg->ctx);
}
static void
_fmpz_mod_mat_set_fmpz_mat(fmpz_mod_mat_t M, const fmpz_mat_t A, const fmpz_mod_ctx_t ctx)
{
slong i, r, c;
r = fmpz_mod_mat_nrows(M, ctx);
c = fmpz_mod_mat_ncols(M, ctx);
for (i = 0; i < r; i++)
_fmpz_mod_vec_set_fmpz_vec(M->rows[i], A->rows[i], c, ctx);
}
void fmpz_mod_mat_set_fmpz_mat(fmpz_mod_mat_t M, const fmpz_mat_t A, const fmpz_mod_ctx_t ctx)
{
slong r, c;
slong limit;
r = fmpz_mod_mat_nrows(M, ctx);
c = fmpz_mod_mat_ncols(M, ctx);
limit = fmpz_size(ctx->n) + r + c;
limit = limit < 64 ? 0 : (limit - 64)/64;
limit = FLINT_MIN(limit, r);
if (limit < 2)
{
_fmpz_mod_mat_set_fmpz_mat(M, A, ctx);
}
else
{
_worker_arg arg;
arg.Mrows = M->rows;
arg.Arows = A->rows;
arg.c = c;
arg.ctx = ctx;
flint_parallel_do(_red_worker, &arg, r, limit, FLINT_PARALLEL_UNIFORM);
}
}