arb/acb_dirichlet/platt_multieval_threaded.c

148 lines
4.1 KiB
C
Raw Permalink Normal View History

2020-09-17 13:03:21 -05:00
/*
Copyright (C) 2020 Rudolph
Copyright (C) 2020 D.H.J. Polymath
This file is part of Arb.
Arb 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 2.1 of the License, or
(at your option) any later version. See <http://www.gnu.org/licenses/>.
*/
#include "acb_dirichlet.h"
#include "pthread.h"
2020-11-14 22:54:17 -06:00
slong platt_get_smk_index(slong B, const fmpz_t j, slong prec);
2020-09-25 22:05:59 -05:00
void get_smk_points(slong * res, slong A, slong B);
2020-09-23 16:51:40 -05:00
void _platt_smk(acb_ptr table, acb_ptr startvec, acb_ptr stopvec,
2020-09-25 22:05:59 -05:00
const slong * smk_points, const arb_t t0, slong A, slong B,
2020-11-14 22:54:17 -06:00
const fmpz_t jstart, const fmpz_t jstop, slong mstart, slong mstop,
2020-09-23 16:51:40 -05:00
slong K, slong prec);
2020-09-17 13:03:21 -05:00
void _acb_dirichlet_platt_multieval(arb_ptr out, acb_srcptr S_table,
2020-11-14 22:54:17 -06:00
const arb_t t0, slong A, slong B, const arb_t h, const fmpz_t J,
2020-09-17 13:03:21 -05:00
slong K, slong sigma, slong prec);
typedef struct
{
2020-09-23 16:51:40 -05:00
acb_ptr S;
acb_ptr startvec;
acb_ptr stopvec;
2020-09-25 22:05:59 -05:00
const slong * smk_points;
2020-09-17 13:03:21 -05:00
arb_srcptr t0;
slong A;
slong B;
slong K;
2020-11-14 22:54:17 -06:00
fmpz_t jstart;
fmpz_t jstop;
2020-09-23 16:51:40 -05:00
slong mstart;
slong mstop;
2020-09-17 13:03:21 -05:00
slong prec;
}
platt_smk_arg_t;
static void *
_platt_smk_thread(void * arg_ptr)
{
platt_smk_arg_t *p = (platt_smk_arg_t *) arg_ptr;
2020-09-25 22:05:59 -05:00
_platt_smk(p->S, p->startvec, p->stopvec, p->smk_points, p->t0, p->A, p->B,
2020-09-23 16:51:40 -05:00
p->jstart, p->jstop, p->mstart, p->mstop, p->K, p->prec);
2020-09-17 13:03:21 -05:00
flint_cleanup();
return NULL;
}
2020-09-25 22:05:59 -05:00
2020-09-17 13:03:21 -05:00
void
acb_dirichlet_platt_multieval_threaded(arb_ptr out, const fmpz_t T, slong A,
2020-11-14 22:54:17 -06:00
slong B, const arb_t h, const fmpz_t J, slong K,
slong sigma, slong prec)
2020-09-17 13:03:21 -05:00
{
2020-11-14 22:54:17 -06:00
slong i, num_threads, N;
fmpz * smk_points;
2020-09-17 13:03:21 -05:00
pthread_t * threads;
platt_smk_arg_t * args;
acb_ptr S;
arb_t t0;
2020-11-14 22:54:17 -06:00
fmpz_t threadtasks;
2020-09-17 13:03:21 -05:00
num_threads = flint_get_num_threads();
2020-11-14 22:54:17 -06:00
if (num_threads < 1)
{
flint_printf("no threads available\n");
flint_abort();
}
N = A*B;
fmpz_init(threadtasks);
2020-09-17 13:03:21 -05:00
threads = flint_malloc(sizeof(pthread_t) * num_threads);
args = flint_malloc(sizeof(platt_smk_arg_t) * num_threads);
2020-11-14 22:54:17 -06:00
fmpz_add_si(threadtasks, J, num_threads - 1);
fmpz_tdiv_q_ui(threadtasks, threadtasks, (ulong) num_threads);
smk_points = _fmpz_vec_init(N);
2020-09-17 13:03:21 -05:00
arb_init(t0);
2020-09-25 22:05:59 -05:00
get_smk_points(smk_points, A, B);
2020-09-17 13:03:21 -05:00
arb_set_fmpz(t0, T);
S = _acb_vec_init(K*N);
for (i = 0; i < num_threads; i++)
{
2020-09-23 16:51:40 -05:00
args[i].S = S;
args[i].startvec = _acb_vec_init(K);
args[i].stopvec = _acb_vec_init(K);
2020-09-25 22:05:59 -05:00
args[i].smk_points = smk_points;
2020-09-17 13:03:21 -05:00
args[i].t0 = t0;
args[i].A = A;
args[i].B = B;
args[i].K = K;
args[i].prec = prec;
2020-11-14 22:54:17 -06:00
fmpz_init(args[i].jstart);
fmpz_init(args[i].jstop);
fmpz_mul_si(args[i].jstart, threadtasks, i);
fmpz_add_ui(args[i].jstart, args[i].jstart, 1);
fmpz_mul_si(args[i].jstop, threadtasks, i + 1);
2020-09-23 16:51:40 -05:00
args[i].mstart = platt_get_smk_index(B, args[i].jstart, prec);
args[i].mstop = platt_get_smk_index(B, args[i].jstop, prec);
2020-09-17 13:03:21 -05:00
}
2020-11-14 22:54:17 -06:00
fmpz_set(args[num_threads-1].jstop, J);
2020-09-23 16:51:40 -05:00
args[num_threads-1].mstop = platt_get_smk_index(B, J, prec);
2020-09-17 13:03:21 -05:00
for (i = 0; i < num_threads; i++)
{
pthread_create(&threads[i], NULL, _platt_smk_thread, &args[i]);
}
for (i = 0; i < num_threads; i++)
{
pthread_join(threads[i], NULL);
}
for (i = 0; i < num_threads; i++)
{
2020-09-23 16:51:40 -05:00
slong k;
for (k = 0; k < K; k++)
{
acb_ptr z;
z = S + N*k + args[i].mstart;
acb_add(z, z, args[i].startvec + k, prec);
z = S + N*k + args[i].mstop;
acb_add(z, z, args[i].stopvec + k, prec);
}
_acb_vec_clear(args[i].startvec, K);
_acb_vec_clear(args[i].stopvec, K);
2020-11-14 22:54:17 -06:00
fmpz_clear(args[i].jstart);
fmpz_clear(args[i].jstop);
2020-09-17 13:03:21 -05:00
}
_acb_dirichlet_platt_multieval(out, S, t0, A, B, h, J, K, sigma, prec);
arb_clear(t0);
_acb_vec_clear(S, K*N);
2020-11-14 22:54:17 -06:00
_fmpz_vec_clear(smk_points, N);
2020-09-25 22:05:59 -05:00
2020-09-23 16:51:40 -05:00
flint_free(args);
flint_free(threads);
2020-09-17 13:03:21 -05:00
}