Changeset: ecb98bf0bd93 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=ecb98bf0bd93
Modified Files:
monetdb5/modules/mal/array.mx
Branch: SciQL-2
Log Message:
ARRAYtiles*(): reduced code redundancy
merged almost identical ("cut&paste") implementations of
ARRAYtiles(cnt|sum|avg)() and ARRAYtiles(min|max)()
into a single implementation
diffs (287 lines):
diff --git a/monetdb5/modules/mal/array.mx b/monetdb5/modules/mal/array.mx
--- a/monetdb5/modules/mal/array.mx
+++ b/monetdb5/modules/mal/array.mx
@@ -541,7 +541,7 @@ ARRAYfiller(Client cntxt, MalBlkPtr mb,
@= tilesAggr
/*
- * array.[sum|avg|cnt] inputs:
+ * array.[sum|avg|cnt|min|max] inputs:
* (cell_val:BAT,
* dim_1:BAT,tile_member_offset_dim_1:BAT,size_dim_1, ...,
* dim_n:BAT,tile_member_offset_dim_n:BAT,size_dim_n)
@@ -556,7 +556,7 @@ ARRAYtiles@4_@1(Client cntxt, MalBlkPtr
@3 *bResT = NULL;
int **bDimsT = NULL, **bOffsetsT = NULL;
BUN p, r, arrcnt = 0, offcnt = 0, cnt = 0;
- @2 sum = 0;
+ @2 @6;
/* FIXME: this code only deal with INT dimensions */
int cidx = 0, *dMin = NULL, *dMax = NULL, *dSize = NULL;
oid arrbase = 0, offbase = 0, vid = 0, mul = 0;
@@ -575,11 +575,11 @@ ARRAYtiles@4_@1(Client cntxt, MalBlkPtr
dMin = (int*) GDKzalloc(sizeof(int) * ndims);
dMax = (int*) GDKzalloc(sizeof(int) * ndims);
dSize = (int*) GDKzalloc(sizeof(int) * ndims);
- if(!bDims || !bDimsT || !bOffsets || !bOffsetsT || !dMin || !dMax ||
!dSize) {
+ if (!bDims || !bDimsT || !bOffsets || !bOffsetsT || !dMin || !dMax ||
!dSize) {
AGGR_CLEANUP();
throw(MAL, "array.@5", MAL_MALLOC_FAIL);
}
- if(!(bVal = BATdescriptor(*(int*)getArgReference(stk,pci,1)))) {
+ if (!(bVal = BATdescriptor(*(int*)getArgReference(stk,pci,1)))) {
AGGR_CLEANUP();
throw(MAL, "array.@5", RUNTIME_OBJECT_MISSING);
}
@@ -642,7 +642,8 @@ ARRAYtiles@4_@1(Client cntxt, MalBlkPtr
bRes = BATnew(TYPE_void, TYPE_@3, BATcount(bVal));
bResT = (@3*) Tloc(bRes, BUNfirst(bRes));
for (p = 0 ; p < arrcnt ; p++) {
- sum = 0; cnt = 0;
+ cnt = 0;
+ @6;
/* loop over all sets of offsets */
for (r = 0; r < offcnt ; r++) {
vid = 0; /* index into bVal for the value of a
qualified tile member */
@@ -670,12 +671,12 @@ ARRAYtiles@4_@1(Client cntxt, MalBlkPtr
if (!skip) {
elm = bValT[vid];
if (elm != @1_nil) {
+ @7;
cnt++;
- sum += elm;
}
}
}
- bResT[p] = (cnt ? @6 : @3_nil);
+ bResT[p] = (cnt ? @8 : @3_nil);
nils |= !cnt;
}
AGGR_CLEANUP();
@@ -694,196 +695,38 @@ ARRAYtiles@4_@1(Client cntxt, MalBlkPtr
return MAL_SUCCEED;
}
@c
-@:tilesAggr(bte,lng,lng,Sum,sum, sum )@
-@:tilesAggr(sht,lng,lng,Sum,sum, sum )@
-@:tilesAggr(int,lng,lng,Sum,sum, sum )@
-@:tilesAggr(lng,lng,lng,Sum,sum, sum )@
-@:tilesAggr(flt,dbl,dbl,Sum,sum, sum )@
-@:tilesAggr(dbl,dbl,dbl,Sum,sum, sum )@
-@:tilesAggr(bte,lng,dbl,Avg,avg, (dbl)sum / (dbl)cnt )@
-@:tilesAggr(sht,lng,dbl,Avg,avg, (dbl)sum / (dbl)cnt )@
-@:tilesAggr(int,lng,dbl,Avg,avg, (dbl)sum / (dbl)cnt )@
-@:tilesAggr(lng,lng,dbl,Avg,avg, (dbl)sum / (dbl)cnt )@
-@:tilesAggr(flt,dbl,dbl,Avg,avg, (dbl)sum / (dbl)cnt )@
-@:tilesAggr(dbl,dbl,dbl,Avg,avg, (dbl)sum / (dbl)cnt )@
-@:tilesAggr(bte,lng,lng,Cnt,cnt, (lng)cnt )@
-@:tilesAggr(sht,lng,lng,Cnt,cnt, (lng)cnt )@
-@:tilesAggr(int,lng,lng,Cnt,cnt, (lng)cnt )@
-@:tilesAggr(lng,lng,lng,Cnt,cnt, (lng)cnt )@
-@:tilesAggr(flt,dbl,lng,Cnt,cnt, (lng)cnt )@
-@:tilesAggr(dbl,dbl,lng,Cnt,cnt, (lng)cnt )@
+@:tilesAggr(bte,lng,lng,Sum,sum, sum = 0, sum += elm, sum )@
+@:tilesAggr(sht,lng,lng,Sum,sum, sum = 0, sum += elm, sum )@
+@:tilesAggr(int,lng,lng,Sum,sum, sum = 0, sum += elm, sum )@
+@:tilesAggr(lng,lng,lng,Sum,sum, sum = 0, sum += elm, sum )@
+@:tilesAggr(flt,dbl,dbl,Sum,sum, sum = 0, sum += elm, sum )@
+@:tilesAggr(dbl,dbl,dbl,Sum,sum, sum = 0, sum += elm, sum )@
-@= tilesMinMax
-/*
- * array.[min|max] inputs:
- * (cell_val:BAT,
- * dim_1:BAT,tile_member_offset_dim_1:BAT,size_dim_1, ...,
- * dim_n:BAT,tile_member_offset_dim_n:BAT,size_dim_n)
- */
-str
-ARRAYtiles@2_@1(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
-{
- BAT *bVal = NULL, *bRes = NULL, **bDims = NULL, **bOffsets = NULL;
- int *ret = (int*) getArgReference(stk,pci,0), i = 0, ndims = 0;
- bit skip = FALSE, nils = FALSE;
- @1 *bValT = NULL, elm = 0;
- @1 *bResT = NULL;
- int **bDimsT = NULL, **bOffsetsT = NULL;
- BUN p, r, arrcnt = 0, offcnt = 0;
- @1 minmax = @1_nil;
- bit first = TRUE;
- /* FIXME: this code only deal with INT dimensions */
- int cidx = 0, *dMin = NULL, *dMax = NULL, *dSize = NULL;
- oid arrbase = 0, offbase = 0, vid = 0, mul = 0;
+@:tilesAggr(bte,lng,dbl,Avg,avg, sum = 0, sum += elm, (dbl)sum / (dbl)cnt )@
+@:tilesAggr(sht,lng,dbl,Avg,avg, sum = 0, sum += elm, (dbl)sum / (dbl)cnt )@
+@:tilesAggr(int,lng,dbl,Avg,avg, sum = 0, sum += elm, (dbl)sum / (dbl)cnt )@
+@:tilesAggr(lng,lng,dbl,Avg,avg, sum = 0, sum += elm, (dbl)sum / (dbl)cnt )@
+@:tilesAggr(flt,dbl,dbl,Avg,avg, sum = 0, sum += elm, (dbl)sum / (dbl)cnt )@
+@:tilesAggr(dbl,dbl,dbl,Avg,avg, sum = 0, sum += elm, (dbl)sum / (dbl)cnt )@
- (void) cntxt;
- (void) mb;
+@:tilesAggr(bte,lng,lng,Cnt,cnt, sum = 0, sum += elm, (lng)cnt )@
+@:tilesAggr(sht,lng,lng,Cnt,cnt, sum = 0, sum += elm, (lng)cnt )@
+@:tilesAggr(int,lng,lng,Cnt,cnt, sum = 0, sum += elm, (lng)cnt )@
+@:tilesAggr(lng,lng,lng,Cnt,cnt, sum = 0, sum += elm, (lng)cnt )@
+@:tilesAggr(flt,dbl,lng,Cnt,cnt, sum = 0, sum += elm, (lng)cnt )@
+@:tilesAggr(dbl,dbl,lng,Cnt,cnt, sum = 0, sum += elm, (lng)cnt )@
- if ( (pci->argc - pci->retc - 1) % 3 != 0)
- throw(MAL, "array.@3", "Unbalanced argument sets");
+@:tilesAggr(bte,bte,bte,Min,min, minmax = bte_nil, minmax = (cnt ?
MIN(minmax,elm) : elm), minmax )@
+@:tilesAggr(sht,sht,sht,Min,min, minmax = sht_nil, minmax = (cnt ?
MIN(minmax,elm) : elm), minmax )@
+@:tilesAggr(int,int,int,Min,min, minmax = int_nil, minmax = (cnt ?
MIN(minmax,elm) : elm), minmax )@
+@:tilesAggr(lng,lng,lng,Min,min, minmax = lng_nil, minmax = (cnt ?
MIN(minmax,elm) : elm), minmax )@
+@:tilesAggr(flt,flt,flt,Min,min, minmax = flt_nil, minmax = (cnt ?
MIN(minmax,elm) : elm), minmax )@
+@:tilesAggr(dbl,dbl,dbl,Min,min, minmax = dbl_nil, minmax = (cnt ?
MIN(minmax,elm) : elm), minmax )@
- ndims = (pci->argc - pci->retc - 1) / 3;
- bDims = (BAT**) GDKzalloc(sizeof(BAT*) * ndims);
- bDimsT = (int**) GDKzalloc(sizeof(int*) * ndims);
- bOffsets = (BAT**) GDKzalloc(sizeof(BAT*) * ndims);
- bOffsetsT = (int**) GDKzalloc(sizeof(int*) * ndims);
- dMin = (int*) GDKzalloc(sizeof(int) * ndims);
- dMax = (int*) GDKzalloc(sizeof(int) * ndims);
- dSize = (int*) GDKzalloc(sizeof(int) * ndims);
- if(!bDims || !bDimsT || !bOffsets || !bOffsetsT || !dMin || !dMax ||
!dSize) {
- AGGR_CLEANUP();
- throw(MAL, "array.@3", MAL_MALLOC_FAIL);
- }
- if (!(bVal = BATdescriptor(*(int*)getArgReference(stk,pci,1)))) {
- AGGR_CLEANUP();
- throw(MAL, "array.@3", RUNTIME_OBJECT_MISSING);
- }
- for (i = 0; i < ndims; i++) {
- bDims[i] = BATdescriptor(*(int*)getArgReference(stk,pci,2+i*3));
- bOffsets[i] =
BATdescriptor(*(int*)getArgReference(stk,pci,2+i*3+1));
- if (!bDims[i] || !bOffsets[i]) {
- AGGR_CLEANUP();
- throw(MAL, "array.@3", RUNTIME_OBJECT_MISSING);
- }
- dSize[i] = *(int*)getArgReference(stk,pci,2+i*3+2);
- }
- /* type check the shapes, prepare iterators, and compute the min/max of
the dimensions */
- if (!BAThdense(bVal)) {
- AGGR_CLEANUP();
- throw(MAL, "array.@3", "head of value BAT must be dense");
- }
- if (bVal->ttype != TYPE_@1) {
- AGGR_CLEANUP();
- throw(MAL, "array.@3", "tail of value BAT must be of type @1");
- }
- arrcnt = BATcount(bVal);
- arrbase = bVal->hseqbase;
- offbase = bOffsets[0]->hseqbase;
- offcnt = BATcount(bOffsets[0]);
- for (i = 0; i < ndims; i++) {
- if (!BAThdense(bDims[i])) {
- AGGR_CLEANUP();
- throw(MAL, "array.@3", "head of all dimension BATs must
be dense");
- }
- if (!BAThdense(bOffsets[i])) {
- AGGR_CLEANUP();
- throw(MAL, "array.@3", "head of all offset BATs must be
dense");
- }
- if (bDims[i]->hseqbase != arrbase || BATcount(bDims[i]) !=
arrcnt) {
- AGGR_CLEANUP();
- throw(MAL, "array.@3", "head of all dimension BATs must
be aligned with head of value BAT");
- }
- if (bOffsets[i]->hseqbase != offbase || BATcount(bOffsets[i])
!= offcnt) {
- AGGR_CLEANUP();
- throw(MAL, "array.@3", "heads of all offset BATs must
be aligned");
- }
- if (bDims[i]->ttype != TYPE_int || bDims[i]->ttype !=
bOffsets[i]->ttype) {
- AGGR_CLEANUP();
- throw(MAL, "array.@3", SEMANTIC_TYPE_MISMATCH);
- }
- BATmin(bDims[i], &(dMin[i]));
- BATmax(bDims[i], &(dMax[i]));
- }
-
- /* access tails as arrays */
- bValT = (@1*) Tloc(bVal, BUNfirst(bVal));
- for (i = 0; i < ndims; i++) {
- bDimsT[i] = (int*) Tloc(bDims[i], BUNfirst(bDims[i]));
- bOffsetsT[i] = (int*) Tloc(bOffsets[i], BUNfirst(bOffsets[i]));
- }
-
- /* For each anchor piont, compute all cells belong to this tile
(bVal.head
- * is the group nr.) and compute the SUM */
- bRes = BATnew(TYPE_void, TYPE_@1, BATcount(bVal));
- bResT = (@1*) Tloc(bRes, BUNfirst(bRes));
- for (p = 0 ; p < arrcnt ; p++) {
- minmax = @1_nil;
- first = TRUE;
- /* loop over all sets of offsets */
- for (r = 0; r < offcnt ; r++) {
- vid = 0; /* index into bVal for the value of a
qualified tile member */
- mul = 1;
- skip = FALSE;
- /* for the index of the anchor point on dimension d_i,
check if the
- * resulting index is within the dimension range after
having
- * shifted according this set of offset on dimension
d_i.
- * If yes, update 'vid' so that we know the OID of the
qualified
- * cell at the end; otherwise, skip.
- */
- /* TODO: we can skip more. If the j-th value
bOffsets[i]
- * disqualifies the index on dimension d_i, we can jump
to the next
- * of bOffsets[i] which value follows the j-th value */
- for (i = ndims - 1; i >= 0; i--) {
- cidx = bDimsT[i][p] + bOffsetsT[i][r];
- if (dMin[i] <= cidx && cidx <= dMax[i]) {
- vid += mul * (cidx - dMin[i]);
- } else {
- skip = TRUE;
- break; /* skip remaining dimensions */
- }
- mul *= dSize[i];
- }
- if (!skip) {
- elm = bValT[vid];
- if (elm != @1_nil) {
- if (first) {
- minmax = elm;
- first = FALSE;
- }
- else
- minmax = @4(minmax,elm);
- }
- }
- }
- bResT[p] = minmax;
- nils |= minmax == @1_nil;
- }
- AGGR_CLEANUP();
- BATsetcount(bRes, arrcnt);
- BATseqbase(bRes, arrbase);
- bRes->hdense = TRUE;
- BATkey(bRes, TRUE);
- bRes->hsorted = 1;
- bRes->hrevsorted = (arrcnt <= 1);
- bRes->tsorted = (arrcnt <= 1);
- bRes->trevsorted = (arrcnt <= 1);
- bRes->T->nil = nils;
- bRes->T->nonil = !nils;
- BATkey(BATmirror(bRes), FALSE);
- BBPkeepref(*ret = bRes->batCacheid);
- return MAL_SUCCEED;
-}
-@c
-@:tilesMinMax(bte,Min,min,MIN)@
-@:tilesMinMax(sht,Min,min,MIN)@
-@:tilesMinMax(int,Min,min,MIN)@
-@:tilesMinMax(lng,Min,min,MIN)@
-@:tilesMinMax(flt,Min,min,MIN)@
-@:tilesMinMax(dbl,Min,min,MIN)@
-@:tilesMinMax(bte,Max,max,MAX)@
-@:tilesMinMax(sht,Max,max,MAX)@
-@:tilesMinMax(int,Max,max,MAX)@
-@:tilesMinMax(lng,Max,max,MAX)@
-@:tilesMinMax(flt,Max,max,MAX)@
-@:tilesMinMax(dbl,Max,max,MAX)@
+@:tilesAggr(bte,bte,bte,Max,max, minmax = bte_nil, minmax = (cnt ?
MAX(minmax,elm) : elm), minmax )@
+@:tilesAggr(sht,sht,sht,Max,max, minmax = sht_nil, minmax = (cnt ?
MAX(minmax,elm) : elm), minmax )@
+@:tilesAggr(int,int,int,Max,max, minmax = int_nil, minmax = (cnt ?
MAX(minmax,elm) : elm), minmax )@
+@:tilesAggr(lng,lng,lng,Max,max, minmax = lng_nil, minmax = (cnt ?
MAX(minmax,elm) : elm), minmax )@
+@:tilesAggr(flt,flt,flt,Max,max, minmax = flt_nil, minmax = (cnt ?
MAX(minmax,elm) : elm), minmax )@
+@:tilesAggr(dbl,dbl,dbl,Max,max, minmax = dbl_nil, minmax = (cnt ?
MAX(minmax,elm) : elm), minmax )@
@}
_______________________________________________
checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list