Blender  V3.3
kernel_function.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright 2011-2022 Blender Foundation */
3 
4 #pragma once
5 
6 #include "util/debug.h"
7 #include "util/system.h"
8 
10 
11 /* A wrapper around per-microarchitecture variant of a kernel function.
12  *
13  * Provides a function-call-like API which gets routed to the most suitable implementation.
14  *
15  * For example, on a computer which only has SSE4.1 the kernel_sse41 will be used. */
16 template<typename FunctionType> class CPUKernelFunction {
17  public:
18  CPUKernelFunction(FunctionType kernel_default,
19  FunctionType kernel_sse2,
20  FunctionType kernel_sse3,
21  FunctionType kernel_sse41,
22  FunctionType kernel_avx,
23  FunctionType kernel_avx2)
24  {
26  kernel_default, kernel_sse2, kernel_sse3, kernel_sse41, kernel_avx, kernel_avx2);
27  }
28 
29  template<typename... Args> inline auto operator()(Args... args) const
30  {
31  assert(kernel_info_.kernel);
32 
33  return kernel_info_.kernel(args...);
34  }
35 
36  const char *get_uarch_name() const
37  {
38  return kernel_info_.uarch_name;
39  }
40 
41  protected:
42  /* Helper class which allows to pass human-readable microarchitecture name together with function
43  * pointer. */
44  class KernelInfo {
45  public:
46  KernelInfo() : KernelInfo("", nullptr)
47  {
48  }
49 
50  /* TODO(sergey): Use string view, to have higher-level functionality (i.e. comparison) without
51  * memory allocation. */
52  KernelInfo(const char *uarch_name, FunctionType kernel)
54  {
55  }
56 
57  const char *uarch_name;
58  FunctionType kernel;
59  };
60 
61  KernelInfo get_best_kernel_info(FunctionType kernel_default,
62  FunctionType kernel_sse2,
63  FunctionType kernel_sse3,
64  FunctionType kernel_sse41,
65  FunctionType kernel_avx,
66  FunctionType kernel_avx2)
67  {
68  /* Silence warnings about unused variables when compiling without some architectures. */
69  (void)kernel_sse2;
70  (void)kernel_sse3;
71  (void)kernel_sse41;
72  (void)kernel_avx;
73  (void)kernel_avx2;
74 
75 #ifdef WITH_CYCLES_OPTIMIZED_KERNEL_AVX2
77  return KernelInfo("AVX2", kernel_avx2);
78  }
79 #endif
80 
81 #ifdef WITH_CYCLES_OPTIMIZED_KERNEL_AVX
82  if (DebugFlags().cpu.has_avx() && system_cpu_support_avx()) {
83  return KernelInfo("AVX", kernel_avx);
84  }
85 #endif
86 
87 #ifdef WITH_CYCLES_OPTIMIZED_KERNEL_SSE41
88  if (DebugFlags().cpu.has_sse41() && system_cpu_support_sse41()) {
89  return KernelInfo("SSE4.1", kernel_sse41);
90  }
91 #endif
92 
93 #ifdef WITH_CYCLES_OPTIMIZED_KERNEL_SSE3
94  if (DebugFlags().cpu.has_sse3() && system_cpu_support_sse3()) {
95  return KernelInfo("SSE3", kernel_sse3);
96  }
97 #endif
98 
99 #ifdef WITH_CYCLES_OPTIMIZED_KERNEL_SSE2
100  if (DebugFlags().cpu.has_sse2() && system_cpu_support_sse2()) {
101  return KernelInfo("SSE2", kernel_sse2);
102  }
103 #endif
104 
105  return KernelInfo("default", kernel_default);
106  }
107 
109 };
110 
KernelInfo(const char *uarch_name, FunctionType kernel)
const char * get_uarch_name() const
KernelInfo kernel_info_
CPUKernelFunction(FunctionType kernel_default, FunctionType kernel_sse2, FunctionType kernel_sse3, FunctionType kernel_sse41, FunctionType kernel_avx, FunctionType kernel_avx2)
auto operator()(Args... args) const
KernelInfo get_best_kernel_info(FunctionType kernel_default, FunctionType kernel_sse2, FunctionType kernel_sse3, FunctionType kernel_sse41, FunctionType kernel_avx, FunctionType kernel_avx2)
CPU cpu
Definition: debug.h:128
#define CCL_NAMESPACE_END
Definition: cuda/compat.h:9
DebugFlags & DebugFlags()
Definition: debug.h:159
SyclQueue void void size_t num_bytes void
bool has_avx2()
Definition: debug.h:42
bool system_cpu_support_avx2()
Definition: system.cpp:251
bool system_cpu_support_avx()
Definition: system.cpp:247
bool system_cpu_support_sse3()
Definition: system.cpp:237
bool system_cpu_support_sse41()
Definition: system.cpp:242
bool system_cpu_support_sse2()
Definition: system.cpp:232