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 #ifndef SC_OPENCL_OPBASE_HXX
11 #define SC_OPENCL_OPBASE_HXX
13 #include <sal/log.hxx>
15 #include "clcc/clew.h"
17 #include "formula/token.hxx"
18 #include "formula/vectortoken.hxx"
19 #include <boost/shared_ptr.hpp>
20 #include <boost/noncopyable.hpp>
24 namespace sc
{ namespace opencl
{
26 class FormulaTreeNode
;
34 UnhandledToken(formula::FormulaToken
*t
,
35 const char *const m
, std::string fn
="", int ln
=0):
36 mToken(t
), mMessage(m
), mFile(fn
), mLineNumber(ln
) {}
37 formula::FormulaToken
*mToken
;
43 /// Failed in marshaling
47 const char *strerror(cl_int i
)
49 #define CASE(val) case val: return #val
53 CASE(CL_DEVICE_NOT_FOUND
);
54 CASE(CL_DEVICE_NOT_AVAILABLE
);
55 CASE(CL_COMPILER_NOT_AVAILABLE
);
56 CASE(CL_MEM_OBJECT_ALLOCATION_FAILURE
);
57 CASE(CL_OUT_OF_RESOURCES
);
58 CASE(CL_OUT_OF_HOST_MEMORY
);
59 CASE(CL_PROFILING_INFO_NOT_AVAILABLE
);
60 CASE(CL_MEM_COPY_OVERLAP
);
61 CASE(CL_IMAGE_FORMAT_MISMATCH
);
62 CASE(CL_IMAGE_FORMAT_NOT_SUPPORTED
);
63 CASE(CL_BUILD_PROGRAM_FAILURE
);
65 CASE(CL_INVALID_VALUE
);
66 CASE(CL_INVALID_DEVICE_TYPE
);
67 CASE(CL_INVALID_PLATFORM
);
68 CASE(CL_INVALID_DEVICE
);
69 CASE(CL_INVALID_CONTEXT
);
70 CASE(CL_INVALID_QUEUE_PROPERTIES
);
71 CASE(CL_INVALID_COMMAND_QUEUE
);
72 CASE(CL_INVALID_HOST_PTR
);
73 CASE(CL_INVALID_MEM_OBJECT
);
74 CASE(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR
);
75 CASE(CL_INVALID_IMAGE_SIZE
);
76 CASE(CL_INVALID_SAMPLER
);
77 CASE(CL_INVALID_BINARY
);
78 CASE(CL_INVALID_BUILD_OPTIONS
);
79 CASE(CL_INVALID_PROGRAM
);
80 CASE(CL_INVALID_PROGRAM_EXECUTABLE
);
81 CASE(CL_INVALID_KERNEL_NAME
);
82 CASE(CL_INVALID_KERNEL_DEFINITION
);
83 CASE(CL_INVALID_KERNEL
);
84 CASE(CL_INVALID_ARG_INDEX
);
85 CASE(CL_INVALID_ARG_VALUE
);
86 CASE(CL_INVALID_ARG_SIZE
);
87 CASE(CL_INVALID_KERNEL_ARGS
);
88 CASE(CL_INVALID_WORK_DIMENSION
);
89 CASE(CL_INVALID_WORK_GROUP_SIZE
);
90 CASE(CL_INVALID_WORK_ITEM_SIZE
);
91 CASE(CL_INVALID_GLOBAL_OFFSET
);
92 CASE(CL_INVALID_EVENT_WAIT_LIST
);
93 CASE(CL_INVALID_EVENT
);
94 CASE(CL_INVALID_OPERATION
);
95 CASE(CL_INVALID_GL_OBJECT
);
96 CASE(CL_INVALID_BUFFER_SIZE
);
97 CASE(CL_INVALID_MIP_LEVEL
);
98 CASE(CL_INVALID_GLOBAL_WORK_SIZE
);
100 return "Unknown OpenCL error code";
106 OpenCLError(cl_int err
): mError(err
)
108 SAL_INFO("sc.opencl", "OpenCLError:" << mError
<< ": " << strerror(mError
));
113 /// Inconsistent state
117 Unhandled(std::string fn
="", int ln
=0):
118 mFile(fn
), mLineNumber(ln
) {}
123 typedef boost::shared_ptr
<FormulaTreeNode
> FormulaTreeNodeRef
;
125 class FormulaTreeNode
128 FormulaTreeNode(formula::FormulaToken
*ft
): mpCurrentFormula(ft
)
132 std::vector
<FormulaTreeNodeRef
> Children
;
133 formula::FormulaToken
*GetFormulaToken(void) const
135 return mpCurrentFormula
;
138 formula::FormulaToken
*const mpCurrentFormula
;
141 /// (Partially) abstract base class for an operand
142 class DynamicKernelArgument
: boost::noncopyable
145 DynamicKernelArgument(const std::string
&s
, FormulaTreeNodeRef ft
);
147 const std::string
&GetNameAsString(void) const { return mSymName
; }
148 /// Generate declaration
149 virtual void GenDecl(std::stringstream
&ss
) const = 0;
151 /// When declared as input to a sliding window function
152 virtual void GenSlidingWindowDecl(std::stringstream
&ss
) const = 0;
154 /// When referenced in a sliding window function
155 virtual std::string
GenSlidingWindowDeclRef(bool=false) const = 0;
157 /// When Mix, it will be called
158 virtual std::string
GenDoubleSlidingWindowDeclRef(bool=false) const
159 { return std::string(""); }
161 /// When Mix, it will be called
162 virtual std::string
GenStringSlidingWindowDeclRef(bool=false) const
163 { return std::string(""); }
165 /// Generate use/references to the argument
166 virtual void GenDeclRef(std::stringstream
&ss
) const;
168 /// Create buffer and pass the buffer to a given kernel
169 virtual size_t Marshal(cl_kernel
, int, int, cl_program
) = 0;
171 virtual ~DynamicKernelArgument() {}
173 virtual void GenSlidingWindowFunction(std::stringstream
&) {}
174 const std::string
&GetSymName(void) const { return mSymName
; }
175 formula::FormulaToken
*GetFormulaToken(void) const;
176 virtual size_t GetWindowSize(void) const = 0;
177 virtual std::string
DumpOpName(void) const { return std::string(""); }
178 virtual void DumpInlineFun(std::set
<std::string
>& ,
179 std::set
<std::string
>& ) const {}
180 const std::string
& GetName(void) const { return mSymName
; }
181 virtual bool NeedParallelReduction(void) const { return false; }
184 std::string mSymName
;
185 FormulaTreeNodeRef mFormulaTree
;
188 /// Holds an input (read-only) argument reference to a SingleVectorRef.
189 /// or a DoubleVectorRef for non-sliding-window argument of complex functions
190 /// like SumOfProduct
191 /// In most of the cases the argument is introduced
192 /// by a Push operation in the given RPN.
193 class VectorRef
: public DynamicKernelArgument
196 VectorRef(const std::string
&s
, FormulaTreeNodeRef ft
, int index
= 0);
198 const std::string
&GetNameAsString(void) const { return mSymName
; }
199 /// Generate declaration
200 virtual void GenDecl(std::stringstream
&ss
) const;
201 /// When declared as input to a sliding window function
202 virtual void GenSlidingWindowDecl(std::stringstream
&ss
) const;
204 /// When referenced in a sliding window function
205 virtual std::string
GenSlidingWindowDeclRef(bool=false) const;
207 /// Create buffer and pass the buffer to a given kernel
208 virtual size_t Marshal(cl_kernel
, int, int, cl_program
);
210 virtual ~VectorRef();
212 virtual void GenSlidingWindowFunction(std::stringstream
&) {}
213 const std::string
&GetSymName(void) const { return mSymName
; }
214 virtual size_t GetWindowSize(void) const;
215 virtual std::string
DumpOpName(void) const { return std::string(""); }
216 virtual void DumpInlineFun(std::set
<std::string
>& ,
217 std::set
<std::string
>& ) const {}
218 const std::string
& GetName(void) const { return mSymName
; }
219 virtual cl_mem
GetCLBuffer(void) const { return mpClmem
; }
220 virtual bool NeedParallelReduction(void) const { return false; }
223 // Used by marshaling
225 // index in multiple double vector refs that have multiple ranges
228 /// Abstract class for code generation
233 typedef std::vector
<std::string
> ArgVector
;
234 typedef std::vector
<std::string
>::iterator ArgVectorIter
;
235 virtual std::string
GetBottom(void) {return "";};
236 virtual std::string
Gen2(const std::string
&/*lhs*/,
237 const std::string
&/*rhs*/) const {return "";}
238 virtual std::string
Gen(ArgVector
& /*argVector*/){return "";};
239 virtual std::string
BinFuncName(void)const {return "";};
240 virtual void BinInlineFun(std::set
<std::string
>& ,
241 std::set
<std::string
>& ) {}
242 virtual bool takeString() const = 0;
243 virtual bool takeNumeric() const = 0;
247 class SlidingFunctionBase
: public OpBase
250 typedef boost::shared_ptr
<DynamicKernelArgument
> SubArgument
;
251 typedef std::vector
<SubArgument
> SubArguments
;
252 virtual void GenSlidingWindowFunction(std::stringstream
&,
253 const std::string
, SubArguments
&) = 0;
254 virtual ~SlidingFunctionBase() {};
257 class Normal
: public SlidingFunctionBase
260 virtual void GenSlidingWindowFunction(std::stringstream
&ss
,
261 const std::string sSymName
, SubArguments
&vSubArguments
);
262 virtual bool takeString() const { return false; }
263 virtual bool takeNumeric() const { return true; }
266 class CheckVariables
:public Normal
269 void GenTmpVariables(std::stringstream
&ss
, SubArguments
&vSubArguments
);
270 void CheckSubArgumentIsNan(std::stringstream
&ss
,
271 SubArguments
&vSubArguments
, int argumentNum
);
272 void CheckAllSubArgumentIsNan(std::stringstream
&ss
,
273 SubArguments
&vSubArguments
);
275 void CheckSubArgumentIsNan2(std::stringstream
&ss
,
276 SubArguments
&vSubArguments
, int argumentNum
, std::string p
);
277 void UnrollDoubleVector(std::stringstream
&ss
,
278 std::stringstream
&unrollstr
, const formula::DoubleVectorRefToken
* pCurDVR
,
286 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */