From 7eac7837a37e9030d35c7895a7c4051a0b4ae0b1 Mon Sep 17 00:00:00 2001 From: Bill Sun Date: Fri, 11 Feb 2022 02:09:38 -0500 Subject: [PATCH] updated code for groupby and windowed aggregations --- .gitignore | 6 +++- Makefile | 8 ++++++ engine/ast.py | 13 ++++----- engine/ddl.py | 15 ++++++---- engine/expr.py | 4 +-- engine/groupby.py | 9 +++--- engine/projection.py | 4 +++ header.k | 66 +++++++++++++++++++++++++++++++++---------- mmw.cpp | 48 +++++++++++++++++++++++++++++++ mmw.so | Bin 0 -> 31200 bytes prompt.py | 3 -- 11 files changed, 137 insertions(+), 39 deletions(-) create mode 100644 Makefile create mode 100644 mmw.cpp create mode 100644 mmw.so diff --git a/.gitignore b/.gitignore index 948a9a8..dc09fca 100644 --- a/.gitignore +++ b/.gitignore @@ -20,4 +20,8 @@ k *.pdf test*.c* *.csv -*.out \ No newline at end of file +*.out +*.asm +!mmw.so +*.k +!header.k \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..fef8c50 --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +all: + g++ mmw.cpp --std=c++1z -shared -fPIC -Ofast -march=native -g0 -s -o mmw.so +avx512: + g++ mmw.cpp --std=c++1z -shared -fPIC -Ofast -mavx512f -g0 -s -o mmw.so +debug: + g++ mmw.cpp --std=c++1z -shared -fPIC -O0 -march=native -g3 -o mmw.so +clean: + rm mmw.so -rf diff --git a/engine/ast.py b/engine/ast.py index 86adaaf..210e3e8 100644 --- a/engine/ast.py +++ b/engine/ast.py @@ -4,7 +4,7 @@ from engine.utils import base62uuid # replace column info with this later. class ColRef: - def __init__(self, k9name, _ty, cobj, cnt, table, name, id): + def __init__(self, k9name, _ty, cobj, cnt, table, name, id, order = None, compound = False): self.k9name = k9name self.type = _ty self.cobj = cobj @@ -12,6 +12,9 @@ class ColRef: self.table = table self.name = name self.id = id + self.order = order # True -> asc, False -> dsc; None -> unordered + self.compound = compound # compound field (list as a field) + self.views = [] self.__arr__ = (k9name, _ty, cobj, cnt, table, name, id) def __getitem__(self, key): @@ -31,6 +34,7 @@ class TableInfo: self.cxt = cxt self.views = set() self.rec = None + self.groupinfo = None for c in cols: self.add_col(c) @@ -44,13 +48,6 @@ class TableInfo: if type(c) is ColRef: c = c.cobj k9name = 'c' + base62uuid(7) - # k9name = self.table_name + c['name'] - # if k9name in self.cxt.k9cols_byname: # duplicate names? - # root = self.cxt.k9cols_byname[k9name] - # k9name = k9name + root.cnt - # root.cnt += 1 - - # column: (k9name, type, original col_object, dup_count) col_object = ColRef(k9name, (list(c['type'].keys()))[0], c, 1, self,c['name'], len(self.columns)) self.cxt.k9cols_byname[k9name] = col_object diff --git a/engine/ddl.py b/engine/ddl.py index 84fc205..91dfb8e 100644 --- a/engine/ddl.py +++ b/engine/ddl.py @@ -37,15 +37,18 @@ class load(ast_node): name="load" def produce(self, node): node = node[self.name] - tablename = 'l'+base62uuid(7) - keys = 'k'+base62uuid(7) - self.emit(f"{tablename}:`csv ? 1:\"{node['file']['literal']}\"") - self.emit(f"{keys}:!{tablename}") table:TableInfo = self.context.tables_byname[node['table']] - + n_keys = len(table.columns) + keys = '' + for _ in n_keys: + keys+='`tk'+base62uuid(6) + tablename = 'l'+base62uuid(7) + + self.emit(f"{tablename}:[{keys}!+(`csv ? 1:\"{node['file']['literal']}\")][{keys}]") + for i, c in enumerate(table.columns): c:ColRef - self.emit(f'{c.k9name}:{tablename}[({keys})[{i}]]') + self.emit(f'{c.k9name}:{tablename}[{i}]') class outfile(ast_node): name="_outfile" diff --git a/engine/expr.py b/engine/expr.py index 2d62c89..7c41776 100644 --- a/engine/expr.py +++ b/engine/expr.py @@ -8,17 +8,17 @@ class expr(ast_node): 'min': 'min', 'avg': 'avg', 'sum': 'sum', + 'mod':'mod', 'mins': ['mins', 'minsw'], 'maxs': ['maxs', 'maxsw'], 'avgs': ['avgs', 'avgsw'], 'sums': ['sums', 'sumsw'], } binary_ops = { - 'sub':'-', + 'sub':'-', 'add':'+', 'mul':'*', 'div':'%', - 'mod':'mod', 'and':'&', 'or':'|', 'gt':'>', diff --git a/engine/groupby.py b/engine/groupby.py index 090c75d..5b54c12 100644 --- a/engine/groupby.py +++ b/engine/groupby.py @@ -12,7 +12,7 @@ class groupby(ast_node): if type(node) is not list: node = [node] g_contents = '(' - + first_col = '' for i, g in enumerate(node): v = g['value'] e = expr(self, v).k9expr @@ -21,7 +21,8 @@ class groupby(ast_node): tmpcol = 't' + base62uuid(7) self.emit(f'{tmpcol}:{e}') e = tmpcol - + if i == 0: + first_col = e g_contents += e + (';'if i < len(node)-1 else '') self.emit(f'{self.group}:'+g_contents+')') @@ -29,8 +30,8 @@ class groupby(ast_node): if len(node) <= 1: self.emit(f'{self.group}:={self.group}') else: - self.emit(f'{self.group}:groupby[{self.group}[0];+{self.group}]') - + self.emit(f'{self.group}:groupby[+({self.group},(,!(#({first_col}))))]') + def consume(self, _): self.referenced = self.datasource.rec self.datasource.rec = None diff --git a/engine/projection.py b/engine/projection.py index 0df274e..2a3d24f 100644 --- a/engine/projection.py +++ b/engine/projection.py @@ -5,6 +5,8 @@ from engine.expr import expr from engine.scan import filter from engine.utils import base62uuid, enlist, base62alp from engine.ddl import outfile +import copy + class projection(ast_node): name='select' def __init__(self, parent:ast_node, node, context:Context = None, outname = None, disp = True): @@ -62,6 +64,8 @@ class projection(ast_node): if 'groupby' in node: self.group_node = groupby(self, node['groupby']) + self.datasource = copy(self.datasource) # shallow copy + self.datasource.groupinfo = self.group_node else: self.group_node = None diff --git a/header.k b/header.k index 287f913..f0df0c2 100644 --- a/header.k +++ b/header.k @@ -1,5 +1,7 @@ import`csv +md:{y-x*_y%x} + maxs:{[L]{max(x, y)}\L} mins:{[L]{min(x, y)}\L} sums:{[L]{(x + y)}\L} @@ -7,22 +9,56 @@ sums:{[L]{(x + y)}\L} avgsimpl:{[L;i] curr:L[i]%(i+1); $[i<(#L)-1;curr, avgsimpl[L;i+1];curr]} avgs:{[L] avgsimpl[sums[L];0]} -maxswimp:{[L;w;i] curr:max(L@(((i-w)+!w)|0)); $[i<#L;curr, maxswimp[L; w; i + 1];curr]} -maxsw:{[w;L]maxswimp[L; w; 1]} +/ maxswimp:{[L;w;i] curr:max(L@(((i-w)+!w)|0)); $[i<#L;curr, maxswimp[L; w; i + 1];curr]} +/ maxsw:{[w;L]maxswimp[L; w; 1]} + +/ minswimp:{[L;w;i] curr:min(L@(((i-w)+!w)|0)); $[i<#L;curr, maxswimp[L; w; i + 1];curr]} +/ minsw:{[w;L]minswimp[L;w;1]} + +/ avgswimp:{[L;w;s;i] s:(s+L[i])-L[i-w];curr:s%((i+1)&w);$[i<(#L)-1; curr, avgswimp[L; w; s; i+1]; curr]} +/ avgsw:{[w;L] avgswimp[L;w;0;0]} + +/ sumswimp:{[L;w;s;i] s:(s+L[i])-L[i-w];$[i<(#L)-1; s, sumswimp[L; w; s; i+1]; s]} +/ sumsw:{[w;L] sumswimp[L;w;0;0]} + + +groupby0:{[L] + {[x;y] + x:$[(@x)=`i;(,(L[0]))!,(,0);x]; + k:(,(L[y]));gvk:x[k][0]; + found:$[(gvk[0]+gvk[1])>0;1;L[y] in !x]; + cg:(,L[y])!$[found;,gvk[0],y;,(,y)]; + (x,cg)}/!(#L)} + +groupBy:{[x]groupBySingle:{[a;x] + findAll:{[c;xx] + f:{[i;c]$[(c[0])[i]~c[1];i+1;0]}; + @[!#xx;!#xx;f;(#xx)#,(xx;c)]}; + z:findAll[a;x]; + b:(findAll[0;z]_(!(1+#z)))-1;(a;b)}; + x:+x;y:?x; + @[y;!#y;groupBySingle;(#y)#,x]} -minswimp:{[L;w;i] curr:min(L@(((i-w)+!w)|0)); $[i<#L;curr, maxswimp[L; w; i + 1];curr]} -minsw:{[w;L]minswimp[L;w;1]} +groupby:{[L] + L:^+L; + dimy:(#(L[0]))-1; + ((({[L;dim;x;y] + x:$[x~0;(,(dim#(L[0])),0);x]; + curr:dim#(L[y]); + $[(dim#*x)~curr;x;((,curr,y),x)]}[L;dimy])/!(#L));(+L)[dimy]) } -avgswimp:{[L;w;s;i] s:(s+L[i])-L[i-w];curr:s%((i+1)&w);$[i<(#L)-1; curr, avgswimp[L; w; s; i+1]; curr]} -avgsw:{[w;L] avgswimp[L;w;0;0]} +lststr:{[L](+({[x;y] ($x,$y)}/L))[0]} +delist:{[L] $[(@L)in(`LL`LC`LG`L);delist[(,/L)];L]} +cntlist:{[L;i] $[(@L)in(`LL`LC`LG`L);cntlist[(,/L);i+1];i+1]} -sumswimp:{[L;w;s;i] s:(s+L[i])-L[i-w];$[i<(#L)-1; s, sumswimp[L; w; s; i+1]; s]} -sumsw:{[w;L] sumswimp[L;w;0;0]} +sumswkrl:{[L;w;x;y] ((x-L[y-w])+L[y])} +sumsw:{[L;w] $[(#L)=0;L;(sumswkrl[L;w])\@[!#L;0;L[0]]]} +avgswkrl:{[L;w;x;y] (x-(L[y-w]-L[y])%w)} +avgsw:{[L;w] $[(#L)=0;L;(avgswkrl[L;w])\@[!#L;0;L[0]]]} -groupbyi:{[L;GV;i] - k:(,(L[i]));gvk:GV[k][0]; - found:$[(gvk[0]+gvk[1])>0;1;L[i] in !GV]; - cg:(,L[i])!$[found;,gvk[0],i;,(,i)]; - $[i<(#L)-1; groupbyi[L;(GV,cg);i+1]; (GV,cg)]} -groupbys:{[L;ll] GV1:(,(L[0]))!,(,0);$[ll>1;groupbyi[L;GV1;1];GV1]} -groupby:{[l;L] $[(#l)=0;,();groupbys[L;#l]]} +/ minsw:{[w;L] ({[L;w;x] min(L[$[x>w;(!w) + ((x-w)+1);!(x+1)]])}[L;w])'!#L} +import`mmw +minsw:{[w;L] ret:L; mmw[ret;((`g ($@ret)[0]), (#ret), w, 65536)];ret} +maxsw:{[w;L] ret:L; mmw[ret;((`g ($@ret)[0]), (#ret), w, 65537)];ret} +minswip:{[w;L] mmw[L;((`g ($@L)[0]), (#L), w, 65536)];} +maxswip:{[w;L] mmw[L;((`g ($@L)[0]), (#L), w, 65537)];} \ No newline at end of file diff --git a/mmw.cpp b/mmw.cpp new file mode 100644 index 0000000..33f15ae --- /dev/null +++ b/mmw.cpp @@ -0,0 +1,48 @@ + +#include +#include +#include +#include + +using std::size_t; +using std::uint32_t; + +template +void running(void *array, uint32_t len, uint32_t w){ + using std::deque; + T* arr = static_cast (array); + deque> cache; + for(int i = 0; i < len; ++i){ + if(!cache.empty() && cache.front().second == i-w) cache.pop_front(); + if constexpr(minmax) + while(!cache.empty() && cache.back().first>arr[i]) cache.pop_back(); + else + while(!cache.empty() && cache.back().first +inline void mm(void *array, uint32_t len, uint32_t w, bool mm){ + mm? running(array, len, w) : running(array, len, w); +} +extern "C" { + #include + + int mmw(void *array, unsigned long long misc[]){ + char _ty = misc[0]; + uint32_t len = misc[1]; + uint32_t w = misc[2]; + bool minmax = misc[3]-0x10000; + switch(_ty){ + case 'F': mm(array, len, w, minmax); break; + case 'C': case 'G': mm(array, len, w, minmax); break; + case 'H': mm(array, len, w, minmax); break; + case 'D': case 'I': mm(array, len, w, minmax); break; + case 'T': case 'J': mm(array, len, w, minmax); break; + case 'L': if(len == 0) break; + default: printf("nyi %c\n", _ty); + } + return 0; + } +} diff --git a/mmw.so b/mmw.so new file mode 100644 index 0000000000000000000000000000000000000000..dd2900d524d70f02d205aaca8f7618b841cd5b08 GIT binary patch literal 31200 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 EU#!f*SO5S3 literal 0 HcmV?d00001 diff --git a/prompt.py b/prompt.py index bdf0abf..3ed66c1 100644 --- a/prompt.py +++ b/prompt.py @@ -7,9 +7,6 @@ import sys if sys.platform != 'win32': import readline -# else: -# import pyreadline3 - test_parser = True # code to test parser