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