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 INCLUDED_SC_SOURCE_CORE_OPENCL_OPBASE_HXX
11 : #define INCLUDED_SC_SOURCE_CORE_OPENCL_OPBASE_HXX
12 :
13 : #include <sal/log.hxx>
14 :
15 : #include <clew/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 :
23 : #include "calcconfig.hxx"
24 :
25 : namespace sc { namespace opencl {
26 :
27 : class FormulaTreeNode;
28 :
29 : /// Exceptions
30 :
31 : /// Failed in parsing
32 0 : class UnhandledToken
33 : {
34 : public:
35 : UnhandledToken( formula::FormulaToken* t, const char* m, const std::string& fn = "", int ln = 0 );
36 :
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 : public:
47 : OpenCLError( const std::string& function, cl_int error, const std::string& file, int line );
48 :
49 : std::string mFunction;
50 : cl_int mError;
51 : std::string mFile;
52 : int mLineNumber;
53 : };
54 :
55 : /// Inconsistent state
56 0 : class Unhandled
57 : {
58 : public:
59 : Unhandled( const std::string& fn = "", int ln = 0 );
60 :
61 : std::string mFile;
62 : int mLineNumber;
63 : };
64 :
65 : typedef boost::shared_ptr<FormulaTreeNode> FormulaTreeNodeRef;
66 :
67 0 : class FormulaTreeNode
68 : {
69 : public:
70 0 : FormulaTreeNode( const formula::FormulaToken* ft ) : mpCurrentFormula(ft)
71 : {
72 0 : Children.reserve(8);
73 0 : }
74 : std::vector<FormulaTreeNodeRef> Children;
75 0 : formula::FormulaToken* GetFormulaToken() const
76 : {
77 0 : return const_cast<formula::FormulaToken*>(mpCurrentFormula.get());
78 : }
79 :
80 : private:
81 : formula::FormulaConstTokenRef mpCurrentFormula;
82 : };
83 :
84 : /// (Partially) abstract base class for an operand
85 : class DynamicKernelArgument : boost::noncopyable
86 : {
87 : public:
88 : DynamicKernelArgument( const ScCalcConfig& config, const std::string& s, FormulaTreeNodeRef ft );
89 0 : virtual ~DynamicKernelArgument() {}
90 :
91 : /// Generate declaration
92 : virtual void GenDecl( std::stringstream& ss ) const = 0;
93 :
94 : /// When declared as input to a sliding window function
95 : virtual void GenSlidingWindowDecl( std::stringstream& ss ) const = 0;
96 :
97 : /// When referenced in a sliding window function
98 : virtual std::string GenSlidingWindowDeclRef( bool = false ) const = 0;
99 :
100 : /// Create buffer and pass the buffer to a given kernel
101 : virtual size_t Marshal( cl_kernel, int, int, cl_program ) = 0;
102 :
103 : virtual size_t GetWindowSize() const = 0;
104 :
105 : /// When Mix, it will be called
106 : virtual std::string GenDoubleSlidingWindowDeclRef( bool = false ) const;
107 :
108 : /// When Mix, it will be called
109 : virtual std::string GenStringSlidingWindowDeclRef( bool = false ) const;
110 :
111 : virtual bool IsMixedArgument() const;
112 :
113 : /// Generate use/references to the argument
114 : virtual void GenDeclRef( std::stringstream& ss ) const;
115 : virtual void GenNumDeclRef( std::stringstream& ss ) const;
116 :
117 : virtual void GenStringDeclRef( std::stringstream& ss ) const;
118 :
119 : virtual void GenSlidingWindowFunction( std::stringstream& );
120 : formula::FormulaToken* GetFormulaToken() const;
121 : virtual std::string DumpOpName() const;
122 : virtual void DumpInlineFun( std::set<std::string>&, std::set<std::string>& ) const;
123 : const std::string& GetName() const;
124 : virtual bool NeedParallelReduction() const;
125 :
126 : protected:
127 : const ScCalcConfig& mCalcConfig;
128 : std::string mSymName;
129 : FormulaTreeNodeRef mFormulaTree;
130 : };
131 :
132 : typedef boost::shared_ptr<DynamicKernelArgument> DynamicKernelArgumentRef;
133 :
134 : /// Holds an input (read-only) argument reference to a SingleVectorRef.
135 : /// or a DoubleVectorRef for non-sliding-window argument of complex functions
136 : /// like SumOfProduct
137 : /// In most of the cases the argument is introduced
138 : /// by a Push operation in the given RPN.
139 : class VectorRef : public DynamicKernelArgument
140 : {
141 : public:
142 : VectorRef( const ScCalcConfig& config, const std::string& s, FormulaTreeNodeRef ft, int index = 0 );
143 : virtual ~VectorRef();
144 :
145 : /// Generate declaration
146 : virtual void GenDecl( std::stringstream& ss ) const SAL_OVERRIDE;
147 : /// When declared as input to a sliding window function
148 : virtual void GenSlidingWindowDecl( std::stringstream& ss ) const SAL_OVERRIDE;
149 :
150 : /// When referenced in a sliding window function
151 : virtual std::string GenSlidingWindowDeclRef( bool = false ) const SAL_OVERRIDE;
152 :
153 : /// Create buffer and pass the buffer to a given kernel
154 : virtual size_t Marshal( cl_kernel, int, int, cl_program ) SAL_OVERRIDE;
155 :
156 : virtual void GenSlidingWindowFunction( std::stringstream& ) SAL_OVERRIDE;
157 : virtual size_t GetWindowSize() const SAL_OVERRIDE;
158 : virtual std::string DumpOpName() const SAL_OVERRIDE;
159 : virtual void DumpInlineFun( std::set<std::string>&, std::set<std::string>& ) const SAL_OVERRIDE;
160 : const std::string& GetName() const;
161 : cl_mem GetCLBuffer() const;
162 : virtual bool NeedParallelReduction() const SAL_OVERRIDE;
163 :
164 : protected:
165 : // Used by marshaling
166 : cl_mem mpClmem;
167 : // index in multiple double vector refs that have multiple ranges
168 : const int mnIndex;
169 : };
170 :
171 : /// Abstract class for code generation
172 0 : class OpBase
173 : {
174 : public:
175 : typedef std::vector<std::string> ArgVector;
176 : typedef std::vector<std::string>::iterator ArgVectorIter;
177 0 : virtual std::string GetBottom() { return "";};
178 0 : virtual std::string Gen2( const std::string&/*lhs*/,
179 0 : const std::string&/*rhs*/ ) const { return "";}
180 0 : static std::string Gen( ArgVector& /*argVector*/ ) { return "";};
181 0 : virtual std::string BinFuncName() const { return "";};
182 0 : virtual void BinInlineFun( std::set<std::string>&,
183 0 : std::set<std::string>& ) { }
184 : virtual bool takeString() const = 0;
185 : virtual bool takeNumeric() const = 0;
186 : //Continue process 'Zero' or Not(like OpMul, not continue process when meet
187 : // 'Zero'
188 0 : virtual bool ZeroReturnZero() { return false;}
189 0 : virtual ~OpBase() { }
190 : };
191 :
192 0 : class SlidingFunctionBase : public OpBase
193 : {
194 : public:
195 : typedef std::vector<DynamicKernelArgumentRef> SubArguments;
196 : virtual void GenSlidingWindowFunction( std::stringstream&,
197 : const std::string&, SubArguments& ) = 0;
198 0 : virtual ~SlidingFunctionBase() { }
199 : };
200 :
201 0 : class Normal : public SlidingFunctionBase
202 : {
203 : public:
204 : virtual void GenSlidingWindowFunction( std::stringstream& ss,
205 : const std::string& sSymName, SubArguments& vSubArguments ) SAL_OVERRIDE;
206 0 : virtual bool takeString() const SAL_OVERRIDE { return false; }
207 0 : virtual bool takeNumeric() const SAL_OVERRIDE { return true; }
208 : };
209 :
210 0 : class CheckVariables : public Normal
211 : {
212 : public:
213 : static void GenTmpVariables( std::stringstream& ss, SubArguments& vSubArguments );
214 : static void CheckSubArgumentIsNan( std::stringstream& ss,
215 : SubArguments& vSubArguments, int argumentNum );
216 : static void CheckAllSubArgumentIsNan( std::stringstream& ss,
217 : SubArguments& vSubArguments );
218 : // only check isNan
219 : static void CheckSubArgumentIsNan2( std::stringstream& ss,
220 : SubArguments& vSubArguments, int argumentNum, std::string p );
221 : static void UnrollDoubleVector( std::stringstream& ss,
222 : std::stringstream& unrollstr, const formula::DoubleVectorRefToken* pCurDVR,
223 : int nCurWindowSize );
224 : };
225 :
226 : }}
227 :
228 : #endif
229 :
230 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|