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(
ShVariable(
new ShVariableNode(SH_OUTPUT,
00131 (*inIt)->size(), (*inIt)->specialType())));
00132 out.name((*inIt)->name());
00133 outputs.push_back(out);
00134 }
00135
00136
int size = outputs.size();
00137
00138
00139 std::vector<bool> used(size,
false);
00140
for(
typename RangeVec::const_iterator irvIt = mranges.begin();
00141 irvIt != mranges.end(); ++irvIt) {
00142
int start = irvIt->absStartIndex( p.node()->inputs );
00143
int end = irvIt->absEndIndex( p.node()->inputs );
00144
00145
if(start == OFFSET_RANGE_BAD_OFFSET || end == OFFSET_RANGE_BAD_OFFSET )
continue;
00146
if(start == OFFSET_RANGE_BAD_INDEX || end == OFFSET_RANGE_BAD_INDEX ) {
00147 std::ostringstream os;
00148 os <<
"Invalid ShManipulator Range " << irvIt->toString()
00149 <<
" for an ShProgram with output size " << size;
00150
shError(
ShAlgebraException(os.str()));
00151 }
00152
00153
for(i = start; i <= end; ++i) {
00154
if(used[i]) {
00155 std::ostringstream os;
00156 os <<
"Duplicate index " << i <<
" in range " << irvIt->toString()
00157 <<
" not allowed for input manipulators";
00158
shError(
ShAlgebraException(os.str()));
00159 }
00160 used[i] =
true;
00161
00162
ShVariable input(
new ShVariableNode(SH_INPUT,
00163 outputs[i].node()->size(), outputs[i].node()->specialType()));
00164 input.name(outputs[i].name());
00165
00166 shASN(outputs[i], input);
00167 }
00168 }
00169 } SH_END;
00170
00171
return connect(permuter, p);
00172 }
00173
00174
template<
typename T>
00175 ShProgram operator<<(const ShManipulator<T> &m,
const ShProgram &p) {
00176
typedef typename ShManipulator<T>::IndexRangeVector RangeVec;
00177 RangeVec mranges = m.
getRanges();
00178
00179
ShProgram permuter =
SH_BEGIN_PROGRAM() {
00180
00181 std::vector<ShVariable> inputs;
00182
for(ShProgramNode::VarList::const_iterator outIt = p.node()->outputs.begin();
00183 outIt != p.node()->outputs.end(); ++outIt) {
00184
ShVariable in(
new ShVariableNode(SH_INPUT, (*outIt)->size(),
00185 (*outIt)->specialType()));
00186 in.name((*outIt)->name());
00187 inputs.push_back(in);
00188 }
00189
00190
int size = inputs.size();
00191
00192
00193
for(
typename RangeVec::const_iterator irvIt = mranges.begin();
00194 irvIt != mranges.end(); ++irvIt) {
00195
int start = irvIt->absStartIndex( p.node()->outputs );
00196
int end = irvIt->absEndIndex( p.node()->outputs );
00197
00198
if(start == OFFSET_RANGE_BAD_OFFSET || end == OFFSET_RANGE_BAD_OFFSET )
continue;
00199
if(start == OFFSET_RANGE_BAD_INDEX || end == OFFSET_RANGE_BAD_INDEX ) {
00200 std::ostringstream os;
00201 os <<
"Invalid ShManipulator Range " << irvIt->toString() <<
00202
" for an ShProgram with output size " << size;
00203
shError(
ShAlgebraException(os.str()));
00204 }
00205
00206
for(
int i = start; i <= end; ++i) {
00207
ShVariable output(
new ShVariableNode(SH_OUTPUT,
00208 inputs[i].node()->size(), inputs[i].node()->specialType()));
00209 output.name( inputs[i].name() );
00210
00211 shASN(output, inputs[i]);
00212 }
00213 }
00214 } SH_END;
00215
00216
return connect(p, permuter);
00217 }
00218
00219
template<
typename T>
00220 ShManipulator<T> shSwizzle(T i0) {
00221
ShManipulator<T> m;
00222 m(i0);
00223
return m;
00224 }
00225
template<
typename T>
00226 ShManipulator<T>
shSwizzle(T i0, T i1) {
00227 ShManipulator<T> m;
00228 m(i0); m(i1);
00229
return m;
00230 }
00231
template<
typename T>
00232 ShManipulator<T>
shSwizzle(T i0, T i1, T i2) {
00233 ShManipulator<T> m;
00234 m(i0); m(i1); m(i2);
00235
return m;
00236 }
00237
00238
template<
typename T>
00239 ShManipulator<T>
shSwizzle(T i0, T i1, T i2, T i3) {
00240 ShManipulator<T> m;
00241 m(i0); m(i1); m(i2); m(i3);
00242
return m;
00243 }
00244
00245
template<
typename T>
00246 ShManipulator<T>
shSwizzle(T i0, T i1, T i2, T i3, T i4) {
00247 ShManipulator<T> m;
00248 m(i0); m(i1); m(i2); m(i3); m(i4);
00249
return m;
00250 }
00251
00252
template<
typename T>
00253 ShManipulator<T>
shSwizzle(T i0, T i1, T i2, T i3, T i4, T i5) {
00254 ShManipulator<T> m;
00255 m(i0); m(i1); m(i2); m(i3); m(i4); m(i5);
00256
return m;
00257 }
00258
00259
template<
typename T>
00260 ShManipulator<T>
shSwizzle(T i0, T i1, T i2, T i3, T i4, T i5, T i6) {
00261 ShManipulator<T> m;
00262 m(i0); m(i1); m(i2); m(i3); m(i4); m(i5); m(i6);
00263
return m;
00264 }
00265
00266
template<
typename T>
00267 ShManipulator<T>
shSwizzle(T i0, T i1, T i2, T i3, T i4, T i5, T i6, T i7) {
00268 ShManipulator<T> m;
00269 m(i0); m(i1); m(i2); m(i3); m(i4); m(i5); m(i6); m(i7);
00270
return m;
00271 }
00272
00273
template<
typename T>
00274 ShManipulator<T>
shSwizzle(T i0, T i1, T i2, T i3, T i4, T i5, T i6, T i7, T i8) {
00275 ShManipulator<T> m;
00276 m(i0); m(i1); m(i2); m(i3); m(i4); m(i5); m(i6);
00277 m(i7); m(i8);
00278
return m;
00279 }
00280
00281
template<
typename T>
00282 ShManipulator<T>
shSwizzle(T i0, T i1, T i2, T i3, T i4, T i5, T i6, T i7, T i8, T i9) {
00283 ShManipulator<T> m;
00284 m(i0); m(i1); m(i2); m(i3); m(i4); m(i5); m(i6);
00285 m(i7); m(i8); m(i9);
00286
return m;
00287 }
00288
00289
template<
typename T>
00290 ShManipulator<T>
shSwizzle(std::vector<T> indices) {
00291 ShManipulator<T> m;
00292
for(
typename std::vector<T>::iterator it = indices.begin();
00293 it != indices.end(); ++it) {
00294 m(*it);
00295 }
00296
return m;
00297 }
00298
00299
template<
typename T>
00300 ShManipulator<T> shRange(T i) {
00301
ShManipulator<T> m;
00302 m(i);
00303
return m;
00304 }
00305
00306
template<
typename T>
00307 ShManipulator<T>
shRange(T start, T end) {
00308 ShManipulator<T> m;
00309 m(start, end);
00310
return m;
00311 }
00312
00313
template<
typename T>
00314 ShManipulator<T> shExtract(T k) {
00315
ShManipulator<T> m;
00316 m(k);
00317
typedef typename ShManipulator<T>::IndexRange Range;
00318 m(Range(k,_FIRST,k,-1));
00319 m(Range(k,1,k,_LAST));
00320
return m;
00321 }
00322
00323
template<
typename T>
00324 ShManipulator<T> shInsert(T k) {
00325
ShManipulator<T> m;
00326
typedef typename ShManipulator<T>::IndexRange Range;
00327
00328 m(Range(k,_SECOND,k,0));
00329 m(Range(k,_FIRST,k,_FIRST));
00330 m(Range(k,1,k,_LAST));
00331 std::cout << m.
toString() << std::endl;
00332
return m;
00333 }
00334
00335
template<
typename T>
00336 ShManipulator<T> shDrop(T k) {
00337
ShManipulator<T> m;
00338
typedef typename ShManipulator<T>::IndexRange Range;
00339 m(Range(k,_FIRST,k,-1));
00340 m(Range(k,1,k,_LAST));
00341
return m;
00342 }
00343
00344 }
00345
00346
#endif