Files
paddlepaddle--paddle/test/cpp/compat/c10_DispatchKey_test.cc
T
2026-07-13 12:40:42 +08:00

249 lines
8.9 KiB
C++

// Copyright (c) 2026 PaddlePaddle 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 <c10/core/DispatchKey.h>
#include <cstdint>
#include <functional>
#include "gtest/gtest.h"
// Use EXPECT_TRUE with == instead of EXPECT_EQ for enum types
// because gtest's EXPECT_EQ needs operator<< which is declared
// but not yet implemented for DispatchKey/BackendComponent.
#define EXPECT_DK_EQ(a, b) EXPECT_TRUE((a) == (b))
#define EXPECT_BC_EQ(a, b) EXPECT_TRUE((a) == (b))
// Helper: wrap in a non-constexpr call to force runtime evaluation.
template <typename F, typename... Args>
auto runtime_call(F f, Args... args) -> decltype(f(args...)) {
return f(args...);
}
// ==========================================================================
// Tests for constexpr/inline functions in c10::DispatchKey.h
// ==========================================================================
// ---------- isAliasDispatchKey
// ------------------------------------------------
TEST(DispatchKeyTest, IsAliasDispatchKey) {
// Alias keys: Autograd .. CompositeExplicitAutogradNonFunctional
c10::DispatchKey alias = c10::DispatchKey::Autograd;
EXPECT_TRUE(c10::isAliasDispatchKey(alias));
alias = c10::DispatchKey::CompositeImplicitAutograd;
EXPECT_TRUE(c10::isAliasDispatchKey(alias));
alias = c10::DispatchKey::CompositeExplicitAutograd;
EXPECT_TRUE(c10::isAliasDispatchKey(alias));
alias = c10::DispatchKey::CompositeExplicitAutogradNonFunctional;
EXPECT_TRUE(c10::isAliasDispatchKey(alias));
// Non-alias keys
c10::DispatchKey non_alias = c10::DispatchKey::CPU;
EXPECT_FALSE(c10::isAliasDispatchKey(non_alias));
non_alias = c10::DispatchKey::Dense;
EXPECT_FALSE(c10::isAliasDispatchKey(non_alias));
non_alias = c10::DispatchKey::Undefined;
EXPECT_FALSE(c10::isAliasDispatchKey(non_alias));
}
// ---------- isPerBackendFunctionalityKey -------------------------------------
TEST(DispatchKeyTest, IsPerBackendFunctionalityKey) {
// Per-backend keys: Dense, Quantized, Sparse, SparseCsr,
// AutogradFunctionality, NestedTensor
c10::DispatchKey k = c10::DispatchKey::Dense;
EXPECT_TRUE(c10::isPerBackendFunctionalityKey(k));
k = c10::DispatchKey::Quantized;
EXPECT_TRUE(c10::isPerBackendFunctionalityKey(k));
k = c10::DispatchKey::Sparse;
EXPECT_TRUE(c10::isPerBackendFunctionalityKey(k));
k = c10::DispatchKey::SparseCsr;
EXPECT_TRUE(c10::isPerBackendFunctionalityKey(k));
k = c10::DispatchKey::AutogradFunctionality;
EXPECT_TRUE(c10::isPerBackendFunctionalityKey(k));
k = c10::DispatchKey::NestedTensor;
EXPECT_TRUE(c10::isPerBackendFunctionalityKey(k));
// Non per-backend keys
k = c10::DispatchKey::BackendSelect;
EXPECT_FALSE(c10::isPerBackendFunctionalityKey(k));
k = c10::DispatchKey::Python;
EXPECT_FALSE(c10::isPerBackendFunctionalityKey(k));
k = c10::DispatchKey::Undefined;
EXPECT_FALSE(c10::isPerBackendFunctionalityKey(k));
}
// ---------- toBackendComponent(DispatchKey)
// -----------------------------------
TEST(DispatchKeyTest, ToBackendComponentDense) {
c10::DispatchKey k = c10::DispatchKey::CPU;
c10::BackendComponent bc = c10::toBackendComponent(k);
EXPECT_BC_EQ(bc, c10::BackendComponent::CPUBit);
}
TEST(DispatchKeyTest, ToBackendComponentQuantized) {
c10::DispatchKey k = c10::DispatchKey::QuantizedCPU;
c10::BackendComponent bc = c10::toBackendComponent(k);
EXPECT_BC_EQ(bc, c10::BackendComponent::CPUBit);
}
TEST(DispatchKeyTest, ToBackendComponentSparse) {
c10::DispatchKey k = c10::DispatchKey::SparseCPU;
c10::BackendComponent bc = c10::toBackendComponent(k);
EXPECT_BC_EQ(bc, c10::BackendComponent::CPUBit);
}
TEST(DispatchKeyTest, ToBackendComponentSparseCsr) {
c10::DispatchKey k = c10::DispatchKey::SparseCsrCPU;
c10::BackendComponent bc = c10::toBackendComponent(k);
EXPECT_BC_EQ(bc, c10::BackendComponent::CPUBit);
}
TEST(DispatchKeyTest, ToBackendComponentNestedTensor) {
c10::DispatchKey k = c10::DispatchKey::NestedTensorCPU;
c10::BackendComponent bc = c10::toBackendComponent(k);
EXPECT_BC_EQ(bc, c10::BackendComponent::CPUBit);
}
TEST(DispatchKeyTest, ToBackendComponentAutograd) {
c10::DispatchKey k = c10::DispatchKey::AutogradCPU;
c10::BackendComponent bc = c10::toBackendComponent(k);
EXPECT_BC_EQ(bc, c10::BackendComponent::CPUBit);
}
TEST(DispatchKeyTest, ToBackendComponentInvalid) {
// A functionality-only key (no backend range) → InvalidBit
c10::DispatchKey k = c10::DispatchKey::BackendSelect;
c10::BackendComponent bc = c10::toBackendComponent(k);
EXPECT_BC_EQ(bc, c10::BackendComponent::InvalidBit);
}
// ---------- toFunctionalityKey -----------------------------------------------
TEST(DispatchKeyTest, ToFunctionalityKeyPure) {
// A pure functionality key maps to itself.
c10::DispatchKey k = c10::DispatchKey::Dense;
EXPECT_DK_EQ(c10::toFunctionalityKey(k), c10::DispatchKey::Dense);
k = c10::DispatchKey::BackendSelect;
EXPECT_DK_EQ(c10::toFunctionalityKey(k), c10::DispatchKey::BackendSelect);
}
TEST(DispatchKeyTest, ToFunctionalityKeyDenseBackend) {
c10::DispatchKey k = c10::DispatchKey::CPU;
EXPECT_DK_EQ(c10::toFunctionalityKey(k), c10::DispatchKey::Dense);
k = c10::DispatchKey::CUDA;
EXPECT_DK_EQ(c10::toFunctionalityKey(k), c10::DispatchKey::Dense);
}
TEST(DispatchKeyTest, ToFunctionalityKeyQuantizedBackend) {
c10::DispatchKey k = c10::DispatchKey::QuantizedCPU;
EXPECT_DK_EQ(c10::toFunctionalityKey(k), c10::DispatchKey::Quantized);
}
TEST(DispatchKeyTest, ToFunctionalityKeySparseBackend) {
c10::DispatchKey k = c10::DispatchKey::SparseCPU;
EXPECT_DK_EQ(c10::toFunctionalityKey(k), c10::DispatchKey::Sparse);
}
TEST(DispatchKeyTest, ToFunctionalityKeySparseCsrBackend) {
c10::DispatchKey k = c10::DispatchKey::SparseCsrCPU;
EXPECT_DK_EQ(c10::toFunctionalityKey(k), c10::DispatchKey::SparseCsr);
}
TEST(DispatchKeyTest, ToFunctionalityKeyNestedTensorBackend) {
c10::DispatchKey k = c10::DispatchKey::NestedTensorCPU;
EXPECT_DK_EQ(c10::toFunctionalityKey(k), c10::DispatchKey::NestedTensor);
}
TEST(DispatchKeyTest, ToFunctionalityKeyAutogradBackend) {
c10::DispatchKey k = c10::DispatchKey::AutogradCPU;
EXPECT_DK_EQ(c10::toFunctionalityKey(k),
c10::DispatchKey::AutogradFunctionality);
}
TEST(DispatchKeyTest, ToFunctionalityKeyBeyondRuntime) {
// Keys beyond EndOfRuntimeBackendKeys map to Undefined.
c10::DispatchKey k = c10::DispatchKey::Autograd;
EXPECT_DK_EQ(c10::toFunctionalityKey(k), c10::DispatchKey::Undefined);
}
// ---------- toRuntimePerBackendFunctionalityKey ------------------------------
TEST(DispatchKeyTest, ToRuntimeKeyDense) {
c10::DispatchKey k = c10::toRuntimePerBackendFunctionalityKey(
c10::DispatchKey::Dense, c10::BackendComponent::CPUBit);
EXPECT_DK_EQ(k, c10::DispatchKey::CPU);
}
TEST(DispatchKeyTest, ToRuntimeKeySparse) {
c10::DispatchKey k = c10::toRuntimePerBackendFunctionalityKey(
c10::DispatchKey::Sparse, c10::BackendComponent::CPUBit);
EXPECT_DK_EQ(k, c10::DispatchKey::SparseCPU);
}
TEST(DispatchKeyTest, ToRuntimeKeySparseCsr) {
c10::DispatchKey k = c10::toRuntimePerBackendFunctionalityKey(
c10::DispatchKey::SparseCsr, c10::BackendComponent::CPUBit);
EXPECT_DK_EQ(k, c10::DispatchKey::SparseCsrCPU);
}
TEST(DispatchKeyTest, ToRuntimeKeyQuantized) {
c10::DispatchKey k = c10::toRuntimePerBackendFunctionalityKey(
c10::DispatchKey::Quantized, c10::BackendComponent::CPUBit);
EXPECT_DK_EQ(k, c10::DispatchKey::QuantizedCPU);
}
TEST(DispatchKeyTest, ToRuntimeKeyNestedTensor) {
c10::DispatchKey k = c10::toRuntimePerBackendFunctionalityKey(
c10::DispatchKey::NestedTensor, c10::BackendComponent::CPUBit);
EXPECT_DK_EQ(k, c10::DispatchKey::NestedTensorCPU);
}
TEST(DispatchKeyTest, ToRuntimeKeyAutograd) {
c10::DispatchKey k = c10::toRuntimePerBackendFunctionalityKey(
c10::DispatchKey::AutogradFunctionality, c10::BackendComponent::CPUBit);
EXPECT_DK_EQ(k, c10::DispatchKey::AutogradCPU);
}
TEST(DispatchKeyTest, ToRuntimeKeyNonPerBackend) {
// A key that is not per-backend should map to Undefined.
c10::DispatchKey k = c10::toRuntimePerBackendFunctionalityKey(
c10::DispatchKey::BackendSelect, c10::BackendComponent::CPUBit);
EXPECT_DK_EQ(k, c10::DispatchKey::Undefined);
}
// ---------- std::hash<DispatchKey> -------------------------------------------
TEST(DispatchKeyTest, Hash) {
std::hash<c10::DispatchKey> hasher;
c10::DispatchKey k = c10::DispatchKey::CPU;
EXPECT_EQ(hasher(k), static_cast<size_t>(k));
}