Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : */
9 :
10 : #ifndef SC_OPENCL_OPBASE_HXX
11 : #define SC_OPENCL_OPBASE_HXX
12 :
13 : #include <sal/log.hxx>
14 :
15 : #include "clcc/clew.h"
16 :
17 : #include "formula/token.hxx"
18 : #include "formula/vectortoken.hxx"
19 : #include <boost/shared_ptr.hpp>
20 : #include <boost/noncopyable.hpp>
21 : #include <set>
22 : #define ISNAN
23 :
24 : namespace sc { namespace opencl {
25 :
26 : class FormulaTreeNode;
27 :
28 : /// Exceptions
29 :
30 : /// Failed in parsing
31 0 : class UnhandledToken
32 : {
33 : public:
34 0 : UnhandledToken(formula::FormulaToken *t,
35 : const char *const m, std::string fn="", int ln=0):
36 0 : mToken(t), mMessage(m), mFile(fn), mLineNumber(ln) {}
37 : formula::FormulaToken *mToken;
38 : std::string mMessage;
39 : std::string mFile;
40 : int mLineNumber;
41 : };
42 :
43 : /// Failed in marshaling
44 0 : class OpenCLError
45 : {
46 : private:
47 : const char *strerror(cl_int i)
48 : {
49 : #define CASE(val) case val: return #val
50 : switch (i)
51 : {
52 : CASE(CL_SUCCESS);
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);
64 : CASE(CL_MAP_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);
99 : default:
100 : return "Unknown OpenCL error code";
101 : }
102 : #undef CASE
103 : }
104 :
105 : public:
106 0 : OpenCLError(cl_int err, std::string fn, int ln): mError(err),
107 0 : mFile(fn), mLineNumber(ln)
108 : {
109 : SAL_INFO("sc.opencl", "OpenCLError:" << mError << ": " << strerror(mError));
110 0 : }
111 : cl_int mError;
112 : std::string mFile;
113 : int mLineNumber;
114 : };
115 :
116 : /// Inconsistent state
117 0 : class Unhandled
118 : {
119 : public:
120 0 : Unhandled(std::string fn="", int ln=0):
121 0 : mFile(fn), mLineNumber(ln) {}
122 : std::string mFile;
123 : int mLineNumber;
124 : };
125 :
126 : typedef boost::shared_ptr<FormulaTreeNode> FormulaTreeNodeRef;
127 :
128 0 : class FormulaTreeNode
129 : {
130 : public:
131 0 : FormulaTreeNode(const formula::FormulaToken* ft): mpCurrentFormula(ft)
132 : {
133 0 : Children.reserve(8);
134 0 : }
135 : std::vector<FormulaTreeNodeRef> Children;
136 0 : formula::FormulaToken *GetFormulaToken(void) const
137 : {
138 0 : return const_cast<formula::FormulaToken*>(mpCurrentFormula.get());
139 : }
140 : private:
141 : formula::FormulaConstTokenRef mpCurrentFormula;
142 : };
143 :
144 : /// (Partially) abstract base class for an operand
145 : class DynamicKernelArgument : boost::noncopyable
146 : {
147 : public:
148 : DynamicKernelArgument(const std::string &s, FormulaTreeNodeRef ft);
149 :
150 0 : const std::string &GetNameAsString(void) const { return mSymName; }
151 : /// Generate declaration
152 : virtual void GenDecl(std::stringstream &ss) const = 0;
153 :
154 : /// When declared as input to a sliding window function
155 : virtual void GenSlidingWindowDecl(std::stringstream &ss) const = 0;
156 :
157 : /// When referenced in a sliding window function
158 : virtual std::string GenSlidingWindowDeclRef(bool=false) const = 0;
159 :
160 : /// When Mix, it will be called
161 0 : virtual std::string GenDoubleSlidingWindowDeclRef(bool=false) const
162 0 : { return std::string(""); }
163 :
164 : /// When Mix, it will be called
165 0 : virtual std::string GenStringSlidingWindowDeclRef(bool=false) const
166 0 : { return std::string(""); }
167 :
168 : /// Generate use/references to the argument
169 : virtual void GenDeclRef(std::stringstream &ss) const;
170 :
171 : /// Create buffer and pass the buffer to a given kernel
172 : virtual size_t Marshal(cl_kernel, int, int, cl_program) = 0;
173 :
174 0 : virtual ~DynamicKernelArgument() {}
175 :
176 0 : virtual void GenSlidingWindowFunction(std::stringstream &) {}
177 : const std::string &GetSymName(void) const { return mSymName; }
178 : formula::FormulaToken *GetFormulaToken(void) const;
179 : virtual size_t GetWindowSize(void) const = 0;
180 0 : virtual std::string DumpOpName(void) const { return std::string(""); }
181 0 : virtual void DumpInlineFun(std::set<std::string>& ,
182 0 : std::set<std::string>& ) const {}
183 0 : const std::string& GetName(void) const { return mSymName; }
184 0 : virtual bool NeedParallelReduction(void) const { return false; }
185 :
186 : protected:
187 : std::string mSymName;
188 : FormulaTreeNodeRef mFormulaTree;
189 : };
190 :
191 : /// Holds an input (read-only) argument reference to a SingleVectorRef.
192 : /// or a DoubleVectorRef for non-sliding-window argument of complex functions
193 : /// like SumOfProduct
194 : /// In most of the cases the argument is introduced
195 : /// by a Push operation in the given RPN.
196 : class VectorRef : public DynamicKernelArgument
197 : {
198 : public:
199 : VectorRef(const std::string &s, FormulaTreeNodeRef ft, int index = 0);
200 :
201 : const std::string &GetNameAsString(void) const { return mSymName; }
202 : /// Generate declaration
203 : virtual void GenDecl(std::stringstream &ss) const SAL_OVERRIDE;
204 : /// When declared as input to a sliding window function
205 : virtual void GenSlidingWindowDecl(std::stringstream &ss) const SAL_OVERRIDE;
206 :
207 : /// When referenced in a sliding window function
208 : virtual std::string GenSlidingWindowDeclRef(bool=false) const SAL_OVERRIDE;
209 :
210 : /// Create buffer and pass the buffer to a given kernel
211 : virtual size_t Marshal(cl_kernel, int, int, cl_program) SAL_OVERRIDE;
212 :
213 : virtual ~VectorRef();
214 :
215 0 : virtual void GenSlidingWindowFunction(std::stringstream &) SAL_OVERRIDE {}
216 : const std::string &GetSymName(void) const { return mSymName; }
217 : virtual size_t GetWindowSize(void) const SAL_OVERRIDE;
218 0 : virtual std::string DumpOpName(void) const SAL_OVERRIDE { return std::string(""); }
219 0 : virtual void DumpInlineFun(std::set<std::string>& ,
220 0 : std::set<std::string>& ) const SAL_OVERRIDE {}
221 0 : const std::string& GetName(void) const { return mSymName; }
222 0 : virtual cl_mem GetCLBuffer(void) const { return mpClmem; }
223 0 : virtual bool NeedParallelReduction(void) const SAL_OVERRIDE { return false; }
224 :
225 : protected:
226 : // Used by marshaling
227 : cl_mem mpClmem;
228 : // index in multiple double vector refs that have multiple ranges
229 : const int mnIndex;
230 : };
231 : /// Abstract class for code generation
232 :
233 0 : class OpBase
234 : {
235 : public:
236 : typedef std::vector<std::string> ArgVector;
237 : typedef std::vector<std::string>::iterator ArgVectorIter;
238 0 : virtual std::string GetBottom(void) {return "";};
239 0 : virtual std::string Gen2(const std::string &/*lhs*/,
240 0 : const std::string &/*rhs*/) const {return "";}
241 0 : virtual std::string Gen(ArgVector& /*argVector*/){return "";};
242 0 : virtual std::string BinFuncName(void)const {return "";};
243 0 : virtual void BinInlineFun(std::set<std::string>& ,
244 0 : std::set<std::string>& ) {}
245 : virtual bool takeString() const = 0;
246 : virtual bool takeNumeric() const = 0;
247 0 : virtual ~OpBase() {}
248 : };
249 :
250 0 : class SlidingFunctionBase : public OpBase
251 : {
252 : public:
253 : typedef boost::shared_ptr<DynamicKernelArgument> SubArgument;
254 : typedef std::vector<SubArgument> SubArguments;
255 : virtual void GenSlidingWindowFunction(std::stringstream &,
256 : const std::string&, SubArguments &) = 0;
257 0 : virtual ~SlidingFunctionBase() {};
258 : };
259 :
260 0 : class Normal: public SlidingFunctionBase
261 : {
262 : public:
263 : virtual void GenSlidingWindowFunction(std::stringstream &ss,
264 : const std::string &sSymName, SubArguments &vSubArguments) SAL_OVERRIDE;
265 0 : virtual bool takeString() const SAL_OVERRIDE { return false; }
266 0 : virtual bool takeNumeric() const SAL_OVERRIDE { return true; }
267 : };
268 :
269 0 : class CheckVariables:public Normal
270 : {
271 : public:
272 : void GenTmpVariables(std::stringstream &ss, SubArguments &vSubArguments);
273 : void CheckSubArgumentIsNan(std::stringstream &ss,
274 : SubArguments &vSubArguments, int argumentNum);
275 : void CheckAllSubArgumentIsNan(std::stringstream &ss,
276 : SubArguments &vSubArguments);
277 : // only check isNan
278 : void CheckSubArgumentIsNan2(std::stringstream &ss,
279 : SubArguments &vSubArguments, int argumentNum, std::string p);
280 : void UnrollDoubleVector(std::stringstream &ss,
281 : std::stringstream &unrollstr, const formula::DoubleVectorRefToken* pCurDVR,
282 : int nCurWindowSize);
283 : };
284 :
285 : }}
286 :
287 : #endif
288 :
289 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|