changeset 275:06dab015a54d

GPUWorker
author ikkun
date Wed, 01 Feb 2017 20:24:28 +0900
parents d14eb393023d
children 27bc962020de
files src/parallel_execution/GPUWorker.cbc src/parallel_execution/GPUtwice.cbc
diffstat 2 files changed, 95 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/parallel_execution/GPUWorker.cbc	Wed Feb 01 20:24:28 2017 +0900
@@ -0,0 +1,68 @@
+#include <libkern/OSAtomic.h>
+
+#include "context.h"
+#include "origin_cs.h"
+
+static void start_worker(Worker* worker);
+
+union Data* createGPUWorker(struct Context* context, int id, Queue* queue) {
+    struct Worker* worker = ALLOC(context, Worker);
+    struct GPUWorker* gpuWorker = ALLOC(context, GPUWorker);
+    worker->worker = (union Data*)gpuWorker;
+    worker->tasks = queue;
+    cpuWorker->id = id;
+    worker->taskReceive = C_taskReceiveGPUWorker;
+    worker->shutdown = C_shutdownGPUWorker;
+    pthread_create(&worker->worker->GPUWorker.thread, NULL, (void*)&start_GPUworker, worker);
+    return (union Data*)(worker);
+}
+
+static void start_worker(Worker* worker) {
+    GPUWorker* gpuWorker = (GPUWorker*)worker->worker;
+    gpuWorker->context = NEW(struct Context);
+    initContext(gpuWorker->context);
+    Gearef(gpuWorker->context, Worker)->worker = (union Data*)worker;
+    goto meta(gpuWorker->context, C_taskReceiveGPUWorker);
+}
+
+__code taskReceiveGPUWorker(struct Context* context, Worker* worker, Queue* queue) {
+    queue->queue = (union Data*)worker->tasks;
+    queue->next = C_getTask;
+    goto meta(context, worker->tasks->take);
+}
+
+__code taskReceiveGPUWorker_stub(struct Context* context) {
+    GPUWorker* gpuWorker = (GPUWorker *)GearImpl(context, GPUWorker, gPUworker);
+    pthread_cond_wait(&gpuWorker->cond, &gpuWorker->mutex);
+    goto taskReceiveGPUWorker(context, &Gearef(context, Worker)->worker->Worker, Gearef(context, Queue));
+}
+
+__code getGPUTask(struct Context* context, Worker* worker, struct Context* task) {
+    if (!task)
+        return; // end thread
+    task->worker = worker;
+    context->next = C_taskReceiveGPUWorker; // set CG after task exec
+    goto meta(task, task->next);
+}
+
+__code getGPUTask_stub(struct Context* context) {
+    Worker* worker = &Gearef(context,Worker)->worker->Worker;
+    struct Context* task = &Gearef(context, Queue)->data->Context;
+    goto getGPUTask(context, worker, task);
+}
+
+#ifdef USE_CUDA
+__code twiceGpu(struct Context* context) {
+    cuMemcpyHtoDAsync(context,context,context,context->stream);
+    cuLaunchkanel();
+    cuMemcpyDtoHAsync();
+}
+#endif
+
+__code shutdownWorker(struct Context* context, CPUWorker* worker) {
+}
+
+__code shutdownWorker_stub(struct Context* context) {
+    CPUWorker* worker = (CPUWorker *)GearImpl(context, Worker, worker);
+    goto shutdownWorker(context,worker);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/parallel_execution/GPUtwice.cbc	Wed Feb 01 20:24:28 2017 +0900
@@ -0,0 +1,27 @@
+#include <stdio.h>
+
+#include "context.h"
+#include "origin_cs.h"
+
+__code twice(struct Context* context, struct LoopCounter* loopCounter, int index, int prefix, int* array, struct Context* workerContext) {
+    int i = loopCounter->i;
+    if (i < prefix) {
+        array[i+index*prefix] = array[i+index*prefix]*2;
+        loopCounter->i++;
+
+        goto meta(context, C_twice);
+    }
+
+    loopCounter->i = 0;
+    goto meta(workerContext, workerContext->next);
+}
+
+__code twice_stub(struct Context* context) {
+    struct Context* workerContext = context->worker->worker->CPUWorker.context;
+    //入力のDataGearをGPUにbuffer経由で送る
+    //twiceカーネルが定義されてなければそれをロードする
+    //結果を取ってくるコマンドを入力する
+    //コマンドの終了待ちを行う
+    //continationにそってGPUworkerに戻る
+    goto twice(context, Gearef(context, LoopCounter), 0, 0, NULL, workerContext);
+}