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_IN_SPECIALIZED 00025 #define IVL_CORE_DETAILS_LOOPS_META_IN_SPECIALIZED 00026 00027 namespace ivl { 00028 namespace loops { 00029 00030 // cancellation of all in_specialized. used for debugging or 00031 // desperation purposes 00032 #if 0 00033 // case (cancellation) of seq_nd being specialized 00034 template< 00035 class F, class A1, class A2, 00036 class O_OPTIMAL_ACCESS, 00037 int I_SPECIALIZED, class O_ITER_1, class O_ITER_2 00038 > 00039 struct loop_base_nd<2, F, A1, A2, 00040 O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag, 00041 types::t_false, types::number<I_SPECIALIZED>, 00042 O_ITER_1, types::term, 00043 O_ITER_2, types::term> 00044 : 00045 public loop_base_nd<3, F, A1, A2, 00046 O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag, 00047 types::t_false, types::t_false, 00048 O_ITER_1, typename types::best_fast_iterator_nd<A2>::type, 00049 O_ITER_2, typename types::best_fast_iterator_nd<A2>::type> 00050 { }; 00051 00052 // case (cancellation) of seq being specialized 00053 template< 00054 class F, class A1, class A2, 00055 class O_OPTIMAL_ACCESS, class I_OPTIMAL_ACCESS, 00056 int I_SPECIALIZED, class O_ITER_1, class O_ITER_2 00057 > 00058 struct loop_base_nd<2, F, A1, A2, 00059 O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS, 00060 types::t_false, types::number<I_SPECIALIZED>, 00061 O_ITER_1, types::term, 00062 O_ITER_2, types::term> 00063 : 00064 public loop_base_nd<3, F, A1, A2, 00065 O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS, 00066 types::t_false, types::t_false, 00067 O_ITER_1, typename A2::types::best_iterator<A2>::type, 00068 O_ITER_2, types::term> 00069 { }; 00070 00071 #else 00072 00073 // --- first case : not nd --------------------------------------- 00074 00075 // case of input seq iterator being specialized 00076 template< 00077 class F, class A1, class A2, 00078 class O_OPTIMAL_ACCESS, class I_OPTIMAL_ACCESS, 00079 int I_SPECIALIZED, class O_ITER_1, class O_ITER_2 00080 > 00081 struct loop_base_nd<2, F, A1, A2, 00082 O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS, 00083 types::t_false, types::number<I_SPECIALIZED>, 00084 O_ITER_1, types::term, 00085 O_ITER_2, types::term> 00086 { 00087 static 00088 inline 00089 void exec(A1& out, A2& in, 00090 int inner_dim_1, int inner_dim_2) 00091 { 00092 using namespace ivl::types; 00093 00094 if(in.iter_specialization() == I_SPECIALIZED) { 00095 loop_base_nd<3, F, A1, A2, 00096 O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS, 00097 t_false, t_false, 00098 O_ITER_1, typename 00099 types::best_fast_iterator_nd<A2, I_SPECIALIZED>::type, 00100 term, term>::exec(out, in, inner_dim_1, inner_dim_2); 00101 } 00102 else { 00103 loop_base_nd<2, F, A1, A2, 00104 O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS, 00105 t_false, number<I_SPECIALIZED - 1>, 00106 O_ITER_1, term, term, term 00107 >::exec(out, in, inner_dim_1, inner_dim_2); 00108 } 00109 } 00110 }; 00111 00112 // case (post-specialization) of input seq iterator being specialized 00113 template< 00114 class F, class A1, class A2, 00115 class O_OPTIMAL_ACCESS, class I_OPTIMAL_ACCESS, 00116 class O_ITER_1, class O_ITER_2 00117 > 00118 struct loop_base_nd<2, F, A1, A2, 00119 O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS, 00120 types::t_false, types::number<0>, 00121 O_ITER_1, types::term, 00122 O_ITER_2, types::term> 00123 : 00124 public loop_base_nd<3, F, A1, A2, 00125 O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS, 00126 types::t_false, types::t_false, 00127 O_ITER_1, typename types::best_iterator<A2>::type, 00128 O_ITER_2, types::term> 00129 { }; 00130 00131 // --- seq_nd ----------------------------------------------------- 00132 00133 // case (detection) of input seq_nd iterator being specialized 00134 00135 // subcase 1: both iterators still unknown 00136 template< 00137 class F, class A1, class A2, 00138 class O_OPTIMAL_ACCESS, 00139 int I_SPECIALIZED, 00140 class O_ITER_1, 00141 class O_ITER_2 00142 > 00143 struct loop_base_nd<21, F, A1, A2, 00144 O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag, 00145 types::t_false, ivl::types::number<I_SPECIALIZED>, 00146 O_ITER_1, types::term, 00147 O_ITER_2, types::term> 00148 { 00149 static 00150 inline 00151 void exec(A1& out, A2& in, 00152 int inner_dim_1, int inner_dim_2) 00153 { 00154 using namespace ivl::types; 00155 00156 if(in.iter_specialization_nd(inner_dim_1) == I_SPECIALIZED 00157 && in.iter_specialization_nd(inner_dim_2) == I_SPECIALIZED) { 00158 loop_base_nd<3, F, A1, A2, 00159 O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag, 00160 t_false, t_false, 00161 O_ITER_1, typename 00162 types::best_fast_iterator_nd<A2, I_SPECIALIZED>::type, 00163 O_ITER_2, typename 00164 types::best_fast_iterator_nd<A2, I_SPECIALIZED>::type 00165 >::exec(out, in, inner_dim_1, inner_dim_2); 00166 } 00167 else if(in.iter_specialization_nd(inner_dim_1) == I_SPECIALIZED 00168 && in.iter_specialization_nd(inner_dim_2) != I_SPECIALIZED) { 00169 loop_base_nd<21, F, A1, A2, 00170 O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag, 00171 t_false, number<I_SPECIALIZED - 1>, 00172 O_ITER_1, typename 00173 types::best_fast_iterator_nd<A2, I_SPECIALIZED>::type, 00174 O_ITER_2, term 00175 >::exec(out, in, inner_dim_1, inner_dim_2); 00176 } 00177 else if(in.iter_specialization_nd(inner_dim_1) != I_SPECIALIZED 00178 && in.iter_specialization_nd(inner_dim_2) == I_SPECIALIZED) { 00179 loop_base_nd<21, F, A1, A2, 00180 O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag, 00181 t_false, number<I_SPECIALIZED - 1>, 00182 O_ITER_1, term, 00183 O_ITER_2, typename 00184 types::best_fast_iterator_nd<A2, I_SPECIALIZED>::type 00185 >::exec(out, in, inner_dim_1, inner_dim_2); 00186 } 00187 else { 00188 loop_base_nd<21, F, A1, A2, 00189 O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag, 00190 t_false, number<I_SPECIALIZED - 1>, 00191 O_ITER_1, term, O_ITER_2, term>:: 00192 exec(out, in, inner_dim_1, inner_dim_2); 00193 } 00194 } 00195 }; 00196 00197 // subcase 2: iterator 1 still unknown 00198 template< 00199 class F, class A1, class A2, 00200 class O_OPTIMAL_ACCESS, 00201 int I_SPECIALIZED, 00202 class O_ITER_1, 00203 class O_ITER_2, class I_ITER_2 00204 > 00205 struct loop_base_nd<21, F, A1, A2, 00206 O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag, 00207 types::t_false, ivl::types::number<I_SPECIALIZED>, 00208 O_ITER_1, types::term, 00209 O_ITER_2, I_ITER_2> 00210 { 00211 static 00212 inline 00213 void exec(A1& out, A2& in, 00214 int inner_dim_1, int inner_dim_2) 00215 { 00216 using namespace ivl::types; 00217 00218 if(in.iter_specialization_nd(inner_dim_1) == I_SPECIALIZED) { 00219 loop_base_nd<3, F, A1, A2, 00220 O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag, 00221 t_false, t_false, 00222 O_ITER_1, typename 00223 types::best_fast_iterator_nd<A2, I_SPECIALIZED>::type, 00224 O_ITER_2, I_ITER_2 00225 >::exec(out, in, inner_dim_1, inner_dim_2); 00226 } 00227 else { 00228 loop_base_nd<21, F, A1, A2, 00229 O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag, 00230 t_false, number<I_SPECIALIZED - 1>, 00231 O_ITER_1, term, O_ITER_2, I_ITER_2>:: 00232 exec(out, in, inner_dim_1, inner_dim_2); 00233 } 00234 } 00235 }; 00236 00237 // subcase 2: iterator 2 still unknown 00238 template< 00239 class F, class A1, class A2, 00240 class O_OPTIMAL_ACCESS, 00241 int I_SPECIALIZED, 00242 class O_ITER_1, class I_ITER_1, 00243 class O_ITER_2 00244 > 00245 struct loop_base_nd<21, F, A1, A2, 00246 O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag, 00247 types::t_false, ivl::types::number<I_SPECIALIZED>, 00248 O_ITER_1, I_ITER_1, 00249 O_ITER_2, 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(in.iter_specialization_nd(inner_dim_2) == I_SPECIALIZED) { 00259 loop_base_nd<3, F, A1, A2, 00260 O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag, 00261 t_false, t_false, 00262 O_ITER_1, I_ITER_1, 00263 O_ITER_2, typename 00264 types::best_fast_iterator_nd<A2, I_SPECIALIZED>::type 00265 >::exec(out, in, inner_dim_1, inner_dim_2); 00266 } 00267 else { 00268 loop_base_nd<21, F, A1, A2, 00269 O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag, 00270 t_false, number<I_SPECIALIZED - 1>, 00271 O_ITER_1, I_ITER_1, O_ITER_2, term>:: 00272 exec(out, in, inner_dim_1, inner_dim_2); 00273 } 00274 } 00275 }; 00276 00277 00278 // post-specialization fill-up of unspecialized nd_iterators with default 00279 00280 template< 00281 class F, class A1, class A2, 00282 class O_OPTIMAL_ACCESS, 00283 class O_ITER_1, 00284 class O_ITER_2, class I_ITER_2 00285 > 00286 struct loop_base_nd<21, F, A1, A2, 00287 O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag, 00288 types::t_false, ivl::types::number<0>, 00289 O_ITER_1, types::term, 00290 O_ITER_2, I_ITER_2> 00291 : 00292 public loop_base_nd<3, F, A1, A2, 00293 O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag, 00294 types::t_false, types::t_false, 00295 O_ITER_1, typename types::best_fast_iterator_nd<A2>::type, 00296 O_ITER_2, I_ITER_2> 00297 { }; 00298 00299 template< 00300 class F, class A1, class A2, 00301 class O_OPTIMAL_ACCESS, 00302 class O_ITER_1, class I_ITER_1, 00303 class O_ITER_2 00304 > 00305 struct loop_base_nd<21, F, A1, A2, 00306 O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag, 00307 types::t_false, ivl::types::number<0>, 00308 O_ITER_1, I_ITER_1, 00309 O_ITER_2, types::term> 00310 : 00311 public loop_base_nd<3, F, A1, A2, 00312 O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag, 00313 types::t_false, types::t_false, 00314 O_ITER_1, I_ITER_1, 00315 O_ITER_2, typename types::best_fast_iterator_nd<A2>::type 00316 > 00317 { }; 00318 00319 template< 00320 class F, class A1, class A2, 00321 class O_OPTIMAL_ACCESS, 00322 class O_ITER_1, 00323 class O_ITER_2 00324 > 00325 struct loop_base_nd<21, F, A1, A2, 00326 O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag, 00327 types::t_false, ivl::types::number<0>, 00328 O_ITER_1, types::term, 00329 O_ITER_2, types::term> 00330 : 00331 public loop_base_nd<3, F, A1, A2, 00332 O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag, 00333 types::t_false, types::t_false, 00334 O_ITER_1, typename types::best_fast_iterator_nd<A2>::type, 00335 O_ITER_2, typename types::best_fast_iterator_nd<A2>::type> 00336 { }; 00337 00338 // case (initialization) of input seq_nd iterator being specialized 00339 template< 00340 class F, class A1, class A2, 00341 class O_OPTIMAL_ACCESS, 00342 int I_SPECIALIZED, 00343 class O_ITER_1, class O_ITER_2 00344 > 00345 struct loop_base_nd<2, F, A1, A2, 00346 O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag, 00347 types::t_false, ivl::types::number<I_SPECIALIZED>, 00348 O_ITER_1, types::term, 00349 O_ITER_2, types::term> 00350 : 00351 public loop_base_nd<21, F, A1, A2, 00352 O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag, 00353 types::t_false, ivl::types::number<I_SPECIALIZED>, 00354 O_ITER_1, types::term, 00355 O_ITER_2, types::term> 00356 { }; 00357 00358 #endif // end of cancellation selection branch 00359 00360 } /* namespace loops */ 00361 } /* namespace ivl */ 00362 00363 #endif // IVL_CORE_DETAILS_LOOPS_META_IN_SPECIALIZED