changeset 362:d93dceb84c75

Merge
author Tatsuki IHA <innparusu@cr.ie.u-ryukyu.ac.jp>
date Wed, 28 Jun 2017 05:51:32 +0900
parents a2c01ab30ea2 (current diff) ba5959d7901d (diff)
children 3aab69fc4c28
files src/parallel_execution/context.h src/parallel_execution/generate_stub.pl
diffstat 5 files changed, 214 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/parallel_execution/CMakeLists.txt	Wed Jun 28 05:48:39 2017 +0900
+++ b/src/parallel_execution/CMakeLists.txt	Wed Jun 28 05:51:32 2017 +0900
@@ -94,3 +94,9 @@
       test/stack_test.cbc SingleLinkedStack.cbc
 )
 
+GearsCommand(
+  TARGET
+      sort
+  SOURCES
+      examples/sort.cbc
+)
--- a/src/parallel_execution/context.h	Wed Jun 28 05:48:39 2017 +0900
+++ b/src/parallel_execution/context.h	Wed Jun 28 05:51:32 2017 +0900
@@ -283,6 +283,19 @@
     struct Integer {
         int value;
     } Integer;
+    struct SortArray {//そもそもこれは必要なのか?
+        struct SortArray *sortArray;
+        struct Integer **array;//Array arrayじゃできない?
+        int loop_counter;
+        int loop_counter2;
+        int loop_counter3;
+        int d;
+        enum Code make_array;
+        enum Code print;
+        enum Code bitonic_sort;
+        enum Code kernel;
+        enum Code swap;
+    }SortArray;
 }; // union Data end       this is necessary for context generator
 
 typedef union Data Data;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/parallel_execution/examples/SortArray.cbc	Wed Jun 28 05:51:32 2017 +0900
@@ -0,0 +1,13 @@
+typedef struct SortArray<Impl>{
+    SortArray *sortArray;
+    Integer **array;
+    int loop_counter;
+    int loop_counter2;
+    int loop_counter3;
+    int d;
+    __code print(struct SortArray* sortArray, __code next(...));
+    __code make_array(struct SortArray* sortArray, __code next(...));
+    __code bitonic_sort(struct SortArray* sortArray, __code next(...));
+    __code kernel(struct SortArray* sortArray, __code next(...));
+    __code swap(struct SortArray* sortArray, __code next(...));
+} SortArray;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/parallel_execution/examples/sort.cbc	Wed Jun 28 05:51:32 2017 +0900
@@ -0,0 +1,94 @@
+#include<stdio.h>
+#include <stdlib.h>
+#include "../../context.h"
+#define MAX 20
+#define LOGN 5
+
+int main(int argc, char const* argv[]) {
+    struct Context* main_context = NEW(struct Context);
+    initContext(main_context);
+    main_context->next = C_sort_start;
+    goto start_code(main_context);
+}
+
+__code sort_start(struct SortArray* sortArray){
+    sortArray->sortArray = new SortArray();
+    sortArray->sortArray->array = (Integer**)ALLOC_ARRAY(context, Integer, MAX);//ALLOC_ARRAYはDSの配列なのでintではできない
+    sortArray->sortArray->loop_counter = 0;
+    sortArray->sortArray->loop_counter2 = 0;
+    sortArray->sortArray->loop_counter3 = 0;
+    srand((unsigned) time(NULL));
+    goto meta(context, C_make_array);
+}
+
+__code make_array(struct SortArray* sortArray){//乱数生成
+    if (sortArray->sortArray->loop_counter == MAX){//ループの終了→配列表示へ
+        sortArray->sortArray->loop_counter = 0;
+        goto meta(context, C_print);
+    }
+    struct Integer* integer = new Integer();
+    integer->value = rand() % 20;
+    sortArray->sortArray->array[sortArray->sortArray->loop_counter] = integer;
+    sortArray->sortArray->loop_counter++;
+    goto meta(context, C_make_array);
+}
+
+__code print(struct SortArray* sortArray){//配列表示
+    if (sortArray->sortArray->loop_counter == MAX){//ループの終了→ソートへ       
+        printf("\n");
+        if(sortArray->sortArray->loop_counter2 > 0){//ソート終わってたら終了
+            goto meta(context, C_exit_code);
+        }
+        sortArray->sortArray->loop_counter = 0;
+        sortArray->sortArray->loop_counter2 = 0; 
+        goto meta(context, C_bitonic_sort);
+    }
+    
+    printf("%d, ", sortArray->sortArray->array[sortArray->sortArray->loop_counter]->value);
+    sortArray->sortArray->loop_counter++;
+    goto meta(context, C_print);
+}
+
+__code bitonic_sort(struct SortArray* sortArray){//ソートの繰り返し
+    if (sortArray->sortArray->loop_counter >= LOGN){//ループの終了→配列表示へ
+        sortArray->sortArray->loop_counter = 0;
+        goto meta(context, C_print);
+    }
+    goto meta(context, C_kernel);
+}
+
+__code kernel(struct SortArray* sortArray){//ソートの中身
+    int i = sortArray->sortArray->loop_counter3;    
+    int d = 0;
+    int up;
+   
+    if (sortArray->sortArray->loop_counter2 > sortArray->sortArray->loop_counter){//ループの終了→上のループへ
+        sortArray->sortArray->loop_counter++;
+        goto meta(context, C_bitonic_sort);
+    }
+    
+    sortArray->sortArray->d = 1 << (sortArray->sortArray->loop_counter - sortArray->sortArray->loop_counter2);
+    d = sortArray->sortArray->d;
+    
+    if (i < GET_SIZE(sortArray->sortArray->array)){
+        up = ((i >> sortArray->sortArray->loop_counter) & 2) == 0;
+        if ((i & d) == 0 && (sortArray->sortArray->array[i] > sortArray->sortArray->array[i | d]) == up) {//ここ入ってない
+            goto meta(context, C_swap);
+        }
+    }
+    
+    sortArray->sortArray->loop_counter2++;
+    goto meta(context, C_kernel);
+}
+
+__code swap(struct SortArray* sortArray){//配列の要素を入れ替える
+    int i = sortArray->sortArray->loop_counter3;
+    int d = sortArray->sortArray->d;
+    
+    struct Integer *tmp = sortArray->sortArray->array[i];
+    sortArray->sortArray->array[i] = sortArray->sortArray->array[i | d];
+    sortArray->sortArray->array[i | d] = tmp;
+    
+    sortArray->sortArray->loop_counter3++;
+    goto meta(context, C_kernel);//上位のループへ
+}
--- a/src/parallel_execution/generate_stub.pl	Wed Jun 28 05:48:39 2017 +0900
+++ b/src/parallel_execution/generate_stub.pl	Wed Jun 28 05:51:32 2017 +0900
@@ -38,21 +38,59 @@
 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+)/) {
+            if (/^typedef struct (\w+)\s*<(.*)>/) {
                 $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"; 
@@ -74,8 +112,29 @@
                 $ttype = $2;
             }
             $var{$name}->{$tname} = $ttype;
-	} elsif (/\_\_code (\w+)\(/) {
-            $code{$name}->{$1} = 1;
+        } 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;
+                }
+            }
         }
         if (/^}/) {
             $inTypedef = 0;
@@ -99,6 +158,7 @@
         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";
@@ -253,6 +313,31 @@
                     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