From 3efb37536149f438a68a1742c35d827e1fbd7860 Mon Sep 17 00:00:00 2001 From: Anthony Barbier Date: Fri, 20 Jul 2018 15:30:46 +0100 Subject: COMPMID-1347: Fixed fallback CPUInfo populate function and added latest CPUs Added IDs for A35/A75r0/A75r1/A76 Fixed variant encoding in midr Update dot / fp16 support based on CPUInfo models detected Change-Id: I308a453a4085fa192a92cf98db72c9dff749bb7d Reviewed-on: https://eu-gerrit-1.euhpc.arm.com/140833 Tested-by: Jenkins Reviewed-by: Pablo Tello Reviewed-by: Giorgio Arena Reviewed-by: Georgios Pinitas --- src/runtime/CPUUtils.cpp | 83 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 62 insertions(+), 21 deletions(-) (limited to 'src/runtime/CPUUtils.cpp') diff --git a/src/runtime/CPUUtils.cpp b/src/runtime/CPUUtils.cpp index cf29ce0053..c6bd907b36 100644 --- a/src/runtime/CPUUtils.cpp +++ b/src/runtime/CPUUtils.cpp @@ -69,13 +69,35 @@ namespace using namespace arm_compute; #if !defined(BARE_METAL) && (defined(__arm__) || defined(__aarch64__)) -struct PerCPUData + +bool model_supports_dot(CPUModel model) { - CPUModel model = CPUModel::GENERIC; - unsigned int midr = 0; - bool model_set = false; -}; + switch(model) + { + case CPUModel::A55r1: + case CPUModel::A75r1: + case CPUModel::A76: + return true; + default: + return false; + } +} +bool model_supports_fp16(CPUModel model) +{ + switch(model) + { + case CPUModel::A35: + case CPUModel::A55r0: + case CPUModel::A55r1: + case CPUModel::A75r0: + case CPUModel::A75r1: + case CPUModel::A76: + return true; + default: + return false; + } +} /* Convert an MIDR register value to a CPUModel enum value. */ CPUModel midr_to_model(const unsigned int midr) { @@ -91,7 +113,9 @@ CPUModel midr_to_model(const unsigned int midr) case 0xd03: model = CPUModel::A53; break; - + case 0xd04: + model = CPUModel::A35; + break; case 0xd05: if(variant != 0) { @@ -102,7 +126,19 @@ CPUModel midr_to_model(const unsigned int midr) model = CPUModel::A55r0; } break; - + case 0xd0a: + if(variant != 0) + { + model = CPUModel::A75r1; + } + else + { + model = CPUModel::A75r0; + } + break; + case 0xd0b: + model = CPUModel::A76; + break; default: model = CPUModel::GENERIC; break; @@ -111,7 +147,7 @@ CPUModel midr_to_model(const unsigned int midr) return model; } -void populate_models_cpuid(std::vector &cpusv) +void populate_models_cpuid(std::vector &cpusv) { // If the CPUID capability is present, MIDR information is provided in /sys. Use that to populate the CPU model table. uint32_t i = 0; @@ -127,15 +163,13 @@ void populate_models_cpuid(std::vector &cpusv) if(bool(getline(file, line))) { const unsigned long midr = support::cpp11::stoul(line, nullptr, support::cpp11::NumericBase::BASE_16); - c.midr = (midr & 0xffffffff); - c.model = midr_to_model(c.midr); - c.model_set = true; + c = midr_to_model(midr & 0xffffffff); } } } } -void populate_models_cpuinfo(std::vector &cpusv) +void populate_models_cpuinfo(std::vector &cpusv) { // If "long-form" cpuinfo is present, parse that to populate models. std::regex proc_regex("^processor.*(\\d+)$"); @@ -170,9 +204,7 @@ void populate_models_cpuinfo(std::vector &cpusv) if(curcpu >= 0) { - cpusv[curcpu].midr = midr; - cpusv[curcpu].model = midr_to_model(midr); - cpusv[curcpu].model_set = true; + cpusv[curcpu] = midr_to_model(midr); } midr = 0; @@ -191,7 +223,7 @@ void populate_models_cpuinfo(std::vector &cpusv) if(std::regex_match(line, match, var_regex)) { int varv = support::cpp11::stoi(match[1], nullptr, support::cpp11::NumericBase::BASE_16); - midr |= (varv << 16); + midr |= (varv << 20); continue; } @@ -213,9 +245,7 @@ void populate_models_cpuinfo(std::vector &cpusv) if(curcpu >= 0) { - cpusv[curcpu].midr = midr; - cpusv[curcpu].model = midr_to_model(midr); - cpusv[curcpu].model_set = true; + cpusv[curcpu] = midr_to_model(midr); } } } @@ -333,7 +363,7 @@ void get_cpu_configuration(CPUInfo &cpuinfo) cpuinfo.set_cpu_num(max_cpus); cpuinfo.set_fp16(fp16_support); cpuinfo.set_dotprod(dot_support); - std::vector percpu(max_cpus); + std::vector percpu(max_cpus, CPUModel::GENERIC); if(cpuid) { populate_models_cpuid(percpu); @@ -341,11 +371,22 @@ void get_cpu_configuration(CPUInfo &cpuinfo) else { populate_models_cpuinfo(percpu); + + // Update dot product and FP16 support if all CPUs support these features: + bool all_support_dot = true; + bool all_support_fp16 = true; + for(auto cpu : percpu) + { + all_support_dot &= model_supports_dot(cpu); + all_support_fp16 &= model_supports_fp16(cpu); + } + cpuinfo.set_dotprod(all_support_dot); + cpuinfo.set_fp16(all_support_fp16); } int j(0); for(const auto &v : percpu) { - cpuinfo.set_cpu_model(j++, v.model); + cpuinfo.set_cpu_model(j++, v); } #else /* !defined(BARE_METAL) && (defined(__arm__) || defined(__aarch64__)) */ ARM_COMPUTE_UNUSED(cpuinfo); -- cgit v1.2.1