diff options
-rw-r--r-- | sc/source/core/opencl/formulagroupcl.cxx | 71 | ||||
-rw-r--r-- | sc/source/core/opencl/opbase.hxx | 10 |
2 files changed, 66 insertions, 15 deletions
diff --git a/sc/source/core/opencl/formulagroupcl.cxx b/sc/source/core/opencl/formulagroupcl.cxx index c4290f4eafd6..c02cef7578b9 100644 --- a/sc/source/core/opencl/formulagroupcl.cxx +++ b/sc/source/core/opencl/formulagroupcl.cxx @@ -72,8 +72,6 @@ size_t VectorRef::Marshal(cl_kernel k, int argno, int, cl_program) const formula::DoubleVectorRefToken* pDVR = dynamic_cast< const formula::DoubleVectorRefToken* >(ref); assert(pDVR); - if (pDVR->GetArrays()[mnIndex].mpNumericArray == NULL) - throw Unhandled(); pHostBuffer = const_cast<double*>( pDVR->GetArrays()[mnIndex].mpNumericArray); szHostBuffer = pDVR->GetArrayLength() * sizeof(double); @@ -84,12 +82,35 @@ size_t VectorRef::Marshal(cl_kernel k, int argno, int, cl_program) KernelEnv kEnv; OpenclDevice::setKernelEnv(&kEnv); cl_int err; - mpClmem = clCreateBuffer(kEnv.mpkContext, - (cl_mem_flags) CL_MEM_READ_ONLY|CL_MEM_USE_HOST_PTR, - szHostBuffer, - pHostBuffer, &err); - if (CL_SUCCESS != err) - throw OpenCLError(err); + if (pHostBuffer) + { + mpClmem = clCreateBuffer(kEnv.mpkContext, + (cl_mem_flags) CL_MEM_READ_ONLY|CL_MEM_USE_HOST_PTR, + szHostBuffer, + pHostBuffer, &err); + if (CL_SUCCESS != err) + throw OpenCLError(err); + } + else + { + if (szHostBuffer == 0) + szHostBuffer = sizeof(double); // a dummy small value + // Marshal as a buffer of NANs + mpClmem = clCreateBuffer(kEnv.mpkContext, + (cl_mem_flags) CL_MEM_READ_ONLY|CL_MEM_ALLOC_HOST_PTR, + szHostBuffer, NULL, &err); + if (CL_SUCCESS != err) + throw OpenCLError(err); + double *pNanBuffer = (double*)clEnqueueMapBuffer( + kEnv.mpkCmdQueue, mpClmem, CL_TRUE, CL_MAP_WRITE, 0, + szHostBuffer, 0, NULL, NULL, &err); + if (CL_SUCCESS != err) + throw OpenCLError(err); + for (size_t i = 0; i < szHostBuffer/sizeof(double); i++) + pNanBuffer[i] = NAN; + err = clEnqueueUnmapMemObject(kEnv.mpkCmdQueue, mpClmem, + pNanBuffer, 0, NULL, NULL); + } err = clSetKernelArg(k, argno, sizeof(cl_mem), (void*)&mpClmem); if (CL_SUCCESS != err) @@ -1414,9 +1435,9 @@ public: KernelEnv kEnv; OpenclDevice::setKernelEnv(&kEnv); cl_int err; + DynamicKernelArgument *Arg = mvSubArguments[0].get(); DynamicKernelSlidingArgument<VectorRef> *slidingArgPtr = - dynamic_cast< DynamicKernelSlidingArgument<VectorRef> *> - (mvSubArguments[0].get()); + dynamic_cast< DynamicKernelSlidingArgument<VectorRef> *> (Arg); cl_mem mpClmem2; if (OpSumCodeGen->NeedReductionKernel()) @@ -1590,6 +1611,8 @@ DynamicKernelArgument *VectorRefFactory(const std::string &s, //Black lists ineligible classes here .. // SUMIFS does not perform parallel reduction at DoubleVectorRef level if (dynamic_cast<OpSumIfs*>(pCodeGen.get())) { + if (index == 0) // the first argument of OpSumIfs cannot be strings anyway + return new DynamicKernelSlidingArgument<VectorRef>(s, ft, pCodeGen, index); return new DynamicKernelSlidingArgument<Base>(s, ft, pCodeGen, index); } // AVERAGE is not supported yet @@ -1650,7 +1673,9 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments( assert(pDVR); for (size_t j = 0; j < pDVR->GetArrays().size(); ++j) { - if (pDVR->GetArrays()[j].mpNumericArray) + if (pDVR->GetArrays()[j].mpNumericArray || + (pDVR->GetArrays()[j].mpNumericArray == NULL && + pDVR->GetArrays()[j].mpStringArray == NULL )) mvSubArguments.push_back( SubArgument(VectorRefFactory<VectorRef>( ts, ft->Children[i], mpCodeGen, j))); @@ -1687,9 +1712,17 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments( SubArgument(new DynamicKernelStringArgument( ts, ft->Children[i]))); } + else if (pSVR->GetArray().mpStringArray == NULL && + pSVR->GetArray().mpNumericArray == NULL) + { + // Push as an array of NANs + mvSubArguments.push_back( + SubArgument(new VectorRef(ts, + ft->Children[i]))); + } else throw UnhandledToken(pChild, - "Got unhandled case here"); + "Got unhandled case here", __FILE__, __LINE__); } else if (pChild->GetType() == formula::svDouble) { mvSubArguments.push_back( SubArgument(new DynamicKernelConstantArgument(ts, @@ -2736,7 +2769,8 @@ DynamicKernel* DynamicKernel::create(ScDocument& /* rDoc */, } catch (const UnhandledToken &ut) { std::cerr << "\nDynamic formual compiler: unhandled token: "; - std::cerr << ut.mMessage << "\n"; + std::cerr << ut.mMessage << " at "; + std::cerr << ut.mFile << ":" << ut.mLineNumber << "\n"; #ifdef NO_FALLBACK_TO_SWINTERP assert(false); #else @@ -2840,6 +2874,17 @@ bool FormulaGroupInterpreterOpenCL::interpret( ScDocument& rDoc, return false; #endif } + catch (const Unhandled &uh) { + std::cerr << "Dynamic formula compiler: unhandled case:"; + std::cerr <<" at "; + std::cerr << uh.mFile << ":" << uh.mLineNumber << "\n"; +#ifdef NO_FALLBACK_TO_SWINTERP + assert(false); + return true; +#else + return false; +#endif + } catch (...) { std::cerr << "Dynamic formula compiler: unhandled compiler error\n"; #ifdef NO_FALLBACK_TO_SWINTERP diff --git a/sc/source/core/opencl/opbase.hxx b/sc/source/core/opencl/opbase.hxx index 135ec4ddb4e3..22a9316f9015 100644 --- a/sc/source/core/opencl/opbase.hxx +++ b/sc/source/core/opencl/opbase.hxx @@ -30,9 +30,12 @@ class UnhandledToken { public: UnhandledToken(formula::FormulaToken *t, - const char *const m): mToken(t), mMessage(m) {} + const char *const m, std::string fn="", int ln=0): + mToken(t), mMessage(m), mFile(fn), mLineNumber(ln) {} formula::FormulaToken *mToken; std::string mMessage; + std::string mFile; + int mLineNumber; }; /// Failed in marshaling @@ -47,7 +50,10 @@ public: class Unhandled { public: - Unhandled() {} + Unhandled(std::string fn="", int ln=0): + mFile(fn), mLineNumber(ln) {} + std::string mFile; + int mLineNumber; }; typedef boost::shared_ptr<FormulaTreeNode> FormulaTreeNodeRef; |