00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef __MMX__STRUCTURED_BLOCK__HPP
00014 #define __MMX__STRUCTURED_BLOCK__HPP
00015 #include <algebramix/structured_naive.hpp>
00016 #include <algebramix/matrix_block.hpp>
00017
00018 namespace mmx {
00019
00020
00021
00022
00023
00024 struct matrix_structured_multiply {};
00025
00026 template<typename V>
00027 struct implementation<matrix_structured_multiply,V,matrix_naive>:
00028 public implementation<matrix_multiply,V>
00029 {
00030 typedef implementation<matrix_multiply,V> Mat;
00031 typedef implementation<vector_linear,V> Vec;
00032
00033 static inline
00034 half_size (nat n) {
00035 return (n+1) >> 1;
00036 }
00037
00038 template<typename Op,
00039 typename TD, typename T1, typename T2,
00040 typename D , typename S1, typename S2> static void
00041 smul (D* d, const S1* s1, const S2* s2,
00042 nat r, nat rr, nat l, nat ll, nat c, nat cc);
00043
00044 template<typename TD, typename T1, typename T2>
00045 struct structured_helper {
00046 template<typename Op, typename D, typename S1, typename S2> static void
00047 mul (D* d, const S1* s1, const S2* s2,
00048 nat r, nat rr, nat l, nat ll, nat c, nat cc) {
00049 typedef typename Op::acc_op Acc;
00050 if (l == 0) Mat::clr<Op> (d, r, rr, c, cc);
00051 else if (l == 1) Op::set_op (*d, *s1, *s2);
00052 else {
00053 nat hr= half_size (r);
00054 nat hl= half_size (l);
00055 nat hc= half_size (c);
00056
00057 smul<Op, typename TD::ul, typename T1::ul, typename T2::ul>
00058 (d,
00059 s1,
00060 s2,
00061 hr, rr, hl, ll, hc, cc);
00062 smul<Acc, typename TD::ul, typename T1::ur, typename T2::ll>
00063 (d,
00064 s1 + Mat::index (0, hl, rr, ll),
00065 s2 + Mat::index (hl, 0, ll, cc),
00066 hr, rr, ll - hl, ll, hc, cc);
00067 smul<Op, typename TD::ur, typename T1::ul, typename T2::ur>
00068 (d + Mat::index (0, hc, rr, cc),
00069 s1,
00070 s2 + Mat::index (0, hc, ll, cc),
00071 hr, rr, hl, ll, cc - hc, cc);
00072 smul<Acc, typename TD::ur, typename T1::ur, typename T2::lr>
00073 (d + Mat::index (0, hc, rr, cc),
00074 s1 + Mat::index (0, hl, rr, ll),
00075 s2 + Mat::index (hl, hc, ll, cc),
00076 hr, rr, ll - hl, ll, cc - hc, cc);
00077
00078 smul<Op, typename TD::ll, typename T1::lr, typename T2::ll>
00079 (d + Mat::index (hr, 0, rr, cc),
00080 s1 + Mat::index (hr, hl, rr, ll),
00081 s2 + Mat::index (hl, 0, ll, cc),
00082 rr - hr, rr, ll - hl, ll, hc, cc);
00083 smul<Acc, typename TD::ll, typename T1::ll, typename T2::ul>
00084 (d + Mat::index (hr, 0, rr, cc),
00085 s1 + Mat::index (hr, 0, rr, ll),
00086 s2,
00087 rr - hr, rr, hl, ll, hc, cc);
00088 smul<Op, typename TD::lr, typename T1::lr, typename T2::lr>
00089 (d + Mat::index (hr, hc, rr, cc),
00090 s1 + Mat::index (hr, hl, rr, ll),
00091 s2 + Mat::index (hl, hc, ll, cc),
00092 rr - hr, rr, ll - hl, ll, cc - hc, cc);
00093 smul<Acc, typename TD::lr, typename T1::ll, typename T2::ur>
00094 (d + Mat::index (hr, hc, rr, cc),
00095 s1 + Mat::index (hr, 0, rr, ll),
00096 s2 + Mat::index (0, hc, ll, cc),
00097 rr - hr, rr, hl, ll, cc - hc, cc);
00098 }
00099 }
00100 };
00101
00102 struct noop_helper {
00103 template<typename Op, typename D, typename S1, typename S2>
00104 static inline void
00105 mul (D* d, const S1* s1, const S2* s2,
00106 nat r, nat rr, nat l, nat ll, nat c, nat cc) {
00107 (void) d; (void) s1; (void) s2;
00108 (void) r; (void) rr; (void) l; (void) ll; (void) c; (void) cc;
00109 }
00110 };
00111
00112 template<typename T1, typename T2>
00113 struct structured_helper<zero_matrix,T1,T2>: public noop_helper {};
00114
00115 template<typename TD, typename T2>
00116 struct structured_helper<TD,zero_matrix,T2>: public noop_helper {};
00117
00118 template<typename TD, typename T1>
00119 struct structured_helper<TD,T1,zero_matrix>: public noop_helper {};
00120
00121 template<typename TD>
00122 struct structured_helper<TD,zero_matrix,zero_matrix>: public noop_helper {};
00123
00124 template<typename T1>
00125 struct structured_helper<zero_matrix,T1,zero_matrix>: public noop_helper {};
00126
00127 template<typename T2>
00128 struct structured_helper<zero_matrix,zero_matrix,T2>: public noop_helper {};
00129
00130 template<>
00131 struct structured_helper<zero_matrix,zero_matrix,zero_matrix>:
00132 public noop_helper {};
00133
00134 template<typename Op,
00135 typename TD, typename T1, typename T2,
00136 typename D, typename S1, typename S2> static inline void
00137 smul (D* d, const S1* s1, const S2* s2,
00138 nat r, nat rr, nat l, nat ll, nat c, nat cc) {
00139 structured_helper<TD,T1,T2>::template mul<Op>
00140 (d, s1, s2, r, rr, l, ll, c, cc);
00141 }
00142
00143 };
00144
00145 }
00146 #endif //__MMX__STRUCTURED_BLOCK__HPP