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 software is provided 'as-is', without any express or implied
00006 // warranty. In no event will the authors be held liable for any damages
00007 // arising from the use of this software.
00008 // 
00009 // Permission is granted to anyone to use this software for any purpose,
00010 // including commercial applications, and to alter it and redistribute it
00011 // freely, subject to the following restrictions:
00012 // 
00013 // 1. The origin of this software must not be misrepresented; you must
00014 // not claim that you wrote the original software. If you use this
00015 // software in a product, an acknowledgment in the product documentation
00016 // would be appreciated but is not required.
00017 // 
00018 // 2. Altered source versions must be plainly marked as such, and must
00019 // not be misrepresented as being the original software.
00020 // 
00021 // 3. This notice may not be removed or altered from any source
00022 // distribution.
00024 #ifndef SHEVAL_HPP 
00025 #define SHEVAL_HPP
00026 
00027 #include <vector>
00028 #include <map>
00029 #include "ShHashMap.hpp"
00030 #include "ShInfo.hpp"
00031 #include "ShStatement.hpp"
00032 #include "ShVariant.hpp"
00033 #include "ShOperation.hpp"
00034 #include "ShRefCount.hpp"
00035 #include "ShHalf.hpp"
00036 
00037 namespace SH {
00038 
00062 // forward declarations
00063 //class ShVariant;
00064 class ShEvalOp;
00065 //typedef ShPointer<ShVariant> ShVariant*;
00066 //typedef ShPointer<const ShVariant> const ShVariant*;
00067 
00068 struct 
00069 SH_DLLEXPORT
00070 ShEvalOpInfo: public ShInfo {
00071   ShOperation m_op;
00072 
00073   const ShEvalOp* m_evalOp;
00074 
00075   // type indices of the destination and sources
00076   // These are set to a valid value type except when the src/dest is not
00077   // used for m_op 
00078   ShValueType m_dest;
00079   ShValueType m_src[3]; 
00080 
00081   ShEvalOpInfo(ShOperation op, const ShEvalOp* evalOp, ShValueType dest, 
00082       ShValueType src0, ShValueType src1, ShValueType src2);
00083 
00084   ShInfo* clone() const;
00085 
00086   std::string encode() const;
00087 };
00088 
00089 class 
00090 SH_DLLEXPORT
00091 ShEval {
00092   public:
00101     void operator()(ShOperation op, ShVariant* dest,
00102         const ShVariant* a, const ShVariant* b, const ShVariant* c) const;
00103 
00104     void operator()(ShOperation op, ShVariantPtr dest,
00105         ShVariantCPtr a, ShVariantCPtr b, ShVariantCPtr c) const;
00106     // @}
00107 
00109     void addOp(ShOperation op, const ShEvalOp* evalOp, ShValueType dest, 
00110         ShValueType src0, ShValueType src1 = SH_VALUETYPE_END, 
00111         ShValueType src2 = SH_VALUETYPE_END); 
00112 
00119     const ShEvalOpInfo* getEvalOpInfo(ShOperation op, ShValueType dest,
00120         ShValueType src0, ShValueType src1 = SH_VALUETYPE_END, 
00121         ShValueType src2 = SH_VALUETYPE_END) const;
00122     const ShEvalOpInfo* getEvalOpInfo(const ShStatement &stmt) const;
00124 
00126     std::string availableOps() const;
00127 
00128     static ShEval* instance();
00129 
00130   private:
00131     ShEval();
00132 
00133 
00134     typedef std::list<ShEvalOpInfo> OpInfoList;
00135     typedef OpInfoList OpInfoMap[SH_OPERATION_END];
00136     OpInfoMap m_evalOpMap; 
00137 
00138     typedef ShPairPairHashMap<ShOperation, ShValueType, ShValueType, ShValueType, const ShEvalOpInfo*> EvalOpCache;
00139     mutable EvalOpCache  m_evalOpCache;
00140 
00141     static ShEval* m_instance;
00142 };
00143 
00144 class 
00145 SH_DLLEXPORT
00146 ShEvalOp {
00147   public:
00148     virtual ~ShEvalOp();
00149 
00150     // Wraps an operation where at least dest and a are non-null.
00151     virtual void operator()(ShVariant* dest, const ShVariant* a, 
00152         const ShVariant* b, const ShVariant* c) const = 0;
00153 };
00154 
00155 // The strategy for defining ops is to use separate classes to hold
00156 // and register operations for different categories of types.
00157 //
00158 // Each of these "concrete" evaluation evalOps must implement
00159 // 1) the virtual void ShEvalOp::operator()(...)
00160 //    This is used to evaluate ShVariables
00161 //
00162 // 2) Functions 
00163 //    template<ShOperation S>
00164 //    static void unaryOp(ShDataVariant<T1> &dest, const ShDataVariant<T2> &src);
00165 //
00166 //    and similarly for binary, ternary ops 
00167 //    (for most ops, only T1 = T2 is supported directly,
00168 //    but for range arithmetic ops, some args may be in a range arithmetic
00169 //    type and other args might not)
00170 //
00171 //    These can be specialized to implement specific ops,
00172 //    and thus used directly for computation on data from
00173 //    ShGenerics without going through ANY layers of virtual 
00174 //    function calls.
00175 
00179 template<ShOperation S, typename T>
00180 struct ShRegularOp: public ShEvalOp {
00181   void operator()(ShVariant* dest, const ShVariant* a, 
00182       const ShVariant* b, const ShVariant* c) const; 
00183 };
00184 
00185 // If functions could be partially specialized, then wouldn't need
00186 // to wrap this in a class.
00187 
00188 // TODO might want to break this down into a few more subclasses to handle
00189 // 1) special float/double cmath functions (for C built in types)
00190 // 2) other special functions (sgn, rcp, rsq, etc.) that C types don't have
00191 // OR, use helper functions 
00192 template<ShOperation S, typename T>
00193 struct ShConcreteRegularOp {
00194   typedef ShDataVariant<T, SH_HOST> Variant;
00195   typedef Variant* DataPtr; 
00196   typedef const Variant* DataCPtr; 
00197 
00198   static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0);
00199 };
00200 
00202 // has little code snippets for functions like sgn, rcp, rsq, etc.
00203 // that are not built-in cmath functions.
00204 //
00205 //TODO - not all the functions make sense on integer types...may
00206 //want to not declare the ones that don't make sense...
00207 template<ShOperation S, typename T>
00208 struct ShConcreteCTypeOp {
00209   typedef ShDataVariant<T, SH_HOST> Variant;
00210   typedef Variant* DataPtr; 
00211   typedef const Variant* DataCPtr; 
00212 
00213   static void doop(DataPtr dest, DataCPtr a, DataCPtr b = 0, DataCPtr c = 0);
00214 };
00215 
00216 template<ShOperation S, typename T>
00217 struct ShRegularOpChooser {
00218   typedef ShConcreteRegularOp<S, T> Op;
00219 };
00220 
00221 #define SHOPC_CTYPE_OP(T)\
00222 template<ShOperation S>\
00223 struct ShRegularOpChooser<S, T> {\
00224   typedef ShConcreteCTypeOp<S, T> Op;\
00225 };
00226 
00227 SHOPC_CTYPE_OP(double);
00228 SHOPC_CTYPE_OP(float);
00229 SHOPC_CTYPE_OP(ShHalf);
00230 SHOPC_CTYPE_OP(int);
00231 
00232 // initializes the regular Ops for a floating point type T
00233 // with ShOpEvalOp<OP, T> objects
00234 template<typename T>
00235 void _shInitFloatOps();
00236 
00237 // initializes the regular Ops for an integer type T
00238 // (a subset of the floating point ones)
00239 template<typename T>
00240 void _shInitIntOps();
00241 
00242 }
00243 
00244 #include "ShEvalImpl.hpp"
00245 #include "ShConcreteRegularOpImpl.hpp"
00246 #include "ShConcreteCTypeOpImpl.hpp"
00247 
00248 #endif

Generated on Thu Apr 21 17:32:46 2005 for Sh by  doxygen 1.4.2