diff options
Diffstat (limited to 'ruy/context.cc')
-rw-r--r-- | ruy/context.cc | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/ruy/context.cc b/ruy/context.cc new file mode 100644 index 0000000..1a70303 --- /dev/null +++ b/ruy/context.cc @@ -0,0 +1,109 @@ +/* Copyright 2019 Google LLC. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "ruy/context.h" + +#include "ruy/check_macros.h" +#include "ruy/detect_arm.h" +#include "ruy/detect_x86.h" +#include "ruy/have_built_path_for.h" +#include "ruy/platform.h" + +namespace ruy { + +void Context::SetRuntimeEnabledPaths(Path paths) { + runtime_enabled_paths_ = paths; +} + +Path Context::GetRuntimeEnabledPaths() { + // This function should always return the same value on a given machine. + // When runtime_enabled_paths_ has its initial value kNone, it performs + // some platform detection to resolve it to specific Path values. + + // Fast path: already resolved. + if (runtime_enabled_paths_ != Path::kNone) { + return runtime_enabled_paths_; + } + + // Need to resolve now. Start by considering all paths enabled. + runtime_enabled_paths_ = kAllPaths; + + // This mechanism is intended to be used for testing and benchmarking. For + // example, one can set RUY_FORCE_DISABLE_PATHS to Path::kAvx512 in order to + // evaluate AVX2 performance on an AVX-512 machine. +#ifdef RUY_FORCE_DISABLE_PATHS + runtime_enabled_paths_ = runtime_enabled_paths_ & ~(RUY_FORCE_DISABLE_PATHS); +#endif + +#if RUY_PLATFORM(ARM) + // Now selectively disable paths that aren't supported on this machine. + if ((runtime_enabled_paths_ & Path::kNeonDotprod) != Path::kNone) { + if (!DetectDotprod()) { + runtime_enabled_paths_ = runtime_enabled_paths_ & ~Path::kNeonDotprod; + // Sanity check. + RUY_DCHECK((runtime_enabled_paths_ & Path::kNeonDotprod) == Path::kNone); + } + } +#endif // RUY_PLATFORM(ARM) + +#if RUY_PLATFORM(X86) + // TODO(b/147376783): SSE 4.2 and AVX-VNNI support is incomplete / + // placeholder. Optimization is not finished. In particular the dimensions of + // the kernel blocks can be changed as desired. + // + if ((runtime_enabled_paths_ & Path::kSse42) != Path::kNone) { + if (!(HaveBuiltPathForSse42() && DetectCpuSse42())) { + runtime_enabled_paths_ = runtime_enabled_paths_ & ~Path::kSse42; + // Sanity check. + RUY_DCHECK((runtime_enabled_paths_ & Path::kSse42) == Path::kNone); + } + } + + if ((runtime_enabled_paths_ & Path::kAvx2) != Path::kNone) { + if (!(HaveBuiltPathForAvx2() && DetectCpuAvx2())) { + runtime_enabled_paths_ = runtime_enabled_paths_ & ~Path::kAvx2; + // Sanity check. + RUY_DCHECK((runtime_enabled_paths_ & Path::kAvx2) == Path::kNone); + } + } + + if ((runtime_enabled_paths_ & Path::kAvx512) != Path::kNone) { + if (!(HaveBuiltPathForAvx512() && DetectCpuAvx512())) { + runtime_enabled_paths_ = runtime_enabled_paths_ & ~Path::kAvx512; + // Sanity check. + RUY_DCHECK((runtime_enabled_paths_ & Path::kAvx512) == Path::kNone); + } + } + + // TODO(b/147376783): SSE 4.2 and AVX-VNNI support is incomplete / + // placeholder. Optimization is not finished. In particular the dimensions of + // the kernel blocks can be changed as desired. + // + if ((runtime_enabled_paths_ & Path::kAvxVnni) != Path::kNone) { + if (!(HaveBuiltPathForAvxVnni() && DetectCpuAvxVnni())) { + runtime_enabled_paths_ = runtime_enabled_paths_ & ~Path::kAvxVnni; + // Sanity check. + RUY_DCHECK((runtime_enabled_paths_ & Path::kAvxVnni) == Path::kNone); + } + } +#endif // RUY_PLATFORM(X86) + + // Sanity check. We can't possibly have disabled all paths, as some paths + // are universally available (kReference, kStandardCpp). + RUY_DCHECK_NE(runtime_enabled_paths_, Path::kNone); + return runtime_enabled_paths_; +} + +} // namespace ruy |