Changeset: af513e091f06 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=af513e091f06
Modified Files:
monetdb5/extras/bwd/bwd.c
monetdb5/extras/bwd/cl_program_utilities.c
monetdb5/extras/bwd/operations.c
monetdb5/extras/bwd/utilities.c
monetdb5/extras/bwd/utilities.h
Branch: bwd
Log Message:
* got something running that is halfway towards tpch6 (select count(l_shipdate)
as revenue from lineitem where l_shipdate >= date '1994-01-01' and l_shipdate <
date '2013-01-01' and l_discount between 1.0 - 0.01 and 1.0 + 0.01;)
* fixed an insane number of bugs
* unified in-gpu representation of bats (a struct with the first value
being the count)
Unterschiede (gekürzt von 675 auf 300 Zeilen):
diff --git a/monetdb5/extras/bwd/bwd.c b/monetdb5/extras/bwd/bwd.c
--- a/monetdb5/extras/bwd/bwd.c
+++ b/monetdb5/extras/bwd/bwd.c
@@ -144,7 +144,9 @@ char* resolveBatToAttribute(bat bid, Cli
}
}
}
- return "unknown";
+ char* buffer = malloc(32);
+ snprintf(buffer, 32, "%d", bid);
+ return buffer;
/* BAT *bn = store_funcs.bind_col(tr, c, 0); */
diff --git a/monetdb5/extras/bwd/cl_program_utilities.c
b/monetdb5/extras/bwd/cl_program_utilities.c
--- a/monetdb5/extras/bwd/cl_program_utilities.c
+++ b/monetdb5/extras/bwd/cl_program_utilities.c
@@ -43,10 +43,15 @@ cl_program getProjectionLeftjoinProgram(
const char* sourceCode = "__kernel void project (\n"
"__global struct{int count; int padding; char values[];}*
outputTail,\n"
"__global struct{int count; int padding; int positions[];}*
inputTail,"
- "__global const char* approximation\n) {\n"
+ "__global const struct{int count; int padding; char values[];}*
approximationTail\n) {\n"
+ " __global const char* approximation =
approximationTail->values;"
" const int offset =
inputTail->positions[get_global_id(0)]*approximationBytes;\n"
- " for(int i = 0; i < approximationBytes; i++)\n"
+ " int value = 0;"
+ " for(int i = 0; i < approximationBytes; i++){\n"
" outputTail->values[get_global_id(0)*approximationBytes+i]
= approximation[offset + i];\n"
+ " value += approximation[offset + i] << 8*i;"
+ " }\n"
+ /* " printf(\"projected value (%d): %d\\n\",
inputTail->positions[get_global_id(0)], value);" */
"}";
char options[64];
snprintf(options, 64, "-D approximationBytes=%d",
approximationBits/8);
@@ -69,33 +74,35 @@ cl_program getProjectionLeftjoinProgram(
/* } */
cl_program getUSelectProgram(int type, char* predicateOperation, char*
predicateOperation2, unsigned int approximationBits){
- const char* sourceCodeTemplate = "__kernel void uselect
(\n"
- "__global struct{int count; int padding; int
positions[];}* outputHead,\n"
- "__global struct{int count; int padding; char
values[];}* outputTail,\n"
- "__global const char* approximation"
- ",\n"
- "const %1$s operand,\n"
- "const %1$s operand2\n"
- ") {\n"
- " %1$s value = 0;\n"
- " const size_t inputOffset = get_global_id(0)*%4$d;\n"
- " for(int i = 0; i < %4$d; i++)\n"
- " value += (approximation[inputOffset + i] <<
((i+sizeof(%1$s) - %4$d)*8));\n"
- "\n"
- " if((value %2$s operand)"
- " && (%5$d || value %3$s operand2)"
- " )"
- "{\n"
- " const int index =
atomic_inc(&(outputHead->count));"
- " const int offset = index * %4$d;\n"
- " outputHead->positions[index] =
get_global_id(0);\n"
- " for(int i = 0; i < %4$d; i++)\n"
- " outputTail->values[offset+i] =
approximation[inputOffset + i];\n"
- " }\n"
- "}";
- char* sourceCode = malloc(16384);
- snprintf(sourceCode, 16384, sourceCodeTemplate,
(str[]){[TYPE_int] = "int"}[type], approximateOperation(predicateOperation),
approximateOperation(predicateOperation2), approximationBits/8,
predicateOperation2 == NULL?1:0);
- cl_program program = compileProgram(sourceCode,"");
- free(sourceCode);
- return program;
+ const char* sourceCodeTemplate = "__kernel void uselect (\n"
+ "__global struct{int count; int padding; int positions[];}*
outputHead,\n"
+ "__global struct{int count; int padding; char values[];}*
outputTail,\n"
+ "__global const struct{int count; int padding; char values[];}*
approximationTail\n"
+ ",\n"
+ "const %1$s operand,\n"
+ "const %1$s operand2\n"
+ ") {\n"
+ " __global const char* approximation =
approximationTail->values;"
+ " %1$s value = 0;\n"
+ " const size_t inputOffset = get_global_id(0)*%4$d;\n"
+ " for(int i = 0; i < %4$d; i++)\n"
+ " value += (approximation[inputOffset + i] <<
((i+sizeof(%1$s) - %4$d)*8));\n"
+ "\n"
+ " if((value %2$s operand)"
+ " && (%5$d || value %3$s operand2)"
+ " )"
+ "{\n"
+ " const int index = atomic_inc(&(outputHead->count));"
+ " atomic_inc(&(outputTail->count));" // TODO: this could
probably be done more efficiently
+ " const int offset = index * %4$d;\n"
+ " outputHead->positions[index] = get_global_id(0);\n"
+ " for(int i = 0; i < %4$d; i++)\n"
+ " outputTail->values[offset+i] = approximation[inputOffset
+ i];\n"
+ " }\n"
+ "}";
+ char* sourceCode = malloc(16384);
+ snprintf(sourceCode, 16384, sourceCodeTemplate, (str[]){[TYPE_int] =
"int"}[type], approximateOperation(predicateOperation),
approximateOperation(predicateOperation2), approximationBits/8,
predicateOperation2 == NULL?1:0);
+ cl_program program = compileProgram(sourceCode,"");
+ free(sourceCode);
+ return program;
}
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
@@ -19,27 +19,27 @@ static const int activateWorkInProgress
#pragma mark Actual MAL Operations Implementation
-static const char* typeNames[] = {[TYPE_int] = "int", [TYPE_void] = "void",
[TYPE_oid] = "oid"};
-
-typedef struct {
- int count;
- int padding;
- char elements[];
-} clTail;
-
-typedef struct {
- int count;
- int padding;
- int positions[];
-} clHead;
+int getCount(cl_mem memoryObject){
+ cl_int err = 0;
+ int result;
+ err = clEnqueueReadBuffer(getCommandQueue(), memoryObject, CL_TRUE, 0,
sizeof(int), &result, 0, NULL, NULL);
+
+ if(err)
+ printf("#%s, clEnqueueReadBuffer: %s;\n", __func__,
clError(err));
+ return result;
+}
clHead* getPositionsColumn(cl_mem memoryObject, clHead* buffer, size_t*
bufferSize){
- cl_int err;
+ cl_int err = 0;
if(!buffer)
clGetMemObjectInfo(memoryObject, CL_MEM_SIZE, sizeof(size_t),
bufferSize, NULL);
- else
- err = clEnqueueReadBuffer(getCommandQueue(), memoryObject,
CL_TRUE, 0, *bufferSize, buffer, 0, NULL, NULL);
- if(err) printf("#%s, clEnqueueReadBuffer: %s;\n", __func__,
clError(err));
+ else{
+ assert(*bufferSize > 0);
+ err = clEnqueueReadBuffer(getCommandQueue(), memoryObject,
CL_TRUE, 0, *bufferSize, buffer, 0, NULL, NULL); }
+
+ if(err){
+ printf("#%s, clEnqueueReadBuffer: %s;\n", __func__,
clError(err));
+ }
return buffer;
}
@@ -62,8 +62,10 @@ str BWDLeftJoinApproximate(bat * res, ba
}
BAT* left = BATdescriptor(*l);
- if(BAThvoid(left) && BATtvoid(left) && BAThvoid(right) &&
right->tseqbase != oid_nil){
- // not sure if this is actually used (or even correct)
+ printf ("%s left bat (%d) is of type [%s%s, %s%s]\n", __func__,
left->batCacheid, typeNames[BAThtype(left)], BAThvoid(left)?" (void)":"",
typeNames[BATttype(left)], BATtvoid(left)?" (void)":"");
+
+ if(0 && BAThvoid(left) && BATtvoid(left) && BAThvoid(right) &&
right->tseqbase != oid_nil){
+ // the more I think about this, the more I feel this case can
never happen
BAT* result = BATnew(ATOMtype(left->htype),
ATOMtype(right->ttype), left->batCount);
BATsetcount(result, left->batCount);
bzero(Tloc(result, BUNfirst(result)),
left->batCount*sizeof(int));
@@ -88,20 +90,17 @@ str BWDLeftJoinApproximate(bat * res, ba
BBPreleaseref(left->batCacheid);
BBPreleaseref(right->batCacheid);
return MAL_SUCCEED;
- } else if(BAThvoid(left) && BAThvoid(right) && right->tseqbase
!= oid_nil){
+ } else if(BAThvoid(left) && BAThvoid(right) && right->tseqbase !=
oid_nil){
cl_mem leftColumn = batTailApproximation(left);
if(!leftColumn) leftColumn =
batHeadApproximation(BATmirror(left));
cl_mem rightColumn = batTailApproximation(right);
if(!rightColumn) rightColumn =
batHeadApproximation(BATmirror(right));
cl_program program =
getProjectionLeftjoinProgram(batTailApproximationBits(right));
-
-
cl_int err;
cl_kernel projectKernel = clCreateKernel(program, "project",
&err);
if(err) printf("#%s, clCreateKernel: %s;\n", __func__,
clError(err));
-
int headCount; // :-)
if((err = clEnqueueReadBuffer(getCommandQueue(), leftColumn,
CL_TRUE, 0, sizeof(int), &headCount , 0, NULL, NULL)))
printf("#%s, clEnqueueReadBuffer: %s;\n", __func__,
clError(err));
@@ -109,12 +108,13 @@ str BWDLeftJoinApproximate(bat * res, ba
BAT* result = BATnew(TYPE_void, ATOMtype(right->ttype), 0);
{
const unsigned int newIndex =
getNextFreeDecomposedBATSlotIndex();
- DecomposedBATSlot* slot =
getDecomposedBATSlot(newIndex);
+ DecomposedBATSlot* slot =
getDecomposedBATSlotForIndex(newIndex);
BATsetprop(result, batRegistryIndex, TYPE_int,
(int[]){newIndex});
slot->approximationBits =
batTailApproximationBits(right);
slot->residuals = NULL;
slot->tailPositions = leftColumn;
slot->tailApproximation =
clCreateBuffer(getCLContext(), CL_MEM_READ_WRITE,
headCount*slot->approximationBits/8+sizeof(clTail), NULL, &err);
+ assert(slot->tailPositions);
if(err) printf("#%s, clCreateBuffer: %s;\n", __func__,
clError(err));
clEnqueueWriteBuffer(getCommandQueue(),
slot->tailApproximation, CL_TRUE, 0, sizeof(int), &headCount, 0, NULL, NULL);
// I wonder what is faster transfering a single integer to the GPU or running a
kernel that initializes a value
@@ -162,13 +162,15 @@ str BWDLeftJoinRefine(bat * res, bat * l
return ALGleftjoin(res, l, r);
}
BAT* left = BATdescriptor(*l);
+ printf ("%s left bat (%d) is of type [%s%s, %s%s]\n", __func__,
left->batCacheid, typeNames[BAThtype(left)], BAThvoid(left)?" (void)":"",
typeNames[BATttype(left)], BATtvoid(left)?" (void)":"");
BAT* right = BATdescriptor(*r);
BAT* refinement;
BAT* approximation = BATdescriptor(*approx);
const register size_t approximationBits =
batTailApproximationBits(right);
/* BATnew(approximation->htype, approximation->ttype,
approximation->batCount); */
- if(BAThvoid(left) && BATtvoid(left) && BAThvoid(right) &&
right->tseqbase != oid_nil){
+ if(0 && BAThvoid(left) && BATtvoid(left) && BAThvoid(right) &&
right->tseqbase != oid_nil){
+ // not very likely optimization, hence disabled
if(!batTailIsDecomposed(right))
throw (MAL, "bwd.BWDLeftJoinApproximate", "bat is not
decomposed: %d", *r);
refinement = BATnew(ATOMtype(left->htype),
ATOMtype(right->ttype), left->batCount);
@@ -236,7 +238,7 @@ static inline void superverboseprintf(co
static inline str uselect(bat *res, bat *bid, ptr val, char *OP, ptr val2,
char *OP2, Client cntxt){
- BAT* data = BATdescriptor(*bid);
+BAT* data = BATdescriptor(*bid);
if(data == NULL)
return MAL_SUCCEED;
assert(ATOMstorage(BATttype(data)) == TYPE_int); // type specific
@@ -244,23 +246,28 @@ static inline str uselect(bat *res, bat
throw (MAL, "bwd problem", "while running %s, I noticed that
bat is not decomposed: %s", __func__, resolveBatToAttribute(data->batCacheid,
cntxt));
BAT* result = BATnew(BAThtype(data), TYPE_void, data->batCount);
//TODO: not sure if we actually need to allocate space here (count could be 0)
- if(data->batCount){
+ size_t dataCount = getCount(batTailApproximation(data));
+
+ if(dataCount){
{
const unsigned int newIndex =
getNextFreeDecomposedBATSlotIndex();
- DecomposedBATSlot* slot =
getDecomposedBATSlot(newIndex);
+ DecomposedBATSlot* slot =
getDecomposedBATSlotForIndex(newIndex);
BATsetprop(result, batRegistryIndex, TYPE_int,
(int[]){newIndex});
slot->approximationBits =
batTailApproximationBits(data);
slot->residuals = NULL;
cl_int err;
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);
+ const int size = dataCount*sizeof(int)+sizeof(clHead);
+ slot->headApproximation =
clCreateBuffer(getCLContext(), CL_MEM_READ_WRITE, size, NULL, &err);
slot->tailPositions = slot->headApproximation;
+ assert(slot->tailPositions);
+
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));
}
- cl_program program = getUSelectProgram(BATttype(data), OP, OP2,
batTailApproximationBits(data));
+ cl_program program =
getUSelectProgram(ATOMstorage(BATttype(data)), OP, OP2?OP2:"==",
batTailApproximationBits(data));
int err;
@@ -279,9 +286,10 @@ static inline str uselect(bat *res, bat
if((err = clSetKernelArg(selectKernel, 3+i,
sizeof(int), &(parameters[i])))) // type specific
printf("#%s, clSetKernelArg(%d): %s;\n",
__func__, 3+i, clError(err));
- err = clEnqueueNDRangeKernel(getCommandQueue(), selectKernel,
1, (const size_t[]){0}, (const size_t[]){BATcount(data)}, (const size_t[]){1},
0, NULL, NULL);
+ err = clEnqueueNDRangeKernel(getCommandQueue(), selectKernel,
1, (const size_t[]){0}, (const size_t[]){dataCount}, (const size_t[]){1}, 0,
NULL, NULL);
if(err) printf("#%s, clEnqueueNDRangeKernel: %s;\n", __func__,
clError(err));
}
+ printf ("%s result bat (%d) is of type [%s%s, %s%s]\n", __func__,
result->batCacheid, typeNames[BAThtype(result)], BAThvoid(result)?" (void)":"",
typeNames[BATttype(result)], BATtvoid(result)?" (void)":"");
BBPkeepref(*res = result->batCacheid);
BBPreleaseref(*bid);
return MAL_SUCCEED;
@@ -325,7 +333,8 @@ str uselectrefine(bat *res, bat *bid, pt
clTail* compressedTail;
{
size_t approximationSize;
-
clGetMemObjectInfo(batTailApproximation(approximation), CL_MEM_SIZE,
sizeof(size_t), &approximationSize, NULL);
+
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) printf("#%s, clEnqueueReadBuffer:
%s;\n", __func__, clError(err));
@@ -340,79 +349,79 @@ str uselectrefine(bat *res, bat *bid, pt
const unsigned int residualBytes =
batTailResidualBits(data)/8;
int i = 0, j = 0;
+
+ if(1){
#define refineLoopDoubleOperator(comparator, comparator2)
\
- while(i < candidateCount) {
\
+ while(i < candidateCount) {
\
+ 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 &&
\
+ deCompressedValue comparator2
*(int*)val2) { \
+ positionRegion[j++] = index;
\
+ }
\
+ }
+#define refineLoopSingleOperator(comparator)
\
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list