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

ShInstructions.cpp

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 #include <cmath> 00028 #include "ShInstructions.hpp" 00029 #include "ShStatement.hpp" 00030 #include "ShContext.hpp" 00031 #include "ShDebug.hpp" 00032 #include "ShError.hpp" 00033 00034 #ifdef WIN32 00035 // TODO: quick fix, maybe this should be handled elsewhere or 00036 // implemented better? 00037 inline float roundf(float f) { return floorf(f + 0.5); } 00038 inline float cbrtf(float f) { return pow(f, 1.0f/3.0f); } 00039 #endif /* WIN32 */ 00040 00041 namespace { 00042 00043 using namespace SH; 00044 00045 inline bool immediate() 00046 { 00047 return !ShContext::current()->parsing(); 00048 } 00049 00050 inline void sizes_match(const ShVariable& a, const ShVariable& b) 00051 { 00052 SH_DEBUG_ASSERT(a.size() == b.size()); 00053 } 00054 00055 inline void sizes_match(const ShVariable& a, const ShVariable& b, 00056 const ShVariable& c, bool scalar_b = false, bool scalar_c = false) 00057 { 00058 SH_DEBUG_ASSERT(((scalar_b && b.size() == 1) || a.size() == b.size()) && 00059 ((scalar_c && c.size() == 1) || a.size() == c.size())); 00060 } 00061 00062 inline void has_values(const ShVariable& a) 00063 { 00064 SH_DEBUG_ASSERT(a.hasValues()); 00065 } 00066 00067 inline void has_values(const ShVariable& a, const ShVariable& b) 00068 { 00069 SH_DEBUG_ASSERT(a.hasValues()); 00070 SH_DEBUG_ASSERT(b.hasValues()); 00071 } 00072 00073 inline void has_values(const ShVariable& a, const ShVariable& b, const ShVariable& c) 00074 { 00075 SH_DEBUG_ASSERT(a.hasValues()); 00076 SH_DEBUG_ASSERT(b.hasValues()); 00077 SH_DEBUG_ASSERT(c.hasValues()); 00078 } 00079 00080 inline void has_values(const ShVariable& a, const ShVariable& b, 00081 const ShVariable& c, const ShVariable& d) 00082 { 00083 SH_DEBUG_ASSERT(a.hasValues()); 00084 SH_DEBUG_ASSERT(b.hasValues()); 00085 SH_DEBUG_ASSERT(c.hasValues()); 00086 SH_DEBUG_ASSERT(d.hasValues()); 00087 } 00088 00089 inline void addStatement(const ShStatement& stmt) 00090 { 00091 ShContext::current()->parsing()->tokenizer.blockList()->addStatement(stmt); 00092 } 00093 00094 typedef float T; 00095 00096 inline T slt(T a, T b) { return a < b ? 1.0f : 0.0f; } 00097 inline T sle(T a, T b) { return a <= b ? 1.0f : 0.0f; } 00098 inline T sgt(T a, T b) { return a > b ? 1.0f : 0.0f; } 00099 inline T sge(T a, T b) { return a >= b ? 1.0f : 0.0f; } 00100 inline T seq(T a, T b) { return a == b ? 1.0f : 0.0f; } 00101 inline T sne(T a, T b) { return a != b ? 1.0f : 0.0f; } 00102 inline T max(T a, T b) { return a > b ? a : b; } 00103 inline T min(T a, T b) { return a < b ? a : b; } 00104 inline T lrp(T alpha, T a, T b) { return alpha*a + (1.0f-alpha)*b; } 00105 inline T cond(T alpha, T a, T b) { return alpha > 0.0f ? a : b; } 00106 inline T mad(T a, T b, T c) { return a * b + c; } 00107 inline T frac(T a) { return fmodf(a, 1.0f); } 00108 inline T sgn(T a) { return (a < 0.0f ? -1.0f : (a == 0.0f ? 0.0f : 1.0f)); } 00109 00110 // TODO: Replace ifdef with an autoconf check 00111 #ifdef WIN32 00112 inline T exp2f(T a) { return powf(2.0, a); } 00113 inline T exp10f(T a) { return powf(10.0, a); } 00114 inline T log2f(T a) { return logf(a)/logf(2.0); } 00115 #endif 00116 #ifdef __APPLE__ 00117 inline T exp10f(T a) { return powf(10.0, a); } 00118 #endif 00119 } 00120 00121 #define CWISE_BINARY_OP(d, a, b, op) \ 00122 do {\ 00123 has_values(d, a, b);\ 00124 T* v_d = new T[d.size()];\ 00125 T* v_a = new T[a.size()];\ 00126 a.getValues(v_a);\ 00127 T* v_b = new T[b.size()];\ 00128 b.getValues(v_b);\ 00129 for (int i = 0; i < d.size(); i++) v_d[i] = op(v_a[(a.size() == 1 ? 0 : i)],\ 00130 v_b[(b.size() == 1 ? 0 : i)]);\ 00131 d.setValues(v_d);\ 00132 delete [] v_d;\ 00133 delete [] v_a;\ 00134 delete [] v_b;\ 00135 } while (0) 00136 00137 #define CWISE_BINARY_INLOP(d, a, b, op) \ 00138 do {\ 00139 has_values(d, a, b);\ 00140 T* v_d = new T[d.size()];\ 00141 T* v_a = new T[a.size()];\ 00142 a.getValues(v_a);\ 00143 T* v_b = new T[b.size()];\ 00144 b.getValues(v_b);\ 00145 for (int i = 0; i < d.size(); i++) v_d[i] = v_a[(a.size() == 1 ? 0 : i)] op\ 00146 v_b[(b.size() == 1 ? 0 : i)];\ 00147 d.setValues(v_d);\ 00148 delete [] v_d;\ 00149 delete [] v_a;\ 00150 delete [] v_b;\ 00151 } while (0) 00152 00153 #define CWISE_TRINARY_OP(d, a, b, c, op) \ 00154 do {\ 00155 has_values(d, a, b, c);\ 00156 T* v_a = new T[a.size()];\ 00157 a.getValues(v_a);\ 00158 T* v_b = new T[b.size()];\ 00159 b.getValues(v_b);\ 00160 T* v_c = new T[c.size()];\ 00161 c.getValues(v_c);\ 00162 T* v_d = new T[d.size()];\ 00163 for (int i = 0; i < d.size(); i++) v_d[i] = op(v_a[(a.size() == 1 ? 0 : i)],\ 00164 v_b[(b.size() == 1 ? 0 : i)],\ 00165 v_c[(c.size() == 1 ? 0 : i)]\ 00166 );\ 00167 d.setValues(v_d);\ 00168 delete [] v_d;\ 00169 delete [] v_a;\ 00170 delete [] v_b;\ 00171 delete [] v_c;\ 00172 } while (0) 00173 00174 #define CWISE_UNARY_OP(d, a, op) \ 00175 do {\ 00176 has_values(d, a);\ 00177 T* v_a = new T[a.size()];\ 00178 T* v_d = new T[d.size()];\ 00179 a.getValues(v_a);\ 00180 for (int i = 0; i < d.size(); i++) v_d[i] = op(v_a[(a.size() == 1 ? 0 : i)]);\ 00181 d.setValues(v_d);\ 00182 delete [] v_a;\ 00183 delete [] v_d;\ 00184 } while (0) 00185 00186 namespace SH { 00187 00188 void shASN(ShVariable& dest, const ShVariable& src) 00189 { 00190 sizes_match(dest, src); 00191 if (immediate()) { 00192 has_values(dest, src); 00193 T* vals = new T[src.size()]; 00194 src.getValues(vals); 00195 dest.setValues(vals); 00196 delete [] vals; 00197 } else { 00198 ShStatement stmt(dest, SH_OP_ASN, src); 00199 addStatement(stmt); 00200 } 00201 } 00202 00203 void shADD(ShVariable& dest, const ShVariable& a, const ShVariable& b) 00204 { 00205 sizes_match(dest, a, b, true, true); 00206 if (immediate()) { 00207 CWISE_BINARY_INLOP(dest, a, b, +); 00208 } else { 00209 ShStatement stmt(dest, a, SH_OP_ADD, b); 00210 addStatement(stmt); 00211 } 00212 } 00213 00214 void shMUL(ShVariable& dest, const ShVariable& a, const ShVariable& b) 00215 { 00216 sizes_match(dest, a, b, true, true); 00217 if (immediate()) { 00218 CWISE_BINARY_INLOP(dest, a, b, *); 00219 } else { 00220 ShStatement stmt(dest, a, SH_OP_MUL, b); 00221 addStatement(stmt); 00222 } 00223 } 00224 00225 void shDIV(ShVariable& dest, const ShVariable& a, const ShVariable& b) 00226 { 00227 sizes_match(dest, a, b, true, true); 00228 if (immediate()) { 00229 CWISE_BINARY_INLOP(dest, a, b, /); 00230 } else { 00231 ShStatement stmt(dest, a, SH_OP_DIV, b); 00232 addStatement(stmt); 00233 } 00234 } 00235 00236 void shSLT(ShVariable& dest, const ShVariable& a, const ShVariable& b) 00237 { 00238 sizes_match(dest, a, b, true, true); 00239 if (immediate()) { 00240 CWISE_BINARY_OP(dest, a, b, slt); 00241 } else { 00242 ShStatement stmt(dest, a, SH_OP_SLT, b); 00243 addStatement(stmt); 00244 } 00245 } 00246 00247 void shSLE(ShVariable& dest, const ShVariable& a, const ShVariable& b) 00248 { 00249 sizes_match(dest, a, b, true, true); 00250 if (immediate()) { 00251 CWISE_BINARY_OP(dest, a, b, sle); 00252 } else { 00253 ShStatement stmt(dest, a, SH_OP_SLE, b); 00254 addStatement(stmt); 00255 } 00256 } 00257 00258 void shSGT(ShVariable& dest, const ShVariable& a, const ShVariable& b) 00259 { 00260 sizes_match(dest, a, b, true, true); 00261 if (immediate()) { 00262 CWISE_BINARY_OP(dest, a, b, sgt); 00263 } else { 00264 ShStatement stmt(dest, a, SH_OP_SGT, b); 00265 addStatement(stmt); 00266 } 00267 } 00268 00269 void shSGE(ShVariable& dest, const ShVariable& a, const ShVariable& b) 00270 { 00271 sizes_match(dest, a, b, true, true); 00272 if (immediate()) { 00273 CWISE_BINARY_OP(dest, a, b, sge); 00274 } else { 00275 ShStatement stmt(dest, a, SH_OP_SGE, b); 00276 addStatement(stmt); 00277 } 00278 } 00279 00280 void shSEQ(ShVariable& dest, const ShVariable& a, const ShVariable& b) 00281 { 00282 sizes_match(dest, a, b, true, true); 00283 if (immediate()) { 00284 CWISE_BINARY_OP(dest, a, b, seq); 00285 } else { 00286 ShStatement stmt(dest, a, SH_OP_SEQ, b); 00287 addStatement(stmt); 00288 } 00289 } 00290 00291 void shSNE(ShVariable& dest, const ShVariable& a, const ShVariable& b) 00292 { 00293 sizes_match(dest, a, b, true, true); 00294 if (immediate()) { 00295 CWISE_BINARY_OP(dest, a, b, sne); 00296 } else { 00297 ShStatement stmt(dest, a, SH_OP_SNE, b); 00298 addStatement(stmt); 00299 } 00300 } 00301 00302 void shABS(ShVariable& dest, const ShVariable& a) 00303 { 00304 sizes_match(dest, a); 00305 if (immediate()) { 00306 CWISE_UNARY_OP(dest, a, std::fabs); 00307 } else { 00308 ShStatement stmt(dest, SH_OP_ABS, a); 00309 addStatement(stmt); 00310 } 00311 } 00312 00313 void shACOS(ShVariable& dest, const ShVariable& a) 00314 { 00315 sizes_match(dest, a); 00316 if (immediate()) { 00317 CWISE_UNARY_OP(dest, a, std::acos); 00318 } else { 00319 ShStatement stmt(dest, SH_OP_ACOS, a); 00320 addStatement(stmt); 00321 } 00322 } 00323 00324 void shASIN(ShVariable& dest, const ShVariable& a) 00325 { 00326 sizes_match(dest, a); 00327 if (immediate()) { 00328 CWISE_UNARY_OP(dest, a, std::asin); 00329 } else { 00330 ShStatement stmt(dest, SH_OP_ASIN, a); 00331 addStatement(stmt); 00332 } 00333 } 00334 00335 void shATAN(ShVariable& dest, const ShVariable& a) 00336 { 00337 sizes_match(dest, a); 00338 if (immediate()) { 00339 CWISE_UNARY_OP(dest, a, std::atan); 00340 } else { 00341 ShStatement stmt(dest, SH_OP_ATAN, a); 00342 addStatement(stmt); 00343 } 00344 } 00345 00346 void shATAN2(ShVariable& dest, const ShVariable& a, const ShVariable& b) 00347 { 00348 sizes_match(dest, a, b); 00349 if (immediate()) { 00350 CWISE_BINARY_OP(dest, a, b, atan2f); 00351 } else { 00352 ShStatement stmt(dest, a, SH_OP_ATAN2, b); 00353 addStatement(stmt); 00354 } 00355 } 00356 00357 void shCBRT(ShVariable& dest, const ShVariable& a) 00358 { 00359 sizes_match(dest, a); 00360 if (immediate()) { 00361 CWISE_UNARY_OP(dest, a, cbrtf); 00362 } else { 00363 ShStatement stmt(dest, SH_OP_CBRT, a); 00364 addStatement(stmt); 00365 } 00366 } 00367 void shCEIL(ShVariable& dest, const ShVariable& a) 00368 { 00369 sizes_match(dest, a); 00370 if (immediate()) { 00371 CWISE_UNARY_OP(dest, a, ceilf); 00372 } else { 00373 ShStatement stmt(dest, SH_OP_CEIL, a); 00374 addStatement(stmt); 00375 } 00376 } 00377 00378 void shCOS(ShVariable& dest, const ShVariable& a) 00379 { 00380 sizes_match(dest, a); 00381 if (immediate()) { 00382 CWISE_UNARY_OP(dest, a, std::cos); 00383 } else { 00384 ShStatement stmt(dest, SH_OP_COS, a); 00385 addStatement(stmt); 00386 } 00387 } 00388 00389 void shCMUL(ShVariable& dest, const ShVariable& a) 00390 { 00391 SH_DEBUG_ASSERT(dest.size() == 1); 00392 if (immediate()) { 00393 T* v_a = new T[a.size()]; 00394 a.getValues(v_a); 00395 T f = v_a[0]; 00396 for (int i = 1; i < a.size(); i++) f *= v_a[i]; 00397 dest.setValues(&f); 00398 delete [] v_a; 00399 } else { 00400 ShStatement stmt(dest, SH_OP_CMUL, a); 00401 addStatement(stmt); 00402 } 00403 } 00404 00405 void shCSUM(ShVariable& dest, const ShVariable& a) 00406 { 00407 SH_DEBUG_ASSERT(dest.size() == 1); 00408 if (immediate()) { 00409 T* v_a = new T[a.size()]; 00410 a.getValues(v_a); 00411 T f = v_a[0]; 00412 for (int i = 1; i < a.size(); i++) f += v_a[i]; 00413 dest.setValues(&f); 00414 delete [] v_a; 00415 } else { 00416 ShStatement stmt(dest, SH_OP_CMUL, a); 00417 addStatement(stmt); 00418 } 00419 } 00420 00421 void shDOT(ShVariable& dest, const ShVariable& a, const ShVariable& b) 00422 { 00423 SH_DEBUG_ASSERT(dest.size() == 1); 00424 sizes_match(a, b); 00425 if (immediate()) { 00426 T* v_a = new T[a.size()]; 00427 a.getValues(v_a); 00428 T* v_b = new T[a.size()]; 00429 b.getValues(v_b); 00430 T f = 0.0; 00431 for (int i = 0; i < a.size(); i++) f += v_a[i] * v_b[i]; 00432 dest.setValues(&f); 00433 delete [] v_a; 00434 delete [] v_b; 00435 } else { 00436 ShStatement stmt(dest, a, SH_OP_DOT, b); 00437 addStatement(stmt); 00438 } 00439 } 00440 00441 void shDX(ShVariable& dest, const ShVariable& a) 00442 { 00443 sizes_match(dest, a); 00444 if (immediate()) { 00445 shError(ShScopeException("Cannot take derivatives in immediate mode")); 00446 } else { 00447 ShStatement stmt(dest, SH_OP_DX, a); 00448 addStatement(stmt); 00449 } 00450 } 00451 00452 void shDY(ShVariable& dest, const ShVariable& a) 00453 { 00454 sizes_match(dest, a); 00455 if (immediate()) { 00456 shError(ShScopeException("Cannot take derivatives in immediate mode")); 00457 } else { 00458 ShStatement stmt(dest, SH_OP_DY, a); 00459 addStatement(stmt); 00460 } 00461 } 00462 00463 void shEXP(ShVariable& dest, const ShVariable& a) 00464 { 00465 sizes_match(dest, a); 00466 if (immediate()) { 00467 CWISE_UNARY_OP(dest, a, expf); 00468 } else { 00469 ShStatement stmt(dest, SH_OP_EXP, a); 00470 addStatement(stmt); 00471 } 00472 } 00473 00474 void shEXP2(ShVariable& dest, const ShVariable& a) 00475 { 00476 sizes_match(dest, a); 00477 if (immediate()) { 00478 CWISE_UNARY_OP(dest, a, exp2f); 00479 } else { 00480 ShStatement stmt(dest, SH_OP_EXP2, a); 00481 addStatement(stmt); 00482 } 00483 } 00484 00485 void shEXP10(ShVariable& dest, const ShVariable& a) 00486 { 00487 sizes_match(dest, a); 00488 if (immediate()) { 00489 CWISE_UNARY_OP(dest, a, exp10f); 00490 } else { 00491 ShStatement stmt(dest, SH_OP_EXP10, a); 00492 addStatement(stmt); 00493 } 00494 } 00495 00496 void shFLR(ShVariable& dest, const ShVariable& a) 00497 { 00498 sizes_match(dest, a); 00499 if (immediate()) { 00500 CWISE_UNARY_OP(dest, a, floorf); 00501 } else { 00502 ShStatement stmt(dest, SH_OP_FLR, a); 00503 addStatement(stmt); 00504 } 00505 } 00506 00507 void shMOD(ShVariable& dest, const ShVariable& a, const ShVariable& b) 00508 { 00509 sizes_match(dest, a, b); 00510 if (immediate()) { 00511 CWISE_BINARY_OP(dest, a, b, fmodf); 00512 } else { 00513 ShStatement stmt(dest, a, SH_OP_MOD, b); 00514 addStatement(stmt); 00515 } 00516 } 00517 00518 void shFRAC(ShVariable& dest, const ShVariable& a) 00519 { 00520 sizes_match(dest, a); 00521 if (immediate()) { 00522 CWISE_UNARY_OP(dest, a, frac); 00523 } else { 00524 ShStatement stmt(dest, SH_OP_FRAC, a); 00525 addStatement(stmt); 00526 } 00527 } 00528 00529 void shLRP(ShVariable& dest, const ShVariable& alpha, 00530 const ShVariable& a, const ShVariable& b) 00531 { 00532 SH_DEBUG_ASSERT(dest.size() == a.size() && 00533 dest.size() == b.size() && 00534 (dest.size() == alpha.size() || alpha.size() == 1)); 00535 if (immediate()) { 00536 CWISE_TRINARY_OP(dest, alpha, a, b, lrp); 00537 } else { 00538 ShStatement stmt(dest, SH_OP_LRP, alpha, a, b); 00539 addStatement(stmt); 00540 } 00541 } 00542 00543 void shLOG(ShVariable& dest, const ShVariable& a) 00544 { 00545 sizes_match(dest, a); 00546 if (immediate()) { 00547 CWISE_UNARY_OP(dest, a, logf); 00548 } else { 00549 ShStatement stmt(dest, SH_OP_LOG, a); 00550 addStatement(stmt); 00551 } 00552 } 00553 00554 void shLOG2(ShVariable& dest, const ShVariable& a) 00555 { 00556 sizes_match(dest, a); 00557 if (immediate()) { 00558 CWISE_UNARY_OP(dest, a, log2f); 00559 } else { 00560 ShStatement stmt(dest, SH_OP_LOG2, a); 00561 addStatement(stmt); 00562 } 00563 } 00564 00565 void shLOG10(ShVariable& dest, const ShVariable& a) 00566 { 00567 sizes_match(dest, a); 00568 if (immediate()) { 00569 CWISE_UNARY_OP(dest, a, log10f); 00570 } else { 00571 ShStatement stmt(dest, SH_OP_LOG10, a); 00572 addStatement(stmt); 00573 } 00574 } 00575 00576 void shMAD(ShVariable& dest, const ShVariable& a, 00577 const ShVariable& b, const ShVariable& c) 00578 { 00579 SH_DEBUG_ASSERT(dest.size() == c.size() && 00580 (dest.size() == a.size() || (dest.size() == b.size() && a.size() == 1)) && 00581 (dest.size() == b.size() || (dest.size() == a.size() && b.size() == 1))); 00582 if (immediate()) { 00583 CWISE_TRINARY_OP(dest, a, b, c, mad); 00584 } else { 00585 ShStatement stmt(dest, SH_OP_MAD, a, b, c); 00586 addStatement(stmt); 00587 } 00588 } 00589 00590 void shMAX(ShVariable& dest, const ShVariable& a, const ShVariable& b) 00591 { 00592 sizes_match(dest, a, b); 00593 if (immediate()) { 00594 CWISE_BINARY_OP(dest, a, b, max); 00595 } else { 00596 ShStatement stmt(dest, a, SH_OP_MAX, b); 00597 addStatement(stmt); 00598 } 00599 } 00600 00601 void shMIN(ShVariable& dest, const ShVariable& a, const ShVariable& b) 00602 { 00603 sizes_match(dest, a, b); 00604 if (immediate()) { 00605 CWISE_BINARY_OP(dest, a, b, min); 00606 } else { 00607 ShStatement stmt(dest, a, SH_OP_MIN, b); 00608 addStatement(stmt); 00609 } 00610 } 00611 00612 void shPOW(ShVariable& dest, const ShVariable& a, const ShVariable& b) 00613 { 00614 sizes_match(dest, a, b, false, true); 00615 if (immediate()) { 00616 CWISE_BINARY_OP(dest, a, b, powf); 00617 } else { 00618 ShStatement stmt(dest, a, SH_OP_POW, b); 00619 addStatement(stmt); 00620 } 00621 } 00622 00623 void shRCP(ShVariable& dest, const ShVariable& a) 00624 { 00625 sizes_match(dest, a); 00626 if (immediate()) { 00627 CWISE_UNARY_OP(dest, a, 1.0f / ); 00628 } else { 00629 ShStatement stmt(dest, SH_OP_RCP, a); 00630 addStatement(stmt); 00631 } 00632 } 00633 00634 void shRND(ShVariable& dest, const ShVariable& a) 00635 { 00636 sizes_match(dest, a); 00637 if (immediate()) { 00638 CWISE_UNARY_OP(dest, a, roundf); 00639 } else { 00640 ShStatement stmt(dest, SH_OP_RND, a); 00641 addStatement(stmt); 00642 } 00643 } 00644 00645 void shRSQ(ShVariable& dest, const ShVariable& a) 00646 { 00647 sizes_match(dest, a); 00648 if (immediate()) { 00649 CWISE_UNARY_OP(dest, a, 1.0f / sqrt); 00650 } else { 00651 ShStatement stmt(dest, SH_OP_RSQ, a); 00652 addStatement(stmt); 00653 } 00654 } 00655 00656 void shSGN(ShVariable& dest, const ShVariable& a) 00657 { 00658 sizes_match(dest, a); 00659 if (immediate()) { 00660 CWISE_UNARY_OP(dest, a, sgn); 00661 } else { 00662 ShStatement stmt(dest, SH_OP_SGN, a); 00663 addStatement(stmt); 00664 } 00665 } 00666 00667 void shSIN(ShVariable& dest, const ShVariable& a) 00668 { 00669 sizes_match(dest, a); 00670 if (immediate()) { 00671 CWISE_UNARY_OP(dest, a, std::sin); 00672 } else { 00673 ShStatement stmt(dest, SH_OP_SIN, a); 00674 addStatement(stmt); 00675 } 00676 } 00677 00678 void shSQRT(ShVariable& dest, const ShVariable& a) 00679 { 00680 sizes_match(dest, a); 00681 if (immediate()) { 00682 CWISE_UNARY_OP(dest, a, std::sqrt); 00683 } else { 00684 ShStatement stmt(dest, SH_OP_SQRT, a); 00685 addStatement(stmt); 00686 } 00687 } 00688 00689 void shTAN(ShVariable& dest, const ShVariable& a) 00690 { 00691 sizes_match(dest, a); 00692 if (immediate()) { 00693 CWISE_UNARY_OP(dest, a, std::tan); 00694 } else { 00695 ShStatement stmt(dest, SH_OP_TAN, a); 00696 addStatement(stmt); 00697 } 00698 } 00699 00700 void shNORM(ShVariable& dest, const ShVariable& a) 00701 { 00702 sizes_match(dest, a); 00703 if (immediate()) { 00704 T* v_a = new T[a.size()]; 00705 a.getValues(v_a); 00706 T s = 0.0; 00707 for (int i = 0; i < a.size(); i++) s += v_a[i] * v_a[i]; 00708 s = std::sqrt(s); 00709 for (int i = 0; i < a.size(); i++) v_a[i] /= s; 00710 dest.setValues(v_a); 00711 delete [] v_a; 00712 } else { 00713 ShStatement stmt(dest, SH_OP_NORM, a); 00714 addStatement(stmt); 00715 } 00716 } 00717 00718 void shXPD(ShVariable& dest, const ShVariable& a, const ShVariable& b) 00719 { 00720 SH_DEBUG_ASSERT(dest.size() == 3 && a.size() == 3 && b.size() == 3); 00721 if (immediate()) { 00722 T v_a[3]; 00723 a.getValues(v_a); 00724 T v_b[3]; 00725 b.getValues(v_b); 00726 T result[3]; 00727 result[0] = v_a[1] * v_b[2] - v_a[2] * v_b[1]; 00728 result[1] = -(v_a[0] * v_b[2] - v_a[2] * v_b[0]); 00729 result[2] = v_a[0] * v_b[1] - v_a[1] * v_b[0]; 00730 dest.setValues(result); 00731 } else { 00732 ShStatement stmt(dest, a, SH_OP_XPD, b); 00733 addStatement(stmt); 00734 } 00735 } 00736 00737 void shCOND(ShVariable& dest, const ShVariable& alpha, 00738 const ShVariable& a, const ShVariable& b) 00739 { 00740 SH_DEBUG_ASSERT(dest.size() == a.size() && 00741 dest.size() == b.size() && 00742 (dest.size() == alpha.size() || alpha.size() == 1)); 00743 if (immediate()) { 00744 CWISE_TRINARY_OP(dest, alpha, a, b, cond); 00745 } else { 00746 ShStatement stmt(dest, SH_OP_COND, alpha, a, b); 00747 addStatement(stmt); 00748 } 00749 } 00750 00751 void shKIL(const ShVariable& a) 00752 { 00753 SH_DEBUG_ASSERT(!immediate()); 00754 ShStatement stmt(a, SH_OP_KIL, a); 00755 addStatement(stmt); 00756 } 00757 00758 }

Generated on Mon Oct 18 14:17:39 2004 for Sh by doxygen 1.3.7