1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include <opencl/openclwrapper.hxx>
14 using namespace formula
;
16 namespace sc
{ namespace opencl
{
18 UnhandledToken::UnhandledToken(
19 formula::FormulaToken
* t
, const char* m
, const std::string
& fn
, int ln
) :
20 mToken(t
), mMessage(m
), mFile(fn
), mLineNumber(ln
) {}
22 OpenCLError::OpenCLError( const std::string
& function
, cl_int error
, const std::string
& file
, int line
) :
23 mFunction(function
), mError(error
), mFile(file
), mLineNumber(line
)
25 // Not sure if this SAL_INFO() is useful; the place in
26 // CLInterpreterContext::launchKernel() where OpenCLError is
27 // caught already uses SAL_WARN() to display it.
29 // SAL_INFO("sc.opencl", "OpenCL error: " << ::opencl::errorString(mError));
32 Unhandled::Unhandled( const std::string
& fn
, int ln
) :
33 mFile(fn
), mLineNumber(ln
) {}
35 DynamicKernelArgument::DynamicKernelArgument( const ScCalcConfig
& config
, const std::string
& s
,
36 FormulaTreeNodeRef ft
) :
37 mCalcConfig(config
), mSymName(s
), mFormulaTree(ft
) { }
39 std::string
DynamicKernelArgument::GenDoubleSlidingWindowDeclRef( bool ) const
41 return std::string("");
44 /// When Mix, it will be called
45 std::string
DynamicKernelArgument::GenStringSlidingWindowDeclRef( bool ) const
47 return std::string("");
50 bool DynamicKernelArgument::IsMixedArgument() const
55 /// Generate use/references to the argument
56 void DynamicKernelArgument::GenDeclRef( std::stringstream
& ss
) const
61 void DynamicKernelArgument::GenNumDeclRef( std::stringstream
& ss
) const
66 void DynamicKernelArgument::GenStringDeclRef( std::stringstream
& ss
) const
71 void DynamicKernelArgument::GenSlidingWindowFunction( std::stringstream
& ) {}
73 FormulaToken
* DynamicKernelArgument::GetFormulaToken() const
75 return mFormulaTree
->GetFormulaToken();
78 std::string
DynamicKernelArgument::DumpOpName() const
80 return std::string("");
83 void DynamicKernelArgument::DumpInlineFun( std::set
<std::string
>&, std::set
<std::string
>& ) const {}
85 const std::string
& DynamicKernelArgument::GetName() const
90 bool DynamicKernelArgument::NeedParallelReduction() const
95 VectorRef::VectorRef( const ScCalcConfig
& config
, const std::string
& s
, FormulaTreeNodeRef ft
, int idx
) :
96 DynamicKernelArgument(config
, s
, ft
), mpClmem(NULL
), mnIndex(idx
)
100 std::stringstream ss
;
101 ss
<< mSymName
<< "s" << mnIndex
;
106 VectorRef::~VectorRef()
111 err
= clReleaseMemObject(mpClmem
);
112 SAL_WARN_IF(err
!= CL_SUCCESS
, "sc.opencl", "clReleaseMemObject failed: " << ::opencl::errorString(err
));
116 /// Generate declaration
117 void VectorRef::GenDecl( std::stringstream
& ss
) const
119 ss
<< "__global double *" << mSymName
;
122 /// When declared as input to a sliding window function
123 void VectorRef::GenSlidingWindowDecl( std::stringstream
& ss
) const
125 VectorRef::GenDecl(ss
);
128 /// When referenced in a sliding window function
129 std::string
VectorRef::GenSlidingWindowDeclRef( bool nested
) const
131 std::stringstream ss
;
132 formula::SingleVectorRefToken
* pSVR
=
133 dynamic_cast<formula::SingleVectorRefToken
*>(DynamicKernelArgument::GetFormulaToken());
135 ss
<< "(gid0 < " << pSVR
->GetArrayLength() << "?";
136 ss
<< mSymName
<< "[gid0]";
142 void VectorRef::GenSlidingWindowFunction( std::stringstream
& ) {}
144 size_t VectorRef::GetWindowSize() const
146 FormulaToken
* pCur
= mFormulaTree
->GetFormulaToken();
148 if (const formula::DoubleVectorRefToken
* pCurDVR
=
149 dynamic_cast<const formula::DoubleVectorRefToken
*>(pCur
))
151 return pCurDVR
->GetRefRowSize();
153 else if (dynamic_cast<const formula::SingleVectorRefToken
*>(pCur
))
155 // Prepare intermediate results (on CPU for now)
164 std::string
VectorRef::DumpOpName() const
166 return std::string("");
169 void VectorRef::DumpInlineFun( std::set
<std::string
>&, std::set
<std::string
>& ) const {}
171 const std::string
& VectorRef::GetName() const
176 cl_mem
VectorRef::GetCLBuffer() const
181 bool VectorRef::NeedParallelReduction() const
186 void Normal::GenSlidingWindowFunction(
187 std::stringstream
& ss
, const std::string
& sSymName
, SubArguments
& vSubArguments
)
190 ss
<< "\ndouble " << sSymName
;
191 ss
<< "_" << BinFuncName() << "(";
192 for (unsigned i
= 0; i
< vSubArguments
.size(); i
++)
196 vSubArguments
[i
]->GenSlidingWindowDecl(ss
);
197 argVector
.push_back(vSubArguments
[i
]->GenSlidingWindowDeclRef());
200 ss
<< "double tmp = " << GetBottom() << ";\n\t";
201 ss
<< "int gid0 = get_global_id(0);\n\t";
203 ss
<< Gen(argVector
);
205 ss
<< "return tmp;\n";
209 void CheckVariables::GenTmpVariables(
210 std::stringstream
& ss
, SubArguments
& vSubArguments
)
212 for (unsigned i
= 0; i
< vSubArguments
.size(); i
++)
220 void CheckVariables::CheckSubArgumentIsNan( std::stringstream
& ss
,
221 SubArguments
& vSubArguments
, int argumentNum
)
224 if (vSubArguments
[i
]->GetFormulaToken()->GetType() ==
225 formula::svSingleVectorRef
)
227 const formula::SingleVectorRefToken
* pTmpDVR1
=
228 static_cast<const formula::SingleVectorRefToken
*>(vSubArguments
[i
]->GetFormulaToken());
229 ss
<< " if(singleIndex>=";
230 ss
<< pTmpDVR1
->GetArrayLength();
233 ss
<< vSubArguments
[i
]->GenSlidingWindowDeclRef(true);
237 ss
<< "=0;\n else \n";
241 ss
<< vSubArguments
[i
]->GenSlidingWindowDeclRef(true);
244 if (vSubArguments
[i
]->GetFormulaToken()->GetType() ==
245 formula::svDoubleVectorRef
)
247 const formula::DoubleVectorRefToken
* pTmpDVR2
=
248 static_cast<const formula::DoubleVectorRefToken
*>(vSubArguments
[i
]->GetFormulaToken());
249 ss
<< " if(doubleIndex>=";
250 ss
<< pTmpDVR2
->GetArrayLength();
253 ss
<< vSubArguments
[i
]->GenSlidingWindowDeclRef(false);
257 ss
<< "=0;\n else \n";
261 ss
<< vSubArguments
[i
]->GenSlidingWindowDeclRef(false);
264 if (vSubArguments
[i
]->GetFormulaToken()->GetType() == formula::svDouble
||
265 vSubArguments
[i
]->GetFormulaToken()->GetOpCode() != ocPush
)
269 ss
<< vSubArguments
[i
]->GenSlidingWindowDeclRef();
273 ss
<< "=0;\n else \n";
277 ss
<< vSubArguments
[i
]->GenSlidingWindowDeclRef();
284 void CheckVariables::CheckSubArgumentIsNan2( std::stringstream
& ss
,
285 SubArguments
& vSubArguments
, int argumentNum
, std::string p
)
288 if (vSubArguments
[i
]->GetFormulaToken()->GetType() == formula::svDouble
)
293 vSubArguments
[i
]->GenDeclRef(ss
);
301 vSubArguments
[i
]->GenDeclRef(ss
);
302 if (vSubArguments
[i
]->GetFormulaToken()->GetType() ==
303 formula::svDoubleVectorRef
)
304 ss
<< "[" << p
.c_str() << "]";
305 else if (vSubArguments
[i
]->GetFormulaToken()->GetType() ==
306 formula::svSingleVectorRef
)
307 ss
<< "[get_group_id(1)]";
311 void CheckVariables::CheckAllSubArgumentIsNan(
312 std::stringstream
& ss
, SubArguments
& vSubArguments
)
314 ss
<< " int k = gid0;\n";
315 for (unsigned i
= 0; i
< vSubArguments
.size(); i
++)
317 CheckSubArgumentIsNan(ss
, vSubArguments
, i
);
321 void CheckVariables::UnrollDoubleVector( std::stringstream
& ss
,
322 std::stringstream
& unrollstr
, const formula::DoubleVectorRefToken
* pCurDVR
,
326 if (!pCurDVR
->IsStartFixed() && pCurDVR
->IsEndFixed())
328 ss
<< " loop = (" << nCurWindowSize
<< " - gid0)/";
329 ss
<< unrollSize
<< ";\n";
331 else if (pCurDVR
->IsStartFixed() && !pCurDVR
->IsEndFixed())
333 ss
<< " loop = (" << nCurWindowSize
<< " + gid0)/";
334 ss
<< unrollSize
<< ";\n";
339 ss
<< " loop = " << nCurWindowSize
<< "/" << unrollSize
<< ";\n";
342 ss
<< " for ( int j = 0;j< loop; j++)\n";
345 if (!pCurDVR
->IsStartFixed() && pCurDVR
->IsEndFixed())
347 ss
<< "gid0 + j * " << unrollSize
<< ";\n";
351 ss
<< "j * " << unrollSize
<< ";\n";
354 if (!pCurDVR
->IsStartFixed() && !pCurDVR
->IsEndFixed())
356 ss
<< " int doubleIndex = i+gid0;\n";
360 ss
<< " int doubleIndex = i;\n";
363 for (int j
= 0; j
< unrollSize
; j
++)
365 ss
<< unrollstr
.str();
367 ss
<< "doubleIndex++;\n";
370 ss
<< " for (int i = ";
371 if (!pCurDVR
->IsStartFixed() && pCurDVR
->IsEndFixed())
373 ss
<< "gid0 + loop *" << unrollSize
<< "; i < ";
374 ss
<< nCurWindowSize
<< "; i++)\n";
376 else if (pCurDVR
->IsStartFixed() && !pCurDVR
->IsEndFixed())
378 ss
<< "0 + loop *" << unrollSize
<< "; i < gid0+";
379 ss
<< nCurWindowSize
<< "; i++)\n";
383 ss
<< "0 + loop *" << unrollSize
<< "; i < ";
384 ss
<< nCurWindowSize
<< "; i++)\n";
387 if (!pCurDVR
->IsStartFixed() && !pCurDVR
->IsEndFixed())
389 ss
<< " int doubleIndex = i+gid0;\n";
393 ss
<< " int doubleIndex = i;\n";
395 ss
<< unrollstr
.str();
401 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */