ivl 679
|
00001 /* This file is part of the ivl C++ library <http://image.ntua.gr/ivl>. 00002 A C++ template library extending syntax towards mathematical notation. 00003 00004 Copyright (C) 2012 Yannis Avrithis <iavr@image.ntua.gr> 00005 Copyright (C) 2012 Kimon Kontosis <kimonas@image.ntua.gr> 00006 00007 ivl is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU Lesser General Public License 00009 version 3 as published by the Free Software Foundation. 00010 00011 Alternatively, you can redistribute it and/or modify it under the terms 00012 of the GNU General Public License version 2 as published by the Free 00013 Software Foundation. 00014 00015 ivl is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00018 See the GNU General Public License for more details. 00019 00020 You should have received a copy of the GNU General Public License 00021 and a copy of the GNU Lesser General Public License along 00022 with ivl. If not, see <http://www.gnu.org/licenses/>. */ 00023 00024 #ifndef IVL_CORE_DETAILS_LOOPS_META_OUT_SPECIALIZED 00025 #define IVL_CORE_DETAILS_LOOPS_META_OUT_SPECIALIZED 00026 00027 // for loops_nd_meta 00028 00029 // -- specialized iterators 00030 00031 namespace ivl { 00032 namespace loops { 00033 00034 // cancellation of all out_specialized. used for debugging or 00035 // desperation purposes 00036 #if 0 00037 // case (cancellation) of seq_nd being specialized 00038 template< 00039 class F, class A1, class A2, 00040 class I_OPTIMAL_ACCESS, 00041 int O_SPECIALIZED, class I_SPECIALIZED 00042 > 00043 struct loop_base_nd<1, F, A1, A2, 00044 ivl::data::nd_seq_optimal_tag, I_OPTIMAL_ACCESS, 00045 ivl::types::number<O_SPECIALIZED>, I_SPECIALIZED, 00046 types::term, types::term, 00047 types::term, types::term> 00048 : 00049 public loop_base_nd<2, F, A1, A2, 00050 ivl::data::nd_seq_optimal_tag, I_OPTIMAL_ACCESS, 00051 types::t_false, I_SPECIALIZED, 00052 typename A1::_fast_iterator_nd, types::term, 00053 typename A1::_fast_iterator_nd, types::term> 00054 { }; 00055 00056 // case (cancellation) of seq being specialized 00057 template< 00058 class F, class A1, class A2, 00059 class O_OPTIMAL_ACCESS, class I_OPTIMAL_ACCESS, 00060 int O_SPECIALIZED, class I_SPECIALIZED 00061 > 00062 struct loop_base_nd<1, F, A1, A2, 00063 O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS, 00064 ivl::types::number<O_SPECIALIZED>, I_SPECIALIZED, 00065 types::term, types::term, 00066 types::term, types::term> 00067 : 00068 public loop_base_nd<2, F, A1, A2, 00069 O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS, 00070 types::t_false, I_SPECIALIZED, 00071 typename A1::iterator, types::term, 00072 types::term, types::term> 00073 { }; 00074 00075 #else 00076 00077 // --- first case : not nd --------------------------------------- 00078 00079 // case of output seq iterator being specialized 00080 template< 00081 class F, class A1, class A2, 00082 class O_OPTIMAL_ACCESS, class I_OPTIMAL_ACCESS, 00083 int O_SPECIALIZED, class I_SPECIALIZED 00084 > 00085 struct loop_base_nd<1, F, A1, A2, 00086 O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS, 00087 ivl::types::number<O_SPECIALIZED>, I_SPECIALIZED, 00088 types::term, types::term, 00089 types::term, types::term> 00090 { 00091 static 00092 inline 00093 void exec(A1& out, A2& in, 00094 int inner_dim_1, int inner_dim_2) 00095 { 00096 using namespace ivl::types; 00097 00098 if(out.iter_specialization() == O_SPECIALIZED) { 00099 loop_base_nd<2, F, A1, A2, 00100 O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS, 00101 t_false, I_SPECIALIZED, 00102 typename A1:: 00103 template s_iterator<O_SPECIALIZED>::type, term, 00104 term, term>::exec(out, in, inner_dim_1, inner_dim_2); 00105 } 00106 else { 00107 loop_base_nd<1, F, A1, A2, 00108 O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS, 00109 number<O_SPECIALIZED - 1>, I_SPECIALIZED, 00110 term, term, term, term>:: 00111 exec(out, in, inner_dim_1, inner_dim_2); 00112 } 00113 } 00114 }; 00115 00116 // case (post-specialization) of output seq iterator being specialized 00117 template< 00118 class F, class A1, class A2, 00119 class O_OPTIMAL_ACCESS, class I_OPTIMAL_ACCESS, 00120 class I_SPECIALIZED 00121 > 00122 struct loop_base_nd<1, F, A1, A2, 00123 O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS, 00124 ivl::types::number<0>, I_SPECIALIZED, 00125 types::term, types::term, 00126 types::term, types::term> 00127 : 00128 public loop_base_nd<2, F, A1, A2, 00129 O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS, 00130 types::t_false, I_SPECIALIZED, 00131 typename A1::iterator, types::term, 00132 types::term, types::term> 00133 { }; 00134 00135 // --- seq_nd ----------------------------------------------------- 00136 00137 // case (detection) of output seq_nd iterator being specialized 00138 00139 // subcase 1: both iterators still unknown 00140 template< 00141 class F, class A1, class A2, 00142 class I_OPTIMAL_ACCESS, 00143 int O_SPECIALIZED, class I_SPECIALIZED 00144 > 00145 struct loop_base_nd<11, F, A1, A2, 00146 ivl::data::nd_seq_optimal_tag, I_OPTIMAL_ACCESS, 00147 ivl::types::number<O_SPECIALIZED>, I_SPECIALIZED, 00148 types::term, types::term, 00149 types::term, types::term> 00150 { 00151 static 00152 inline 00153 void exec(A1& out, A2& in, 00154 int inner_dim_1, int inner_dim_2) 00155 { 00156 using namespace ivl::types; 00157 00158 if(out.iter_specialization_nd(inner_dim_1) == O_SPECIALIZED 00159 && out.iter_specialization_nd(inner_dim_2) == O_SPECIALIZED) { 00160 loop_base_nd<2, F, A1, A2, 00161 ivl::data::nd_seq_optimal_tag, I_OPTIMAL_ACCESS, 00162 t_false, I_SPECIALIZED, 00163 typename A1:: 00164 template _fast_s_iterator_nd<O_SPECIALIZED>::type, term, 00165 typename A1:: 00166 template _fast_s_iterator_nd<O_SPECIALIZED>::type, term 00167 >::exec(out, in, inner_dim_1, inner_dim_2); 00168 } 00169 else if(out.iter_specialization_nd(inner_dim_1) == O_SPECIALIZED 00170 && out.iter_specialization_nd(inner_dim_2) != O_SPECIALIZED) { 00171 loop_base_nd<11, F, A1, A2, 00172 ivl::data::nd_seq_optimal_tag, I_OPTIMAL_ACCESS, 00173 number<O_SPECIALIZED - 1>, I_SPECIALIZED, 00174 typename A1:: 00175 template _fast_s_iterator_nd<O_SPECIALIZED>::type, term, 00176 term, term 00177 >::exec(out, in, inner_dim_1, inner_dim_2); 00178 } 00179 else if(out.iter_specialization_nd(inner_dim_1) != O_SPECIALIZED 00180 && out.iter_specialization_nd(inner_dim_2) == O_SPECIALIZED) { 00181 loop_base_nd<11, F, A1, A2, 00182 ivl::data::nd_seq_optimal_tag, I_OPTIMAL_ACCESS, 00183 number<O_SPECIALIZED - 1>, I_SPECIALIZED, 00184 term, term, 00185 typename A1:: 00186 template _fast_s_iterator_nd<O_SPECIALIZED>::type, term 00187 >::exec(out, in,inner_dim_1, inner_dim_2); 00188 } 00189 else { 00190 loop_base_nd<11, F, A1, A2, 00191 ivl::data::nd_seq_optimal_tag, I_OPTIMAL_ACCESS, 00192 number<O_SPECIALIZED - 1>, I_SPECIALIZED, 00193 term, term, term, term 00194 >::exec(out, in, inner_dim_1, inner_dim_2); 00195 } 00196 } 00197 }; 00198 00199 // subcase 2: iterator 1 still unknown 00200 template< 00201 class F, class A1, class A2, 00202 class I_OPTIMAL_ACCESS, 00203 int O_SPECIALIZED, class I_SPECIALIZED, 00204 class O_ITER_2 00205 > 00206 struct loop_base_nd<11, F, A1, A2, 00207 ivl::data::nd_seq_optimal_tag, I_OPTIMAL_ACCESS, 00208 ivl::types::number<O_SPECIALIZED>, I_SPECIALIZED, 00209 types::term, types::term, 00210 O_ITER_2, types::term> 00211 { 00212 static 00213 inline 00214 void exec(A1& out, A2& in, 00215 int inner_dim_1, int inner_dim_2) 00216 { 00217 using namespace ivl::types; 00218 00219 if(out.iter_specialization_nd(inner_dim_1) == O_SPECIALIZED) { 00220 loop_base_nd<2, F, A1, A2, 00221 ivl::data::nd_seq_optimal_tag, I_OPTIMAL_ACCESS, 00222 types::t_false, I_SPECIALIZED, 00223 typename A1:: 00224 template _fast_s_iterator_nd<O_SPECIALIZED>::type, term, 00225 O_ITER_2, term 00226 >::exec(out, in, inner_dim_1, inner_dim_2); 00227 } 00228 else { 00229 loop_base_nd<11, F, A1, A2, 00230 ivl::data::nd_seq_optimal_tag, I_OPTIMAL_ACCESS, 00231 number<O_SPECIALIZED - 1>, I_SPECIALIZED, 00232 term, term, O_ITER_2, term 00233 >::exec(out, in, inner_dim_1, inner_dim_2); 00234 } 00235 } 00236 }; 00237 00238 // subcase 3: iterator 2 still unknown 00239 template< 00240 class F, class A1, class A2, 00241 class I_OPTIMAL_ACCESS, 00242 int O_SPECIALIZED, class I_SPECIALIZED, 00243 class O_ITER_1 00244 > 00245 struct loop_base_nd<11, F, A1, A2, 00246 ivl::data::nd_seq_optimal_tag, I_OPTIMAL_ACCESS, 00247 ivl::types::number<O_SPECIALIZED>, I_SPECIALIZED, 00248 O_ITER_1, types::term, 00249 types::term, types::term> 00250 { 00251 static 00252 inline 00253 void exec(A1& out, A2& in, 00254 int inner_dim_1, int inner_dim_2) 00255 { 00256 using namespace ivl::types; 00257 00258 if(out.iter_specialization_nd(inner_dim_2) == O_SPECIALIZED) { 00259 loop_base_nd<2, F, A1, A2, 00260 ivl::data::nd_seq_optimal_tag, I_OPTIMAL_ACCESS, 00261 types::t_false, I_SPECIALIZED, 00262 O_ITER_1, term, 00263 typename A1:: 00264 template _fast_s_iterator_nd<O_SPECIALIZED>::type, term 00265 >::exec(out, in, inner_dim_1, inner_dim_2); 00266 } 00267 else { 00268 loop_base_nd<11, F, A1, A2, 00269 ivl::data::nd_seq_optimal_tag, I_OPTIMAL_ACCESS, 00270 number<O_SPECIALIZED - 1>, I_SPECIALIZED, 00271 O_ITER_1, term, term, term 00272 >::exec(out, in, inner_dim_1, inner_dim_2); 00273 } 00274 } 00275 }; 00276 00277 // post-specialization fill-up of unspecialized nd_iterators with default 00278 00279 template< 00280 class F, class A1, class A2, 00281 class I_OPTIMAL_ACCESS, 00282 class I_SPECIALIZED, 00283 class O_ITER_2 00284 > 00285 struct loop_base_nd<11, F, A1, A2, 00286 ivl::data::nd_seq_optimal_tag, I_OPTIMAL_ACCESS, 00287 ivl::types::number<0>, I_SPECIALIZED, 00288 types::term, types::term, 00289 O_ITER_2, types::term> 00290 : 00291 public loop_base_nd<2, F, A1, A2, 00292 ivl::data::nd_seq_optimal_tag, I_OPTIMAL_ACCESS, 00293 types::t_false, I_SPECIALIZED, 00294 typename A1::_fast_iterator_nd, types::term, 00295 O_ITER_2, types::term> 00296 { }; 00297 00298 00299 template< 00300 class F, class A1, class A2, 00301 class I_OPTIMAL_ACCESS, 00302 class I_SPECIALIZED, 00303 class O_ITER_1 00304 > 00305 struct loop_base_nd<11, F, A1, A2, 00306 ivl::data::nd_seq_optimal_tag, I_OPTIMAL_ACCESS, 00307 ivl::types::number<0>, I_SPECIALIZED, 00308 O_ITER_1, types::term, 00309 types::term, types::term> 00310 : 00311 public loop_base_nd<2, F, A1, A2, 00312 ivl::data::nd_seq_optimal_tag, I_OPTIMAL_ACCESS, 00313 types::t_false, I_SPECIALIZED, 00314 O_ITER_1, types::term, 00315 typename A1::_fast_iterator_nd, types::term> 00316 { }; 00317 00318 00319 template< 00320 class F, class A1, class A2, 00321 class I_OPTIMAL_ACCESS, 00322 class I_SPECIALIZED 00323 > 00324 struct loop_base_nd<11, F, A1, A2, 00325 ivl::data::nd_seq_optimal_tag, I_OPTIMAL_ACCESS, 00326 ivl::types::number<0>, I_SPECIALIZED, 00327 types::term, types::term, 00328 types::term, types::term> 00329 : 00330 public loop_base_nd<2, F, A1, A2, 00331 ivl::data::nd_seq_optimal_tag, I_OPTIMAL_ACCESS, 00332 types::t_false, I_SPECIALIZED, 00333 typename A1::_fast_iterator_nd, types::term, 00334 typename A1::_fast_iterator_nd, types::term> 00335 { }; 00336 00337 // case (initialization) of output seq_nd iterator being specialized 00338 template< 00339 class F, class A1, class A2, 00340 class I_OPTIMAL_ACCESS, 00341 int O_SPECIALIZED, class I_SPECIALIZED 00342 > 00343 struct loop_base_nd<1, F, A1, A2, 00344 ivl::data::nd_seq_optimal_tag, I_OPTIMAL_ACCESS, 00345 ivl::types::number<O_SPECIALIZED>, I_SPECIALIZED, 00346 types::term, types::term, 00347 types::term, types::term> 00348 : 00349 public loop_base_nd<11, F, A1, A2, 00350 ivl::data::nd_seq_optimal_tag, I_OPTIMAL_ACCESS, 00351 ivl::types::number<O_SPECIALIZED>, I_SPECIALIZED, 00352 types::term, types::term, 00353 types::term, types::term> 00354 { }; 00355 00356 #endif // end of cancellation selection branch 00357 00358 } /* namespace loops */ 00359 } /* namespace ivl */ 00360 00361 #endif // IVL_CORE_DETAILS_LOOPS_META_OUT_SPECIALIZED