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_LOOPS_ND_META 00025 #define IVL_CORE_DETAILS_LOOPS_META_LOOPS_ND_META 00026 00027 /* 00028 * This file contains the various template structs which lead to compile-time 00029 * decision of the right loop::exec() function to be called for the requested 00030 * operands, among the available exec loops. There is also run-time decision 00031 * when SPECIALIZED ITERATORS are involved which does a recursive loop from 00032 * 1 to max specialization to check which is the correct int template argument 00033 * to provide to the loop function. 00034 * Please you are notified that the below code is not readable but complicated. 00035 * There is no essence of time wasting in the below code except from the little 00036 * overhead of the specialized iterator decision and the lost compiled time, so 00037 * no optimizations or changes are predicted for that code. 00038 * A little hint for the code wanna understander for that code is that the 00039 * number which is the first template argument of loop_base is the step in 00040 * which the decision process is at. step 1 resolves the left-side (output) 00041 * iterator, step 2 the right-side (input) iterator and step 3 is ready to 00042 * find the correct specialization of loop_base to call the corresponding ::exec. 00043 */ 00044 00045 /* Todo: 00046 Missing cases! are specialized_nd x specialized_1d which are treated 00047 as specialized_nd x non_specialized_1d or they just dont work (not checked). 00048 */ 00049 00050 namespace ivl { 00051 namespace loops { 00052 00053 template< 00054 int STEP, 00055 class F, 00056 class OUT, 00057 class IN, 00058 class O_OPTIMAL_ACCESS, 00059 class I_OPTIMAL_ACCESS, 00060 class O_SPECIALIZED, 00061 class I_SPECIALIZED, 00062 class O_ITER_1 = types::term, 00063 class I_ITER_1 = types::term, 00064 class O_ITER_2 = types::term, 00065 class I_ITER_2 = types::term 00066 > 00067 struct loop_base_nd { }; 00068 00069 // retrieve type for the output iterator if no specialization 00070 template< 00071 class F, class A1, class A2, 00072 class I_OPTIMAL_ACCESS, class ANY 00073 > 00074 struct loop_base_nd<1, F, A1, A2, 00075 ivl::data::nd_seq_optimal_tag, I_OPTIMAL_ACCESS, 00076 types::t_false, ANY, 00077 types::term, types::term, 00078 types::term, types::term> 00079 : 00080 public loop_base_nd<2, F, A1, A2, 00081 ivl::data::nd_seq_optimal_tag, I_OPTIMAL_ACCESS, 00082 types::t_false, ANY, 00083 typename A1::_fast_iterator_nd, types::term, 00084 typename A1::_fast_iterator_nd, types::term> 00085 { }; 00086 00087 template< 00088 class F, class A1, class A2, 00089 class O_OPTIMAL_ACCESS, class I_OPTIMAL_ACCESS, class ANY 00090 > 00091 struct loop_base_nd<1, F, A1, A2, 00092 O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS, 00093 types::t_false, ANY, 00094 types::term, types::term, 00095 types::term, types::term> 00096 : 00097 public loop_base_nd<2, F, A1, A2, 00098 O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS, 00099 types::t_false, ANY, 00100 typename A1::iterator, types::term, 00101 types::term, types::term> 00102 { }; 00103 /* 00104 // state proceed after specialization has completed. 00105 template< 00106 class F, class A1, class A2, 00107 class O_OPTIMAL_ACCESS, class I_OPTIMAL_ACCESS, class ANY, 00108 class O_ITER_1, class O_ITER_2 00109 > 00110 struct loop_base_nd<11, F, A1, A2, 00111 O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS, 00112 types::t_false, ANY, 00113 O_ITER_1, types::term, 00114 O_ITER_2, types::term> 00115 : 00116 public loop_base_nd<2, F, A1, A2, 00117 O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS, 00118 types::t_false, ANY, 00119 O_ITER_1, types::term, 00120 O_ITER_2, types::term> 00121 { }; 00122 */ 00123 00124 // retrieve type for the input iterator if no specialization 00125 template< 00126 class F, class A1, class A2, 00127 class O_OPTIMAL_ACCESS, class ANY, 00128 class O_ITER_1, class O_ITER_2 00129 > 00130 struct loop_base_nd<2, F, A1, A2, 00131 O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag, 00132 ANY, types::t_false, 00133 O_ITER_1, types::term, 00134 O_ITER_2, types::term> 00135 : 00136 public loop_base_nd<3, F, A1, A2, 00137 O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag, 00138 ANY, types::t_false, 00139 O_ITER_1, typename types::best_fast_iterator_nd<A2>::type, 00140 O_ITER_2, typename types::best_fast_iterator_nd<A2>::type> 00141 { }; 00142 00143 template< 00144 class F, class A1, class A2, 00145 class O_OPTIMAL_ACCESS, class I_OPTIMAL_ACCESS, class ANY, 00146 class O_ITER_1, class O_ITER_2 00147 > 00148 struct loop_base_nd<2, F, A1, A2, 00149 O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS, 00150 ANY, types::t_false, 00151 O_ITER_1, types::term, 00152 O_ITER_2, types::term> 00153 : 00154 public loop_base_nd<3, F, A1, A2, 00155 O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS, 00156 ANY, types::t_false, 00157 O_ITER_1, typename types::best_iterator<A2>::type, 00158 O_ITER_2, types::term> 00159 { 00160 }; 00161 /* 00162 // state proceed after specialization has succeeded 00163 template< 00164 class F, class A1, class A2, 00165 class O_OPTIMAL_ACCESS, class I_OPTIMAL_ACCESS, class ANY, 00166 class O_ITER_1, class O_ITER_2, 00167 class I_ITER_1, class I_ITER_2 00168 > 00169 struct loop_base_nd<21, F, A1, A2, 00170 O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS, 00171 ANY, types::t_false, 00172 O_ITER_1, I_ITER_1, 00173 O_ITER_2, I_ITER_2> 00174 : 00175 public loop_base_nd<3, F, A1, A2, 00176 O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS, 00177 ANY, types::t_false, 00178 O_ITER_1, I_ITER_1, 00179 O_ITER_2, I_ITER_2> 00180 { }; 00181 */ 00182 // specialization cases are included in files in_specialized.hpp and 00183 // out_specialized.hpp 00184 00185 // cases depending on optimal access 00186 00188 template< 00189 class F, class A1, class A2, 00190 class O_ITER_1, class I_ITER_1, class O_ITER_2, class I_ITER_2 00191 > 00192 struct loop_base_nd<3, F, A1, A2, 00193 ivl::data::nd_seq_optimal_tag, ivl::data::nd_seq_optimal_tag, 00194 types::t_false, types::t_false, 00195 O_ITER_1, I_ITER_1, O_ITER_2, I_ITER_2> 00196 { 00197 static inline 00198 void exec(A1& out, A2& in, 00199 int inner_dim_1, int inner_dim_2); 00200 }; 00201 00203 template< 00204 class F, class A1, class A2, 00205 class O_OPTIMAL_ACCESS, 00206 class O_ITER_1, class I_ITER_1, class I_ITER_2 00207 > 00208 struct loop_base_nd<3, F, A1, A2, 00209 O_OPTIMAL_ACCESS, ivl::data::nd_seq_optimal_tag, 00210 types::t_false, types::t_false, 00211 O_ITER_1, I_ITER_1, types::term, I_ITER_2> 00212 { 00213 static inline 00214 void exec(A1& out, A2& in, 00215 int inner_dim_1, int inner_dim_2); 00216 }; 00217 00219 template< 00220 class F, class A1, class A2, 00221 class I_OPTIMAL_ACCESS, 00222 class O_ITER_1, class I_ITER_1, class O_ITER_2 00223 > 00224 struct loop_base_nd<3, F, A1, A2, 00225 ivl::data::nd_seq_optimal_tag, I_OPTIMAL_ACCESS, 00226 types::t_false, types::t_false, 00227 O_ITER_1, I_ITER_1, O_ITER_2, types::term> 00228 { 00229 static inline 00230 void exec(A1& out, A2& in, 00231 int inner_dim_1, int inner_dim_2); 00232 }; 00233 00235 template< 00236 class F, class A1, class A2, 00237 class O_OPTIMAL_ACCESS, class I_OPTIMAL_ACCESS, 00238 class O_ITER_1, class I_ITER_1 00239 > 00240 struct loop_base_nd<3, F, A1, A2, 00241 O_OPTIMAL_ACCESS, I_OPTIMAL_ACCESS, 00242 types::t_false, types::t_false, 00243 O_ITER_1, I_ITER_1, types::term, types::term> 00244 { 00245 static inline 00246 void exec(A1& out, const A2& in, 00247 int inner_dim_1, int inner_dim_2) 00248 { 00249 ivl::loops::loop<F>(out.base(), in.base()); 00250 } 00251 }; 00252 00253 00254 } /* namespace loops */ 00255 } /* namespace ivl */ 00256 00257 #endif // IVL_CORE_DETAILS_LOOPS_META_LOOPS_ND_META