Changeset: a65a0bb38045 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=a65a0bb38045
Modified Files:
        monetdb5/extras/bwd/operations.c
        monetdb5/extras/bwd/optimizer.c
        monetdb5/extras/bwd/utilities.c
        monetdb5/extras/bwd/utilities.h
Branch: bwd
Log Message:

* using fully decomposed bat-storage on the GPU as well
  * this should make it easier to emulate the behaviour of monetdb operators 
(markT, I'm looking at you)
* still not doing an approximation of a leftjoin


Unterschiede (gekürzt von 324 auf 300 Zeilen):

diff --git a/monetdb5/extras/bwd/operations.c b/monetdb5/extras/bwd/operations.c
--- a/monetdb5/extras/bwd/operations.c
+++ b/monetdb5/extras/bwd/operations.c
@@ -103,18 +103,13 @@ typedef struct {
        int count;
        int padding;
        char elements[];
-} clBAT;
+} clTail;
 
-typedef union {
-       struct {
-               int index;
-               char value[];
-       } intIndexed;
-       struct {
-               int index;
-               char value[];
-       } longIndexed;
-} indexedValue;
+typedef struct {
+       int count;
+       int padding;
+       int positions[];
+} clHead;
 
 char* approximateOperation(char* exactOperation){
        if (exactOperation[1] == '\0') 
@@ -131,9 +126,7 @@ str BWDThetauselectApproximate(bat *res,
        if(!batTailIsDecomposed(data))
                throw (MAL, "bwd problem", "while running %s, I noticed that 
bat is not decomposed: %d", __func__, data->batCacheid);
        {
-               const char* typeNames[] = {[TYPE_int] = "int"};
-               BAT* result = BATnew(BAThtype(data), BATttype(data), 
data->batCount);
-
+               BAT* result = BATnew(BAThtype(data), TYPE_void, data->batCount);
                {
                        const unsigned int newIndex = 
getNextFreeDecomposedBATSlotIndex();
                        DecomposedBATSlot* slot = 
getDecomposedBATSlot(newIndex);
@@ -141,16 +134,16 @@ str BWDThetauselectApproximate(bat *res,
                        slot->approximationBits = 
batTailApproximationBits(data);
                        slot->residuals = NULL;
                        cl_int err;
-                       slot->approximation = clCreateBuffer(getCLContext(), 
CL_MEM_READ_WRITE, (BATcount(data)+1)*(clDeviceAddressBytes() + 
slot->approximationBits/8)+sizeof(clBAT), NULL, &err);
-                       void* zeros = 
calloc((BATcount(data)+1)*(clDeviceAddressBytes() + 
slot->approximationBits/8)+sizeof(clBAT), 1); //TODO: migrate buffer 
initialization to GPU
-                       clEnqueueWriteBuffer(getCommandQueue(), 
slot->approximation, CL_TRUE, 0, (BATcount(data)+1)*(clDeviceAddressBytes() + 
slot->approximationBits/8)+sizeof(clBAT), zeros, 0, NULL, NULL);
-                       free(zeros);
+                       slot->tailApproximation = 
clCreateBuffer(getCLContext(), CL_MEM_READ_WRITE, 
BATcount(data)*slot->approximationBits/8+sizeof(clTail), NULL, &err);
+                       slot->headApproximation = 
clCreateBuffer(getCLContext(), CL_MEM_READ_WRITE, 
BATcount(data)*sizeof(int)+sizeof(clHead), NULL, &err);
+                       clEnqueueWriteBuffer(getCommandQueue(), 
slot->headApproximation, CL_TRUE, 0, sizeof(int), (int[1]){}, 0, NULL, NULL); 
// I wonder what is faster transfering a single integer to the GPU or running a 
kernel that initializes a value
                        if(err) printf("#%s, clCreateBuffer: %s;\n", __func__, 
clError(err));
 
                }
 
                const char* sourceCodeTemplate = "__kernel void uselect (\n"
-                       "__global struct{int count; int padding; char 
elements[];}* output,\n"
+                       "__global struct{int count; int padding; int 
positions[];}* outputHead,"
+                       "__global struct{int count; int padding; char 
values[];}* outputTail,\n"
                        "__global const char* approximation,\n"
                        "const %1$s operand\n"
                        ") {\n"
@@ -159,35 +152,36 @@ str BWDThetauselectApproximate(bat *res,
                        "  for(int i = 0; i < %3$d; i++)\n"
                        "    value += (approximation[inputOffset + i] << 
((i+sizeof(%1$s) - %3$d)*8));\n"
                        "\n"
-                       "  if(value %2$s operand){\n"
-                       "    const size_t offset = atomic_inc(&(output->count)) 
* (sizeof(size_t) + %3$d);\n"
-                       "    for(int i = 0; i < sizeof(size_t); i++)\n"
-                       "      output->elements[offset+i] = (get_global_id(0) 
>> (i*8));\n"
+                       "  if(1 || value %2$s operand){\n"
+                       "    const int index = 
atomic_inc(&(outputHead->count));"
+                       "    const int offset = index * %3$d;\n"
+                       "    outputHead->positions[index] = get_global_id(0);\n"
                        "    for(int i = 0; i < %3$d; i++)\n"
-                       "      output->elements[offset+sizeof(size_t)+i] = 
approximation[inputOffset + i];\n"
+                       "      outputTail->values[offset+i] = 
approximation[inputOffset + i];\n"
                        "  }\n"
                        "}";
                char* sourceCode = malloc(16384);
-               snprintf(sourceCode, 16384, sourceCodeTemplate, 
typeNames[BATttype(data)], approximateOperation(*OP), 
batTailApproximationBits(data)/8, 32-batTailApproximationBits(data));
+               snprintf(sourceCode, 16384, sourceCodeTemplate, 
(str[]){[TYPE_int] = "int"}[BATttype(data)], approximateOperation(*OP), 
batTailApproximationBits(data)/8, 32-batTailApproximationBits(data));
                superverboseprintf("#%s, sourceCode: %s;\n", __func__, 
sourceCode);
                cl_int err;
                cl_program program = clCreateProgramWithSource(getCLContext(), 
1, (const char*[]){sourceCode}, (size_t[]){strlen(sourceCode)}, &err);
                if(err) THRprintf(GDKout, "#%s, clCreateProgramWithSource: 
%s;\n", __func__, clError(err));
                err = clBuildProgram(program, 1, (const 
cl_device_id[]){getDeviceID()}, "", NULL, NULL);
                if(err) {
-                       THRprintf(GDKout, "#%s, clBuildProgram: %s;\n", 
__func__, clError(err));
+                       printf("#%s, clBuildProgram: %s;\n", __func__, 
clError(err));
                        size_t bufferSize;
                        char* buffer;
                        clGetProgramBuildInfo(program, getDeviceID(), 
CL_PROGRAM_BUILD_LOG, 0, NULL, &bufferSize);
                        clGetProgramBuildInfo(program, getDeviceID(), 
CL_PROGRAM_BUILD_LOG, bufferSize, (buffer = alloca(bufferSize)), NULL);
-                       THRprintf(GDKout, "#%s, clBuildProgram log: %s;\n", 
__func__, buffer);
+                       printf("#%s, clBuildProgram log: %s;\n", __func__, 
buffer);
                }
 
                cl_kernel selectKernel = clCreateKernel(program, "uselect", 
&err);
                if(err) THRprintf(GDKout, "#%s, clCreateKernel: %s;\n", 
__func__, clError(err));
-               err = clSetKernelArg(selectKernel, 0, sizeof(cl_mem), 
(cl_mem[]){batTailApproximation(result)}); if (err) THRprintf(GDKout, "#%s, 
clSetKernelArg(%d): %s;\n", __func__, 0, clError(err));
-               err = clSetKernelArg(selectKernel, 1, sizeof(cl_mem), 
(cl_mem[]){batTailApproximation(data)}); if (err) THRprintf(GDKout, "#%s, 
clSetKernelArg(%d): %s;\n", __func__, 1, clError(err));
-               err = clSetKernelArg(selectKernel, 2, sizeof(int), 
(int[]){((*(int*)val)>>batTailResidualBits(data))<<batTailResidualBits(data)}); 
if (err) THRprintf(GDKout, "#%s, clSetKernelArg(%d): %s;\n", __func__, 2, 
clError(err)); // type specific
+               err = clSetKernelArg(selectKernel, 0, sizeof(cl_mem), 
(cl_mem[]){batHeadApproximation(result)}); if (err) THRprintf(GDKout, "#%s, 
clSetKernelArg(%d): %s;\n", __func__, 0, clError(err));
+               err = clSetKernelArg(selectKernel, 1, sizeof(cl_mem), 
(cl_mem[]){batTailApproximation(result)}); if (err) THRprintf(GDKout, "#%s, 
clSetKernelArg(%d): %s;\n", __func__, 0, clError(err));
+               err = clSetKernelArg(selectKernel, 2, sizeof(cl_mem), 
(cl_mem[]){batTailApproximation(data)}); if (err) THRprintf(GDKout, "#%s, 
clSetKernelArg(%d): %s;\n", __func__, 1, clError(err));
+               err = clSetKernelArg(selectKernel, 3, sizeof(int), 
(int[]){((*(int*)val)>>batTailResidualBits(data))<<batTailResidualBits(data)}); 
if (err) THRprintf(GDKout, "#%s, clSetKernelArg(%d): %s;\n", __func__, 2, 
clError(err)); // type specific
 
                err = clEnqueueNDRangeKernel(getCommandQueue(), selectKernel, 
1, (const size_t[]){0}, (const size_t[]){BATcount(data)}, (const size_t[]){1}, 
0, NULL, NULL);
                if(err) THRprintf(GDKout, "#%s, clEnqueueNDRangeKernel: %s;\n", 
__func__, clError(err));
@@ -203,21 +197,31 @@ str BWDThetauselectRefine(bat *res, bat 
        assert(BATttype(data) == TYPE_int); // type specific
 
        BAT* approximation = BATdescriptor(*approx);
-       assert(BATttype(approximation) == TYPE_int); // type specific
+       assert(BATttype(data) == TYPE_int); // type specific
 
-       size_t approximationSize;
-       clGetMemObjectInfo(batTailApproximation(approximation), CL_MEM_SIZE, 
sizeof(size_t), &approximationSize, NULL);
+       clHead* compressedHead;
+       {
+               size_t approximationSize;
+               clGetMemObjectInfo(batHeadApproximation(approximation), 
CL_MEM_SIZE, sizeof(size_t), &approximationSize, NULL);
+               compressedHead = malloc(approximationSize);
+               cl_int err = clEnqueueReadBuffer(getCommandQueue(), 
batHeadApproximation(approximation), CL_TRUE, 0, approximationSize, 
compressedHead , 0, NULL, NULL);        
+               if(err) THRprintf(GDKout, "#%s, clEnqueueReadBuffer: %s;\n", 
__func__, clError(err));
+       }
+       clTail* compressedTail;
+       {
+               size_t approximationSize;
+               clGetMemObjectInfo(batTailApproximation(approximation), 
CL_MEM_SIZE, sizeof(size_t), &approximationSize, NULL);
+               compressedTail = malloc(approximationSize);
+               cl_int err = clEnqueueReadBuffer(getCommandQueue(), 
batTailApproximation(approximation), CL_TRUE, 0, approximationSize, 
compressedTail , 0, NULL, NULL);        
+               if(err) THRprintf(GDKout, "#%s, clEnqueueReadBuffer: %s;\n", 
__func__, clError(err));
+       }
 
+       
+       const size_t candidateCount = compressedHead->count;
+       BAT* result = BATnew(BAThtype(data), TYPE_void, candidateCount);
 
-       BAT* result = BATnew(BAThtype(data), BATttype(data), 
data->batCount+(sizeof(clBAT)/Tsize(data)));
-       BATseqbase(result, 0);
-
-       clBAT* resultClBAT = (clBAT*) malloc(approximationSize);
-       cl_int err = clEnqueueReadBuffer(getCommandQueue(), 
batTailApproximation(approximation), CL_TRUE, 0, approximationSize, 
resultClBAT, 0, NULL, NULL);    
-       if(err) THRprintf(GDKout, "#%s, clEnqueueReadBuffer: %s;\n", __func__, 
clError(err));
-       int* resultRegion = (int*) Tloc(result, BUNfirst(result)); // type 
specific
+       /* int* resultRegion = (int*) Tloc(result, BUNfirst(result)); // type 
specific */
        oid* positionRegion = (oid*) Hloc(result, BUNfirst(result)); // type 
specific
-       size_t candidateCount = resultClBAT->count;
        const unsigned int approximationMask = ~((1 << (32 - 
batTailApproximationBits(approximation)))-1);
        const unsigned char* residuals = batTailResiduals(data);
        const unsigned int residualMask = (1 << batTailResidualBits(data))-1;
@@ -225,13 +229,12 @@ str BWDThetauselectRefine(bat *res, bat 
        int i = 0, j = 0;
 
 #define refineLoop(comparator) while(i < candidateCount) {                     
                                \
-               const int offset = (clDeviceAddressBytes() + 
batTailApproximationBits(approximation)/8)*i++; \
-               const int index = *(int*)&resultClBAT->elements[offset];        
                                \
-               const int compressedValue = 
*(int*)&(resultClBAT->elements[clDeviceAddressBytes()+offset]); \
+               const int index = compressedHead->positions[i];                 
                        \
+               const int offset = 
(batTailApproximationBits(approximation)/8)*i++; \
+               const int compressedValue = 
*(int*)&(compressedTail->elements[offset]); \
                const int deCompressedValue = (compressedValue << 
batTailResidualBits(approximation)) + (*(int*)&residuals[index*residualBytes] & 
residualMask); \
                if(deCompressedValue comparator *(int*)val) {                   
                                                                                
        \
-               positionRegion[j] = index; \
-    resultRegion[j++] = deCompressedValue; \
+               positionRegion[j++] = index; \
                }\
 }
        switch (*OP[0]){
@@ -254,7 +257,9 @@ str BWDThetauselectRefine(bat *res, bat 
        }
 #undef refineLoop
        BATsetcount(result, j);
-       free(resultClBAT);
+       BATseqbase(BATmirror(result), oid_nil);
+       free(compressedHead);
+       free(compressedTail);
        
 
        BBPkeepref(*res = result->batCacheid);
diff --git a/monetdb5/extras/bwd/optimizer.c b/monetdb5/extras/bwd/optimizer.c
--- a/monetdb5/extras/bwd/optimizer.c
+++ b/monetdb5/extras/bwd/optimizer.c
@@ -1,5 +1,7 @@
 #include "bwd.h"
 #include "opt_prelude.h"
+#include "mal_type.h"
+#include "opt_statistics.h"
 
 
 #pragma mark Utility Functions
@@ -21,25 +23,48 @@ static inline void rename_function(Instr
 };
 
 
+
 static inline int OPTBWDImplementation(Client client, MalBlkPtr malBlock, 
MalStkPtr stack, InstrPtr instruction){
        InstrPtr* oldProgram = malBlock->stmt;
        size_t instructionCount = malBlock->stop;
-       
+       size_t initialNumberOfVariables = malBlock->vtop;
+       int* approximations = alloca(initialNumberOfVariables*sizeof(int));
+       for (int i = 0; i < initialNumberOfVariables; ++i) 
+    approximations[i] = 0;
+       for (int i = 0; i < instructionCount; ++i) 
+               if(oldProgram[i]->modname == sqlRef && oldProgram[i]->fcnname 
== bindRef)
+                       approximations[getDestVar(oldProgram[i])] = 
getDestVar(oldProgram[i]);
        newMalBlkStmt(malBlock, malBlock->ssize + 1);
-       int i;
-       for (i = 0; i < instructionCount; ++i) {
+       for (int i = 0; i < instructionCount; ++i) {
+               ////////////////////////////// propagate approximations 
//////////////////////////////
+               if((oldProgram[i]->modname == batRef && oldProgram[i]->fcnname 
== reverseRef) ||
+                       (oldProgram[i]->modname == algebraRef && 
oldProgram[i]->fcnname == markTRef)){
+                       approximations[getDestVar(oldProgram[i])] = 
newTmpVariable(malBlock, getDestType(malBlock, oldProgram[i]));
+                       InstrPtr approximationReverse = 
copyInstruction(oldProgram[i]);
+                       setDestVar(approximationReverse, 
approximations[getDestVar(oldProgram[i])]);
+                       setArg(approximationReverse, 1, 
approximations[getArg(oldProgram[i],1)]);
+                       pushInstruction(malBlock, approximationReverse);
+               }
+
+
+               ////////////////////////////// rewrite operators 
//////////////////////////////
                if(match_function(oldProgram[i], "algebra", "thetauselect")
                         || match_function(oldProgram[i], "algebra", 
"leftjoin")) {
-                       int approximateResultVariable = 
newTmpVariable(malBlock, getDestType(malBlock, oldProgram[i]));
+                       approximations[getDestVar(oldProgram[i])] = 
newTmpVariable(malBlock, getDestType(malBlock, oldProgram[i]));
                        {
                                InstrPtr approximateLeftjoin = 
newInstruction(malBlock, ASSIGNsymbol);
                                char functionNameBuffer[512];
                                snprintf(functionNameBuffer, 512, 
"%sapproximate", oldProgram[i]->fcnname);
                                rename_function(approximateLeftjoin, "bwd", 
functionNameBuffer, (int[]){0}, client);
-                               setDestVar(approximateLeftjoin, 
approximateResultVariable);
+                               setDestVar(approximateLeftjoin, 
approximations[getDestVar(oldProgram[i])]);
                                int j;
-                               for (j = 1; j < oldProgram[i]->argc; ++j) 
-                                       approximateLeftjoin = 
pushArgument(malBlock, approximateLeftjoin, getArg(oldProgram[i], j));
+                               for (j = 1; j < oldProgram[i]->argc; ++j) {
+                                       if(isaBatType(getArgType(malBlock, 
oldProgram[i], j)))
+                                               approximateLeftjoin = 
pushArgument(malBlock, approximateLeftjoin, 
approximations[getArg(oldProgram[i], j)]);
+                                       else
+                                               approximateLeftjoin = 
pushArgument(malBlock, approximateLeftjoin, getArg(oldProgram[i], j));
+                               }
+                                       
                                pushInstruction(malBlock, approximateLeftjoin);
                        }
                        {
@@ -51,12 +76,13 @@ static inline int OPTBWDImplementation(C
                                int j;
                                for (j = 1; j < oldProgram[i]->argc; ++j) 
                                        refineLeftjoin = pushArgument(malBlock, 
refineLeftjoin, getArg(oldProgram[i], j));
-                               refineLeftjoin = pushArgument(malBlock, 
refineLeftjoin, approximateResultVariable);
+                               refineLeftjoin = pushArgument(malBlock, 
refineLeftjoin, approximations[getDestVar(oldProgram[i])]);
                                pushInstruction(malBlock, refineLeftjoin);
                        }
                } else {
                        pushInstruction(malBlock, oldProgram[i]);
                }
+                       
        }
        printf ("rewriting plan for bwd\n");
        return 0;
@@ -114,7 +140,7 @@ str OPTBWD(Client cntxt, MalBlkPtr mb, M
        }
        DEBUGoptimizers
                mnstr_printf(cntxt->fdout,"#opt_reduce: " LLFMT " ms\n",t);
-       QOTupdateStatistics("BWD",actions,t);
+       /* QOTupdateStatistics("BWD",actions,t); */
        addtoMalBlkHistory(mb,"BWD");
        return msg;
 }
diff --git a/monetdb5/extras/bwd/utilities.c b/monetdb5/extras/bwd/utilities.c
--- a/monetdb5/extras/bwd/utilities.c
+++ b/monetdb5/extras/bwd/utilities.c
@@ -135,9 +135,17 @@ const cl_mem batTailApproximation(const 
                        printf("#batTailApproximation: bat hasn't been 
decomposed;\n");
                        return NULL;
                }
-               return 
getDecomposedBATSlot(rightTailApproximationProperty->v.val.ival)->approximation;
+               return 
getDecomposedBATSlot(rightTailApproximationProperty->v.val.ival)->tailApproximation;
 }
 
+const cl_mem batHeadApproximation(const BAT* subject){
+               PROPrec* rightTailApproximationProperty;
+               if(!(rightTailApproximationProperty = BATgetprop(subject, 
batRegistryIndex))){
+                       printf("#batTailApproximation: bat hasn't been 
decomposed;\n");
+                       return NULL;
+               }
+               return 
getDecomposedBATSlot(rightTailApproximationProperty->v.val.ival)->headApproximation;
+}
 const size_t batTailApproximationBits(const BAT* subject){
                PROPrec* rightTailApproximationProperty;
                if(!(rightTailApproximationProperty = BATgetprop(subject, 
batRegistryIndex))){
@@ -193,7 +201,7 @@ const unsigned int decomposeIntArray(con
        }
        {
                cl_int err;
-               slot->approximation = clCreateBuffer(getCLContext(), 
CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, (size+1)*(slot->approximationBits/8), 
approximation, &err);
+               slot->tailApproximation = clCreateBuffer(getCLContext(), 
CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, (size+1)*(slot->approximationBits/8), 
approximation, &err);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to