#include <cstring>
#include <mutex>
#include <string>
#include "common/utils.hpp"
#include "cpu/aarch64/cpu_isa_traits.hpp"
#include "cpu/cpu_engine.hpp"
#include "cpu/platform.hpp"
namespace dnnl {
namespace impl {
namespace cpu {
namespace aarch64 {
namespace {
#ifdef DNNL_ENABLE_MAX_CPU_ISA
cpu_isa_t init_max_cpu_isa() {
cpu_isa_t max_cpu_isa_val = isa_all;
static std::string isa_val = getenv_string_user("MAX_CPU_ISA");
if (!isa_val.empty()) {
#define IF_HANDLE_CASE(cpu_isa) \
if (isa_val.compare(cpu_isa_traits<cpu_isa>::user_option_env) == 0) \
max_cpu_isa_val = cpu_isa
#define ELSEIF_HANDLE_CASE(cpu_isa) else IF_HANDLE_CASE(cpu_isa)
IF_HANDLE_CASE(isa_all);
ELSEIF_HANDLE_CASE(asimd);
ELSEIF_HANDLE_CASE(sve_128);
ELSEIF_HANDLE_CASE(sve_256);
ELSEIF_HANDLE_CASE(sve_512);
#undef IF_HANDLE_CASE
#undef ELSEIF_HANDLE_CASE
}
return max_cpu_isa_val;
}
set_once_before_first_get_setting_t<cpu_isa_t> &max_cpu_isa() {
static set_once_before_first_get_setting_t<cpu_isa_t> max_cpu_isa_setting(
init_max_cpu_isa());
return max_cpu_isa_setting;
}
#endif
}
struct isa_info_t {
isa_info_t(cpu_isa_t aisa) : isa(aisa) {};
dnnl_cpu_isa_t convert_to_public_enum(void) const {
switch (isa) {
case sve_512:
return static_cast<dnnl_cpu_isa_t>(dnnl_cpu_isa_sve_512);
case sve_256:
return static_cast<dnnl_cpu_isa_t>(dnnl_cpu_isa_sve_256);
case sve_128:
return static_cast<dnnl_cpu_isa_t>(dnnl_cpu_isa_sve_128);
case asimd: return static_cast<dnnl_cpu_isa_t>(dnnl_cpu_isa_asimd);
default: return dnnl_cpu_isa_default;
}
}
const char *get_name() const {
switch (isa) {
case sve_512: return "AArch64 SVE (512 bits)";
case sve_256: return "AArch64 SVE (256 bits)";
case sve_128: return "AArch64 SVE (128 bits)";
case asimd: return "AArch64 (with Advanced SIMD & floating-point)";
default: return "AArch64";
}
}
cpu_isa_t isa;
};
static isa_info_t get_isa_info_t(void) {
#define HANDLE_CASE(cpu_isa) \
if (mayiuse(cpu_isa)) return isa_info_t(cpu_isa);
HANDLE_CASE(sve_512);
HANDLE_CASE(sve_256);
HANDLE_CASE(sve_128);
HANDLE_CASE(asimd);
#undef HANDLE_CASE
return isa_info_t(isa_undef);
}
const char *get_isa_info() {
return get_isa_info_t().get_name();
}
cpu_isa_t get_max_cpu_isa() {
return get_isa_info_t().isa;
}
cpu_isa_t get_max_cpu_isa_mask(bool soft) {
MAYBE_UNUSED(soft);
#ifdef DNNL_ENABLE_MAX_CPU_ISA
return max_cpu_isa().get(soft);
#else
return isa_all;
#endif
}
status_t set_max_cpu_isa(dnnl_cpu_isa_t isa) {
using namespace dnnl::impl::status;
#ifdef DNNL_ENABLE_MAX_CPU_ISA
using namespace dnnl::impl;
using namespace dnnl::impl::cpu;
cpu_isa_t isa_to_set = isa_undef;
#define HANDLE_CASE(cpu_isa) \
case cpu_isa_traits<cpu_isa>::user_option_val: isa_to_set = cpu_isa; break;
switch (isa) {
HANDLE_CASE(isa_all);
HANDLE_CASE(asimd);
HANDLE_CASE(sve_128);
HANDLE_CASE(sve_256);
HANDLE_CASE(sve_512);
default: return invalid_arguments;
}
assert(isa_to_set != isa_undef);
#undef HANDLE_CASE
if (max_cpu_isa().set(isa_to_set))
return success;
else
return invalid_arguments;
#else
return unimplemented;
#endif
}
dnnl_cpu_isa_t get_effective_cpu_isa() {
return get_isa_info_t().convert_to_public_enum();
}
} } } }