Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

ShEval.hpp

00001 // Sh: A GPU metaprogramming language.
00002 //
00003 // Copyright 2003-2005 Serious Hack Inc.
00004 // 
00005 // This library is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License, or (at your option) any later version.
00009 //
00010 // This library is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Lesser General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with this library; if not, write to the Free Software
00017 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
00018 // MA  02110-1301, USA
00020 #ifndef SHEVAL_HPP 
00021 #define SHEVAL_HPP
00022 
00023 #include <vector>
00024 #include <map>
00025 #include "ShHashMap.hpp"
00026 #include "ShInfo.hpp"
00027 #include "ShStatement.hpp"
00028 #include "ShVariant.hpp"
00029 #include "ShOperation.hpp"
00030 #include "ShRefCount.hpp"
00031 #include "ShHalf.hpp"
00032 
00033 namespace SH {
00034 
00058 // forward declarations
00059 //class ShVariant;
00060 class ShEvalOp;
00061 //typedef ShPointer<ShVariant> ShVariant*;
00062 //typedef ShPointer<const ShVariant> const ShVariant*;
00063 
00064 struct 
00065 SH_DLLEXPORT
00066 ShEvalOpInfo: public ShInfo {
00067   ShOperation m_op;
00068 
00069   const ShEvalOp* m_evalOp;
00070 
00071   // type indices of the destination and sources
00072   // These are set to a valid value type except when the src/dest is not
00073   // used for m_op 
00074   ShValueType m_dest;
00075   ShValueType m_src[3]; 
00076 
00077   ShEvalOpInfo(ShOperation op, const ShEvalOp* evalOp, ShValueType dest, 
00078       ShValueType src0, ShValueType src1, ShValueType src2);
00079 
00080   ShInfo* clone() const;
00081 
00082   std::string encode() const;
00083 };
00084 
00085 class 
00086 SH_DLLEXPORT
00087 ShEval {
00088   public:
00097     void operator()(ShOperation op, ShVariant* dest,
00098         const ShVariant* a, const ShVariant* b, const ShVariant* c) const;
00099 
00100     void operator()(ShOperation op, ShVariantPtr dest,
00101         ShVariantCPtr a, ShVariantCPtr b, ShVariantCPtr c) const;
00102     // @}
00103 
00105     void addOp(ShOperation op, const ShEvalOp* evalOp, ShValueType dest, 
00106         ShValueType src0, ShValueType src1 = SH_VALUETYPE_END, 
00107         ShValueType src2 = SH_VALUETYPE_END); 
00108 
00115     const ShEvalOpInfo* getEvalOpInfo(ShOperation op, ShValueType dest,
00116         ShValueType src0, ShValueType src1 = SH_VALUETYPE_END, 
00117         ShValueType src2 = SH_VALUETYPE_END) const;
00118     const ShEvalOpInfo* getEvalOpInfo(const ShStatement &stmt) const;
00120 
00122     std::string availableOps() const;
00123 
00124     static ShEval* instance();
00125 
00126   private:
00127     ShEval();
00128 
00129 
00130     typedef std::list<ShEvalOpInfo> OpInfoList;
00131     typedef OpInfoList OpInfoMap[SH_OPERATION_END];
00132     OpInfoMap m_evalOpMap; 
00133 
00134     typedef ShPairPairHashMap<ShOperation, ShValueType, ShValueType, ShValueType, const ShEvalOpInfo*> EvalOpCache;
00135     mutable EvalOpCache  m_evalOpCache;
00136 
00137     static ShEval* m_instance;
00138 };
00139 
00140 class 
00141 SH_DLLEXPORT
00142 ShEvalOp {
00143   public:
00144     virtual ~ShEvalOp();
00145 
00146     // Wraps an operation where at least dest and a are non-null.
00147     virtual void operator()(ShVariant* dest, const ShVariant* a, 
00148         const ShVariant* b, const ShVariant* c) const = 0;
00149 };
00150 
00151 // The strategy for defining ops is to use separate classes to hold
00152 // and register operations for different categories of types.
00153 //
00154 // Each of these "concrete" evaluation evalOps must implement
00155 // 1) the virtual void ShEvalOp::operator()(...)
00156 //    This is used to evaluate ShVariables
00157 //
00158 // 2) Functions 
00159 //    template<ShOperation S>
00160 //    static void unaryOp(ShDataVariant<T1> &dest, const ShDataVariant<T2> &src);
00161 //
00162 //    and similarly for binary, ternary ops 
00163 //    (for most ops, only T1 = T2 is supported directly,
00164 //    but for range arithmetic ops, some args may be in a range arithmetic
00165 //    type and other args might not)
00166 //
00167 //    These can be specialized to implement specific ops,
00168 //    and thus used directly for computation on data from
00169 //    ShGenerics without going through ANY layers of virtual 
00170 //    function calls.
00171 
00175 template<ShOperation S, typename T>
00176 struct ShRegularOp: public ShEvalOp {
00177   void operator()(ShVariant* dest, const ShVariant* a, 
00178       const ShVariant* b, const ShVariant* c) const; 
00179 };
00180 
00181 // If functions could be partially specialized, then wouldn't need
00182 // to wrap this in a class.
00183 
00184 // TODO might want to break this down into a few more subclasses to handle
00185 // 1) special float/double cmath functions (for C built in types)
00186 // 2) other special functions (sgn, rcp, rsq, etc.) that C types don't have
00187 // OR, use helper functions 
00188 template<ShOperation S, typename T>
00189 struct ShConcreteRegularOp {
00190   typedef ShDataVariant<T, SH_HOST> Variant;
00191   typedef Variant* DataPtr; 
00192   typedef const Variant* DataCPtr; 
00193 
00194   static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0);
00195 };
00196 
00198 // has little code snippets for functions like sgn, rcp, rsq, etc.
00199 // that are not built-in cmath functions.
00200 //
00201 //TODO - not all the functions make sense on integer types...may
00202 //want to not declare the ones that don't make sense...
00203 template<ShOperation S, typename T>
00204 struct ShConcreteCTypeOp {
00205   typedef ShDataVariant<T, SH_HOST> Variant;
00206   typedef Variant* DataPtr; 
00207   typedef const Variant* DataCPtr; 
00208 
00209   static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0);
00210 };
00211 
00212 template<ShOperation S, typename T>
00213 struct ShRegularOpChooser {
00214   typedef ShConcreteRegularOp<S, T> Op;
00215 };
00216 
00217 #define SHOPC_CTYPE_OP(T)\
00218 template<ShOperation S>\
00219 struct ShRegularOpChooser<S, T> {\
00220   typedef ShConcreteCTypeOp<S, T> Op;\
00221 };
00222 
00223 SHOPC_CTYPE_OP(double);
00224 SHOPC_CTYPE_OP(float);
00225 SHOPC_CTYPE_OP(ShHalf);
00226 SHOPC_CTYPE_OP(int);
00227 
00228 // initializes the regular Ops for a floating point type T
00229 // with ShOpEvalOp<OP, T> objects
00230 template<typename T>
00231 void _shInitFloatOps();
00232 
00233 // initializes the regular Ops for an integer type T
00234 // (a subset of the floating point ones)
00235 template<typename T>
00236 void _shInitIntOps();
00237 
00238 }
00239 
00240 #include "ShEvalImpl.hpp"
00241 #include "ShConcreteRegularOpImpl.hpp"
00242 #include "ShConcreteCTypeOpImpl.hpp"
00243 
00244 #endif

Generated on Thu Jul 28 17:33:02 2005 for Sh by  doxygen 1.4.3-20050530