Mercurial > hg > Members > menikon > CbC_xv6
changeset 110:8c7c1ea49f21
impl auto gen context tools
author | anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 27 Nov 2019 21:21:42 +0900 |
parents | 4f9d95dc4efd |
children | 239bd73abac6 |
files | src/gearsTools/lib/Gears/Context.pm src/gearsTools/lib/Gears/Context/Template/XV6.pm src/gearsTools/lib/Gears/Util.pm src/plautogen/impl/SingleLinkedStack.h src/plautogen/interface/Meta.h src/plautogen/interface/Stack.h src/plautogen/interface/UInteger.h |
diffstat | 7 files changed, 490 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gearsTools/lib/Gears/Context.pm Wed Nov 27 21:21:42 2019 +0900 @@ -0,0 +1,200 @@ +package Gears::Context; + +use strict; +use warnings; + +use Gears::Util; +use Gears::Context::Template::XV6; +use Carp qw/croak/; + +sub new { + my ($class, %args) = @_; + my $self = { + data_gears_with_count => {}, + find_root => $args{find_root} // ".", + output => $args{output}, + }; + + if ($args{compile_sources}) { + $self->{compile_sources} = $args{compile_sources}; + map { Gears::Util->file_checking($_); } @{$self->{compile_sources}}; + } + + return bless $self, $class; +} + + +sub extraction_dg_compile_sources { + my $self = shift; + my %counter; + for my $cbc_file (@{$self->{compile_sources}}) { + open my $fh , '<', $cbc_file; + while (my $line = <$fh>) { + if ($line =~ /#interface\s*"(.*)\.h"/ || $line =~ /^\/\/\s*use\s*"(.*)\.h"/) { + $self->{data_gears_with_count}->{$1}->{caller}->{$cbc_file}++; + $counter{interfaces}->{$1}++; + next; + } + + if ($line =~ /^(\w+)(\*)+ *create(\w+)\(([^]]*)\)/) { + my $interface = $1; + my $implementation = $3; + $self->{data_gears_with_count}->{$interface}->{caller}->{$cbc_file}++; + $self->{data_gears_with_count}->{$implementation}->{caller}->{$cbc_file}++; + $counter{interfaces}->{$interface}++; + $counter{impl}->{$implementation}++; + next; + } + + if ($line =~ /Gearef\(context,\s*(\w+)\)/) { + my $implementation = $1; + $counter{impl}->{$implementation}++; + $self->{data_gears_with_count}->{$implementation}->{caller}->{$cbc_file}++; + next; + } + + if ($line =~ /ALLOCATE_(?:PTR_)?ARRAY\(context,\s*(\w+),[\s\w]+\)/) { + my $implementation = $1; + $counter{impl}->{$implementation}++; + $self->{data_gears_with_count}->{$implementation}->{caller}->{$cbc_file}++; + next; + } + + if ($line =~ /ALLOCATE_DATA_GEAR\((\w+),\s*(\w+)\)/) { + my $implementation = $2; + $counter{impl}->{$implementation}++; + $self->{data_gears_with_count}->{$implementation}->{caller}->{$cbc_file}++; + next; + } + + #TaskManagerImpl* taskManager = (TaskManagerImpl*)GearImpl(context, TaskManager, taskManager); + if ($line =~ /\((\w+)\*\)GearImpl\(context,\s*(\w+),\s*(\w+)\)/) { + my $interface = $2; + my $implementation = $1; + $self->{data_gears_with_count}->{$interface}->{caller}->{$cbc_file}++; + $counter{interfaces}->{$interface}++; + $counter{impl}->{$implementation}++; + next; + } + + if ($line =~ /^__code/) { + while ($line =~ /struct (\w+)\s*\*/g) { + next if $1 eq "Context"; + $self->{data_gears_with_count}->{$1}->{caller}->{$cbc_file}++; + next if (exists $counter{interfaces}->{$1}); + $counter{impl}->{$1}++; + } + } + } + close $fh; + } + $counter{interfaces}->{Meta}++; + $counter{interfaces}->{TaskManager}++; + $self->{data_gears_with_count}->{Meta}++; + $self->{data_gears_with_count}->{TaskManager}++; + return \%counter; +} + +sub set_data_gear_header_path { + my $self = shift; + my @data_gears_name; + if (@_) { + @data_gears_name = @_; + } else { + map { push (@data_gears_name,$_) if $_ ne "Context" } keys %{$self->{data_gears_with_count}}; + } + return _find_headers($self->{find_root},\@data_gears_name); +} + +sub update_dg_each_header_path { + my ($self, $dgs, $dg2path) = @_; + my $new_dgs; + for my $kind (keys %$dgs) { + for my $dg_name (keys %{$dgs->{$kind}}) { + if ($dg2path->{$dg_name}) { + $new_dgs->{$kind}->{$dg_name} = $dg2path->{$dg_name}; + } else { + croak "failed trans header $dg_name\n"; + } + } + } + return $new_dgs; +} + +sub tree2create_context_h { + my ($self, $dg2path) = @_; + + my $data_struct_str = $dg2path ? $self->tree2data_struct_str($dg2path) : "\n"; + + my $output = $self->_select_output(); + Gears::Context::Template::XV6->emit_top_header($output); + Gears::Context::Template::XV6->emit_data_gears($output,$data_struct_str); + Gears::Context::Template::XV6->emit_last_header($output); + close $output; +} + +sub _select_output { + my $self = shift; + print "$self->{output}\n"; + if ($self->{output} eq 'stdout') { + return *STDOUT; + } + open my $fh, '>', $self->{output}; + return $fh; +} + +sub tree2data_struct_str { + my ($self, $dg_str) = @_; + my $data_struct_str = ""; + for my $interface (sort keys %$dg_str) { + $data_struct_str .= Gears::Util->h2context_str($dg_str->{$interface}->{elem}); + next unless ($dg_str->{$interface}->{impl}); + for my $impl (sort keys %{$dg_str->{$interface}->{impl}}) { + $data_struct_str .= Gears::Util->h2context_str($dg_str->{$interface}->{impl}->{$impl}); + } + } + return $data_struct_str; +} + +sub createImplTree_from_header { + my ($self, $dg2path) = @_; + my %dg_str = (); + + my $inters = $dg2path->{interfaces}; + my $impls = $dg2path->{impl}; + + use Data::Dumper; + use DDP {deparse => 1}; + print Dumper $dg2path; + p $self; + + map { $dg_str{$_}->{elem} = Gears::Util->parse_interface($inters->{$_}) } keys %$inters; + + map { + my $res = Gears::Util->parse($impls->{$_}); + if ($res->{isa}) { + $dg_str{$res->{isa}}->{impl}->{$_} = $res; + } else { + $dg_str{$_}->{elem} = $res; + } + } keys %$impls; + return \%dg_str; +} + +sub _find_headers { + my ($search_bash_path, $targets) = @_; + my %res; + map { $res{$_}++ } @$targets; + + my $header_paths = Gears::Util->find_headers_path($search_bash_path); + map { + /(\w+)\.h/; + my $header_tile = $1; + if (exists $res{$header_tile}){ + $res{$header_tile} = $_; + } + } @$header_paths; + return \%res; +} + +1;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gearsTools/lib/Gears/Context/Template/XV6.pm Wed Nov 27 21:21:42 2019 +0900 @@ -0,0 +1,194 @@ +package Gears::Context::Template::XV6; +use strict; +use warnings; + +sub emit_top_header { + my ($class, $out) = @_; +my $str = << 'EOFEOF'; +/* Context definition for llrb example */ +// #ifdef CBC_CONTEXT_H does not work well +#define CBC_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 + +#ifndef NULL +# if defined __GNUG__ && \ + (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)) +# define NULL (__null) +# else +# if !defined(__cplusplus) +# define NULL ((void*)0) +# else +# define NULL (0) +# endif +# endif +#endif + +#ifdef XV6KERNEL +extern void* kmalloc (int order); +#define calloc(a,b) kmalloc((a)*(b)) +#define free(a) kfree(a) +#else +#define calloc(a,b) malloc((a)*(b)) +#define free(a) free(a) +#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(cbc_context, dseg) ({\ + Meta* meta = (Meta*)cbc_context->heap;\ + meta->type = D_##dseg;\ + meta->size = sizeof(dseg);\ + meta->len = 1;\ + cbc_context->heap += sizeof(Meta);\ + cbc_context->data[D_##dseg] = cbc_context->heap; cbc_context->heap += sizeof(dseg); (dseg *)cbc_context->data[D_##dseg]; }) + +#define ALLOC_DATA_TYPE(cbc_context, dseg, t) ({\ + Meta* meta = (Meta*)cbc_context->heap;\ + meta->type = D_##t;\ + meta->size = sizeof(t);\ + meta->len = 1;\ + cbc_context->heap += sizeof(Meta);\ + cbc_context->data[D_##dseg] = cbc_context->heap; cbc_context->heap += sizeof(t); (t *)cbc_context->data[D_##dseg]; }) + +#define ALLOCATE(cbc_context, t) ({ \ + Meta* meta = (Meta*)cbc_context->heap;\ + cbc_context->heap += sizeof(Meta);\ + union Data* data = cbc_context->heap; \ + cbc_context->heap += sizeof(t); \ + meta->type = D_##t; \ + meta->size = sizeof(t); \ + meta->len = 1;\ + data; }) + +#define ALLOCATE_ARRAY(cbc_context, t, length) ({ \ + Meta* meta = (Meta*)cbc_context->heap;\ + cbc_context->heap += sizeof(Meta);\ + union Data* data = cbc_context->heap; \ + cbc_context->heap += sizeof(t)*length; \ + meta->type = D_##t; \ + meta->size = sizeof(t)*length; \ + meta->len = length; \ + data; }) + +#define ALLOCATE_PTR_ARRAY(cbc_context, dseg, length) ({\ + Meta* meta = (Meta*)cbc_context->heap;\ + cbc_context->heap += sizeof(Meta);\ + union Data* data = cbc_context->heap; \ + cbc_context->heap += sizeof(dseg *)*length; \ + meta->type = D_##dseg; \ + meta->size = sizeof(dseg *)*length; \ + meta->len = length; \ + data; }) + +#define ALLOCATE_DATA_GEAR(cbc_context, t) ({ \ + union Data* data = ALLOCATE(cbc_context, t); \ + Meta* meta = GET_META(data); \ + meta->wait = createSynchronizedQueue(cbc_context); \ + data; }) + +#define ALLOC(cbc_context, t) (&ALLOCATE(cbc_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(cbc_context, t) (&(cbc_context)->data[D_##t]->t) + +// (SingleLinkedStack *)cbc_context->data[D_Stack]->Stack.stack->Stack.stack + +#define GearImpl(cbc_context, intf, name) (Gearef(cbc_context, intf)->name->intf.name) + +#include "c/enumCode.h" + +enum Relational { + EQ, + GT, + LT, +}; + +#include "c/enumData.h" +#define NDIRECT 12 //fs.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 +EOFEOF + print $out $str; +} + +sub emit_data_gears { + my ($class, $out, $dgs) = @_; + +print $out "union Data {\n"; +print $out $dgs; +print $out <<'EOF'; + struct Context Context; +}; // union Data end this is necessary for context generator +typedef union Data Data; +EOF +} + + +sub emit_last_header { + my($class, $out) = @_; + print $out <<'EOF'; +#include "c/typedefData.h" + +#include "c/extern.h" + +extern __code start_code(struct Context* cbc_context); +extern __code exit_code(struct Context* cbc_context); +extern __code meta(struct Context* cbc_context, enum Code next); +//extern __code par_meta(struct Context* cbc_context, enum Code spawns, enum Code next); +extern __code parGotoMeta(struct Context* cbc_context, enum Code next); +extern void initContext(struct Context* cbc_context); + +// #endif +EOF +} + +1;
--- a/src/gearsTools/lib/Gears/Util.pm Thu Nov 21 21:10:25 2019 +0900 +++ b/src/gearsTools/lib/Gears/Util.pm Wed Nov 27 21:21:42 2019 +0900 @@ -41,7 +41,7 @@ my ($file,$code_verbose) = @_; my $ir = {}; - _file_checking($file); + Gears::Util->file_checking($file); open my $fh, '<', $file; my $line = <$fh>; @@ -63,26 +63,21 @@ next; } next if ($line =~ /^\s+$/); - next if ($line =~ m[//|}]); + next if ($line =~ m[^//]); + next if ($line =~ m[^\}\s*$ir->{name};]); if ($line =~ m|__code (\w+)\(([()\.\*\s\w,_]+)\)|) { - unless ($code_verbose) { - push(@{$ir->{codes}},$1); - next; - } - push(@{$ir->{codes}}, [$1,$2]); - next; + $line = "enum Code $1;\n"; } - $line =~ s/\s*([\w\s\*]+);\s*/$1/; - push(@{$ir->{data}},$1); + push(@{$ir->{content}},$line); } return $ir; } -sub _file_checking { - my $file_name = shift; +sub file_checking { + my ($class, $file_name) = @_; unless (-f $file_name) { croak "invalid filepath :$file_name\n"; } @@ -116,4 +111,41 @@ return $header_file; } +sub find_headers_path { + my $class = shift; + my $find_path = shift // "."; + + my @files; + find( { wanted => sub { push @files, $_ if /\.h/ }, no_chdir => 1 }, $find_path); + + return \@files; +} + +sub h2context_str { + my ($class, $h2context) = @_; + my $context = ''; + my $space = ' '; + + $context = "${space}struct $h2context->{name} {\n"; + my $content_space; + if (exists $h2context->{content}){ + my @chars = split //, $h2context->{content}->[0]; + for my $w (@chars) { + last if ($w !~ /\s/); + $content_space .= $w; + } + } + + unless (defined $content_space) { + $content_space = ""; + } + + for my $c (@{$h2context->{content}}) { + $c =~ s/$content_space//; + $context .= "${space}${space}$c"; + } + $context .= "${space}} $h2context->{name};\n"; + return $context; +} + 1;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/plautogen/impl/SingleLinkedStack.h Wed Nov 27 21:21:42 2019 +0900 @@ -0,0 +1,26 @@ +typedef struct SingleLinkedStack<Type, Isa> impl Stack { + struct Element* top; +} SingleLinkedStack; + +/* + // 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; + */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/plautogen/interface/Meta.h Wed Nov 27 21:21:42 2019 +0900 @@ -0,0 +1,6 @@ +typedef struct Meta <Type, Impl> { + enum DataType type; + long size; + long len; + struct Queue* wait; // tasks waiting this dataGear; +} Meta;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/plautogen/interface/Stack.h Wed Nov 27 21:21:42 2019 +0900 @@ -0,0 +1,17 @@ +typedef struct Stack<Type, Impl>{ + union Data* stack; + union Data* data; + union Data* data1; + /* 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* data, ...)); + __code pop2(Impl* stack, __code next(Type* data, Type* data1, ...)); + __code isEmpty(Impl* stack, __code next(...), __code whenEmpty(...)); + __code get(Impl* stack, __code next(Type* data, ...)); + __code get2(Impl* stack, __code next(Type* data, Type* data1, ...)); + __code next(...); +} Stack;