00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
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
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
00125
00126
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
00137 std::vector<bool> used(size, false);
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
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
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) {
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