Home || Architecture || Video Search || Visual Search || Scripts || Applications || Important Messages || OGL || Src

FuncGenConv2dSep.h

Go to the documentation of this file.
00001 #ifndef Impala_Core_Array_Pattern_FuncGenConv2dSep_h
00002 #define Impala_Core_Array_Pattern_FuncGenConv2dSep_h
00003 
00004 #include "Core/Array/Pattern/Categories.h"
00005 #include "Core/Array/Pattern/ArrayFunc.h"
00006 
00007 namespace Impala
00008 {
00009 namespace Core
00010 {
00011 namespace Array
00012 {
00013 namespace Pattern
00014 {
00015 
00016 
00017 /**********************************************************************/
00073 template<class DstStorT, class SrcStorT, class KerStorT, class KerArithT,
00074          class PixOpT, class RedOpT>
00075 static inline void
00076 FuncGenConv2dSep_Pix_Xdir(DstStorT* dPtr, SrcStorT* sPtr, KerStorT* kPtr,
00077                           int kerWidth, int srcInc, int kerInc, PixOpT& pixOp,
00078                           RedOpT& redOp, KerArithT neutralElement,
00079                           TagCallValue dummy)
00080 {
00081     KerArithT result(neutralElement);
00082     for (int k=0; k<kerWidth; k++)
00083     {
00084         redOp.DoIt(result, pixOp.DoIt(PtrRead(sPtr, KerArithT()),
00085                                       PtrRead(kPtr, KerArithT())));
00086         sPtr += srcInc;
00087         kPtr += kerInc;
00088     }
00089     PtrWrite(dPtr, result);
00090 }
00091 
00097 template<class DstStorT, class SrcStorT, class KerStorT, class KerArithT,
00098          class PixOpT, class RedOpT>
00099 static inline void
00100 FuncGenConv2dSep_Pix_Ydir(DstStorT* dPtr, SrcStorT* sPtr, KerStorT* kPtr,
00101                           int kerWidth, int srcInc, int kerInc, PixOpT& pixOp,
00102                           RedOpT& redOp, KerArithT neutralElement,
00103                           TagCallValue dummy)
00104 {
00105     KerArithT result(neutralElement);
00106     for (int k=0; k<kerWidth; k++)
00107     {
00108         redOp.DoIt(result, pixOp.DoIt(PtrRead(sPtr, KerArithT()),
00109                                       PtrRead(kPtr, KerArithT())));
00110         sPtr += srcInc;
00111         kPtr += kerInc;
00112     }
00113     PtrWrite(dPtr, result);
00114 }
00115 
00117 //End of Pix_variations.
00118 
00119 
00121 
00128 template<class DstArrayT, class SrcArrayT, class KerArrayT,
00129          class PixOpT, class RedOpT>
00130 static void
00131 FuncGenConv2dSep_Line_Xdir(DstArrayT* dst, SrcArrayT* src, KerArrayT* ker,
00132                            PixOpT& pixOp, RedOpT& redOp, int y,
00133                            TagCallValue tag)
00134 {
00135     typedef typename DstArrayT::StorType DstStorT;
00136     typedef typename DstArrayT::ArithType DstArithT;
00137     typedef typename SrcArrayT::StorType SrcStorT;
00138     typedef typename SrcArrayT::ArithType SrcArithT;
00139     typedef typename KerArrayT::StorType KerStorT;
00140     typedef typename KerArrayT::ArithType KerArithT;
00141 
00142     int width = ArrayCW(dst);
00143     int kerWidth = ArrayCW(ker);
00144     int kerBW = ArrayCW(ker) / 2;
00145     KerArithT neutralElement = RedOpT::NeutralElement();
00146     DstStorT* dPtr = ArrayCPB(dst, 0, y);
00147     SrcStorT* sPtr = ArrayCPB(src, -kerBW, y);
00148     KerStorT* kPtr = ArrayCPB(ker, 0, 0);
00149     for (int x=0 ; x<width ; x++)
00150     {
00151         FuncGenConv2dSep_Pix_Xdir(dPtr, sPtr, kPtr, kerWidth,
00152                                   SrcArrayT::ElemSize(), KerArrayT::ElemSize(),
00153                                   pixOp, redOp, neutralElement, tag);
00154         dPtr += DstArrayT::ElemSize();
00155         sPtr += SrcArrayT::ElemSize();
00156     }
00157 }
00158 
00167 template<class DstArrayT, class SrcArrayT, class KerArrayT,
00168          class PixOpT, class RedOpT>
00169 static void
00170 FuncGenConv2dSep_Line_XdirInc(DstArrayT* dst, SrcArrayT* src, KerArrayT* ker,
00171                               PixOpT& pixOp, RedOpT& redOp, int y,
00172                               TagCallPointer dummy)
00173 {
00174     typedef typename DstArrayT::StorType DstStorT;
00175     typedef typename SrcArrayT::StorType SrcStorT;
00176     typedef typename KerArrayT::StorType KerStorT;
00177 
00178     int width = ArrayCW(dst);
00179     int kerWidth = ArrayCW(ker);
00180     int kerBW = ArrayCW(ker) / 2;
00181     KerStorT buf[KerArrayT::ElemSize()];
00182     for (int x=0 ; x<width ; x++)
00183     {
00184         DstStorT* dPtr = ArrayCPB(dst, x, y);
00185         SrcStorT* sPtr = ArrayCPB(src, -kerBW + x, y);
00186         KerStorT* kPtr = ArrayCPB(ker, 0, 0);
00187         redOp.setNeutral(dPtr);
00188         for (int k=0; k<kerWidth; k++)
00189         {
00190             pixOp.DoIt(buf, sPtr, kPtr);
00191             sPtr += SrcArrayT::ElemSize();
00192             kPtr += KerArrayT::ElemSize();
00193             redOp.DoIt(dPtr, buf);
00194         }
00195     }
00196 }
00197 
00206 template<class DstArrayT, class SrcArrayT, class KerArrayT,
00207          class PixOpT, class RedOpT>
00208 static void
00209 FuncGenConv2dSep_Line_XdirInc(DstArrayT* dst, SrcArrayT* src, KerArrayT* ker,
00210                               PixOpT& pixOp, RedOpT& redOp, int y,
00211                               TagCallValue dummy)
00212 {
00213     typedef typename DstArrayT::StorType DstStorT;
00214     typedef typename DstArrayT::ArithType DstArithT;
00215     typedef typename SrcArrayT::StorType SrcStorT;
00216     typedef typename SrcArrayT::ArithType SrcArithT;
00217     typedef typename KerArrayT::StorType KerStorT;
00218     typedef typename KerArrayT::ArithType KerArithT;
00219 
00220     int width = ArrayCW(dst);
00221     int kerWidth = ArrayCW(ker);
00222     int kerBW = ArrayCW(ker) / 2;
00223     KerArithT neutralElement = RedOpT::NeutralElement();
00224     DstStorT* dPtr = ArrayCPB(dst, 0, y);
00225     for (int x=0 ; x<width ; x++)
00226     {
00227         SrcStorT* sPtr = ArrayCPB(src, -kerBW + x, y);
00228         KerStorT* kPtr = ArrayCPB(ker, 0, 0);
00229         KerArithT result(neutralElement);
00230         for (int k=0; k<kerWidth; k++)
00231         {
00232             redOp.DoIt(result, pixOp.DoIt(PtrRead(sPtr, KerArithT()),
00233                                           PtrRead(kPtr, KerArithT())));
00234             sPtr += SrcArrayT::ElemSize();
00235             kPtr += KerArrayT::ElemSize();
00236         }
00237         PtrWrite(dPtr, result);
00238         dPtr += DstArrayT::ElemSize();
00239     }
00240 }
00241 
00270 template<class DstArrayT, class SrcArrayT, class KerArrayT,
00271          class PixOpT, class RedOpT>
00272 static void
00273 FuncGenConv2dSep_Line_YdirNaiInc(DstArrayT* dst, SrcArrayT* src, KerArrayT* ker,
00274                                  PixOpT& pixOp, RedOpT& redOp, int x,
00275                                  TagCallPointer dummy)
00276 {
00277     typedef typename DstArrayT::StorType DstStorT;
00278     typedef typename SrcArrayT::StorType SrcStorT;
00279     typedef typename KerArrayT::StorType KerStorT;
00280 
00281     int height = ArrayCH(dst);
00282     int kerWidth = ArrayCW(ker);
00283     int kerBW = ArrayCW(ker) / 2;
00284     int srcInc = ArrayInc(src, 0, 1);
00285     KerStorT buf[KerArrayT::ElemSize()];
00286     for (int y=0 ; y<height ; y++)
00287     {
00288         DstStorT* dPtr = ArrayCPB(dst, x, y);
00289         SrcStorT* sPtr = ArrayCPB(src, x, -kerBW + y);
00290         KerStorT* kPtr = ArrayCPB(ker, 0, 0);
00291         redOp.setNeutral(dPtr);
00292         for (int k=0; k<kerWidth; k++)
00293         {
00294             pixOp.DoIt(buf, sPtr, kPtr);
00295             sPtr += srcInc;
00296             kPtr += KerArrayT::ElemSize();
00297             redOp.DoIt(dPtr, buf);
00298         }
00299     }
00300 }
00301 
00304 template<class DstArrayT, class SrcArrayT, class KerArrayT,
00305          class PixOpT, class RedOpT>
00306 static void
00307 FuncGenConv2dSep_Line_YdirNaiInc(DstArrayT* dst, SrcArrayT* src, KerArrayT* ker,
00308                                  PixOpT& pixOp, RedOpT& redOp, int x,
00309                                  TagCallValue dummy)
00310 {
00311     typedef typename DstArrayT::StorType DstStorT;
00312     typedef typename DstArrayT::ArithType DstArithT;
00313     typedef typename SrcArrayT::StorType SrcStorT;
00314     typedef typename SrcArrayT::ArithType SrcArithT;
00315     typedef typename KerArrayT::StorType KerStorT;
00316     typedef typename KerArrayT::ArithType KerArithT;
00317 
00318     int height = ArrayCH(dst);
00319     int kerWidth = ArrayCW(ker);
00320     int kerBW = ArrayCW(ker) / 2;
00321     int srcInc = ArrayInc(src, 0, 1);
00322     KerArithT neutralElement = RedOpT::NeutralElement();
00323     for (int y=0 ; y<height ; y++)
00324     {
00325         DstStorT* dPtr = ArrayCPB(dst, x, y);
00326         SrcStorT* sPtr = ArrayCPB(src, x, -kerBW + y);
00327         KerStorT* kPtr = ArrayCPB(ker, 0, 0);
00328         KerArithT result(neutralElement);
00329         for (int k=0; k<kerWidth; k++)
00330         {
00331             redOp.DoIt(result, pixOp.DoIt(PtrRead(sPtr, KerArithT()),
00332                                           PtrRead(kPtr, KerArithT())));
00333             sPtr += srcInc;
00334             kPtr += KerArrayT::ElemSize();
00335         }
00336         PtrWrite(dPtr, result);
00337     }
00338 }
00339 
00342 template<class DstArrayT, class SrcArrayT, class KerArrayT,
00343          class PixOpT, class RedOpT>
00344 static void
00345 FuncGenConv2dSep_Line_YdirSim(DstArrayT* dst, SrcArrayT* src, KerArrayT* ker,
00346                               PixOpT& pixOp, RedOpT& redOp, int y,
00347                               TagCallValue tag)
00348 {
00349     typedef typename DstArrayT::StorType DstStorT;
00350     typedef typename DstArrayT::ArithType DstArithT;
00351     typedef typename SrcArrayT::StorType SrcStorT;
00352     typedef typename SrcArrayT::ArithType SrcArithT;
00353     typedef typename KerArrayT::StorType KerStorT;
00354     typedef typename KerArrayT::ArithType KerArithT;
00355 
00356     int width = ArrayCW(dst);
00357     int kerWidth = ArrayCW(ker);
00358     int kerBW = ArrayCW(ker) / 2;
00359     int srcInc = ArrayInc(src, 0, 1);
00360     KerArithT neutralElement = RedOpT::NeutralElement();
00361     DstStorT* dPtr = ArrayCPB(dst, 0, y);
00362     SrcStorT* sPtr = ArrayCPB(src, 0, -kerBW + y);
00363     KerStorT* kPtr = ArrayCPB(ker, 0, 0);
00364     for (int x=0 ; x<width ; x++)
00365     {
00366         FuncGenConv2dSep_Pix_Ydir(dPtr, sPtr, kPtr, kerWidth, srcInc,
00367                                   KerArrayT::ElemSize(), pixOp, redOp,
00368                                   neutralElement, tag);
00369         sPtr += SrcArrayT::ElemSize();
00370         dPtr += DstArrayT::ElemSize();
00371     }
00372 }
00373 
00376 template<class DstArrayT, class SrcArrayT, class KerArrayT,
00377          class PixOpT, class RedOpT>
00378 static void
00379 FuncGenConv2dSep_Line_YdirSimInc(DstArrayT* dst, SrcArrayT* src, KerArrayT* ker,
00380                                  PixOpT& pixOp, RedOpT& redOp, int y,
00381                                  TagCallValue dummy)
00382 {
00383     typedef typename DstArrayT::StorType DstStorT;
00384     typedef typename DstArrayT::ArithType DstArithT;
00385     typedef typename SrcArrayT::StorType SrcStorT;
00386     typedef typename SrcArrayT::ArithType SrcArithT;
00387     typedef typename KerArrayT::StorType KerStorT;
00388     typedef typename KerArrayT::ArithType KerArithT;
00389 
00390     int width = ArrayCW(dst);
00391     int kerWidth = ArrayCW(ker);
00392     int kerBW = ArrayCW(ker) / 2;
00393     int srcInc = ArrayInc(src, 0, 1);
00394     KerArithT neutralElement = RedOpT::NeutralElement();
00395     DstStorT* dPtr = ArrayCPB(dst, 0, y);
00396     SrcStorT* srcPtr = ArrayCPB(src, 0, -kerBW + y);
00397     for (int x=0 ; x<width ; x++)
00398     {
00399         SrcStorT* sPtr = srcPtr;
00400         KerStorT* kPtr = ArrayCPB(ker, 0, 0);
00401         KerArithT result(neutralElement);
00402         for (int k=0; k<kerWidth; k++)
00403         {
00404             redOp.DoIt(result, pixOp.DoIt(PtrRead(sPtr, KerArithT()),
00405                                           PtrRead(kPtr, KerArithT())));
00406             sPtr += srcInc;
00407             kPtr += KerArrayT::ElemSize();
00408         }
00409         PtrWrite(dPtr, result);
00410         srcPtr += SrcArrayT::ElemSize();
00411         dPtr += DstArrayT::ElemSize();
00412     }
00413 }
00414 
00550 // version of FuncGenConv2dSep_Line_XYdirVerCycInc with split X and Y
00551 // doesn't seem to be better, but maybe if split into two functions...
00552 /*{
00553     ArithT  neutralElement = RedOpT::NeutralElement();
00554     int     lastKerElt = ker2Width-1;
00555     int     bufCycSize = dstWidth * ker2Width;
00556     ArithT* bufOverflow = buf + bufCycSize;
00557 
00558     // first do the X direction (from src to buf) for the last element
00559     // needed for the kernel in the Y direction (all other elements
00560     // needed for the Y direction are already computed and stored in buf)
00561 
00562     ArithT* bPtr = bufPtr;
00563     int width = dstWidth;
00564     while (--width >= 0) {
00565         SrcDataPtrT sPtr(srcPtr);
00566         ArithT result1(neutralElement);
00567         for (int k1=0 ; k1<ker1Width ; k1++)
00568             redOp.DoIt(result1, pixOp.DoIt(sPtr.readIncX(), kernel1[k1]));
00569         bPtr[lastKerElt] = result1;
00570         srcPtr.incX();
00571         bPtr += ker2Width;
00572         if (bPtr >= bufOverflow)
00573             bPtr -= bufCycSize;
00574     }
00575 
00576     // now the Y direction from buf to dst
00577 
00578     while (--dstWidth >= 0) {
00579         ArithT result2(neutralElement);
00580         for (int k2=0 ; k2<ker2Width ; k2++)
00581             redOp.DoIt(result2, pixOp.DoIt(bufPtr[k2], kernel2[k2]));
00582         dstPtr.writeIncX(result2);
00583         bufPtr += ker2Width;
00584         if (bufPtr >= bufOverflow)
00585             bufPtr -= bufCycSize;
00586     }
00587 }*/
00588 
00626 //End of Line_variations.
00627 
00628 
00630 
00981 //End of GenConv2dSep_variations.
00982 
00983 
01028 template<class DstArrayT, class SrcArrayT, class KerArrayT,
01029          class PixOpT, class RedOpT>
01030 void
01031 FuncGenConv2dSepDispatch_H(DstArrayT* dst, SrcArrayT* src, KerArrayT* ker,
01032                            PixOpT& pixOp, RedOpT& redOp, int vType)
01033 {
01034     int height = ArrayCH(dst);
01035     for (int y=0 ; y<height ; y++)
01036     {
01037         if (vType == 1)
01038             FuncGenConv2dSep_Line_Xdir(dst, src, ker, pixOp, redOp, y,
01039                                        typename PixOpT::CallCategory());
01040         if ((vType == 0) || (vType == 2))
01041             FuncGenConv2dSep_Line_XdirInc(dst, src, ker, pixOp, redOp, y,
01042                                           typename PixOpT::CallCategory());
01043     }
01044 }
01045 
01048 template<class DstArrayT, class SrcArrayT, class KerArrayT,
01049          class PixOpT, class RedOpT>
01050 void
01051 FuncGenConv2dSepDispatch_V(DstArrayT* dst, SrcArrayT* src, KerArrayT* ker,
01052                            PixOpT& pixOp, RedOpT& redOp, int vType)
01053 {
01054     int width = ArrayCW(dst);
01055     if (vType == 0)
01056     {
01057         for (int x=0 ; x<width ; x++)
01058         {
01059             FuncGenConv2dSep_Line_YdirNaiInc(dst, src, ker, pixOp, redOp, x,
01060                                              typename PixOpT::CallCategory());
01061         }
01062     }
01063     else
01064     { // vType == 1 or 2
01065         int height = ArrayCH(dst);
01066         for (int y=0 ; y<height ; y++)
01067         {
01068             if (vType == 1)
01069                 FuncGenConv2dSep_Line_YdirSim(dst, src, ker, pixOp, redOp, y,
01070                                               typename PixOpT::CallCategory());
01071             if (vType == 2)
01072                 FuncGenConv2dSep_Line_YdirSimInc(dst, src, ker, pixOp, redOp, y,
01073                                                  typename PixOpT::CallCategory());
01074         }
01075     }
01076 }
01077 
01078 } // namespace Pattern
01079 } // namespace Array
01080 } // namespace Core
01081 } // namespace Impala
01082 
01083 #endif

Generated on Fri Mar 19 09:30:49 2010 for ImpalaSrc by  doxygen 1.5.1