Mercurial > hg > Members > Moririn
changeset 372:d6ce4273e7d1
Add dimension task spawn
author | Tatsuki IHA <innparusu@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 11 Jul 2017 17:47:11 +0900 |
parents | c3a7a086e82a |
children | 03fdea4ef680 |
files | src/parallel_execution/CPUWorker.cbc src/parallel_execution/TaskManagerImpl.cbc src/parallel_execution/context.h src/parallel_execution/generate_stub.pl |
diffstat | 4 files changed, 84 insertions(+), 116 deletions(-) [+] |
line wrap: on
line diff
--- a/src/parallel_execution/CPUWorker.cbc Fri Jul 07 14:58:26 2017 +0900 +++ b/src/parallel_execution/CPUWorker.cbc Tue Jul 11 17:47:11 2017 +0900 @@ -88,8 +88,9 @@ } __code odgCommit3(struct TaskManager* taskManager, struct Context* task) { - if(__sync_fetch_and_sub(&task->idgCount, 1)) { - if(task->idgCount == 0) { + int idgCount = task->idgCount; + if(__sync_bool_compare_and_swap(&task->idgCount, idgCount, idgCount-1)) { // atomic decrement idg counter + if(idgCount-1 == 0) { taskManager->taskManager = (union Data*)task->taskManager; taskManager->context = task; taskManager->next = C_odgCommit1;
--- a/src/parallel_execution/TaskManagerImpl.cbc Fri Jul 07 14:58:26 2017 +0900 +++ b/src/parallel_execution/TaskManagerImpl.cbc Tue Jul 11 17:47:11 2017 +0900 @@ -27,6 +27,23 @@ return taskManager; } +struct Context* cloneTask(struct Context* task) { + struct Context* task1 = NEW(struct Context); + task1->next = task->next; + + for(int i = task->idg; i < task->maxOdg; i++) { + task1->data[i] = task->data[i]; + } + + task1->dim = 0; + task1->idgCount = 0; + task1->idg = task->idg; + task1->maxIdg = task->maxIdg; + task1->odg = task->odg; + task1->maxOdg = task->maxOdg; + return task1; +} + void createWorkers(struct Context* context, TaskManager* taskManager, TaskManagerImpl* taskManagerImpl) { int i = 0; taskManagerImpl->workers = (Worker**)ALLOC_ARRAY(context, Worker, taskManager->maxCPU); @@ -53,14 +70,14 @@ } } -__code spawnTasksTaskManager(struct TaskManager* taskManager, struct TaskManagerImpl* taskManagerImpl, struct Context** contexts) { +__code spawnTasksTaskManager(struct TaskManager* taskManager, struct TaskManagerImpl* taskManagerImpl, struct Context** tasks) { int i = taskManagerImpl->loopCounter->i; - struct Context* task = contexts[i]; - if(i < GET_SIZE(contexts)) { + if(i < GET_SIZE(tasks)) { + struct Context* task = tasks[i]; taskManagerImpl->loopCounter->i++; taskManager->context = task; taskManager->next = C_spawnTasksTaskManager; - goto meta(context, C_setWorker); + goto meta(context, C_setWaitTask); } taskManagerImpl->loopCounter->i = 0; goto meta(context, C_spawnTasksTaskManager1); @@ -74,10 +91,10 @@ Gearef(context, TaskManager)->contexts); } -__code spawnTasksTaskManager1(struct TaskManager* taskManager, struct TaskManagerImpl* taskManagerImpl, struct Context** contexts, __code next(...)) { +__code spawnTasksTaskManager1(struct TaskManager* taskManager, struct TaskManagerImpl* taskManagerImpl, struct Context** tasks, __code next(...)) { int i = taskManagerImpl->loopCounter->i; - struct Context* task = contexts[i]; - if(i < GET_SIZE(contexts)) { + if(i < GET_SIZE(tasks)) { + struct Context* task = tasks[i]; taskManagerImpl->loopCounter->i++; taskManager->context = task; taskManager->next = C_spawnTasksTaskManager1; @@ -96,26 +113,13 @@ Gearef(context, TaskManager)->next1); } -__code setWorker(struct TaskManagerImpl* taskManager, struct Context* task) { - task->workerId = taskManager->sendWorkerIndex; - if(++taskManager->sendWorkerIndex >= taskManager->numWorker) { - taskManager->sendWorkerIndex = 0; - } - goto meta(context, C_setWaitTask); -} - -__code setWorker_stub(struct Context* context) { - TaskManagerImpl* taskManager = (TaskManagerImpl*)GearImpl(context, TaskManager, taskManager); - goto setWorker(context, taskManager, Gearef(context, TaskManager)->context); -} - -__code setWaitTask(struct Queue* queue, struct Context* task, struct LoopCounter* loopCounter, __code next(...)) { +__code setWaitTask(struct Queue* queue, struct LoopCounter* loopCounter, struct Context* task, __code next(...)) { int i = loopCounter->i; - if(task->idg + i < task->maxIdg) { - loopCounter->i++; + if(task->idg+i < task->maxIdg) { queue->queue = (Data *)GET_WAIT_LIST(task->data[task->idg + i]); - queue->next = C_setWaitTask; - queue->data = (Data *)task; + queue->next = C_setWaitTask; + queue->data = (Data *)task; + loopCounter->i++; goto meta(context, queue->queue->Queue.put); } loopCounter->i = 0; @@ -124,11 +128,52 @@ __code setWaitTask_stub(struct Context* context) { struct Context* task = Gearef(context, TaskManager)->context; - goto setWaitTask(context, Gearef(context, Queue), task, Gearef(task, LoopCounter), Gearef(context, TaskManager)->next); + goto setWaitTask(context, + Gearef(context, Queue), + Gearef(task, LoopCounter), + task, + Gearef(context, TaskManager)->next); +} + +__code dimensionTaskSpawn(struct TaskManagerImpl* taskManager, struct Queue* queue, struct LoopCounter* loopCounter, struct Context* task, __code next(...)) { + int i = loopCounter->i; + int dimCount = task->x * task->y * task->z; + // TODO: implement 3-dimension + if(i < dimCount) { + loopCounter->i++; + struct Context* dimTask = cloneTask(task); + task->workerId = taskManager->sendWorkerIndex; + struct Queue* tasks = taskManager->workers[task->workerId]->tasks; + queue->queue = (union Data*)tasks; + queue->data = (union Data*)dimTask; + queue->next = C_dimensionTaskSpawn; + pthread_mutex_unlock(&taskManager->mutex); + goto meta(context, tasks->put); + } + goto next(...); +} + +__code dimensionTaskSpawn_stub(struct Context* context) { + TaskManagerImpl* taskManager = (TaskManagerImpl*)GearImpl(context, TaskManager, taskManager); + struct Context* task = Gearef(context, TaskManager)->context; + goto dimensionTaskSpawn(context, + taskManager, + Gearef(context, Queue), + Gearef(task, LoopCounter), + task, + Gearef(context, TaskManager)->next); } __code spawnTaskManager(struct TaskManagerImpl* taskManager, struct Context* task, __code next(...)) { if (task->idgCount == 0) { + if(context->dim) { + goto meta(context, C_dimensionTaskSpawn); + } + // set workerId + task->workerId = taskManager->sendWorkerIndex; + if(++taskManager->sendWorkerIndex >= taskManager->numWorker) { + taskManager->sendWorkerIndex = 0; + } goto meta(context, C_taskSend); } else { pthread_mutex_unlock(&taskManager->mutex);
--- a/src/parallel_execution/context.h Fri Jul 07 14:58:26 2017 +0900 +++ b/src/parallel_execution/context.h Tue Jul 11 17:47:11 2017 +0900 @@ -94,6 +94,13 @@ CUfunction function; #endif union Data **data; + + /* multi dimension parameter */ + struct Context* contexts; + int dim; + int x; + int y; + int z; }; union Data {
--- a/src/parallel_execution/generate_stub.pl Fri Jul 07 14:58:26 2017 +0900 +++ b/src/parallel_execution/generate_stub.pl Tue Jul 11 17:47:11 2017 +0900 @@ -38,59 +38,21 @@ my %outputArgs; # continuation's output variables my %dataGear; my %dataGearName; -my %generic; -my %dataGearVarType; my $implementation; my $interface; -# interface definision -# -# typedef struct Stack<Type, Impl>{ -# Type* stack; -# Type* data; -# Type* data1; -# __code whenEmpty(...); -# __code clear(Impl* stack,__code next(...)); -# __code push(Impl* stack,Type* data, __code next(...)); -# __code pop(Impl* stack, __code next(Type*, ...)); -# __code pop2(Impl* stack, Type** data, Type** data1, __code next(Type**, Type**, ...)); -# __code isEmpty(Impl* stack, __code next(...), __code whenEmpty(...)); -# __code get(Impl* stack, Type** data, __code next(...)); -# __code get2(Impl* stack,..., __code next(...)); -# __code next(...); -# } Stack; -# -# calling example -# -# goto nodeStack->push((union Data*)node, stackTest3); -# -# generated meta level code -# -# Gearef(context, Stack)->stack = nodeStack->stack; -# Gearef(context, Stack)->data = (union Data*)node; -# Gearef(context, Stack)->next = C_stackTest3; -# goto meta(context, nodeStack->push); - sub getDataGear { my ($filename) = @_; my ($codeGearName, $name, $inTypedef); open my $fd,"<",$filename or die("can't open $filename $!"); while (<$fd>) { if (! $inTypedef) { - if (/^typedef struct (\w+)\s*<(.*)>/) { + if (/^typedef struct (\w+)/) { $inTypedef = 1; $name = $1; $dataGear{$name} = $_; $var{$name} = {}; $code{$name} = {}; - $generic{$name} = \split(/,/,$2); - } elsif (/^typedef struct (\w+)/) { - $inTypedef = 1; - $name = $1; - $dataGear{$name} = $_; - $var{$name} = {}; - $code{$name} = {}; - $generic{$name} = []; } elsif (/^(\w+)(\*)+ create(\w+)\(/) { if (defined $interface) { die "duplicate interface $interface\n"; @@ -112,29 +74,8 @@ $ttype = $2; } $var{$name}->{$tname} = $ttype; - } elsif (/^\_\_code (\w+)\((.*)\)(.*)/) { - my $args = $2; - my $method = $1; - $code{$name}->{$method} = []; - while($args) { - if ($args =~ s/(^\s*,\s*)//) { - } - # continuation case - if ($args =~ s/^(\s)*\_\_code\s+(\w+)\(([^)]*)\)//) { - my $next = $2; - my @args = split(/,/,$3); - push(@{$code{$name}->{$method}},$next); - } elsif ($args =~ s/^(struct|union) (\w+)(\*)+\s(\w+)//) { - my $structType = $1; - my $typeName = $2; - my $varName = $4; - my $typeField = lcfirst($typeName); - push(@{$code{$name}->{$method}},$varName); - } elsif ($args =~ s/(.*,)//) { - } else { - last; - } - } + } elsif (/\_\_code (\w+)\(/) { + $code{$name}->{$1} = 1; } if (/^}/) { $inTypedef = 0; @@ -158,7 +99,6 @@ return 0 if ( $n eq $varname1); } push @{$dataGearVar{$codeGearName}}, $varname1; - push @{$dataGearVarType{$codeGearName}}, $typeName; if ($typeName eq $implementation) { # get implementation $dataGearName{$codeGearName} .= "\t$typeName* $varName = ($typeName*)GearImpl(context, $interface, $varName);\n"; @@ -313,31 +253,6 @@ print $fd $outputVar{$codeGearName}; } next; - } elsif (/^(.*)goto (\w+)\-\>(\w+)\((.*)\);/) { - # handling goto statement - # convert it to the meta call form with two arugments, that is context and enum Code - my $prev = $1; - my $next = $2; - my $method = $3; - my @args = split(/,/,$4); - my @types = @{$dataGearVarType{$codeGearName}}; - my $ntype; - for my $v (@{$dataGearVar{$codeGearName}}) { - my $t = shift @types; - if ($v eq $next) { - $ntype = $t; - } - } - print $fd "\tGearef(context, $ntype)->$next = $next->$next;\n"; - # Put interface argument - my $prot = $code{$ntype}->{$method}; - for my $arg (@args) { - my $p = shift @$prot; - next if ($p eq $arg); - print $fd "\tGearef(context, $ntype)->$p = $arg;\n"; - } - print $fd "${prev}goto meta(context, $next->$next->$ntype.$method);\n"; - next; } elsif (/^(.*)goto (\w+)\((.*)\);/) { # handling goto statement # convert it to the meta call form with two arugments, that is context and enum Code