summaryrefslogtreecommitdiff
path: root/sc/source/core/opencl/opbase.hxx
blob: 22a9316f90153949a09b2f3e068d187e321df037 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#ifndef SC_OPENCL_OPBASE_HXX
#define SC_OPENCL_OPBASE_HXX

#include "clcc/clew.h"

#include "formula/token.hxx"

#include <boost/shared_ptr.hpp>
#include <boost/noncopyable.hpp>
#include <set>
#define ISNAN

namespace sc { namespace opencl {

class FormulaTreeNode;

/// Exceptions

/// Failed in parsing
class UnhandledToken
{
public:
    UnhandledToken(formula::FormulaToken *t,
            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
class OpenCLError
{
public:
    OpenCLError(cl_int err): mError(err) {}
    cl_int mError;
};

/// Inconsistent state
class Unhandled
{
public:
    Unhandled(std::string fn="", int ln=0):
            mFile(fn), mLineNumber(ln) {}
    std::string mFile;
    int mLineNumber;
};

typedef boost::shared_ptr<FormulaTreeNode> FormulaTreeNodeRef;

class FormulaTreeNode
{
public:
    FormulaTreeNode(formula::FormulaToken *ft): mpCurrentFormula(ft)
    {
        Children.reserve(8);
    }
    std::vector<FormulaTreeNodeRef> Children;
    formula::FormulaToken *GetFormulaToken(void) const
    {
        return mpCurrentFormula;
    }
private:
    formula::FormulaToken *const mpCurrentFormula;
};

/// (Partially) abstract base class for an operand
class DynamicKernelArgument : boost::noncopyable
{
public:
    DynamicKernelArgument(const std::string &s, FormulaTreeNodeRef ft);

    const std::string &GetNameAsString(void) const { return mSymName; }
    /// Generate declaration
    virtual void GenDecl(std::stringstream &ss) const = 0;

    /// When declared as input to a sliding window function
    virtual void GenSlidingWindowDecl(std::stringstream &ss) const = 0;

    /// When referenced in a sliding window function
    virtual std::string GenSlidingWindowDeclRef(bool=false) const = 0;

    /// Generate use/references to the argument
    virtual void GenDeclRef(std::stringstream &ss) const;

    /// Create buffer and pass the buffer to a given kernel
    virtual size_t Marshal(cl_kernel, int, int, cl_program) = 0;

    virtual ~DynamicKernelArgument() {}

    virtual void GenSlidingWindowFunction(std::stringstream &) {}
    const std::string &GetSymName(void) const { return mSymName; }
    formula::FormulaToken *GetFormulaToken(void) const;
    virtual size_t GetWindowSize(void) const = 0;
    virtual std::string DumpOpName(void) const { return std::string(""); }
    virtual void DumpInlineFun(std::set<std::string>& ,
        std::set<std::string>& ) const {}
    const std::string& GetName(void) const { return mSymName; }
    virtual bool NeedParallelReduction(void) const { return false; }

protected:
    std::string mSymName;
    FormulaTreeNodeRef mFormulaTree;
};

/// Holds an input (read-only) argument reference to a SingleVectorRef.
/// or a DoubleVectorRef for non-sliding-window argument of complex functions
/// like SumOfProduct
/// In most of the cases the argument is introduced
/// by a Push operation in the given RPN.
class VectorRef : public DynamicKernelArgument
{
public:
    VectorRef(const std::string &s, FormulaTreeNodeRef ft, int index = 0);

    const std::string &GetNameAsString(void) const { return mSymName; }
    /// Generate declaration
    virtual void GenDecl(std::stringstream &ss) const;
    /// When declared as input to a sliding window function
    virtual void GenSlidingWindowDecl(std::stringstream &ss) const;

    /// When referenced in a sliding window function
    virtual std::string GenSlidingWindowDeclRef(bool=false) const;

    /// Create buffer and pass the buffer to a given kernel
    virtual size_t Marshal(cl_kernel, int, int, cl_program);

    virtual ~VectorRef();

    virtual void GenSlidingWindowFunction(std::stringstream &) {}
    const std::string &GetSymName(void) const { return mSymName; }
    virtual size_t GetWindowSize(void) const;
    virtual std::string DumpOpName(void) const { return std::string(""); }
    virtual void DumpInlineFun(std::set<std::string>& ,
        std::set<std::string>& ) const {}
    const std::string& GetName(void) const { return mSymName; }
    virtual cl_mem GetCLBuffer(void) const { return mpClmem; }
    virtual bool NeedParallelReduction(void) const { return false; }

protected:
    // Used by marshaling
    cl_mem mpClmem;
    // index in multiple double vector refs that have multiple ranges
    const int mnIndex;
};
/// Abstract class for code generation

class OpBase
{
public:
    typedef std::vector<std::string> ArgVector;
    typedef std::vector<std::string>::iterator ArgVectorIter;
    virtual std::string GetBottom(void) {return "";};
    virtual std::string Gen2(const std::string &/*lhs*/,
        const std::string &/*rhs*/) const {return "";}
    virtual std::string Gen(ArgVector& /*argVector*/){return "";};
    virtual std::string BinFuncName(void)const {return "";};
    virtual void BinInlineFun(std::set<std::string>& ,
        std::set<std::string>& ) {}
    virtual bool takeString() const = 0;
    virtual bool takeNumeric() const = 0;
    virtual ~OpBase() {}
};

class SlidingFunctionBase : public OpBase
{
public:
    typedef boost::shared_ptr<DynamicKernelArgument> SubArgument;
    typedef std::vector<SubArgument> SubArguments;
    virtual void GenSlidingWindowFunction(std::stringstream &,
        const std::string, SubArguments &) = 0;
    virtual ~SlidingFunctionBase() {};
};

class Normal: public SlidingFunctionBase
{
public:
    virtual void GenSlidingWindowFunction(std::stringstream &ss,
            const std::string sSymName, SubArguments &vSubArguments);
    virtual bool takeString() const { return false; }
    virtual bool takeNumeric() const { return true; }
};

class CheckVariables:public Normal
{
public:
    void GenTmpVariables(std::stringstream &ss, SubArguments &vSubArguments);
    void CheckSubArgumentIsNan(std::stringstream &ss,
            SubArguments &vSubArguments, int argumentNum);
    void CheckAllSubArgumentIsNan(std::stringstream &ss,
            SubArguments &vSubArguments);
    // only check isNan
    void CheckSubArgumentIsNan2(std::stringstream &ss,
            SubArguments &vSubArguments, int argumentNum, std::string p);
};

}}

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */