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

ShManipulatorImpl.hpp

00001 // Sh: A GPU metaprogramming language.
00002 //
00003 // Copyright (c) 2003 University of Waterloo Computer Graphics Laboratory
00004 // Project administrator: Michael D. McCool
00005 // Authors: Zheng Qin, Stefanus Du Toit, Kevin Moule, Tiberiu S. Popa,
00006 //          Michael D. McCool
00007 // 
00008 // This software is provided 'as-is', without any express or implied
00009 // warranty. In no event will the authors be held liable for any damages
00010 // arising from the use of this software.
00011 // 
00012 // Permission is granted to anyone to use this software for any purpose,
00013 // including commercial applications, and to alter it and redistribute it
00014 // freely, subject to the following restrictions:
00015 // 
00016 // 1. The origin of this software must not be misrepresented; you must
00017 // not claim that you wrote the original software. If you use this
00018 // software in a product, an acknowledgment in the product documentation
00019 // would be appreciated but is not required.
00020 // 
00021 // 2. Altered source versions must be plainly marked as such, and must
00022 // not be misrepresented as being the original software.
00023 // 
00024 // 3. This notice may not be removed or altered from any source
00025 // distribution.
00027 #ifndef SHMANIPULATORIMPL_HPP
00028 #define SHMANIPULATORIMPL_HPP
00029 
00030 #include <cstdarg>
00031 #include <cassert>
00032 #include <sstream>
00033 #include "ShVariableNode.hpp"
00034 #include "ShError.hpp"
00035 #include "ShDebug.hpp"
00036 #include "ShAlgebra.hpp"
00037 #include "ShManipulator.hpp"
00038 #include "ShInstructions.hpp"
00039 
00040 namespace SH {
00041 
00042 // TODO figure out a better way...
00043 #define _FIRST -54545454
00044 #define _SECOND -54545453
00045 #define _LAST 54545454
00046 
00047 template<typename T>
00048 OffsetRange<T>::OffsetRange() {}
00049 
00050 template<typename T>
00051 OffsetRange<T>::OffsetRange( T start, T end )
00052   : start( start ), end( end ), startOffset( 0 ), endOffset( 0 ) {}
00053 
00054 template<typename T>
00055 OffsetRange<T>::OffsetRange( T start, int startOffset, T end, int endOffset )
00056   : start( start ), end( end ), startOffset( startOffset ), endOffset( endOffset ) {}
00057 
00058 template<typename T>
00059 int OffsetRange<T>::absStartIndex( const ShProgramNode::VarList vars ) const {
00060   return absIndex( start, startOffset, vars );
00061 }
00062 
00063 template<typename T>
00064 int OffsetRange<T>::absEndIndex( const ShProgramNode::VarList vars ) const {
00065   return absIndex( end, endOffset, vars );
00066 }
00067 
00068 template<typename T>
00069 std::string OffsetRange<T>::toString() const {
00070   std::ostringstream os;
00071   os << "(" << start << (startOffset >= 0 ? "+" : "" ) << startOffset
00072      << ", " << end << (endOffset >= 0 ? "+" : "" ) << endOffset << ")";
00073   return os.str();
00074 }
00075 
00076 template<typename T>
00077 ShManipulator<T>::ShManipulator() {} 
00078 
00079 template<typename T>
00080 ShManipulator<T>::~ShManipulator() {
00081 } 
00082 
00083 template<typename T>
00084 ShManipulator<T>& ShManipulator<T>::operator()(T i) {
00085   m_ranges.push_back(IndexRange(i, i));
00086   return *this;
00087 }
00088 
00089 template<typename T>
00090 ShManipulator<T>& ShManipulator<T>::operator()(T start, T end) {
00091   m_ranges.push_back(IndexRange(start, end));
00092   return *this;
00093 }
00094 
00095 template<typename T>
00096 ShManipulator<T>& ShManipulator<T>::operator()(const IndexRange &range) {
00097   m_ranges.push_back(range);
00098   return *this;
00099 }
00100 
00101 template<typename T>
00102 typename ShManipulator<T>::IndexRangeVector ShManipulator<T>::getRanges() const { 
00103   return m_ranges;
00104 }
00105 
00106 template<typename T>
00107 std::string ShManipulator<T>::toString() const {
00108   std::ostringstream os;
00109   for(typename IndexRangeVector::const_iterator it = m_ranges.begin(); it != m_ranges.end(); ++it) {
00110     if(it != m_ranges.begin()) os << ", ";
00111     os << it->toString();
00112   }
00113   return os.str();
00114 }
00115 
00116 /* input permutation */
00117 template<typename T>
00118 ShProgram operator<<(const ShProgram &p, const ShManipulator<T> &m) {
00119   typedef typename ShManipulator<T>::IndexRangeVector RangeVec;
00120   RangeVec mranges = m.getRanges();
00121   int i;
00122 
00123   ShProgram permuter = SH_BEGIN_PROGRAM() {
00124     /* Make shader outputs from p's inputs 
00125      * default output value is zero, so for those that have
00126      * no matching inputs, they become zero outputs */
00127     std::vector<ShVariable> outputs;
00128     for(ShProgramNode::VarList::const_iterator inIt = p.node()->inputs.begin();
00129         inIt != p.node()->inputs.end(); ++inIt) {
00130       ShVariable out((*inIt)->clone(SH_OUTPUT));
00131       outputs.push_back(out);
00132     }
00133 
00134     int size = outputs.size();
00135 
00136     /* Make shader outputs from permuted ranges of inputs */
00137     std::vector<bool> used(size, false); //mark used inputs
00138     for(typename RangeVec::const_iterator irvIt = mranges.begin();
00139         irvIt != mranges.end(); ++irvIt) {
00140       int start = irvIt->absStartIndex( p.node()->inputs );
00141       int end = irvIt->absEndIndex( p.node()->inputs ); 
00142 
00143       if(start == OFFSET_RANGE_BAD_OFFSET || end == OFFSET_RANGE_BAD_OFFSET ) continue;
00144       if(start == OFFSET_RANGE_BAD_INDEX || end == OFFSET_RANGE_BAD_INDEX ) {
00145         std::ostringstream os;
00146         os << "Invalid ShManipulator Range " << irvIt->toString() 
00147           << " for an ShProgram with output size " << size;
00148         shError(ShAlgebraException(os.str())); 
00149       }
00150 
00151       for(i = start; i <= end; ++i) {
00152         if(used[i]) {
00153           std::ostringstream os;
00154           os << "Duplicate index " << i << " in range " << irvIt->toString() 
00155             << " not allowed for input manipulators"; 
00156           shError(ShAlgebraException(os.str()));
00157         }
00158         used[i] = true;
00159 
00160         ShVariable input(outputs[i].node()->clone(SH_INPUT));
00161         shASN(outputs[i], input);
00162       }
00163     }
00164   } SH_END;
00165 
00166   return connect(permuter, p); 
00167 }
00168 
00169 template<typename T>
00170 ShProgram operator<<(const ShManipulator<T> &m, const ShProgram &p) {
00171   typedef typename ShManipulator<T>::IndexRangeVector RangeVec;
00172   RangeVec mranges = m.getRanges();
00173 
00174   ShProgram permuter = SH_BEGIN_PROGRAM() {
00175     /* Make shader inputs from p's outputs */
00176     std::vector<ShVariable> inputs;
00177     for(ShProgramNode::VarList::const_iterator outIt = p.node()->outputs.begin();
00178         outIt != p.node()->outputs.end(); ++outIt) {
00179       ShVariable in((*outIt)->clone(SH_INPUT));
00180       inputs.push_back(in);
00181     }
00182 
00183     int size = inputs.size();
00184 
00185     /* Make shader outputs from permuted ranges of inputs */
00186     for(typename RangeVec::const_iterator irvIt = mranges.begin();
00187         irvIt != mranges.end(); ++irvIt) {
00188       int start = irvIt->absStartIndex( p.node()->outputs );
00189       int end = irvIt->absEndIndex( p.node()->outputs ); 
00190 
00191       if(start == OFFSET_RANGE_BAD_OFFSET || end == OFFSET_RANGE_BAD_OFFSET ) continue;
00192       if(start == OFFSET_RANGE_BAD_INDEX || end == OFFSET_RANGE_BAD_INDEX ) {
00193         std::ostringstream os;
00194         os << "Invalid ShManipulator Range " << irvIt->toString() << 
00195           " for an ShProgram with output size " << size;
00196         shError(ShAlgebraException(os.str())); 
00197       }
00198 
00199       for(int i = start; i <= end; ++i) { // handles end < start case
00200         ShVariable output(inputs[i].node()->clone(SH_OUTPUT));
00201         shASN(output, inputs[i]);
00202       }
00203     }
00204   } SH_END;
00205 
00206   return connect(p, permuter); 
00207 }
00208 
00209 template<typename T>
00210 ShManipulator<T> shSwizzle(T i0) {
00211   ShManipulator<T> m;
00212   m(i0);
00213   return m;
00214 }
00215 template<typename T>
00216 ShManipulator<T> shSwizzle(T i0, T i1) {
00217   ShManipulator<T> m;
00218   m(i0); m(i1);
00219   return m;
00220 }
00221 template<typename T>
00222 ShManipulator<T> shSwizzle(T i0, T i1, T i2) {
00223   ShManipulator<T> m;
00224   m(i0); m(i1); m(i2); 
00225   return m;
00226 }
00227 
00228 template<typename T>
00229 ShManipulator<T> shSwizzle(T i0, T i1, T i2, T i3) {
00230   ShManipulator<T> m;
00231   m(i0); m(i1); m(i2); m(i3);
00232   return m;
00233 }
00234 
00235 template<typename T>
00236 ShManipulator<T> shSwizzle(T i0, T i1, T i2, T i3, T i4) {
00237   ShManipulator<T> m;
00238   m(i0); m(i1); m(i2); m(i3); m(i4); 
00239   return m;
00240 }
00241 
00242 template<typename T>
00243 ShManipulator<T> shSwizzle(T i0, T i1, T i2, T i3, T i4, T i5) {
00244   ShManipulator<T> m;
00245   m(i0); m(i1); m(i2); m(i3); m(i4); m(i5); 
00246   return m;
00247 }
00248 
00249 template<typename T>
00250 ShManipulator<T> shSwizzle(T i0, T i1, T i2, T i3, T i4, T i5, T i6) {
00251   ShManipulator<T> m;
00252   m(i0); m(i1); m(i2); m(i3); m(i4); m(i5); m(i6); 
00253   return m;
00254 }
00255 
00256 template<typename T>
00257 ShManipulator<T> shSwizzle(T i0, T i1, T i2, T i3, T i4, T i5, T i6, T i7) {
00258   ShManipulator<T> m;
00259   m(i0); m(i1); m(i2); m(i3); m(i4); m(i5); m(i6); m(i7); 
00260   return m;
00261 }
00262 
00263 template<typename T>
00264 ShManipulator<T> shSwizzle(T i0, T i1, T i2, T i3, T i4, T i5, T i6, T i7, T i8) {
00265   ShManipulator<T> m;
00266   m(i0); m(i1); m(i2); m(i3); m(i4); m(i5); m(i6); 
00267   m(i7); m(i8);
00268   return m;
00269 }
00270 
00271 template<typename T>
00272 ShManipulator<T> shSwizzle(T i0, T i1, T i2, T i3, T i4, T i5, T i6, T i7, T i8, T i9) {
00273   ShManipulator<T> m;
00274   m(i0); m(i1); m(i2); m(i3); m(i4); m(i5); m(i6); 
00275   m(i7); m(i8); m(i9);
00276   return m;
00277 }
00278 
00279 template<typename T>
00280 ShManipulator<T> shSwizzle(std::vector<T> indices) {
00281   ShManipulator<T> m;
00282   for(typename std::vector<T>::iterator it = indices.begin();
00283       it != indices.end(); ++it) {
00284     m(*it);
00285   }
00286   return m;
00287 }
00288 
00289 template<typename T>
00290 ShManipulator<T> shRange(T i) {
00291   ShManipulator<T> m;
00292   m(i);
00293   return m;
00294 }
00295 
00296 template<typename T>
00297 ShManipulator<T> shRange(T start, T end) {
00298   ShManipulator<T> m;
00299   m(start, end);
00300   return m;
00301 }
00302 
00303 template<typename T>
00304 ShManipulator<T> shExtract(T k) {
00305   ShManipulator<T> m;
00306   m(k);
00307   typedef typename ShManipulator<T>::IndexRange Range;
00308   m(Range(k,_FIRST,k,-1));
00309   m(Range(k,1,k,_LAST));
00310   return m;
00311 }
00312 
00313 template<typename T>
00314 ShManipulator<T> shInsert(T k) {
00315   ShManipulator<T> m;
00316   typedef typename ShManipulator<T>::IndexRange Range;
00317   
00318   m(Range(k,_SECOND,k,0));
00319   m(Range(k,_FIRST,k,_FIRST));
00320   m(Range(k,1,k,_LAST));
00321   std::cout << m.toString() << std::endl;
00322   return m;
00323 }
00324 
00325 template<typename T>
00326 ShManipulator<T> shDrop(T k) {
00327   ShManipulator<T> m;
00328   typedef typename ShManipulator<T>::IndexRange Range; 
00329   m(Range(k,_FIRST,k,-1));
00330   m(Range(k,1,k,_LAST));
00331   return m;
00332 }
00333 
00334 }
00335 
00336 #endif

Generated on Mon Jan 24 18:36:33 2005 for Sh by  doxygen 1.4.1