diff options
author | Benoit Jacob <benoitjacob@google.com> | 2020-04-24 05:57:48 +0300 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2020-04-24 05:58:07 +0300 |
commit | 6039cccd36aa8dcab7aa9290b6175afded70100b (patch) | |
tree | d6ade6c6e57db2c267223426fa238420e3a66e0f /ruy/ctx_test.cc | |
parent | 970304dcf9ade5d4134226ac185c213dd7f4c8fc (diff) |
Make context.h minimal, not #including other ruy headers.
Context is a powerful tool: it allows ruy to have some persistent resources managed by the user's code. One caveat is that since by design it's about exposing enough internals to the user to allow them to be managed by the user, it's a slippery slope towards exposing too much internals, inflating the user's translation units with ruy details, potentially running into more build issues and more refactoring friction in the future. We need to design this carefully to minimize how much internals are exposed, in particular, how much ruy internal code is #included by ruy public headers.
The basic first step here is a classical 'pimpl' or 'dpointer' idiom, the private members are moved to a CtxImpl class which Context needs to have a raw CtxImpl* pointer to, for which a forward-declaration is enough.
However, much internal ruy code needs to access that CtxImpl, and some of that code is templatized (front-end code in ruy.h, dispatch.h, etc) so needs to be in headers that are included into the user's translation units. So, we need to somehow let this ruy internal code access the CtxImpl without #including its definition.
This is achieved by an interface base class Ctx, which offers all the methods needed by internal ruy code, and is subclassed by CtxImpl. Thus the relationship between Context, Ctx and CtxImpl is:
Context has an owning raw pointer to a CtxImpl; CtxImpl subclasses Ctx.
The roles are:
Context is the user-facing class.
Ctx is what ruy's code uses.
CtxImpl is the Ctx subclass actually defining the data members. It is needed only in a few internal .cc files such as ctx.cc, context.cc.
PiperOrigin-RevId: 308181525
Diffstat (limited to 'ruy/ctx_test.cc')
-rw-r--r-- | ruy/ctx_test.cc | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/ruy/ctx_test.cc b/ruy/ctx_test.cc new file mode 100644 index 0000000..173ac09 --- /dev/null +++ b/ruy/ctx_test.cc @@ -0,0 +1,73 @@ +/* Copyright 2019 The TensorFlow Authors. 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/ctx_impl.h" +#include "ruy/gtest_wrapper.h" +#include "ruy/path.h" +#include "ruy/platform.h" + +namespace ruy { +namespace { + +TEST(ContextInternalTest, EnabledPathsGeneral) { + CtxImpl ctx; + const auto ruy_paths = ctx.GetRuntimeEnabledPaths(); + const auto ruy_paths_repeat = ctx.GetRuntimeEnabledPaths(); + ASSERT_EQ(ruy_paths, ruy_paths_repeat); + EXPECT_NE(ruy_paths, Path::kNone); + EXPECT_EQ(ruy_paths & Path::kReference, Path::kReference); + EXPECT_EQ(ruy_paths & Path::kStandardCpp, Path::kStandardCpp); +} + +#if RUY_PLATFORM(X86) +TEST(ContextInternalTest, EnabledPathsX86) { + CtxImpl ctx; + ctx.SetRuntimeEnabledPaths(Path::kSse42 | Path::kAvx2 | Path::kAvx512 | + Path::kAvxVnni); + const auto ruy_paths = ctx.GetRuntimeEnabledPaths(); + EXPECT_EQ(ruy_paths & Path::kReference, Path::kNone); + EXPECT_EQ(ruy_paths & Path::kStandardCpp, Path::kNone); +} +#endif // RUY_PLATFORM(X86) + +#if RUY_PLATFORM(ARM) +TEST(ContextInternalTest, EnabledPathsArm) { + CtxImpl ctx; + ctx.SetRuntimeEnabledPaths(Path::kNeon | Path::kNeonDotprod); + const auto ruy_paths = ctx.GetRuntimeEnabledPaths(); + EXPECT_EQ(ruy_paths & Path::kReference, Path::kNone); + EXPECT_EQ(ruy_paths & Path::kStandardCpp, Path::kNone); + EXPECT_EQ(ruy_paths & Path::kNeon, Path::kNeon); +} +#endif // RUY_PLATFORM(ARM) + +TEST(ContextInternalTest, ThreadSpecificResources) { + CtxImpl ctx; + for (int i = 1; i <= 4; i++) { + ctx.EnsureThreadSpecificResources(i); + for (int j = 0; j < i; j++) { + EXPECT_NE(ctx.GetThreadSpecificAllocator(j), nullptr); + EXPECT_NE(ctx.GetThreadSpecificTuningResolver(j), nullptr); + } + } +} + +} // namespace +} // namespace ruy + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} |