File indexing completed on 2025-08-28 08:27:08
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #pragma once
0019
0020 #include <utility>
0021 #include <vector>
0022
0023 #include "arrow/status.h"
0024 #include "arrow/util/cpu_info.h"
0025
0026 namespace arrow {
0027 namespace internal {
0028
0029 enum class DispatchLevel : int {
0030
0031
0032 NONE = 0,
0033 SSE4_2,
0034 AVX2,
0035 AVX512,
0036 NEON,
0037 MAX
0038 };
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066 template <typename DynamicFunction>
0067 class DynamicDispatch {
0068 protected:
0069 using FunctionType = typename DynamicFunction::FunctionType;
0070 using Implementation = std::pair<DispatchLevel, FunctionType>;
0071
0072 public:
0073 DynamicDispatch() { Resolve(DynamicFunction::implementations()); }
0074
0075 FunctionType func = {};
0076
0077 protected:
0078
0079 void Resolve(const std::vector<Implementation>& implementations) {
0080 Implementation cur{DispatchLevel::NONE, {}};
0081
0082 for (const auto& impl : implementations) {
0083 if (impl.first >= cur.first && IsSupported(impl.first)) {
0084
0085 cur = impl;
0086 }
0087 }
0088
0089 if (!cur.second) {
0090 Status::Invalid("No appropriate implementation found").Abort();
0091 }
0092 func = cur.second;
0093 }
0094
0095 private:
0096 bool IsSupported(DispatchLevel level) const {
0097 static const auto cpu_info = arrow::internal::CpuInfo::GetInstance();
0098
0099 switch (level) {
0100 case DispatchLevel::NONE:
0101 return true;
0102 case DispatchLevel::SSE4_2:
0103 return cpu_info->IsSupported(CpuInfo::SSE4_2);
0104 case DispatchLevel::AVX2:
0105 return cpu_info->IsSupported(CpuInfo::AVX2);
0106 case DispatchLevel::AVX512:
0107 return cpu_info->IsSupported(CpuInfo::AVX512);
0108 default:
0109 return false;
0110 }
0111 }
0112 };
0113
0114 }
0115 }