00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00024 #ifndef SHMANIPULATORIMPL_HPP
00025 #define SHMANIPULATORIMPL_HPP
00026
00027 #include <cstdarg>
00028 #include <cassert>
00029 #include <sstream>
00030 #include "ShVariableNode.hpp"
00031 #include "ShError.hpp"
00032 #include "ShDebug.hpp"
00033 #include "ShAlgebra.hpp"
00034 #include "ShManipulator.hpp"
00035 #include "ShInstructions.hpp"
00036
00037 namespace SH {
00038
00039
00040 #define _FIRST -54545454
00041 #define _SECOND -54545453
00042 #define _LAST 54545454
00043
00044 template<typename T>
00045 OffsetRange<T>::OffsetRange() {}
00046
00047 template<typename T>
00048 OffsetRange<T>::OffsetRange( T start, T end )
00049 : start( start ), end( end ), startOffset( 0 ), endOffset( 0 ) {}
00050
00051 template<typename T>
00052 OffsetRange<T>::OffsetRange( T start, int startOffset, T end, int endOffset )
00053 : start( start ), end( end ), startOffset( startOffset ), endOffset( endOffset ) {}
00054
00055 template<typename T>
00056 int OffsetRange<T>::absStartIndex( const ShProgramNode::VarList vars ) const {
00057 return absIndex( start, startOffset, vars );
00058 }
00059
00060 template<typename T>
00061 int OffsetRange<T>::absEndIndex( const ShProgramNode::VarList vars ) const {
00062 return absIndex( end, endOffset, vars );
00063 }
00064
00065 template<typename T>
00066 std::string OffsetRange<T>::toString() const {
00067 std::ostringstream os;
00068 os << "(" << start << (startOffset >= 0 ? "+" : "" ) << startOffset
00069 << ", " << end << (endOffset >= 0 ? "+" : "" ) << endOffset << ")";
00070 return os.str();
00071 }
00072
00073 template<typename T>
00074 ShManipulator<T>::ShManipulator() {}
00075
00076 template<typename T>
00077 ShManipulator<T>::~ShManipulator() {
00078 }
00079
00080 template<typename T>
00081 ShManipulator<T>& ShManipulator<T>::operator()(T i) {
00082 m_ranges.push_back(IndexRange(i, i));
00083 return *this;
00084 }
00085
00086 template<typename T>
00087 ShManipulator<T>& ShManipulator<T>::operator()(T start, T end) {
00088 m_ranges.push_back(IndexRange(start, end));
00089 return *this;
00090 }
00091
00092 template<typename T>
00093 ShManipulator<T>& ShManipulator<T>::operator()(const IndexRange &range) {
00094 m_ranges.push_back(range);
00095 return *this;
00096 }
00097
00098 template<typename T>
00099 typename ShManipulator<T>::IndexRangeVector ShManipulator<T>::getRanges() const {
00100 return m_ranges;
00101 }
00102
00103 template<typename T>
00104 std::string ShManipulator<T>::toString() const {
00105 std::ostringstream os;
00106 for(typename IndexRangeVector::const_iterator it = m_ranges.begin(); it != m_ranges.end(); ++it) {
00107 if(it != m_ranges.begin()) os << ", ";
00108 os << it->toString();
00109 }
00110 return os.str();
00111 }
00112
00113
00114 template<typename T>
00115 ShProgram operator<<(const ShProgram &p, const ShManipulator<T> &m) {
00116 typedef typename ShManipulator<T>::IndexRangeVector RangeVec;
00117 RangeVec mranges = m.getRanges();
00118 int i;
00119
00120 ShProgram permuter = SH_BEGIN_PROGRAM() {
00121
00122
00123
00124 std::vector<ShVariable> outputs;
00125 for(ShProgramNode::VarList::const_iterator inIt = p.node()->inputs.begin();
00126 inIt != p.node()->inputs.end(); ++inIt) {
00127 ShVariable out((*inIt)->clone(SH_OUTPUT));
00128 outputs.push_back(out);
00129 }
00130
00131 int size = outputs.size();
00132
00133
00134 std::vector<bool> used(size, false);
00135 for(typename RangeVec::const_iterator irvIt = mranges.begin();
00136 irvIt != mranges.end(); ++irvIt) {
00137 int start = irvIt->absStartIndex( p.node()->inputs );
00138 int end = irvIt->absEndIndex( p.node()->inputs );
00139
00140 if(start == OFFSET_RANGE_BAD_OFFSET || end == OFFSET_RANGE_BAD_OFFSET ) continue;
00141 if(start == OFFSET_RANGE_BAD_INDEX || end == OFFSET_RANGE_BAD_INDEX ) {
00142 std::ostringstream os;
00143 os << "Invalid ShManipulator Range " << irvIt->toString()
00144 << " for an ShProgram with output size " << size;
00145 shError(ShAlgebraException(os.str()));
00146 }
00147
00148 for(i = start; i <= end; ++i) {
00149 if(used[i]) {
00150 std::ostringstream os;
00151 os << "Duplicate index " << i << " in range " << irvIt->toString()
00152 << " not allowed for input manipulators";
00153 shError(ShAlgebraException(os.str()));
00154 }
00155 used[i] = true;
00156
00157 ShVariable input(outputs[i].node()->clone(SH_INPUT));
00158 shASN(outputs[i], input);
00159 }
00160 }
00161 } SH_END;
00162
00163 return connect(permuter, p);
00164 }
00165
00166 template<typename T>
00167 ShProgram operator<<(const ShManipulator<T> &m, const ShProgram &p) {
00168 typedef typename ShManipulator<T>::IndexRangeVector RangeVec;
00169 RangeVec mranges = m.getRanges();
00170
00171 ShProgram permuter = SH_BEGIN_PROGRAM() {
00172
00173 std::vector<ShVariable> inputs;
00174 for(ShProgramNode::VarList::const_iterator outIt = p.node()->outputs.begin();
00175 outIt != p.node()->outputs.end(); ++outIt) {
00176 ShVariable in((*outIt)->clone(SH_INPUT));
00177 inputs.push_back(in);
00178 }
00179
00180 int size = inputs.size();
00181
00182
00183 for(typename RangeVec::const_iterator irvIt = mranges.begin();
00184 irvIt != mranges.end(); ++irvIt) {
00185 int start = irvIt->absStartIndex( p.node()->outputs );
00186 int end = irvIt->absEndIndex( p.node()->outputs );
00187
00188 if(start == OFFSET_RANGE_BAD_OFFSET || end == OFFSET_RANGE_BAD_OFFSET ) continue;
00189 if(start == OFFSET_RANGE_BAD_INDEX || end == OFFSET_RANGE_BAD_INDEX ) {
00190 std::ostringstream os;
00191 os << "Invalid ShManipulator Range " << irvIt->toString() <<
00192 " for an ShProgram with output size " << size;
00193 shError(ShAlgebraException(os.str()));
00194 }
00195
00196 for(int i = start; i <= end; ++i) {
00197 ShVariable output(inputs[i].node()->clone(SH_OUTPUT));
00198 shASN(output, inputs[i]);
00199 }
00200 }
00201 } SH_END;
00202
00203 return connect(p, permuter);
00204 }
00205
00206 template<typename T>
00207 ShManipulator<T> shSwizzle(T i0) {
00208 ShManipulator<T> m;
00209 m(i0);
00210 return m;
00211 }
00212 template<typename T>
00213 ShManipulator<T> shSwizzle(T i0, T i1) {
00214 ShManipulator<T> m;
00215 m(i0); m(i1);
00216 return m;
00217 }
00218 template<typename T>
00219 ShManipulator<T> shSwizzle(T i0, T i1, T i2) {
00220 ShManipulator<T> m;
00221 m(i0); m(i1); m(i2);
00222 return m;
00223 }
00224
00225 template<typename T>
00226 ShManipulator<T> shSwizzle(T i0, T i1, T i2, T i3) {
00227 ShManipulator<T> m;
00228 m(i0); m(i1); m(i2); m(i3);
00229 return m;
00230 }
00231
00232 template<typename T>
00233 ShManipulator<T> shSwizzle(T i0, T i1, T i2, T i3, T i4) {
00234 ShManipulator<T> m;
00235 m(i0); m(i1); m(i2); m(i3); m(i4);
00236 return m;
00237 }
00238
00239 template<typename T>
00240 ShManipulator<T> shSwizzle(T i0, T i1, T i2, T i3, T i4, T i5) {
00241 ShManipulator<T> m;
00242 m(i0); m(i1); m(i2); m(i3); m(i4); m(i5);
00243 return m;
00244 }
00245
00246 template<typename T>
00247 ShManipulator<T> shSwizzle(T i0, T i1, T i2, T i3, T i4, T i5, T i6) {
00248 ShManipulator<T> m;
00249 m(i0); m(i1); m(i2); m(i3); m(i4); m(i5); m(i6);
00250 return m;
00251 }
00252
00253 template<typename T>
00254 ShManipulator<T> shSwizzle(T i0, T i1, T i2, T i3, T i4, T i5, T i6, T i7) {
00255 ShManipulator<T> m;
00256 m(i0); m(i1); m(i2); m(i3); m(i4); m(i5); m(i6); m(i7);
00257 return m;
00258 }
00259
00260 template<typename T>
00261 ShManipulator<T> shSwizzle(T i0, T i1, T i2, T i3, T i4, T i5, T i6, T i7, T i8) {
00262 ShManipulator<T> m;
00263 m(i0); m(i1); m(i2); m(i3); m(i4); m(i5); m(i6);
00264 m(i7); m(i8);
00265 return m;
00266 }
00267
00268 template<typename T>
00269 ShManipulator<T> shSwizzle(T i0, T i1, T i2, T i3, T i4, T i5, T i6, T i7, T i8, T i9) {
00270 ShManipulator<T> m;
00271 m(i0); m(i1); m(i2); m(i3); m(i4); m(i5); m(i6);
00272 m(i7); m(i8); m(i9);
00273 return m;
00274 }
00275
00276 template<typename T>
00277 ShManipulator<T> shSwizzle(std::vector<T> indices) {
00278 ShManipulator<T> m;
00279 for(typename std::vector<T>::iterator it = indices.begin();
00280 it != indices.end(); ++it) {
00281 m(*it);
00282 }
00283 return m;
00284 }
00285
00286 template<typename T>
00287 ShManipulator<T> shRange(T i) {
00288 ShManipulator<T> m;
00289 m(i);
00290 return m;
00291 }
00292
00293 template<typename T>
00294 ShManipulator<T> shRange(T start, T end) {
00295 ShManipulator<T> m;
00296 m(start, end);
00297 return m;
00298 }
00299
00300 template<typename T>
00301 ShManipulator<T> shExtract(T k) {
00302 ShManipulator<T> m;
00303 m(k);
00304 typedef typename ShManipulator<T>::IndexRange Range;
00305 m(Range(k,_FIRST,k,-1));
00306 m(Range(k,1,k,_LAST));
00307 return m;
00308 }
00309
00310 template<typename T>
00311 ShManipulator<T> shInsert(T k) {
00312 ShManipulator<T> m;
00313 typedef typename ShManipulator<T>::IndexRange Range;
00314
00315 m(Range(k,_SECOND,k,0));
00316 m(Range(k,_FIRST,k,_FIRST));
00317 m(Range(k,1,k,_LAST));
00318 std::cout << m.toString() << std::endl;
00319 return m;
00320 }
00321
00322 template<typename T>
00323 ShManipulator<T> shDrop(T k) {
00324 ShManipulator<T> m;
00325 typedef typename ShManipulator<T>::IndexRange Range;
00326 m(Range(k,_FIRST,k,-1));
00327 m(Range(k,1,k,_LAST));
00328 return m;
00329 }
00330
00331 }
00332
00333 #endif