Files
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

202 lines
7.5 KiB
C++

// Copyright © Advanced Micro Devices, Inc., or its affiliates.
// SPDX-License-Identifier: MIT
#include "hipdnn_data_sdk/utilities/EngineNames.hpp"
#include "utilities/EngineOrdering.hpp"
#include <gtest/gtest.h>
using namespace hipdnn_backend::utilities;
using namespace hipdnn_data_sdk::utilities;
TEST(TestEngineOrdering, EmptyVector)
{
std::vector<int64_t> engineIds;
EXPECT_NO_THROW(sortEngineIds(engineIds));
EXPECT_TRUE(engineIds.empty());
}
TEST(TestEngineOrdering, SingleElement)
{
std::vector<int64_t> engineIds = {MIOPEN_ENGINE_ID};
sortEngineIds(engineIds);
ASSERT_EQ(engineIds.size(), 1u);
EXPECT_EQ(engineIds[0], MIOPEN_ENGINE_ID);
}
TEST(TestEngineOrdering, OnlyMiopenEngineDeterministic)
{
std::vector<int64_t> engineIds = {MIOPEN_ENGINE_DETERMINISTIC_ID};
sortEngineIds(engineIds);
ASSERT_EQ(engineIds.size(), 1u);
EXPECT_EQ(engineIds[0], MIOPEN_ENGINE_DETERMINISTIC_ID);
}
TEST(TestEngineOrdering, BothMiopenEngines)
{
// Test with deterministic first (should be reordered)
std::vector<int64_t> engineIds = {MIOPEN_ENGINE_DETERMINISTIC_ID, MIOPEN_ENGINE_ID};
sortEngineIds(engineIds);
ASSERT_EQ(engineIds.size(), 2u);
EXPECT_EQ(engineIds[0], MIOPEN_ENGINE_ID);
EXPECT_EQ(engineIds[1], MIOPEN_ENGINE_DETERMINISTIC_ID);
// Test with correct order (should remain unchanged)
engineIds = {MIOPEN_ENGINE_ID, MIOPEN_ENGINE_DETERMINISTIC_ID};
sortEngineIds(engineIds);
ASSERT_EQ(engineIds.size(), 2u);
EXPECT_EQ(engineIds[0], MIOPEN_ENGINE_ID);
EXPECT_EQ(engineIds[1], MIOPEN_ENGINE_DETERMINISTIC_ID);
}
TEST(TestEngineOrdering, MiopenEnginesWithOthers)
{
// Create a fake "other" engine ID
const int64_t otherEngine1 = HIPBLASLT_ENGINE_ID;
const int64_t otherEngine2 = 999999; // Arbitrary other engine
// Test: other, MIOPEN_ENGINE_DETERMINISTIC, MIOPEN_ENGINE, other
std::vector<int64_t> engineIds
= {otherEngine1, MIOPEN_ENGINE_DETERMINISTIC_ID, MIOPEN_ENGINE_ID, otherEngine2};
sortEngineIds(engineIds);
ASSERT_EQ(engineIds.size(), 4u);
EXPECT_EQ(engineIds[0], MIOPEN_ENGINE_ID) << "MIOPEN_ENGINE should be first";
// Middle two should be otherEngine1 and otherEngine2 in stable order
EXPECT_EQ(engineIds[1], otherEngine1) << "Other engines should maintain stable order";
EXPECT_EQ(engineIds[2], otherEngine2) << "Other engines should maintain stable order";
EXPECT_EQ(engineIds[3], MIOPEN_ENGINE_DETERMINISTIC_ID)
<< "MIOPEN_ENGINE_DETERMINISTIC should be last";
}
TEST(TestEngineOrdering, OnlyOtherEngines)
{
const int64_t otherEngine1 = HIPBLASLT_ENGINE_ID;
const int64_t otherEngine2 = 888888;
const int64_t otherEngine3 = 777777;
std::vector<int64_t> engineIds = {otherEngine1, otherEngine2, otherEngine3};
const std::vector<int64_t> originalOrder = engineIds;
sortEngineIds(engineIds);
// Order should be preserved (stable sort)
ASSERT_EQ(engineIds.size(), 3u);
EXPECT_EQ(engineIds, originalOrder) << "Other engines should maintain their original order";
}
TEST(TestEngineOrdering, ComplexScenario)
{
const int64_t other1 = 111111;
const int64_t other2 = 222222;
const int64_t other3 = 333333;
// Start with: other1, MIOPEN_ENGINE_DETERMINISTIC, other2, MIOPEN_ENGINE, other3
std::vector<int64_t> engineIds
= {other1, MIOPEN_ENGINE_DETERMINISTIC_ID, other2, MIOPEN_ENGINE_ID, other3};
sortEngineIds(engineIds);
ASSERT_EQ(engineIds.size(), 5u);
EXPECT_EQ(engineIds[0], MIOPEN_ENGINE_ID) << "MIOPEN_ENGINE should be first";
EXPECT_EQ(engineIds[1], other1) << "other1 should be second (stable order among others)";
EXPECT_EQ(engineIds[2], other2) << "other2 should be third (stable order among others)";
EXPECT_EQ(engineIds[3], other3) << "other3 should be fourth (stable order among others)";
EXPECT_EQ(engineIds[4], MIOPEN_ENGINE_DETERMINISTIC_ID)
<< "MIOPEN_ENGINE_DETERMINISTIC should be last";
}
TEST(TestEngineOrdering, StableOrderPreservedForOthers)
{
const int64_t other1 = 100;
const int64_t other2 = 200;
const int64_t other3 = 300;
const int64_t other4 = 400;
// Mix with MIOpen engines
std::vector<int64_t> engineIds
= {other1, other2, MIOPEN_ENGINE_DETERMINISTIC_ID, other3, MIOPEN_ENGINE_ID, other4};
sortEngineIds(engineIds);
ASSERT_EQ(engineIds.size(), 6u);
EXPECT_EQ(engineIds[0], MIOPEN_ENGINE_ID);
// The four "other" engines should be in their original relative order
EXPECT_EQ(engineIds[1], other1);
EXPECT_EQ(engineIds[2], other2);
EXPECT_EQ(engineIds[3], other3);
EXPECT_EQ(engineIds[4], other4);
EXPECT_EQ(engineIds[5], MIOPEN_ENGINE_DETERMINISTIC_ID);
}
TEST(TestEngineOrdering, IsIdempotent)
{
std::vector<int64_t> engineIds
= {MIOPEN_ENGINE_DETERMINISTIC_ID, HIPBLASLT_ENGINE_ID, MIOPEN_ENGINE_ID};
sortEngineIds(engineIds);
const auto firstPass = engineIds;
sortEngineIds(engineIds);
EXPECT_EQ(engineIds, firstPass);
}
TEST(TestEngineOrdering, UnknownEngineIdsTreatedAsMiddlePriority)
{
// Engine IDs that don't correspond to any known well-known name should
// sort into the middle bucket (between MIOPEN_ENGINE and
// MIOPEN_ENGINE_DETERMINISTIC) without crashing.
const auto unknown1 = static_cast<int64_t>(0x1234567890ABCDEF);
const auto unknown2 = static_cast<int64_t>(0xFEDCBA0987654321);
std::vector<int64_t> engineIds = {unknown1, MIOPEN_ENGINE_ID, unknown2};
EXPECT_NO_THROW(sortEngineIds(engineIds));
ASSERT_EQ(engineIds.size(), 3u);
EXPECT_EQ(engineIds[0], MIOPEN_ENGINE_ID);
EXPECT_EQ(engineIds[1], unknown1);
EXPECT_EQ(engineIds[2], unknown2);
}
TEST(TestEngineOrdering, AsmRankedAboveRocke)
{
// When both the ASM (ASM_SDPA) and rocKE engines are applicable, ASM
// must be selected first. Start reversed to prove the sort reorders them.
std::vector<int64_t> engineIds = {ROCKE_ENGINE_ID, ASM_SDPA_ENGINE_ID};
sortEngineIds(engineIds);
ASSERT_EQ(engineIds.size(), 2u);
EXPECT_EQ(engineIds[0], ASM_SDPA_ENGINE_ID) << "ASM (ASM_SDPA) should rank above rocKE";
EXPECT_EQ(engineIds[1], ROCKE_ENGINE_ID);
}
TEST(TestEngineOrdering, RockeSelectedWhenAsmAbsent)
{
// With ASM not applicable, rocKE still ranks ahead of generic "other"
// engines and MIOPEN_ENGINE_DETERMINISTIC, matching prior behaviour.
const int64_t otherEngine = HIPBLASLT_ENGINE_ID;
std::vector<int64_t> engineIds = {MIOPEN_ENGINE_DETERMINISTIC_ID, otherEngine, ROCKE_ENGINE_ID};
sortEngineIds(engineIds);
ASSERT_EQ(engineIds.size(), 3u);
EXPECT_EQ(engineIds[0], ROCKE_ENGINE_ID) << "rocKE ranks above other engines when ASM absent";
EXPECT_EQ(engineIds[1], otherEngine);
EXPECT_EQ(engineIds[2], MIOPEN_ENGINE_DETERMINISTIC_ID);
}
TEST(TestEngineOrdering, FullPriorityOrdering)
{
// Full ordering: MIOPEN_ENGINE > ASM_SDPA (ASM) > ROCKE > others >
// MIOPEN_ENGINE_DETERMINISTIC. Provide the candidates shuffled.
const int64_t otherEngine = HIPBLASLT_ENGINE_ID;
std::vector<int64_t> engineIds = {MIOPEN_ENGINE_DETERMINISTIC_ID,
ROCKE_ENGINE_ID,
otherEngine,
ASM_SDPA_ENGINE_ID,
MIOPEN_ENGINE_ID};
sortEngineIds(engineIds);
ASSERT_EQ(engineIds.size(), 5u);
EXPECT_EQ(engineIds[0], MIOPEN_ENGINE_ID);
EXPECT_EQ(engineIds[1], ASM_SDPA_ENGINE_ID);
EXPECT_EQ(engineIds[2], ROCKE_ENGINE_ID);
EXPECT_EQ(engineIds[3], otherEngine);
EXPECT_EQ(engineIds[4], MIOPEN_ENGINE_DETERMINISTIC_ID);
}