|
@@ -30,6 +30,7 @@
|
|
|
#include <sys/socket.h>
|
|
#include <sys/socket.h>
|
|
|
#include <cuda_runtime.h>
|
|
#include <cuda_runtime.h>
|
|
|
|
|
|
|
|
|
|
+#include "atomic_iostream.h"
|
|
|
#include "cudadl.h"
|
|
#include "cudadl.h"
|
|
|
|
|
|
|
|
NTL_CLIENT
|
|
NTL_CLIENT
|
|
@@ -112,7 +113,7 @@ bool dpcallback(void *cbdata, unsigned int *dpwords)
|
|
|
// label is "p" or "q", to be printed to report progress.
|
|
// label is "p" or "q", to be printed to report progress.
|
|
|
// Return 0 on failure, 1 on success.
|
|
// Return 0 on failure, 1 on success.
|
|
|
static int p_dl(const ZZ_p &target, const ZZ_p &base, ZZ &exp,
|
|
static int p_dl(const ZZ_p &target, const ZZ_p &base, ZZ &exp,
|
|
|
- const vec_ZZ &fvec, const string &label)
|
|
|
|
|
|
|
+ const vec_ZZ &fvec, const string &label, unsigned int initial_subproblem_id)
|
|
|
{
|
|
{
|
|
|
const int flen = fvec.length();
|
|
const int flen = fvec.length();
|
|
|
|
|
|
|
@@ -129,23 +130,29 @@ static int p_dl(const ZZ_p &target, const ZZ_p &base, ZZ &exp,
|
|
|
curexp = 0;
|
|
curexp = 0;
|
|
|
|
|
|
|
|
for (int i = 0; i < flen; ++i) {
|
|
for (int i = 0; i < flen; ++i) {
|
|
|
- cout << label << " submodulus " << i+1 << " of " << flen << "... ";
|
|
|
|
|
- cout.flush();
|
|
|
|
|
- // Figure out exp mod fvec[i] by taking each side to the power
|
|
|
|
|
- // of phirho/fvec[i] so that we're working in the
|
|
|
|
|
- // subgroup of order fvec[i].
|
|
|
|
|
- ZZ quotient = phip / fvec[i];
|
|
|
|
|
- ZZ_p subgroup_base = power(base, quotient);
|
|
|
|
|
- ZZ_p subgroup_target = power(target, quotient);
|
|
|
|
|
-
|
|
|
|
|
- if (subgroup_base == 1) {
|
|
|
|
|
- // The original base wasn't a generator of the whole group.
|
|
|
|
|
- if (subgroup_target == 1) {
|
|
|
|
|
- cout << "Non-unique solution (mod " << fvec[i] <<")\n";
|
|
|
|
|
- continue;
|
|
|
|
|
- } else {
|
|
|
|
|
- cout << "Target not in subgroup generated by base\n";
|
|
|
|
|
- return 0;
|
|
|
|
|
|
|
+ ZZ quotient;
|
|
|
|
|
+ ZZ_p subgroup_base;
|
|
|
|
|
+ ZZ_p subgroup_target;
|
|
|
|
|
+
|
|
|
|
|
+ {
|
|
|
|
|
+ AtomicWriter atomic_cout(cout);
|
|
|
|
|
+ atomic_cout << label << " submodulus " << i+1 << " of " << flen << "...\n";
|
|
|
|
|
+ // Figure out exp mod fvec[i] by taking each side to the power
|
|
|
|
|
+ // of phirho/fvec[i] so that we're working in the
|
|
|
|
|
+ // subgroup of order fvec[i].
|
|
|
|
|
+ quotient = phip / fvec[i];
|
|
|
|
|
+ subgroup_base = power(base, quotient);
|
|
|
|
|
+ subgroup_target = power(target, quotient);
|
|
|
|
|
+
|
|
|
|
|
+ if (subgroup_base == 1) {
|
|
|
|
|
+ // The original base wasn't a generator of the whole group.
|
|
|
|
|
+ if (subgroup_target == 1) {
|
|
|
|
|
+ atomic_cout << "Non-unique solution (mod " << fvec[i] <<")\n";
|
|
|
|
|
+ continue;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ atomic_cout << "Target not in subgroup generated by base\n";
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -153,7 +160,6 @@ static int p_dl(const ZZ_p &target, const ZZ_p &base, ZZ &exp,
|
|
|
// subgroup_target with base subgroup_base, knowing that it's in
|
|
// subgroup_target with base subgroup_base, knowing that it's in
|
|
|
// the range [0,fvec[i]).
|
|
// the range [0,fvec[i]).
|
|
|
|
|
|
|
|
- cout << "\n";
|
|
|
|
|
ZZ md = ZZ_p::modulus();
|
|
ZZ md = ZZ_p::modulus();
|
|
|
CBData cbdata(subgroup_base, subgroup_target, fvec[i]);
|
|
CBData cbdata(subgroup_base, subgroup_target, fvec[i]);
|
|
|
struct timeval st, et;
|
|
struct timeval st, et;
|
|
@@ -171,6 +177,11 @@ static int p_dl(const ZZ_p &target, const ZZ_p &base, ZZ &exp,
|
|
|
printf("%ld.%06ld seconds elapsed\n", us_elapsed/1000000,
|
|
printf("%ld.%06ld seconds elapsed\n", us_elapsed/1000000,
|
|
|
us_elapsed % 1000000);
|
|
us_elapsed % 1000000);
|
|
|
|
|
|
|
|
|
|
+ AtomicWriter(cout) << "Timing (subproblemid, label, launches): "
|
|
|
|
|
+ << i+initial_subproblem_id << ", "
|
|
|
|
|
+ << label << ", "
|
|
|
|
|
+ << launch_count << "\n" << std::flush;
|
|
|
|
|
+
|
|
|
CRT(curexp, curmodulus, subgroup_dl, fvec[i]);
|
|
CRT(curexp, curmodulus, subgroup_dl, fvec[i]);
|
|
|
// cout << "CRT\n";
|
|
// cout << "CRT\n";
|
|
|
// cout << "curexp = " << curexp << "\n";
|
|
// cout << "curexp = " << curexp << "\n";
|
|
@@ -192,7 +203,7 @@ typedef struct {
|
|
|
|
|
|
|
|
// Behave like p_dl, but do the work in an asynchronous subprocess
|
|
// Behave like p_dl, but do the work in an asynchronous subprocess
|
|
|
static PDLHandle* p_dl_fork_start(const ZZ &p, const ZZ_p &target,
|
|
static PDLHandle* p_dl_fork_start(const ZZ &p, const ZZ_p &target,
|
|
|
- const ZZ_p &base, const vec_ZZ &fvec, const string &label, int deviceid)
|
|
|
|
|
|
|
+ const ZZ_p &base, const vec_ZZ &fvec, const string &label, int deviceid, unsigned int initial_subproblem_id)
|
|
|
{
|
|
{
|
|
|
PDLHandle *handle = new PDLHandle;
|
|
PDLHandle *handle = new PDLHandle;
|
|
|
int fds[2];
|
|
int fds[2];
|
|
@@ -203,6 +214,11 @@ static PDLHandle* p_dl_fork_start(const ZZ &p, const ZZ_p &target,
|
|
|
return NULL;
|
|
return NULL;
|
|
|
}
|
|
}
|
|
|
handle->rfd = fds[0];
|
|
handle->rfd = fds[0];
|
|
|
|
|
+
|
|
|
|
|
+ cout.flush();
|
|
|
|
|
+ cerr.flush();
|
|
|
|
|
+ // flush the output before forking
|
|
|
|
|
+
|
|
|
pid_t childpid = fork();
|
|
pid_t childpid = fork();
|
|
|
if (childpid == -1) {
|
|
if (childpid == -1) {
|
|
|
perror("fork");
|
|
perror("fork");
|
|
@@ -222,10 +238,10 @@ static PDLHandle* p_dl_fork_start(const ZZ &p, const ZZ_p &target,
|
|
|
|
|
|
|
|
cudaError_t cudares = cudaSetDevice(deviceid);
|
|
cudaError_t cudares = cudaSetDevice(deviceid);
|
|
|
if (cudares != cudaSuccess) {
|
|
if (cudares != cudaSuccess) {
|
|
|
- cerr << "Error setting CUDA device: " << cudaGetErrorString(cudares) << "\n";
|
|
|
|
|
|
|
+ AtomicWriter(cerr) << "Error setting CUDA device: " << cudaGetErrorString(cudares) << "\n";
|
|
|
exit(1);
|
|
exit(1);
|
|
|
}
|
|
}
|
|
|
- int res = p_dl(target_p, base_p, exp, fvec, label);
|
|
|
|
|
|
|
+ int res = p_dl(target_p, base_p, exp, fvec, label, initial_subproblem_id);
|
|
|
|
|
|
|
|
if (res) {
|
|
if (res) {
|
|
|
// Write the result back to the parent using wfd
|
|
// Write the result back to the parent using wfd
|
|
@@ -303,8 +319,8 @@ int main(int argc, char **argv)
|
|
|
|
|
|
|
|
PDLHandle *handle_p, *handle_q;
|
|
PDLHandle *handle_p, *handle_q;
|
|
|
|
|
|
|
|
- handle_p = p_dl_fork_start(p, target, base, pfvec, "p", 0);
|
|
|
|
|
- handle_q = p_dl_fork_start(q, target, base, qfvec, "q", 1);
|
|
|
|
|
|
|
+ handle_p = p_dl_fork_start(p, target, base, pfvec, "p", 0, 0);
|
|
|
|
|
+ handle_q = p_dl_fork_start(q, target, base, qfvec, "q", 1, pfvec.length());
|
|
|
res_p = p_dl_fork_join(handle_p, exp_p);
|
|
res_p = p_dl_fork_join(handle_p, exp_p);
|
|
|
res_q = p_dl_fork_join(handle_q, exp_q);
|
|
res_q = p_dl_fork_join(handle_q, exp_q);
|
|
|
|
|
|