Changeset: 2d7a9d15b03f for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=2d7a9d15b03f
Modified Files:
        sql/backends/monet5/UDF/80_udf.sql
        sql/backends/monet5/UDF/udf.c
        sql/backends/monet5/UDF/udf.h
        sql/backends/monet5/UDF/udf.mal
Branch: arrays
Log Message:

qr UDF for narrow tables


diffs (276 lines):

diff --git a/sql/backends/monet5/UDF/80_udf.sql 
b/sql/backends/monet5/UDF/80_udf.sql
--- a/sql/backends/monet5/UDF/80_udf.sql
+++ b/sql/backends/monet5/UDF/80_udf.sql
@@ -28,9 +28,14 @@ returns bigint external name udf.fuse;
 CREATE FUNCTION qrq(c double, s double)
 RETURNS double external name udf.qrq;
 
-CREATE FUNCTION fotini1(c double, s double)
-RETURNS double external name udf.fotini1;
+CREATE FUNCTION qrUDF_2(c1 double, c2 double)
+RETURNS TABLE(c1 double, c2 double) 
+external name udf.qr;
 
-CREATE FUNCTION fotini2(c double, s double)
-RETURNS TABLE(c1 double, c2 double) 
-external name udf.fotini2;
+CREATE FUNCTION qrUDF_4(c1 double, c2 double, c3 double, c4 double)
+RETURNS TABLE(c1 double, c2 double, c3 double, c4 double) 
+external name udf.qr;
+
+CREATE FUNCTION qrUDF(r integer, c integer, v double)
+RETURNS TABLE(r integer, c integer, v double)
+external name udf.narrowqr;
diff --git a/sql/backends/monet5/UDF/udf.c b/sql/backends/monet5/UDF/udf.c
--- a/sql/backends/monet5/UDF/udf.c
+++ b/sql/backends/monet5/UDF/udf.c
@@ -537,3 +537,230 @@ char* qrUDF_bulk(Client cntxt, MalBlkPtr
 
     return MAL_SUCCEED;
 }
+
+char* narrowqrUDF_bulk(bat *rowsRes, bat* columnsRes, bat* valuesRes, const 
bat *rows, const bat *columns, const bat *values) {
+       BAT *cBAT_in, *cBAT_out, *rBAT_in, *rBAT_out, *vBAT_in, *vBAT_out;
+
+       BAT *rBAT_sorted, *cBAT_sortedR, *vBAT_sortedR;
+       BAT *order;
+
+       int *minColNum, *maxColNum, colNum, colsNum;
+       oid i,j;
+
+       BAT **cols;
+       BAT **q;
+
+       int *rVals, *cVals;
+       double *vVals, *vcVals;
+
+       BUN totalElementsNum;
+
+       if(!(rBAT_in = BATdescriptor(*rows)))
+               return createException(MAL, "udf.qr", MAL_MALLOC_FAIL);
+
+       if(!(cBAT_in = BATdescriptor(*columns))) {
+               BBPunfix(rBAT_in->batCacheid);
+               return createException(MAL, "udf.qr", MAL_MALLOC_FAIL);
+       }
+
+       if(!(vBAT_in = BATdescriptor(*values))) {
+               BBPunfix(rBAT_in->batCacheid);
+               BBPunfix(cBAT_in->batCacheid);
+               return createException(MAL, "udf.qr", MAL_MALLOC_FAIL);
+
+       }
+       
+       totalElementsNum = BATcount(vBAT_in);
+       
+       /*get the minimum and maximum column number */
+       minColNum = (int*)BATmin(cBAT_in, NULL);
+       maxColNum = (int*)BATmax(cBAT_in, NULL);
+       if(!minColNum || !maxColNum) {
+               BBPunfix(rBAT_in->batCacheid);
+               BBPunfix(cBAT_in->batCacheid);
+               BBPunfix(vBAT_in->batCacheid);
+
+               return createException(MAL, "udf.qr", "Problem in BATmin or 
BATmax");
+       }
+       colsNum = *maxColNum-*minColNum+1;
+
+       /* sort the values according to rows */
+       if(BATsubsort(&rBAT_sorted, &order, NULL, rBAT_in, NULL, NULL, 0, 0) != 
GDK_SUCCEED) {
+               BBPunfix(rBAT_in->batCacheid);
+               BBPunfix(cBAT_in->batCacheid);
+               BBPunfix(vBAT_in->batCacheid);
+               return createException(MAL, "udf.qr", "Problem in BATsubsort");
+       }
+
+       if(!(cBAT_sortedR = BATproject(order, cBAT_in))) { 
+               BBPunfix(rBAT_in->batCacheid);
+               BBPunfix(cBAT_in->batCacheid);
+               BBPunfix(vBAT_in->batCacheid);
+
+               BBPunfix(rBAT_sorted->batCacheid);
+       
+               return createException(MAL, "udf.qr", "Problem in BATproject");
+       }
+
+       if(!(vBAT_sortedR = BATproject(order, vBAT_in))) {
+               BBPunfix(rBAT_in->batCacheid);
+               BBPunfix(cBAT_in->batCacheid);
+               BBPunfix(vBAT_in->batCacheid);
+
+               BBPunfix(rBAT_sorted->batCacheid);
+               BBPunfix(cBAT_sortedR->batCacheid);
+
+               return createException(MAL, "udf.qr", "Problem in BATproject");
+       }
+               
+       cols = (BAT**)GDKmalloc(sizeof(BAT*)*colsNum);
+       q = (BAT**)GDKmalloc(sizeof(BAT*)*colsNum);
+       if(!cols || !q) {
+               BBPunfix(rBAT_in->batCacheid);
+               BBPunfix(cBAT_in->batCacheid);
+               BBPunfix(vBAT_in->batCacheid);
+       
+               BBPunfix(rBAT_sorted->batCacheid);
+               BBPunfix(cBAT_sortedR->batCacheid);
+               BBPunfix(vBAT_sortedR->batCacheid);
+
+               if(cols)
+                       GDKfree(cols);
+
+               return createException(MAL, "udf.qr", "Problem allocating 
space");
+       }
+       
+       /* create a copy of all the columns */
+       for(i=0,colNum=*minColNum; colNum<=*maxColNum; i++, colNum++) {
+               BAT *vals;
+               /*get the oids that correspond to this colNum */
+               BAT *colOidsBAT = BATsubselect(cBAT_sortedR, NULL, &colNum, 
&colNum, 1, 1, 0);
+               if(colOidsBAT == NULL) {
+                       BBPunfix(rBAT_in->batCacheid);
+                       BBPunfix(cBAT_in->batCacheid);
+                       BBPunfix(vBAT_in->batCacheid);
+
+                       BBPunfix(rBAT_sorted->batCacheid);
+                       BBPunfix(cBAT_sortedR->batCacheid);
+                       BBPunfix(vBAT_sortedR->batCacheid);
+
+                       return createException(MAL, "udf.qr", "Problem in 
BATsubselect");
+               }
+
+               /* get the values that correspond to these oids */
+               if(!(vals = BATproject(colOidsBAT, vBAT_sortedR))) {
+                       BBPunfix(rBAT_in->batCacheid);
+                       BBPunfix(cBAT_in->batCacheid);
+                       BBPunfix(vBAT_in->batCacheid);
+
+                       BBPunfix(rBAT_sorted->batCacheid);
+                       BBPunfix(cBAT_sortedR->batCacheid);
+                       BBPunfix(vBAT_sortedR->batCacheid);
+       
+                       for(j=0; j<i; j++)
+                               BBPunfix(cols[j]->batCacheid);
+
+                       return createException(MAL, "udf.qr", "Problem in 
BATproject");
+               }
+
+               cols[i] = vals;
+
+               /*create a BAT for the output */
+               q[i] = BATnew(TYPE_void, BATttype(vals), BATcount(vals), 
TRANSIENT);
+       }
+
+       /* I do not need these BATs anymore */
+       BBPunfix(rBAT_sorted->batCacheid);
+       BBPunfix(cBAT_sortedR->batCacheid);
+       BBPunfix(vBAT_sortedR->batCacheid);
+
+       /*start the algorithm*/
+       for(colNum=0 ; colNum<colsNum; colNum++) {
+               int colNum2 =0 ;
+        BAT *col = cols[colNum];
+        double s = computeR(col);
+        q[colNum] = setQ(col,s);
+
+        if(q[colNum] == NULL) {
+                       BBPunfix(rBAT_in->batCacheid);
+                       BBPunfix(cBAT_in->batCacheid);
+                       BBPunfix(vBAT_in->batCacheid);
+
+                       for(i=0; i<(unsigned int)colsNum; i++)
+                               BBPunfix(cols[i]->batCacheid);
+                       for(i=0; i<(unsigned int)colNum; i++)
+                               BBPunfix(q[i]->batCacheid);
+
+                       GDKfree(cols);
+                       GDKfree(q);
+
+            return createException(MAL, "udf.qr", "Problem in setQ");
+        }
+            
+        /* update the other columns */
+        for(colNum2 = colNum+1; colNum2<colsNum; colNum2++) {
+               s = computeR2(cols[colNum2], q[colNum]);
+            cols[colNum2] = updateCol(cols[colNum2], s, q[colNum]);
+        }
+       }
+
+       /* merge the results in a single column */
+       /* the results are ordered by column and subortered by row
+       * because this is how we processed them */
+       rBAT_out = BATnew(TYPE_void, BATttype(rBAT_in), totalElementsNum, 
TRANSIENT);
+       cBAT_out = BATnew(TYPE_void, BATttype(cBAT_in), totalElementsNum, 
TRANSIENT);
+       vBAT_out = BATnew(TYPE_void, BATttype(vBAT_in), totalElementsNum, 
TRANSIENT);
+
+       rVals = (int*)Tloc(rBAT_out, BUNfirst(rBAT_out));
+       cVals = (int*)Tloc(cBAT_out, BUNfirst(cBAT_out));
+       vVals = (double*)Tloc(vBAT_out, BUNfirst(vBAT_out));
+
+       for(i=0, colNum=0; colNum<colsNum; colNum++) {
+               vcVals = (double*)Tloc(q[colNum], BUNfirst(q[colNum]));
+               
+               for(j=0; j<BATcount(q[colNum]); j++, i++) {
+                       rVals[i] = j;
+                       cVals[i] = colNum;
+                       vVals[i] = vcVals[j];
+               }
+
+               BBPunfix(cols[colNum]->batCacheid);
+               BBPunfix(q[colNum]->batCacheid);
+       }
+
+       GDKfree(cols);
+       GDKfree(q);
+
+       BATsetcount(rBAT_out, i);
+    BATseqbase(rBAT_out, 0);
+    rBAT_out->trevsorted = rBAT_out->tsorted = 0;
+    rBAT_out->tkey = 0;
+    rBAT_out->T->nil = 0;
+    rBAT_out->T->nonil = 0;
+
+       BATsetcount(cBAT_out, i);
+    BATseqbase(cBAT_out, 0);
+    cBAT_out->trevsorted = cBAT_out->tsorted = 0;
+    cBAT_out->tkey = 0;
+    cBAT_out->T->nil = 0;
+    cBAT_out->T->nonil = 0;
+
+       BATsetcount(vBAT_out, i);
+    BATseqbase(vBAT_out, 0);
+    vBAT_out->trevsorted = vBAT_out->tsorted = 0;
+    vBAT_out->tkey = 0;
+    vBAT_out->T->nil = 0;
+    vBAT_out->T->nonil = 0;
+
+       BBPunfix(rBAT_in->batCacheid);
+       BBPunfix(cBAT_in->batCacheid);
+       BBPunfix(vBAT_in->batCacheid);
+
+
+       BBPkeepref(*rowsRes = rBAT_out->batCacheid);
+       BBPkeepref(*columnsRes = cBAT_out->batCacheid);
+       BBPkeepref(*valuesRes = vBAT_out->batCacheid);
+
+       return MAL_SUCCEED;
+}
+
diff --git a/sql/backends/monet5/UDF/udf.h b/sql/backends/monet5/UDF/udf.h
--- a/sql/backends/monet5/UDF/udf.h
+++ b/sql/backends/monet5/UDF/udf.h
@@ -47,4 +47,5 @@ udf_export char * UDFBATfuse(bat *ret, c
 udf_export char* UDFqrq(bat *q, const bat *c, const double *s);
 
 udf_export char* qrUDF_bulk(Client cntxt, MalBlkPtr mb, MalStkPtr stk, 
InstrPtr pci);
+udf_export char* narrowqrUDF_bulk(bat *rowsRes, bat* columnsRes, bat* 
valuesRes, const bat *rows, const bat *columns, const bat *values);
 #endif /* _SQL_UDF_H_ */
diff --git a/sql/backends/monet5/UDF/udf.mal b/sql/backends/monet5/UDF/udf.mal
--- a/sql/backends/monet5/UDF/udf.mal
+++ b/sql/backends/monet5/UDF/udf.mal
@@ -58,4 +58,5 @@ address UDFqrq;
 pattern qr(c1:bat[:oid,:dbl]...) (:bat[:oid,:dbl]...)
 address qrUDF_bulk;
 
-
+command narrowqr(rows:bat[:oid,:int], columns:bat[:oid,:int], 
values:bat[:oid,:dbl]) (:bat[:oid,:int], :bat[:oid,:int], :bat[:oid,:dbl])
+address narrowqrUDF_bulk;
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to