Mercurial > hg > Papers > 2020 > soto-midterm
diff src/iterateCall.cbc @ 1:73127e0ab57c
(none)
author | soto@cr.ie.u-ryukyu.ac.jp |
---|---|
date | Tue, 08 Sep 2020 18:38:08 +0900 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iterateCall.cbc Tue Sep 08 18:38:08 2020 +0900 @@ -0,0 +1,96 @@ +#include "../context.h" +#interface "Iterator.h" +#interface "TaskManager.h" +#include <stdio.h> + +Iterator* createMultiDimIterator(struct Context* context, int x, int y, int z) { + struct Iterator* iterator = new Iterator(); + struct MultiDimIterator* multiDimIterator = new MultiDimIterator(); + iterator->iterator = (union Data*)multiDimIterator; + iterator->exec = C_execMultiDimIterator; + iterator->barrier = C_barrierMultiDimIterator; + multiDimIterator->x = x; + multiDimIterator->y = y; + multiDimIterator->z = z; + multiDimIterator->count = x * y * z; + multiDimIterator->counterX = 0; + multiDimIterator->counterY = 0; + multiDimIterator->counterZ = 0; + return iterator; +} + +/** + * create iterateTask with index, that copy from task argument + * @return created iterateTask + * @param task task of the copy source + * @x index + */ +struct Context* createMultiDimIterateTask(struct Context* task, int x, int y, int z) { + struct Context* task1 = NEW(struct Context); + initContext(task1); + task1->taskManager = task->taskManager; + task1->next = task->next; + task1->iterate = 1; + task1->iterator = task->iterator; + task1->idgCount = task->idgCount; + task1->idg = task->idg; + task1->maxIdg = task->maxIdg; + for(int i = task1->idg; i < task1->maxIdg; i++) { + task1->data[i] = task->data[i]; + } + + // create index data gear and register input data to iterate task + struct MultiDim* multiDim = &ALLOCATE_DATA_GEAR(task1, MultiDim)->MultiDim; + multiDim->x = x; + multiDim->y = y; + multiDim->z = z; + task1->data[task1->maxIdg++] = (union Data*)multiDim; + task1->odg = task->odg + 1; + task1->maxOdg = task->maxOdg + 1; + for (int i = task1->odg; i < task1->maxOdg; i++) { + task1->data[i] = task->data[i-1]; + } + + return task1; +} + +__code execMultiDimIterator(struct MultiDimIterator* iterator, struct Context* task, int numGPU, __code next(...)) { + // No GPU device + if (numGPU == 0) { + goto execMultiDimIterator1(); + } + task->iterate = 1; + task->gpu = 1; + struct TaskManager* taskManager = task->taskManager; + goto taskManager->spawn(task, next(...)); +} + +__code execMultiDimIterator1(struct MultiDimIterator* iterator, struct Context* task, __code next(...)) { + int x = iterator->counterX; + int y = iterator->counterY; + int z = iterator->counterZ; + struct Context* iterateTask = createMultiDimIterateTask(task, x, y, z); + struct TaskManager* taskManager = task->taskManager; + goto taskManager->spawn(iterateTask, execMultiDimIterator2); +} + +__code execMultiDimIterator2(struct MultiDimIterator* iterator, struct Context* task, __code next(...)) { + if (++iterator->counterX >= iterator->x) { + iterator->counterX = 0; + if (++iterator->counterY >= iterator->y) { + iterator->counterY = 0; + if (++iterator->counterZ >= iterator->z) { + iterator->counterZ = 0; + goto next(...); + } + } + } + goto execMultiDimIterator1(); +} + +__code barrierMultiDimIterator(struct MultiDimIterator* iterator, struct Context* task, __code next(...), __code whenWait(...)) { + if (task->gpu || __sync_fetch_and_sub(&iterator->count, 1) == 1) { + goto next(...); + } + goto whenWait(...); +}