Expression Templates Library (ETL)
conv_multi_select.hpp
Go to the documentation of this file.
1 //=======================================================================
2 // Copyright (c) 2014-2023 Baptiste Wicht
3 // Distributed under the terms of the MIT License.
4 // (See accompanying file LICENSE or copy at
5 // http://opensource.org/licenses/MIT)
6 //=======================================================================
7 
13 #pragma once
14 
15 namespace etl::detail {
16 
27 template <typename I, typename K, typename C>
29  //Note: since the constexpr values will be known at compile time, the
30  //conditions will be a lot simplified
31 
32  constexpr order input_order = decay_traits<I>::storage_order;
33  constexpr order kernel_order = decay_traits<K>::storage_order;
34  constexpr order output_order = decay_traits<C>::storage_order;
35 
36  //Only the standard implementation is able to handle column major
37  if (input_order == order::ColumnMajor || kernel_order == order::ColumnMajor || output_order == order::ColumnMajor) {
39  }
40 
41  if (impl::cudnn::conv_possible<I, K, C> && is_2d<I> && !no_gpu) {
43  }
44 
45  if (mkl_enabled && conv_valid_fft) {
47  } else if (impl::blas::blas_conv2_possible<I, K, C>) {
49  }
50 
51  if (impl::vec::conv2_possible<vector_mode, I, K, C>) {
52  // TODO When to use VEC and BLAS_VEC ?
54  }
55 
57 }
58 
69 template <typename I, typename K, typename C>
71  //Note: since the constexpr values will be known at compile time, the
72  //conditions will be a lot simplified
73 
74  constexpr order input_order = decay_traits<I>::storage_order;
75  constexpr order kernel_order = decay_traits<K>::storage_order;
76  constexpr order output_order = decay_traits<C>::storage_order;
77 
78  //Only the standard implementation is able to handle column major
79  if (input_order == order::ColumnMajor || kernel_order == order::ColumnMajor || output_order == order::ColumnMajor) {
81  }
82 
83  if (impl::vec::conv2_possible<vector_mode, I, K, C>) {
84  // TODO When to use VEC and BLAS_VEC ?
86  }
87 
88  if (impl::blas::blas_conv2_possible<I, K, C>) {
90  } else if (mkl_enabled && conv_valid_fft) {
92  }
93 
95 }
96 
97 #ifdef ETL_MANUAL_SELECT
98 
106 template <typename I, typename K, typename C>
108  if (local_context().conv_multi_selector.forced) {
109  auto forced = local_context().conv_multi_selector.impl;
110 
111  switch (forced) {
112  //CUDNN cannot always be used
114  if (!impl::cudnn::conv_possible<I, K, C>) { // COVERAGE_EXCLUDE_LINE
115  std::cerr << "Forced selection to CUDNN conv implementation, but not possible for this expression" << std::endl; // COVERAGE_EXCLUDE_LINE
116  return select_default_conv_valid_multi<I, K, C>(local_context().cpu); // COVERAGE_EXCLUDE_LINE
117  } // COVERAGE_EXCLUDE_LINE
118 
119  return forced;
120 
121  //MKL cannot always be used
123  if (!mkl_enabled) { // COVERAGE_EXCLUDE_LINE
124  std::cerr << "Forced selection to MKL conv implementation, but not possible for this expression" << std::endl; // COVERAGE_EXCLUDE_LINE
125  return select_default_conv_valid_multi<I, K, C>(local_context().cpu); // COVERAGE_EXCLUDE_LINE
126  } // COVERAGE_EXCLUDE_LINE
127 
128  return forced;
129 
130  //BLAS cannot always be used
132  if (!impl::blas::blas_conv2_possible<I, K, C>) { // COVERAGE_EXCLUDE_LINE
133  std::cerr << "Forced selection to BLAS conv implementation, but not possible for this expression" << std::endl; // COVERAGE_EXCLUDE_LINE
134  return select_default_conv_valid_multi<I, K, C>(local_context().cpu); // COVERAGE_EXCLUDE_LINE
135  } // COVERAGE_EXCLUDE_LINE
136 
137  return forced;
138 
139  //VEC cannot always be used
141  if (!vec_enabled || !vectorize_impl) {
142  std::cerr << "Forced selection to VEC conv_valid_multi implementation, but not possible for this expression" << std::endl;
143  return select_default_conv_valid_multi<I, K, C>(local_context().cpu); // COVERAGE_EXCLUDE_LINE
144  }
145 
146  return forced;
147 
149  if (!impl::vec::conv2_possible<vector_mode, I, K, C>) {
150  std::cerr << "Forced selection to BLAS_VEC conv_valid_multi implementation, but not possible for this expression" << std::endl;
151  return select_default_conv_valid_multi<I, K, C>(local_context().cpu); // COVERAGE_EXCLUDE_LINE
152  }
153 
154  return forced;
155 
156  // Although it may be suboptimal the forced selection can
157  // always be achieved
158  default:
159  return forced;
160  }
161  }
162 
163  return select_default_conv_valid_multi<I, K, C>(local_context().cpu);
164 }
165 
173 template <typename I, typename K, typename C>
175  if (local_context().conv_multi_selector.forced) {
176  auto forced = local_context().conv_multi_selector.impl;
177 
178  switch (forced) {
179  //BLAS cannot always be used
181  if (!impl::blas::blas_conv2_possible<I, K, C>) { // COVERAGE_EXCLUDE_LINE
182  std::cerr << "Forced selection to BLAS conv implementation, but not possible for this expression" << std::endl; // COVERAGE_EXCLUDE_LINE
183  return select_default_conv_valid_multi_multi_impl<I, K, C>(); // COVERAGE_EXCLUDE_LINE
184  } // COVERAGE_EXCLUDE_LINE
185 
186  return forced;
187 
188  //VEC cannot always be used
191  if (!impl::vec::conv2_possible<vector_mode, I, K, C>) {
192  std::cerr << "Forced selection to VEC conv_valid_multi_multi implementation, but not possible for this expression" << std::endl;
193  return select_default_conv_valid_multi_multi_impl<I, K, C>(); // COVERAGE_EXCLUDE_LINE
194  }
195 
196  return forced;
197 
198  // Although it may be suboptimal the forced selection can
199  // always be achieved
200  default:
201  return forced;
202  }
203  }
204 
205  return select_default_conv_valid_multi_multi_impl<I, K, C>();
206 }
207 
208 #else
209 
217 template <typename I, typename K, typename C>
219  return select_default_conv_valid_multi<I, K, C>(false);
220 }
221 
229 template <typename I, typename K, typename C>
231  return select_default_conv_valid_multi_multi_impl<I, K, C>();
232 }
233 
234 #endif
235 
236 } //end of namespace etl::detail
constexpr bool mkl_enabled
Indicates if the MKL library is available for ETL.
Definition: config.hpp:64
Standard implementation.
constexpr bool conv_valid_fft
Indicates if conv_valid_multi can use FFT.
Definition: config.hpp:40
constexpr etl::conv_multi_impl select_default_conv_valid_multi(bool no_gpu)
Select the implementation of the conv multi of I and K in C.
Definition: conv_multi_select.hpp:28
constexpr bool vectorize_impl
Indicates if the implementations can be automatically vectorized by ETL.
Definition: config.hpp:35
constexpr bool vec_enabled
Indicates if vectorization is available in any format.
Definition: config.hpp:220
order
Storage order of a matrix.
Definition: order.hpp:15
VEC implementation.
Definition: expression_builder.hpp:699
Traits to get information about ETL types.
Definition: tmp.hpp:68
context & local_context()
Return the configuration context of the current thread.
Definition: context.hpp:50
conv_multi_impl
Enumeration describing the different multiple convolution implementations.
Definition: conv_impl.hpp:47
constexpr etl::conv_multi_impl select_conv_valid_multi_impl()
Select the implementation of the conv of I and K in C.
Definition: conv_multi_select.hpp:218
bool cpu
Force CPU evaluation.
Definition: context.hpp:29
GPU implementation.
Column-Major storage.
Reductiont to FFT (valid)
constexpr etl::conv_multi_impl select_default_conv_valid_multi_multi_impl()
Select the implementation of the conv multi of I and K in C.
Definition: conv_multi_select.hpp:70
constexpr etl::conv_multi_impl select_conv_valid_multi_multi_impl()
Select the implementation of the conv of I and K in C.
Definition: conv_multi_select.hpp:230