libidx
/home/rex/ebltrunk/core/libidx/include/idxops_ipp.hpp
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__ */