libidx
|
00001 #ifdef __IPP__ 00002 00004 // idx_copy 00005 00006 #define idx_copy_macro(T) \ 00007 template<> void idx_copy(const idx<T> &src, idx<T> &dst) { \ 00008 idx_checknelems2_all(src, dst); \ 00009 if ( (src.order() == 0) && (dst.order() == 0) ) { \ 00010 *(dst.idx_ptr()) = *(src.idx_ptr()); \ 00011 } else if (dst.contiguousp() && src.contiguousp()) { \ 00012 ipp_copy(src, dst); \ 00013 } else { \ 00014 /*This is slower */ \ 00015 idx_aloop2(isrc, src, T, idst, dst, T) { *idst = *isrc; } \ 00016 } \ 00017 } 00018 00020 // idx_clear 00021 00022 #define idx_clear_macro(T) \ 00023 template<> void idx_clear(idx<T> & inp) { \ 00024 if (inp.contiguousp()) { \ 00025 ipp_clear(inp); \ 00026 } else { \ 00027 idxiter<T> pinp; \ 00028 idx_aloop1_on(pinp,inp) { *pinp = 0; } \ 00029 } \ 00030 } 00031 00033 // idx_fill 00034 00035 #define idx_fill_macro(T) \ 00036 template<> void idx_fill(idx<T> & inp, T v) { \ 00037 if (inp.contiguousp()) { \ 00038 ipp_fill(inp, v); \ 00039 } else { \ 00040 idxiter<T> pinp; \ 00041 idx_aloop1_on(pinp,inp) { *pinp = v; } \ 00042 } \ 00043 } 00044 00046 // idx_minus 00047 00048 #define idx_minus_macro(T) \ 00049 template<> void idx_minus(idx<T> &inp, idx<T> &out) { \ 00050 if (inp.contiguousp() && out.contiguousp()) { \ 00051 ipp_minus(inp, out); \ 00052 } else { \ 00053 idxiter<T> pinp; idxiter<T> pout; \ 00054 idx_aloop2_on(pinp,inp,pout,out) { *pout = - *pinp; } \ 00055 } \ 00056 } 00057 00059 // idx_minus 00060 00061 #define idx_minus_acc_macro(T) \ 00062 template<> void idx_minus_acc(idx<T> &inp, idx<T> &out) { \ 00063 if (inp.contiguousp() && out.contiguousp()) { \ 00064 ipp_minus(inp, out); \ 00065 } else { \ 00066 idxiter<T> pinp; idxiter<T> pout; \ 00067 idx_aloop2_on(pinp,inp,pout,out) { *pout += - *pinp; } \ 00068 } \ 00069 } 00070 00072 // idx_add 00073 00074 #define idx_add_macro_in_place(T) \ 00075 template<> void idx_add(idx<T> &in, idx<T> &out) { \ 00076 if (in.contiguousp() && out.contiguousp()) { \ 00077 ipp_add(in, out); \ 00078 } else { \ 00079 idxiter<T> pin, pout; \ 00080 idx_aloop2_on(pin,in,pout,out) { *pout = *pout + *pin; } \ 00081 } \ 00082 } 00083 00084 #define idx_add_macro(T) \ 00085 template<> void idx_add(idx<T> &in1, idx<T> & in2, idx<T> &out) { \ 00086 if (in1.contiguousp() && in2.contiguousp() && out.contiguousp()) { \ 00087 ipp_add(in1, in2, out); \ 00088 } else { \ 00089 idxiter<T> pi1, pi2, pout; \ 00090 idx_aloop3_on(pi1,in1,pi2,in2,pout,out) { *pout = *pi1 + *pi2; } \ 00091 } \ 00092 } 00093 00095 // idx_sub 00096 00097 #define idx_sub_macro(T) \ 00098 template<> void idx_sub(idx<T> &in1, idx<T> & in2, idx<T> &out) { \ 00099 if (in1.contiguousp() && in2.contiguousp() && out.contiguousp()) { \ 00100 ipp_sub(in1, in2, out); \ 00101 } else { \ 00102 idxiter<T> pi1, pi2, pout; \ 00103 idx_aloop3_on(pi1,in1,pi2,in2,pout,out) { *pout = *pi1 - *pi2; } \ 00104 } \ 00105 } 00106 00108 // idx_mul 00109 00110 #define idx_mul_macro(T) \ 00111 template<> void idx_mul(idx<T> &in1, idx<T> & in2, idx<T> &out) { \ 00112 if (in1.contiguousp() && in2.contiguousp() && out.contiguousp()) { \ 00113 ipp_mul(in1, in2, out); \ 00114 } else { \ 00115 idxiter<T> pi1, pi2, pout; \ 00116 idx_aloop3_on(pi1,in1,pi2,in2,pout,out) { *pout = (*pi1) * (*pi2); } \ 00117 } \ 00118 } 00119 00121 // idx_m2dotm1 00122 00123 #define idx_m2dotm1_macro(T) \ 00124 template<> void idx_m2dotm1(idx<T> &in1, idx<T> & in2, idx<T> &out) { \ 00125 if (in1.contiguousp() && in2.contiguousp() && out.contiguousp()) { \ 00126 ipp_m2dotm1(in1, in2, out); \ 00127 } else { \ 00128 eblerror("not implemented for non contiguous"); \ 00129 /* idxiter<T> pi1, pi2, pout; */ \ 00130 /* idx_aloop3_on(pi1,in1,pi2,in2,pout,out) { *pout = (*pi1) * (*pi2); }*/ \ 00131 } \ 00132 } 00133 00135 // idx_m2dotm1 00136 00137 #define idx_m2dotm2_macro(T) \ 00138 template<> void idx_m2dotm2(idx<T> &in1, idx<T> & in2, idx<T> &out) { \ 00139 if (in1.contiguousp() && in2.contiguousp() && out.contiguousp()) { \ 00140 ipp_m2dotm2(in1, in2, out); \ 00141 } else { \ 00142 eblerror("not implemented for non contiguous"); \ 00143 /* idxiter<T> pi1, pi2, pout; */ \ 00144 /* idx_aloop3_on(pi1,in1,pi2,in2,pout,out) { *pout = (*pi1) * (*pi2); }*/ \ 00145 } \ 00146 } 00147 00149 // idx_div 00150 00151 #define idx_div_macro(T) \ 00152 template<> void idx_div(idx<T> &in1, idx<T> & in2, idx<T> &out) { \ 00153 if (in1.contiguousp() && in2.contiguousp() && out.contiguousp()) { \ 00154 ipp_div(in1, in2, out); \ 00155 } else { \ 00156 idxiter<T> pi1, pi2; idxiter<T> pout; \ 00157 idx_aloop3_on(pi1,in1,pi2,in2,pout,out) { \ 00158 /* TODO: remove this check in optimized version */ \ 00159 /* inefficient check but really important for debugging */ \ 00160 if (*pi2 == 0) \ 00161 eblerror("division by zero"); \ 00162 *pout = (*pi1) / (*pi2); \ 00163 } \ 00164 } \ 00165 } 00166 00168 // idx_addc 00169 00170 #define idx_addc_macro(T) \ 00171 template<> void idx_addc(idx<T> &inp, T c, idx<T> &out) { \ 00172 if (inp.contiguousp() && out.contiguousp()) { \ 00173 ipp_addc(inp, c, out); \ 00174 } else { \ 00175 idxiter<T> pinp; idxiter<T> pout; \ 00176 idx_aloop2_on(pinp,inp,pout,out) { *pout = *pinp + c; } \ 00177 } \ 00178 } 00179 00181 // idx_addc_bounded 00182 00183 #define idx_addc_bounded_macro(T) \ 00184 template<> void idx_addc_bounded(idx<T> &inp, T c, idx<T> &out) { \ 00185 if (inp.contiguousp() && out.contiguousp()) { \ 00186 ipp_addc(inp, c, out); \ 00187 } else { \ 00188 idxiter<T> pinp; idxiter<T> pout; \ 00189 idx_aloop2_on(pinp,inp,pout,out) { \ 00190 *pout = saturate(*pinp + c, T); \ 00191 } \ 00192 } \ 00193 } 00194 00196 // idx_subc_bounded 00197 00198 #define idx_subc_bounded_macro(T) \ 00199 template<> void idx_subc_bounded(idx<T> &inp, T c, idx<T> &out) { \ 00200 if (inp.contiguousp() && out.contiguousp()) { \ 00201 ipp_subc(inp, c, out); \ 00202 } else { \ 00203 idxiter<T> pinp; idxiter<T> pout; \ 00204 idx_aloop2_on(pinp,inp,pout,out) { \ 00205 *pout = saturate(*pinp - c, T); \ 00206 } \ 00207 } \ 00208 } 00209 00211 // idx_dotc 00212 00213 #define idx_dotc_macro(T) \ 00214 template<> void idx_dotc(idx<T> &inp, T c, idx<T> &out) { \ 00215 if (inp.contiguousp() && out.contiguousp()) { \ 00216 ipp_dotc(inp, c, out); \ 00217 } else { \ 00218 idxiter<T> pinp; idxiter<T> pout; \ 00219 idx_aloop2_on(pinp,inp,pout,out) { *pout = *pinp * c; } \ 00220 } \ 00221 } 00222 00224 // idx_dotc_bounded 00225 00226 #define idx_dotc_bounded_macro(T) \ 00227 template<> void idx_dotc_bounded(idx<T> &inp, T c, idx<T> &out) { \ 00228 if (inp.contiguousp() && out.contiguousp()) { \ 00229 ipp_dotc(inp, c, out); \ 00230 } else { \ 00231 idxiter<T> pinp; idxiter<T> pout; \ 00232 idx_aloop2_on(pinp,inp,pout,out) { \ 00233 *pout = saturate(*pinp * c, T); \ 00234 } \ 00235 } \ 00236 } 00237 00239 // idx_abs 00240 00241 #define idx_abs_macro(T) \ 00242 template<> void idx_abs(idx<T> &inp, idx<T> &out) { \ 00243 if (inp.contiguousp() && out.contiguousp()) { \ 00244 ipp_abs(inp, out); \ 00245 } else { \ 00246 idxiter<T> pinp; idxiter<T> pout; \ 00247 idx_aloop2_on(pinp,inp,pout,out) { *pout = (T)(abs(*pinp)); } \ 00248 } \ 00249 } 00250 00252 // idx_threshold (in-place) 00253 00254 #define idx_threshold_in_place_macro(T) \ 00255 template<> void idx_threshold(idx<T> & in, T th) { \ 00256 if (in.contiguousp()) { \ 00257 ipp_threshold_lt(in, th); \ 00258 } else { \ 00259 idxiter<T> pin; \ 00260 idx_aloop1_on(pin,in) { \ 00261 if (*pin < th) \ 00262 *pin = th; \ 00263 } \ 00264 } \ 00265 } 00266 00268 // idx_threshold (not-in-place) 00269 00270 #define idx_threshold_macro(T) \ 00271 template<> void idx_threshold(idx<T> & in, T th, idx<T> & out) { \ 00272 if (in.contiguousp() && out.contiguousp()) { \ 00273 ipp_threshold_lt(in, th, out); \ 00274 } else { \ 00275 idxiter<T> pin; idxiter<T> pout; \ 00276 idx_aloop2_on(pin,in,pout,out) { \ 00277 if (*pin < th) \ 00278 *pout = th; \ 00279 else \ 00280 *pout = *pin; \ 00281 } \ 00282 } \ 00283 } 00284 00286 // idx_threshold (in-place, with value) 00287 00288 #define idx_threshold_in_place_val_macro(T) \ 00289 template<> void idx_threshold(idx<T> & in, T th, T value) { \ 00290 if (in.contiguousp()) { \ 00291 ipp_threshold_lt(in, th, value); \ 00292 } else { \ 00293 idxiter<T> pin; \ 00294 idx_aloop1_on(pin,in) { \ 00295 if (*pin < th) \ 00296 *pin = value; \ 00297 } \ 00298 } \ 00299 } 00300 00302 // idx_threshold (not-in-place, with value) 00303 00304 #define idx_threshold_val_macro(T) \ 00305 template<> void idx_threshold(idx<T> & in, T th, T value, idx<T> & out) { \ 00306 if (in.contiguousp() && out.contiguousp()) { \ 00307 ipp_threshold_lt(in, th, value, out); \ 00308 } else { \ 00309 idxiter<T> pin; idxiter<T> pout; \ 00310 idx_aloop2_on(pin,in,pout,out) { \ 00311 if (*pin < th) \ 00312 *pout = value; \ 00313 else \ 00314 *pout = *pin; \ 00315 } \ 00316 } \ 00317 } 00318 00320 // idx_sqrt 00321 00322 #define idx_sqrt_macro(T) \ 00323 template<> void idx_sqrt(idx<T> &inp, idx<T> &out) { \ 00324 if (inp.contiguousp() && out.contiguousp()) { \ 00325 ipp_sqrt(inp, out); \ 00326 } else { \ 00327 idxiter<T> pin; idxiter<T> pout; \ 00328 idx_aloop2_on(pin,inp,pout,out) { \ 00329 *pout = (T)sqrt(*pin); \ 00330 } \ 00331 } \ 00332 } 00333 00335 // idx_sum 00336 00337 #ifndef __OPENMP__ 00338 00339 #define idx_sum_macro(T) \ 00340 template<> T idx_sum(idx<T> &inp, T* out) { \ 00341 if (inp.contiguousp()) { \ 00342 if (out != NULL) { \ 00343 *out = (T)ipp_sum(inp); \ 00344 return *out; \ 00345 } else { \ 00346 return (T)ipp_sum(inp); \ 00347 } \ 00348 } else { \ 00349 /* there is a much faster and parallel way */ \ 00350 /* of doing this using a tree. */ \ 00351 T z = 0; \ 00352 idxiter<T> pinp; \ 00353 idx_aloop1_on(pinp,inp) { z += *pinp; } \ 00354 if (out != NULL) \ 00355 *out = z; \ 00356 return z; \ 00357 } \ 00358 } 00359 00360 #endif 00361 00363 // idx_sumabs 00364 00365 #define idx_sumabs_macro(T) \ 00366 template<> float64 idx_sumabs(idx<T> & in, T* out) { \ 00367 if (in.contiguousp()) { \ 00368 if (out != NULL) { \ 00369 float64 sum = ipp_sumabs(in); \ 00370 *out = saturate(sum, T); \ 00371 return sum; \ 00372 } \ 00373 return ipp_sumabs(in); \ 00374 } else { \ 00375 /* there is a much faster and parallel way */ \ 00376 /* of doing this using a tree. */ \ 00377 float64 z = 0; \ 00378 idxiter<T> pinp; \ 00379 idx_aloop1_on(pinp,in) { z += abs((float64)(*pinp)); } \ 00380 if (out != NULL) \ 00381 *out = saturate(z, T); \ 00382 return z; \ 00383 } \ 00384 } 00385 00387 // idx_l2norm 00388 00389 #define idx_l2norm_macro(T) \ 00390 template<> float64 idx_l2norm(idx<T> & in) { \ 00391 if (in.contiguousp()) { \ 00392 return ipp_l2norm(in); \ 00393 } else { \ 00394 return sqrt(idx_sumsqr(in)); \ 00395 } \ 00396 } 00397 00399 // idx_mean 00400 00401 #define idx_mean_macro(T) \ 00402 template<> T idx_mean(idx<T> & in, T* out) { \ 00403 if (in.contiguousp()) { \ 00404 if (out != NULL) { \ 00405 *out = (T)ipp_mean(in); \ 00406 return *out; \ 00407 } \ 00408 return (T)ipp_mean(in); \ 00409 } else { \ 00410 if (out != NULL) { \ 00411 *out = (T)(idx_sum(in) / (float64)in.nelements()); \ 00412 return *out; \ 00413 } \ 00414 return (T)(idx_sum(in) / (float64)in.nelements()); \ 00415 } \ 00416 } 00417 00419 // idx_max 00420 00421 #define idx_max_macro(T) \ 00422 template<> T idx_max(idx<T> & m) { \ 00423 if (m.contiguousp()) { \ 00424 return ipp_max(m); \ 00425 } else { \ 00426 T v = *(m.idx_ptr()); \ 00427 { idx_aloop1(i, m, T) { \ 00428 if (*i > v) v = *i; \ 00429 }} \ 00430 return v; \ 00431 } \ 00432 } 00433 00435 // idx_min 00436 00437 #define idx_min_macro(T) \ 00438 template<> T idx_min(idx<T> & m) { \ 00439 if (m.contiguousp()) { \ 00440 return ipp_min(m); \ 00441 } else { \ 00442 T v = *(m.idx_ptr()); \ 00443 { idx_aloop1(i, m, T) { \ 00444 if (*i < v) v = *i; \ 00445 }} \ 00446 return v; \ 00447 } \ 00448 } 00449 00451 // idx_indexmax 00452 00453 #define idx_indexmax_macro(T) \ 00454 template<> intg idx_indexmax(idx<T> & m) { \ 00455 if (m.contiguousp()) { \ 00456 return ipp_indexmax(m); \ 00457 } else { \ 00458 intg i = 0, imax = 0; \ 00459 T v = *(m.idx_ptr()); \ 00460 { idx_aloop1(me, m, T) { \ 00461 if (*me > v) { \ 00462 v = *me; \ 00463 imax = i; \ 00464 } \ 00465 i++; \ 00466 }} \ 00467 return imax; \ 00468 } \ 00469 } 00470 00472 // idx_indexmin 00473 00474 #define idx_indexmin_macro(T) \ 00475 template<> intg idx_indexmin(idx<T> & m) { \ 00476 if (m.contiguousp()) { \ 00477 return ipp_indexmin(m); \ 00478 } else { \ 00479 intg i = 0, imin = 0; \ 00480 T v = *(m.idx_ptr()); \ 00481 { idx_aloop1(me, m, T) { \ 00482 if (*me < v) { \ 00483 v = *me; \ 00484 imin = i; \ 00485 } \ 00486 i++; \ 00487 }} \ 00488 return imin; \ 00489 } \ 00490 } 00491 00493 // idx_max (between 2 idx's, in-place) 00494 00495 #define idx_maxevery_macro(T) \ 00496 template<> void idx_max(idx<T> & in1, idx<T> & in2) { \ 00497 if (in1.contiguousp() && in2.contiguousp()) { \ 00498 return ipp_maxevery(in1, in2); \ 00499 } else { \ 00500 idx_aloop2(i1, in1, T, i2, in2, T) { \ 00501 *i2 = std::max(*i1, *i2); \ 00502 } \ 00503 } \ 00504 } 00505 00507 // idx_max (between 2 idx's, not-in-place) 00508 00509 #define idx_maxevery2_macro(T) \ 00510 template<> void idx_max(idx<T> & in1, idx<T> & in2, idx<T> & out) { \ 00511 if (in1.contiguousp() && in2.contiguousp() && out.contiguousp()) { \ 00512 return ipp_maxevery(in1, in2, out); \ 00513 } else { \ 00514 idx_aloop3(i1, in1, T, i2, in2, T, o, out, T) { \ 00515 *o = std::max(*i1, *i2); \ 00516 } \ 00517 } \ 00518 } 00519 00521 // idx_sqrdist 00522 00523 #define idx_sqrdist_macro(T) \ 00524 template<> float64 idx_sqrdist(idx<T> & in1, idx<T> & in2) { \ 00525 if (in1.contiguousp() && in2.contiguousp()) { \ 00526 return ipp_sqrdist(in1, in2); \ 00527 } else { \ 00528 idx_checknelems2_all(in1, in2); \ 00529 float64 z = 0; \ 00530 float64 tmp; \ 00531 { idx_aloop2(pi1, in1, T, pi2, in2, T) { \ 00532 tmp = (float64)(*pi1) - (float64)(*pi2); \ 00533 z += tmp * tmp; \ 00534 } \ 00535 } \ 00536 return z; \ 00537 } \ 00538 } 00539 00541 // idx_sqrdist (with idx out) 00542 00543 #define idx_sqrdist2_macro(T) \ 00544 template<> void idx_sqrdist(idx<T> & in1, idx<T> & in2, idx<T> & out) { \ 00545 if (in1.contiguousp() && in2.contiguousp() && out.contiguousp()) { \ 00546 ipp_sqrdist(in1, in2, out); \ 00547 } else { \ 00548 idx_checknelems2_all(in1, in2); \ 00549 if (out.order() != 0) \ 00550 eblerror("idx_sqrdist: expecting an idx of order 0"); \ 00551 out.set((T)idx_sqrdist(in1, in2)); \ 00552 } \ 00553 } 00554 00556 // idx_exp 00557 00558 #define idx_exp_macro(T) \ 00559 template<> void idx_exp(idx<T> &inp) { \ 00560 if (inp.contiguousp()) { \ 00561 ipp_exp(inp); \ 00562 } else { \ 00563 idx_aloop1(i, inp, T) { \ 00564 *i = (T)exp(*i); \ 00565 }; \ 00566 } \ 00567 } 00568 00570 // idx_dot 00571 00572 #ifdef __IPP_DOT__ 00573 00574 #define idx_dot_macro(T) \ 00575 template<> T idx_dot(idx<T> & in1, idx<T> & in2) { \ 00576 if (in1.contiguousp() && in2.contiguousp()) { \ 00577 return ipp_dot(in1, in2); \ 00578 } else { \ 00579 T z = 0; \ 00580 { idx_aloop2(pi1, in1, T, pi2, in2, T) { \ 00581 z += *pi1 * *pi2; \ 00582 } \ 00583 } \ 00584 return z; \ 00585 } \ 00586 } 00587 00588 #endif 00589 00590 // TODO: this does not compile 00591 // #ifdef __IPP_DOT__ 00592 00593 /* 00594 #define idx_dot_macro(T) \ 00595 template<> float64 idx_dot(idx<T> & in1, idx<T> & in2) { \ 00596 if (in1.contiguousp() && in2.contiguousp()) { \ 00597 return ipp_dot(in1, in2); \ 00598 } else { \ 00599 float64 z = 0; \ 00600 { idx_aloop2(pi1, in1, T, pi2, in2, T) { \ 00601 z += ((float64)(*pi1)) * ((float64)(*pi2)); \ 00602 } \ 00603 } \ 00604 return z; \ 00605 } \ 00606 } 00607 */ 00608 // #endif 00609 00610 #endif /* #ifdef __IPP__ */