diff src/context.h @ 41:087d7b61c86b

cbc cmake version
author kono
date Sat, 02 Mar 2019 19:01:03 +0900
parents
children 233a68a261fe
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/context.h	Sat Mar 02 19:01:03 2019 +0900
@@ -0,0 +1,453 @@
+/* Context definition for llrb example */
+#ifndef CONTEXT_H
+#define CONTEXT_H
+#include <stdlib.h>
+#include <pthread.h>
+#ifdef USE_CUDAWorker
+#include <cuda.h>
+#include <driver_types.h>
+#include <cuda_runtime.h>
+#include "helper_cuda.h"
+#endif
+
+#define ALLOCATE_SIZE 20000000
+#define NEW(type) (type*)(calloc(1, sizeof(type)))
+#define NEWN(n, type) (type*)(calloc(n, sizeof(type)))
+
+#define ALLOC_DATA(context, dseg) ({\
+    Meta* meta = (Meta*)context->heap;\
+    meta->type = D_##dseg;\
+    meta->size = sizeof(dseg);\
+    meta->len = 1;\
+    context->heap += sizeof(Meta);\
+    context->data[D_##dseg] = context->heap; context->heap += sizeof(dseg); (dseg *)context->data[D_##dseg]; })
+
+#define ALLOC_DATA_TYPE(context, dseg, t) ({\
+    Meta* meta = (Meta*)context->heap;\
+    meta->type = D_##t;\
+    meta->size = sizeof(t);\
+    meta->len = 1;\
+    context->heap += sizeof(Meta);\
+    context->data[D_##dseg] = context->heap; context->heap += sizeof(t); (t *)context->data[D_##dseg]; })
+
+#define ALLOCATE(context, t) ({ \
+    Meta* meta = (Meta*)context->heap;\
+    context->heap += sizeof(Meta);\
+    union Data* data = context->heap; \
+    context->heap += sizeof(t); \
+    meta->type = D_##t; \
+    meta->size = sizeof(t);     \
+    meta->len = 1;\
+    data; })
+
+#define ALLOCATE_ARRAY(context, t, length) ({ \
+    Meta* meta = (Meta*)context->heap;\
+    context->heap += sizeof(Meta);\
+    union Data* data = context->heap; \
+    context->heap += sizeof(t)*length; \
+    meta->type = D_##t; \
+    meta->size = sizeof(t)*length; \
+    meta->len = length; \
+    data;   })
+
+#define ALLOCATE_PTR_ARRAY(context, dseg, length) ({\
+    Meta* meta = (Meta*)context->heap;\
+    context->heap += sizeof(Meta);\
+    union Data* data = context->heap; \
+    context->heap += sizeof(dseg *)*length; \
+    meta->type = D_##dseg; \
+    meta->size = sizeof(dseg *)*length; \
+    meta->len = length; \
+    data; })
+
+#define ALLOCATE_DATA_GEAR(context, t) ({ \
+        union Data* data = ALLOCATE(context, t); \
+        Meta* meta = GET_META(data); \
+        meta->wait = createSynchronizedQueue(context); \
+        data; })
+
+#define ALLOC(context, t) (&ALLOCATE(context, t)->t)
+
+#define GET_META(dseg) ((Meta*)(((void*)dseg) - sizeof(Meta)))
+#define GET_TYPE(dseg) (GET_META(dseg)->type)
+#define GET_SIZE(dseg) (GET_META(dseg)->size)
+#define GET_LEN(dseg) (GET_META(dseg)->len)
+#define GET_WAIT_LIST(dseg) (GET_META(dseg)->wait)
+
+#define Gearef(context, t) (&(context)->data[D_##t]->t)
+
+// (SingleLinkedStack *)context->data[D_Stack]->Stack.stack->Stack.stack
+
+#define GearImpl(context, intf, name) (Gearef(context, intf)->name->intf.name)
+
+#include "c/enumCode.h"
+
+enum Relational {
+    EQ,
+    GT,
+    LT,
+};
+
+#include "c/enumData.h"
+
+struct Context {
+    enum Code next;
+    struct Worker* worker;
+    struct TaskManager* taskManager;
+    int codeNum;
+    __code (**code) (struct Context*);
+    union Data **data;
+    void* heapStart;
+    void* heap;
+    long heapLimit;
+    int dataNum;
+
+    // task parameter
+    int idgCount; //number of waiting dataGear
+    int idg;
+    int maxIdg;
+    int odg;
+    int maxOdg;
+    int gpu; // GPU task
+    struct Context* task;
+    struct Element* taskList;
+#ifdef USE_CUDAWorker
+    int num_exec;
+    CUmodule module;
+    CUfunction function;
+#endif
+    /* multi dimension parameter */
+    int iterate;
+    struct Iterator* iterator;
+    enum Code before;
+};
+
+typedef int Int;
+#ifndef USE_CUDAWorker
+typedef unsigned long long CUdeviceptr;
+#endif
+union Data {
+    struct Meta {
+        enum DataType type;
+        long size;
+        long len;
+        struct Queue* wait; // tasks waiting this dataGear
+    } Meta;
+    struct Context Context;
+    struct Timer {
+        union Data* timer;
+        enum Code start;
+        enum Code end;
+        enum Code next;
+    } Timer;
+    struct TimerImpl {
+        double time;
+    } TimerImpl;
+    struct LoopCounter {
+        int i;
+    } LoopCounter;
+    struct TaskManager {
+        union Data* taskManager;
+        enum Code spawn;      // start NEW context on the worker
+        enum Code spawnTasks; // start NEW tasks on the worker
+        enum Code shutdown;
+        enum Code incrementTaskCount;
+        enum Code decrementTaskCount;
+        enum Code next;
+        enum Code next1;
+        enum Code setWaitTask;
+        struct Context* task;
+        struct Element* taskList;
+        union Data* data;
+    } TaskManager;
+    struct TaskManagerImpl {
+        enum Code next;
+        int numWorker;
+        int sendCPUWorkerIndex;
+        int sendGPUWorkerIndex;
+        int taskCount;
+        pthread_mutex_t mutex;
+        struct Queue* activeQueue;
+        struct Worker** workers;
+        struct Element* taskList;
+        int loopCounter;
+        int cpu;
+        int gpu;
+        int io;
+        int maxCPU;
+    } TaskManagerImpl;
+    struct Worker {
+        union Data* worker;
+        enum Code taskReceive;
+        enum Code shutdown;
+        enum Code next;
+        struct Queue* tasks;
+        pthread_t thread;
+        struct TaskManager* taskManager;
+        struct Context* task;
+    } Worker;
+    struct CPUWorker {
+        pthread_mutex_t mutex;
+        pthread_cond_t cond;
+        struct Context* context;
+        int id;
+        int loopCounter;
+    } CPUWorker;
+#ifdef USE_CUDAWorker
+    struct CUDAWorker {
+        CUdevice device;
+        CUcontext cuCtx;
+        struct Context* context;
+        int id;
+        int loopCounter;
+        int deviceNum;
+        struct Queue* tasks;
+        int runFlag;
+        enum Code next;
+        int numStream;
+        struct Executor* executor;
+        CUstream *stream;
+    } CUDAWorker;
+#else
+    struct CUDAWorker {
+    } CUDAWorker;
+#endif
+    struct Main {
+        enum Code code;
+        enum Code next;
+        struct Queue* args;
+    } Main;
+    // Queue Interface
+    struct Queue {
+        union Data* queue;
+        union Data* data;
+        enum Code whenEmpty;
+        enum Code clear;
+        enum Code put;
+        enum Code take;
+        enum Code isEmpty;
+        enum Code next;
+    } Queue;
+    struct SingleLinkedQueue {
+        struct Element* top;
+        struct Element* last;
+    } SingleLinkedQueue;
+    struct SynchronizedQueue {
+        struct Element* top;
+        struct Element* last;
+        struct Atomic* atomic;
+    } SynchronizedQueue;
+    // Stack Interface
+    struct Stack {
+        union Data* stack;
+        union Data* data;
+        union Data* data1;
+        enum Code whenEmpty;
+        enum Code clear;
+        enum Code push;
+        enum Code pop;
+        enum Code pop2;
+        enum Code isEmpty;
+        enum Code get;
+        enum Code get2;
+        enum Code next;
+    } Stack;
+    // Stack implementations
+    struct SingleLinkedStack {
+        struct Element* top;
+    } SingleLinkedStack;
+    struct ArrayStack {
+        int size;
+        int limit;
+        struct Element* array;
+    } ArrayStack;
+    // Stack implementation end
+    struct Element {
+        union Data* data;
+        struct Element* next;
+    } Element;
+    struct Array {
+        int prefix;
+        Int* array;
+    } Array;
+    struct Tree {
+        union Data* tree;
+        struct Node* node;
+        enum Code put;
+        enum Code get;
+        enum Code remove;
+        enum Code clear;
+        enum Code next;
+    } Tree;
+    struct RedBlackTree {
+        struct Node* root;
+        struct Node* current; // reading node of original tree
+        struct Node* previous; // parent of reading node of original tree
+        struct Node* newNode; // writing node of new tree
+        struct Node* parent;
+        struct Node* grandparent;
+        struct Stack* nodeStack;
+        enum Code findNodeNext;
+        int result;
+    } RedBlackTree;
+    struct RotateTree {
+        enum Code next;
+        struct RedBlackTree* traverse;
+        struct Tree* tree;
+    } RotateTree;
+    struct Node {
+        int key; // comparable data segment
+        union Data* value;
+        struct Node* left;
+        struct Node* right;
+        // need to balancing
+        enum Color {
+            Red,
+            Black,
+            // Red eq 0,Black eq 1. enum name convert intager.
+        } color;
+    } Node;
+    struct Atomic {
+        union Data* atomic;
+        union Data** ptr;
+        union Data* oldData;
+        union Data* newData;
+        enum Code checkAndSet;
+        enum Code next;
+        enum Code fail;
+    } Atomic;
+    struct AtomicReference {
+    } AtomicReference;
+    struct Semaphore {
+        union Data* semaphore;
+        enum Code p;
+        enum Code v;
+        enum Code next;
+    } Semaphore;
+    struct SemaphoreImpl {
+        int value;
+        struct Lock* lock;
+        struct Queue* waitThreadQueue;
+    } SemaphoreImpl;
+    struct Allocate {
+        enum Code next;
+        long size;
+    } Allocate;
+    struct Integer {
+        int value;
+    } Integer;
+    struct SortArray {
+        struct Integer *array; //Array arrayじゃできない?
+        int loopCounter;
+        int block;
+        int first;
+        int prefix;
+    } SortArray;
+    struct Iterator {
+        union Data* iterator;
+        struct Context* task;
+        int numGPU;
+        enum Code exec;
+        enum Code barrier;
+        enum Code whenWait;
+        enum Code next;
+    } Iterator;
+    struct MultiDimIterator {
+        int x;
+        int y;
+        int z;
+        int count;
+        int counterX;
+        int counterY;
+        int counterZ;
+    } MultiDimIterator;
+    struct MultiDim {
+        int x;
+        int y;
+        int z;
+    } MultiDim;
+    struct Executor {
+        union Data* executor;
+        struct Context* task;
+        enum Code read;
+        enum Code exec;
+        enum Code write;
+        enum Code next;
+    } Executor;
+#ifdef USE_CUDAWorker
+    struct CUDAExecutor {
+        CUdeviceptr** kernelParams;
+        struct CUDABuffer* buffer;
+        int maxThreadPerBlock;
+        int maxThreadPerBlockX;
+        int maxThreadPerBlockY;
+        int maxThreadPerBlockZ;
+        struct Timer* timer;
+    } CUDAExecutor;
+    struct CUDABuffer {
+        int inputLen;
+        int outputLen;
+        union Data** inputData;
+        union Data** outputData;
+    } CUDABuffer;
+    CUdeviceptr CUdeviceptr;
+#else
+    struct CUDAExecutor {
+    } CUDAExecutor;
+    struct CUDABuffer {
+    } CUDABuffer;
+    CUdeviceptr CUdeviceptr;
+#endif
+    Int Int;
+    struct Memory {
+        union Data* adr;
+        int length;
+        union Data* body;
+        int hash;
+    } Memory;
+    struct Buffer {
+        union Data* buffer;
+        union Data* data;
+        enum Code put;
+        enum Code take;
+        enum Code next;
+    } Buffer;
+    struct BoundedBuffer {
+        struct Element* top;
+        struct Element* last;
+        struct Semaphore* fullCount;
+        struct Semaphore* emptyCount;
+        struct Semaphore* lock;
+    } BoundedBuffer;
+    struct Lock {
+        union Data* lock;
+        enum Code doLock;
+        enum Code doUnlock;
+        enum Code next;
+    } Lock;
+    struct LockImpl {
+        Int* lock;
+        struct Queue* waitThreadQueue;
+        struct Atomic* atomic;
+        struct Context* lockContext;
+    } LockImpl;
+    struct SpinLock {
+        volatile Int* lock;
+        struct Atomic* atomic;
+        struct Context* lockContext;
+    } SpinLock;
+}; // union Data end       this is necessary for context generator
+typedef union Data Data;
+
+#include "c/typedefData.h"
+
+#include "c/extern.h"
+
+extern __code start_code(struct Context* context);
+extern __code exit_code(struct Context* context);
+extern __code meta(struct Context* context, enum Code next);
+//extern __code par_meta(struct Context* context, enum Code spawns, enum Code next);
+extern __code parGotoMeta(struct Context* context, enum Code next);
+extern void initContext(struct Context* context);
+
+#endif