summaryrefslogtreecommitdiffstats
path: root/sc/source/core/opencl/opbase.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/core/opencl/opbase.hxx')
-rw-r--r--sc/source/core/opencl/opbase.hxx246
1 files changed, 246 insertions, 0 deletions
diff --git a/sc/source/core/opencl/opbase.hxx b/sc/source/core/opencl/opbase.hxx
new file mode 100644
index 000000000..b4a2780f7
--- /dev/null
+++ b/sc/source/core/opencl/opbase.hxx
@@ -0,0 +1,246 @@
+/* -*- 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/.
+ */
+
+#pragma once
+
+#include <clew/clew.h>
+#include <formula/token.hxx>
+#include <formula/types.hxx>
+#include <memory>
+#include <set>
+#include <vector>
+
+namespace formula { class DoubleVectorRefToken; }
+namespace formula { class FormulaToken; }
+struct ScCalcConfig;
+
+namespace sc::opencl {
+
+class FormulaTreeNode;
+
+/// Exceptions
+
+/// Failed in parsing
+class UnhandledToken
+{
+public:
+ UnhandledToken( const char* m, const std::string& fn, int ln );
+
+ std::string mMessage;
+ std::string mFile;
+ int mLineNumber;
+};
+
+/// Failed in marshaling
+class OpenCLError
+{
+public:
+ OpenCLError( const std::string& function, cl_int error, const std::string& file, int line );
+
+ std::string mFunction;
+ cl_int mError;
+ std::string mFile;
+ int mLineNumber;
+};
+
+/// Inconsistent state
+class Unhandled
+{
+public:
+ Unhandled( const std::string& fn, int ln );
+
+ std::string mFile;
+ int mLineNumber;
+};
+
+class InvalidParameterCount
+{
+public:
+ InvalidParameterCount( int parameterCount, const std::string& file, int ln );
+
+ int mParameterCount;
+ std::string mFile;
+ int const mLineNumber;
+};
+
+// Helper macro to be used in code emitting OpenCL code for Calc functions.
+// Requires the vSubArguments parameter.
+#define CHECK_PARAMETER_COUNT(min, max) \
+ do { \
+ const int count = vSubArguments.size(); \
+ if( count < ( min ) || count > ( max )) \
+ throw InvalidParameterCount( count, __FILE__, __LINE__ ); \
+ } while( false )
+
+typedef std::shared_ptr<FormulaTreeNode> FormulaTreeNodeRef;
+
+class FormulaTreeNode
+{
+public:
+ explicit FormulaTreeNode( const formula::FormulaToken* ft ) : mpCurrentFormula(ft)
+ {
+ Children.reserve(8);
+ }
+ std::vector<FormulaTreeNodeRef> Children;
+ formula::FormulaToken* GetFormulaToken() const
+ {
+ return const_cast<formula::FormulaToken*>(mpCurrentFormula.get());
+ }
+
+private:
+ formula::FormulaConstTokenRef mpCurrentFormula;
+};
+
+/// (Partially) abstract base class for an operand
+class DynamicKernelArgument
+{
+public:
+ /// delete copy constructor
+ DynamicKernelArgument( const DynamicKernelArgument& ) = delete;
+
+ /// delete copy-assignment operator
+ const DynamicKernelArgument& operator=( const DynamicKernelArgument& ) = delete;
+
+ DynamicKernelArgument( const ScCalcConfig& config, const std::string& s, const FormulaTreeNodeRef& ft );
+ virtual ~DynamicKernelArgument() {}
+
+ /// 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;
+
+ /// Create buffer and pass the buffer to a given kernel
+ virtual size_t Marshal( cl_kernel, int, int, cl_program ) = 0;
+
+ virtual size_t GetWindowSize() const = 0;
+
+ /// When Mix, it will be called
+ virtual std::string GenDoubleSlidingWindowDeclRef( bool = false ) const;
+
+ /// When Mix, it will be called
+ virtual std::string GenStringSlidingWindowDeclRef( bool = false ) const;
+
+ /// Generate use/references to the argument
+ virtual void GenDeclRef( std::stringstream& ss ) const;
+
+ virtual void GenSlidingWindowFunction( std::stringstream& );
+ formula::FormulaToken* GetFormulaToken() const;
+ virtual std::string DumpOpName() const;
+ virtual void DumpInlineFun( std::set<std::string>&, std::set<std::string>& ) const;
+ const std::string& GetName() const;
+ virtual bool NeedParallelReduction() const;
+ /// If there's actually no argument, i.e. it expands to no code.
+ virtual bool IsEmpty() const { return false; }
+
+protected:
+ const ScCalcConfig& mCalcConfig;
+ std::string mSymName;
+ FormulaTreeNodeRef mFormulaTree;
+};
+
+typedef std::shared_ptr<DynamicKernelArgument> DynamicKernelArgumentRef;
+
+/// 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 ScCalcConfig& config, const std::string& s, const FormulaTreeNodeRef& ft, int index = 0 );
+ virtual ~VectorRef() override;
+
+ /// Generate declaration
+ virtual void GenDecl( std::stringstream& ss ) const override;
+ /// When declared as input to a sliding window function
+ virtual void GenSlidingWindowDecl( std::stringstream& ss ) const override;
+
+ /// When referenced in a sliding window function
+ virtual std::string GenSlidingWindowDeclRef( bool = false ) const override;
+
+ /// Create buffer and pass the buffer to a given kernel
+ virtual size_t Marshal( cl_kernel, int, int, cl_program ) override;
+
+ virtual void GenSlidingWindowFunction( std::stringstream& ) override;
+ virtual size_t GetWindowSize() const override;
+ virtual std::string DumpOpName() const override;
+ virtual void DumpInlineFun( std::set<std::string>&, std::set<std::string>& ) const override;
+ const std::string& GetName() const;
+ cl_mem GetCLBuffer() const;
+ virtual bool NeedParallelReduction() const override;
+
+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:
+ virtual std::string GetBottom() { return "";};
+ virtual std::string Gen2( const std::string&/*lhs*/,
+ const std::string&/*rhs*/ ) const { return "";}
+ static std::string Gen( std::vector<std::string>& /*argVector*/ ) { return "";};
+ virtual std::string BinFuncName() const { return "";};
+ virtual void BinInlineFun( std::set<std::string>&,
+ std::set<std::string>& ) { }
+ virtual bool takeString() const = 0;
+ virtual bool takeNumeric() const = 0;
+ // Whether DoubleRef containing more than one column is handled properly.
+ virtual bool canHandleMultiVector() const { return false; }
+ //Continue process 'Zero' or Not(like OpMul, not continue process when meet
+ // 'Zero'
+ virtual bool ZeroReturnZero() { return false;}
+ virtual ~OpBase() { }
+};
+
+class SlidingFunctionBase : public OpBase
+{
+public:
+ typedef std::vector<DynamicKernelArgumentRef> SubArguments;
+ virtual void GenSlidingWindowFunction( std::stringstream&,
+ const std::string&, SubArguments& ) = 0;
+};
+
+class Normal : public SlidingFunctionBase
+{
+public:
+ virtual void GenSlidingWindowFunction( std::stringstream& ss,
+ const std::string& sSymName, SubArguments& vSubArguments ) override;
+ virtual bool takeString() const override { return false; }
+ virtual bool takeNumeric() const override { return true; }
+};
+
+class CheckVariables : public Normal
+{
+public:
+ static void GenTmpVariables( std::stringstream& ss, const SubArguments& vSubArguments );
+ static void CheckSubArgumentIsNan( std::stringstream& ss,
+ SubArguments& vSubArguments, int argumentNum );
+ static void CheckAllSubArgumentIsNan( std::stringstream& ss,
+ SubArguments& vSubArguments );
+ // only check isnan
+ static void CheckSubArgumentIsNan2( std::stringstream& ss,
+ SubArguments& vSubArguments, int argumentNum, const std::string& p );
+ static void UnrollDoubleVector( std::stringstream& ss,
+ const std::stringstream& unrollstr, const formula::DoubleVectorRefToken* pCurDVR,
+ int nCurWindowSize );
+};
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */