|
@@ -4,13 +4,19 @@ extern "C" {
|
|
|
#include <event2/event.h>
|
|
#include <event2/event.h>
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+#include <NTL/ZZ_p.h>
|
|
|
|
|
+
|
|
|
#include <vector>
|
|
#include <vector>
|
|
|
#include <pthread.h>
|
|
#include <pthread.h>
|
|
|
#include <stdio.h>
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
|
|
+#include "cudadl.h"
|
|
|
|
|
+
|
|
|
#include "evutils.h"
|
|
#include "evutils.h"
|
|
|
#include "subproblem.h"
|
|
#include "subproblem.h"
|
|
|
|
|
|
|
|
|
|
+NTL_CLIENT
|
|
|
|
|
+
|
|
|
typedef enum {
|
|
typedef enum {
|
|
|
WRKCCSTATE_AWAITCMD,
|
|
WRKCCSTATE_AWAITCMD,
|
|
|
WRKCCSTATE_RDPROBLEM,
|
|
WRKCCSTATE_RDPROBLEM,
|
|
@@ -39,6 +45,51 @@ static struct WrkControllerState {
|
|
|
worker_thread_state(WT_NOT_RUNNING) {}
|
|
worker_thread_state(WT_NOT_RUNNING) {}
|
|
|
} wrkctrlstate;
|
|
} wrkctrlstate;
|
|
|
|
|
|
|
|
|
|
+// ----- Below this line are the functions running in the worker thread.
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+// This function is called from inside cuda_dl for each DP it encounters.
|
|
|
|
|
+// It calls the function named "dpcallback" directly. It would be
|
|
|
|
|
+// cleaner if this were passed as a function pointer to cuda_dl, but
|
|
|
|
|
+// that makes nvcc 3.1 segfault. :-p
|
|
|
|
|
+bool dpcallback(void *cbdata, unsigned short threadId,
|
|
|
|
|
+ unsigned short blockId, unsigned int demux, unsigned int *dpwords,
|
|
|
|
|
+ unsigned int a_0, unsigned int a_1, unsigned int a_2,
|
|
|
|
|
+ unsigned int b_0, unsigned int b_1, unsigned int b_2)
|
|
|
|
|
+{
|
|
|
|
|
+ struct bufferevent *bev =
|
|
|
|
|
+ wrkctrlstate.dpnodes[demux % wrkctrlstate.num_connected_dpnodes];
|
|
|
|
|
+
|
|
|
|
|
+ unsigned char DPbuf[(WORDS+6)*sizeof(unsigned int)];
|
|
|
|
|
+ memmove(DPbuf, dpwords, WORDS*sizeof(unsigned int));
|
|
|
|
|
+ memmove(DPbuf+WORDS*sizeof(unsigned int), &a_0, sizeof(unsigned int));
|
|
|
|
|
+ memmove(DPbuf+(WORDS+1)*sizeof(unsigned int), &a_1, sizeof(unsigned int));
|
|
|
|
|
+ memmove(DPbuf+(WORDS+2)*sizeof(unsigned int), &a_2, sizeof(unsigned int));
|
|
|
|
|
+ memmove(DPbuf+(WORDS+3)*sizeof(unsigned int), &b_0, sizeof(unsigned int));
|
|
|
|
|
+ memmove(DPbuf+(WORDS+4)*sizeof(unsigned int), &b_1, sizeof(unsigned int));
|
|
|
|
|
+ memmove(DPbuf+(WORDS+5)*sizeof(unsigned int), &b_2, sizeof(unsigned int));
|
|
|
|
|
+ bufferevent_write(bev, DPbuf, (WORDS+6)*sizeof(unsigned int));
|
|
|
|
|
+
|
|
|
|
|
+ // If worker_thread_state changes to WT_SHOULD_STOP, then signal to
|
|
|
|
|
+ // stop computation by returning true. If for some reason, it
|
|
|
|
|
+ // becomes WT_NOT_RUNNING (which it shouldn't), stop as well.
|
|
|
|
|
+ return wrkctrlstate.worker_thread_state != WT_RUNNING;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static void *worker_thread_start(void *data)
|
|
|
|
|
+{
|
|
|
|
|
+ ZZ_p::init(wrkctrlstate.current_problem->modulus);
|
|
|
|
|
+ cuda_dl(to_ZZ_p(wrkctrlstate.current_problem->base),
|
|
|
|
|
+ to_ZZ_p(wrkctrlstate.current_problem->target),
|
|
|
|
|
+ wrkctrlstate.current_problem->order,
|
|
|
|
|
+ wrkctrlstate.current_problem->modulus, NULL);
|
|
|
|
|
+
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// ----- Above this line are the functions running in the worker thread.
|
|
|
|
|
+// Below are the functions running in the main (communication) thread.
|
|
|
|
|
+
|
|
|
static void stop_working(void)
|
|
static void stop_working(void)
|
|
|
{
|
|
{
|
|
|
cerr << "Stopping work\n";
|
|
cerr << "Stopping work\n";
|
|
@@ -67,6 +118,12 @@ static void stop_working(void)
|
|
|
static void start_working(void)
|
|
static void start_working(void)
|
|
|
{
|
|
{
|
|
|
cerr << "Starting work\n";
|
|
cerr << "Starting work\n";
|
|
|
|
|
+ wrkctrlstate.worker_thread_state = WT_RUNNING;
|
|
|
|
|
+ if (pthread_create(&wrkctrlstate.worker_thread, NULL,
|
|
|
|
|
+ worker_thread_start, NULL)) {
|
|
|
|
|
+ wrkctrlstate.worker_thread = WT_NOT_RUNNING;
|
|
|
|
|
+ cerr << "Could not start worker thread\n";
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static void dpconn_event_cb(struct bufferevent *bev, short events,
|
|
static void dpconn_event_cb(struct bufferevent *bev, short events,
|
|
@@ -81,8 +138,8 @@ static void dpconn_event_cb(struct bufferevent *bev, short events,
|
|
|
}
|
|
}
|
|
|
} else if (events & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) {
|
|
} else if (events & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) {
|
|
|
fprintf(stderr, "Closing connection to dpnode\n");
|
|
fprintf(stderr, "Closing connection to dpnode\n");
|
|
|
- bufferevent_free(bev);
|
|
|
|
|
stop_working();
|
|
stop_working();
|
|
|
|
|
+ bufferevent_free(bev);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|