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
387 lines
12 KiB
C++
387 lines
12 KiB
C++
// Copyright © Advanced Micro Devices, Inc., or its affiliates.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
#include <gtest/gtest.h>
|
|
#include <hipdnn_frontend/Types.hpp>
|
|
#include <hipdnn_frontend/attributes/SdpaAttributes.hpp>
|
|
|
|
using namespace hipdnn_frontend::graph;
|
|
using namespace hipdnn_frontend;
|
|
|
|
namespace
|
|
{
|
|
std::shared_ptr<TensorAttributes> makeTensor(int64_t uid)
|
|
{
|
|
auto t = std::make_shared<TensorAttributes>();
|
|
t->set_uid(uid);
|
|
return t;
|
|
}
|
|
} // namespace
|
|
|
|
TEST(TestSdpaAttributes, DefaultValues)
|
|
{
|
|
const SdpaAttributes attrs;
|
|
|
|
// Required I/O tensors
|
|
EXPECT_EQ(attrs.get_q(), nullptr);
|
|
EXPECT_EQ(attrs.get_k(), nullptr);
|
|
EXPECT_EQ(attrs.get_v(), nullptr);
|
|
EXPECT_EQ(attrs.get_o(), nullptr);
|
|
|
|
// Optional input tensors
|
|
EXPECT_EQ(attrs.get_bias(), nullptr);
|
|
EXPECT_EQ(attrs.get_attn_scale(), nullptr);
|
|
EXPECT_EQ(attrs.get_seq_len_q(), nullptr);
|
|
EXPECT_EQ(attrs.get_seq_len_kv(), nullptr);
|
|
EXPECT_EQ(attrs.get_seed(), nullptr);
|
|
EXPECT_EQ(attrs.get_offset(), nullptr);
|
|
EXPECT_EQ(attrs.get_dropout_mask(), nullptr);
|
|
EXPECT_EQ(attrs.get_dropout_scale(), nullptr);
|
|
EXPECT_EQ(attrs.get_page_table_k(), nullptr);
|
|
EXPECT_EQ(attrs.get_page_table_v(), nullptr);
|
|
EXPECT_EQ(attrs.get_block_mask(), nullptr);
|
|
EXPECT_EQ(attrs.get_sink_token(), nullptr);
|
|
EXPECT_EQ(attrs.get_descale_q(), nullptr);
|
|
EXPECT_EQ(attrs.get_descale_k(), nullptr);
|
|
EXPECT_EQ(attrs.get_descale_v(), nullptr);
|
|
EXPECT_EQ(attrs.get_descale_s(), nullptr);
|
|
EXPECT_EQ(attrs.get_scale_s(), nullptr);
|
|
EXPECT_EQ(attrs.get_scale_o(), nullptr);
|
|
|
|
// Optional output tensors
|
|
EXPECT_EQ(attrs.get_stats(), nullptr);
|
|
EXPECT_EQ(attrs.get_max(), nullptr);
|
|
EXPECT_EQ(attrs.get_sum_exp(), nullptr);
|
|
EXPECT_EQ(attrs.get_rng_dump(), nullptr);
|
|
EXPECT_EQ(attrs.get_amax_s(), nullptr);
|
|
EXPECT_EQ(attrs.get_amax_o(), nullptr);
|
|
|
|
// Boolean flags
|
|
EXPECT_FALSE(attrs.generate_stats.has_value());
|
|
EXPECT_FALSE(attrs.alibi_mask);
|
|
EXPECT_FALSE(attrs.padding_mask);
|
|
EXPECT_FALSE(attrs.causal_mask);
|
|
EXPECT_FALSE(attrs.causal_mask_bottom_right);
|
|
|
|
// Scalar attributes
|
|
EXPECT_FALSE(attrs.dropout_probability.has_value());
|
|
EXPECT_FALSE(attrs.attn_scale_value.has_value());
|
|
EXPECT_FALSE(attrs.left_bound.has_value());
|
|
EXPECT_FALSE(attrs.right_bound.has_value());
|
|
EXPECT_FALSE(attrs.max_seq_len_kv.has_value());
|
|
|
|
// Enum defaults
|
|
EXPECT_EQ(attrs.diagonal_alignment, DiagonalAlignment::TOP_LEFT);
|
|
EXPECT_EQ(attrs.mma_core_mode, DataType::NOT_SET);
|
|
EXPECT_EQ(attrs.implementation, AttentionImplementation::AUTO);
|
|
}
|
|
|
|
TEST(TestSdpaAttributes, SetRequiredTensors)
|
|
{
|
|
SdpaAttributes attrs;
|
|
|
|
auto q = makeTensor(1);
|
|
auto k = makeTensor(2);
|
|
auto v = makeTensor(3);
|
|
auto o = makeTensor(4);
|
|
|
|
attrs.set_q(q).set_k(k).set_v(v).set_o(o);
|
|
|
|
EXPECT_EQ(attrs.get_q(), q);
|
|
EXPECT_EQ(attrs.get_k(), k);
|
|
EXPECT_EQ(attrs.get_v(), v);
|
|
EXPECT_EQ(attrs.get_o(), o);
|
|
|
|
// Unset optional tensors remain null
|
|
EXPECT_EQ(attrs.get_bias(), nullptr);
|
|
EXPECT_EQ(attrs.get_attn_scale(), nullptr);
|
|
EXPECT_EQ(attrs.get_stats(), nullptr);
|
|
}
|
|
|
|
TEST(TestSdpaAttributes, SetInputTensors)
|
|
{
|
|
SdpaAttributes attrs;
|
|
|
|
auto attnMask = makeTensor(10);
|
|
auto scale = makeTensor(11);
|
|
auto seqLenQ = makeTensor(12);
|
|
auto seqLenKv = makeTensor(13);
|
|
auto seed = makeTensor(14);
|
|
auto offset = makeTensor(15);
|
|
auto dropoutMask = makeTensor(16);
|
|
auto dropoutScale = makeTensor(17);
|
|
auto pageTableK = makeTensor(18);
|
|
auto pageTableV = makeTensor(19);
|
|
auto blockMask = makeTensor(20);
|
|
auto sinkToken = makeTensor(21);
|
|
auto descaleQ = makeTensor(22);
|
|
auto descaleK = makeTensor(23);
|
|
auto descaleV = makeTensor(24);
|
|
auto descaleS = makeTensor(25);
|
|
auto scaleS = makeTensor(26);
|
|
auto scaleO = makeTensor(27);
|
|
|
|
attrs.set_bias(attnMask)
|
|
.set_attn_scale(scale)
|
|
.set_seq_len_q(seqLenQ)
|
|
.set_seq_len_kv(seqLenKv)
|
|
.set_seed(seed)
|
|
.set_offset(offset)
|
|
.set_dropout_mask(dropoutMask)
|
|
.set_dropout_scale(dropoutScale)
|
|
.set_paged_attention_k_table(pageTableK)
|
|
.set_paged_attention_v_table(pageTableV)
|
|
.set_block_mask(blockMask)
|
|
.set_sink_token(sinkToken)
|
|
.set_descale_q(descaleQ)
|
|
.set_descale_k(descaleK)
|
|
.set_descale_v(descaleV)
|
|
.set_descale_s(descaleS)
|
|
.set_scale_s(scaleS)
|
|
.set_scale_o(scaleO);
|
|
|
|
EXPECT_EQ(attrs.get_bias(), attnMask);
|
|
EXPECT_EQ(attrs.get_attn_scale(), scale);
|
|
EXPECT_EQ(attrs.get_seq_len_q(), seqLenQ);
|
|
EXPECT_EQ(attrs.get_seq_len_kv(), seqLenKv);
|
|
EXPECT_EQ(attrs.get_seed(), seed);
|
|
EXPECT_EQ(attrs.get_offset(), offset);
|
|
EXPECT_EQ(attrs.get_dropout_mask(), dropoutMask);
|
|
EXPECT_EQ(attrs.get_dropout_scale(), dropoutScale);
|
|
EXPECT_EQ(attrs.get_page_table_k(), pageTableK);
|
|
EXPECT_EQ(attrs.get_page_table_v(), pageTableV);
|
|
EXPECT_EQ(attrs.get_block_mask(), blockMask);
|
|
EXPECT_EQ(attrs.get_sink_token(), sinkToken);
|
|
EXPECT_EQ(attrs.get_descale_q(), descaleQ);
|
|
EXPECT_EQ(attrs.get_descale_k(), descaleK);
|
|
EXPECT_EQ(attrs.get_descale_v(), descaleV);
|
|
EXPECT_EQ(attrs.get_descale_s(), descaleS);
|
|
EXPECT_EQ(attrs.get_scale_s(), scaleS);
|
|
EXPECT_EQ(attrs.get_scale_o(), scaleO);
|
|
}
|
|
|
|
TEST(TestSdpaAttributes, SetOutputTensors)
|
|
{
|
|
SdpaAttributes attrs;
|
|
|
|
auto stats = makeTensor(100);
|
|
auto max = makeTensor(101);
|
|
auto sumExp = makeTensor(102);
|
|
auto rngDump = makeTensor(103);
|
|
auto amaxS = makeTensor(104);
|
|
auto amaxO = makeTensor(105);
|
|
|
|
attrs.set_stats(stats)
|
|
.set_logit_max(max)
|
|
.set_score_sum_exp(sumExp)
|
|
.set_rng_dump(rngDump)
|
|
.set_amax_s(amaxS)
|
|
.set_amax_o(amaxO);
|
|
|
|
EXPECT_EQ(attrs.get_stats(), stats);
|
|
EXPECT_EQ(attrs.get_max(), max);
|
|
EXPECT_EQ(attrs.get_sum_exp(), sumExp);
|
|
EXPECT_EQ(attrs.get_rng_dump(), rngDump);
|
|
EXPECT_EQ(attrs.get_amax_s(), amaxS);
|
|
EXPECT_EQ(attrs.get_amax_o(), amaxO);
|
|
|
|
// Unrelated tensors remain null
|
|
EXPECT_EQ(attrs.get_o(), nullptr);
|
|
}
|
|
|
|
TEST(TestSdpaAttributes, SetDropout)
|
|
{
|
|
SdpaAttributes attrs;
|
|
|
|
auto seed = makeTensor(50);
|
|
auto offset = makeTensor(51);
|
|
attrs.set_dropout(0.1f, seed, offset);
|
|
|
|
ASSERT_TRUE(attrs.dropout_probability.has_value());
|
|
EXPECT_FLOAT_EQ(*attrs.dropout_probability, 0.1f);
|
|
EXPECT_EQ(attrs.get_seed(), seed);
|
|
EXPECT_EQ(attrs.get_offset(), offset);
|
|
}
|
|
|
|
TEST(TestSdpaAttributes, SetBooleanFlags)
|
|
{
|
|
SdpaAttributes attrs;
|
|
|
|
attrs.set_generate_stats(true);
|
|
ASSERT_TRUE(attrs.generate_stats.has_value());
|
|
EXPECT_TRUE(*attrs.generate_stats);
|
|
|
|
attrs.set_generate_stats(false);
|
|
ASSERT_TRUE(attrs.generate_stats.has_value());
|
|
EXPECT_FALSE(*attrs.generate_stats);
|
|
|
|
attrs.set_alibi_mask(true);
|
|
EXPECT_TRUE(attrs.alibi_mask);
|
|
|
|
attrs.set_padding_mask(true);
|
|
EXPECT_TRUE(attrs.padding_mask);
|
|
|
|
attrs.set_causal_mask(true);
|
|
EXPECT_TRUE(attrs.causal_mask);
|
|
|
|
attrs.set_causal_mask_bottom_right(true);
|
|
EXPECT_TRUE(attrs.causal_mask_bottom_right);
|
|
}
|
|
|
|
TEST(TestSdpaAttributes, SetScalarAttributes)
|
|
{
|
|
SdpaAttributes attrs;
|
|
|
|
attrs.set_attn_scale(0.5f);
|
|
ASSERT_TRUE(attrs.attn_scale_value.has_value());
|
|
EXPECT_FLOAT_EQ(*attrs.attn_scale_value, 0.5f);
|
|
|
|
attrs.set_diagonal_band_left_bound(-3);
|
|
ASSERT_TRUE(attrs.left_bound.has_value());
|
|
EXPECT_EQ(*attrs.left_bound, -3);
|
|
|
|
attrs.set_diagonal_band_right_bound(7);
|
|
ASSERT_TRUE(attrs.right_bound.has_value());
|
|
EXPECT_EQ(*attrs.right_bound, 7);
|
|
|
|
attrs.set_paged_attention_max_seq_len_kv(512);
|
|
ASSERT_TRUE(attrs.max_seq_len_kv.has_value());
|
|
EXPECT_EQ(*attrs.max_seq_len_kv, 512);
|
|
}
|
|
|
|
TEST(TestSdpaAttributes, SetEnumAttributes)
|
|
{
|
|
SdpaAttributes attrs;
|
|
|
|
attrs.set_diagonal_alignment(DiagonalAlignment::BOTTOM_RIGHT);
|
|
EXPECT_EQ(attrs.diagonal_alignment, DiagonalAlignment::BOTTOM_RIGHT);
|
|
|
|
attrs.set_mma_core_mode(DataType::HALF);
|
|
EXPECT_EQ(attrs.mma_core_mode, DataType::HALF);
|
|
|
|
attrs.set_implementation(AttentionImplementation::COMPOSITE);
|
|
EXPECT_EQ(attrs.implementation, AttentionImplementation::COMPOSITE);
|
|
|
|
attrs.set_implementation(AttentionImplementation::UNIFIED);
|
|
EXPECT_EQ(attrs.implementation, AttentionImplementation::UNIFIED);
|
|
}
|
|
|
|
//==============================================================================
|
|
// cuDNN source-compatibility setters (native surface)
|
|
//==============================================================================
|
|
|
|
TEST(TestSdpaAttributes, NativeSetAttnScaleFloatPopulatesValueNotTensor)
|
|
{
|
|
SdpaAttributes attrs;
|
|
attrs.set_attn_scale(0.25f);
|
|
|
|
ASSERT_TRUE(attrs.attn_scale_value.has_value());
|
|
EXPECT_FLOAT_EQ(*attrs.attn_scale_value, 0.25f);
|
|
// The float overload must not populate the Attn_scale tensor input.
|
|
EXPECT_EQ(attrs.get_attn_scale(), nullptr);
|
|
}
|
|
|
|
TEST(TestSdpaAttributes, NativeSetLogitMaxRoundTrip)
|
|
{
|
|
SdpaAttributes attrs;
|
|
auto logitMax = makeTensor(60);
|
|
attrs.set_logit_max(logitMax);
|
|
EXPECT_EQ(attrs.get_max(), logitMax);
|
|
}
|
|
|
|
TEST(TestSdpaAttributes, NativeSetScoreSumExpRoundTrip)
|
|
{
|
|
SdpaAttributes attrs;
|
|
auto sumExp = makeTensor(61);
|
|
attrs.set_score_sum_exp(sumExp);
|
|
EXPECT_EQ(attrs.get_sum_exp(), sumExp);
|
|
}
|
|
|
|
TEST(TestSdpaAttributes, NativeSetSlidingWindowLengthMapsToLeftBound)
|
|
{
|
|
SdpaAttributes attrs;
|
|
attrs.set_sliding_window_length(128);
|
|
ASSERT_TRUE(attrs.left_bound.has_value());
|
|
EXPECT_EQ(*attrs.left_bound, 128);
|
|
}
|
|
|
|
TEST(TestSdpaAttributes, NativePagedAttentionTablesRoundTrip)
|
|
{
|
|
SdpaAttributes attrs;
|
|
auto kTable = makeTensor(62);
|
|
auto vTable = makeTensor(63);
|
|
attrs.set_paged_attention_k_table(kTable);
|
|
attrs.set_paged_attention_v_table(vTable);
|
|
EXPECT_EQ(attrs.get_page_table_k(), kTable);
|
|
EXPECT_EQ(attrs.get_page_table_v(), vTable);
|
|
}
|
|
|
|
TEST(TestSdpaAttributes, NativeSetMmaCoreMode)
|
|
{
|
|
SdpaAttributes attrs;
|
|
EXPECT_EQ(attrs.mma_core_mode, DataType::NOT_SET);
|
|
attrs._set_mma_core_mode(DataType::HALF);
|
|
EXPECT_EQ(attrs.mma_core_mode, DataType::HALF);
|
|
}
|
|
|
|
TEST(TestSdpaAttributes, NativeFusedDropoutTwoArg)
|
|
{
|
|
SdpaAttributes attrs;
|
|
auto mask = makeTensor(64);
|
|
auto scale = makeTensor(65);
|
|
attrs.set_dropout(mask, scale);
|
|
EXPECT_EQ(attrs.get_dropout_mask(), mask);
|
|
EXPECT_EQ(attrs.get_dropout_scale(), scale);
|
|
}
|
|
|
|
TEST(TestSdpaAttributes, DeprecatedSetIsInferenceMapsToGenerateStats)
|
|
{
|
|
SdpaAttributes inferAttrs;
|
|
#if defined(__GNUC__) || defined(__clang__)
|
|
#pragma GCC diagnostic push
|
|
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
|
#endif
|
|
inferAttrs.set_is_inference(true);
|
|
#if defined(__GNUC__) || defined(__clang__)
|
|
#pragma GCC diagnostic pop
|
|
#endif
|
|
ASSERT_TRUE(inferAttrs.generate_stats.has_value());
|
|
EXPECT_FALSE(*inferAttrs.generate_stats);
|
|
|
|
SdpaAttributes trainAttrs;
|
|
#if defined(__GNUC__) || defined(__clang__)
|
|
#pragma GCC diagnostic push
|
|
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
|
#endif
|
|
trainAttrs.set_is_inference(false);
|
|
#if defined(__GNUC__) || defined(__clang__)
|
|
#pragma GCC diagnostic pop
|
|
#endif
|
|
ASSERT_TRUE(trainAttrs.generate_stats.has_value());
|
|
EXPECT_TRUE(*trainAttrs.generate_stats);
|
|
}
|
|
|
|
TEST(TestSdpaAttributes, NativeSetScoreModRecordsUnsupported)
|
|
{
|
|
SdpaAttributes attrs;
|
|
attrs.set_score_mod([](int) { return 0; });
|
|
|
|
ASSERT_TRUE(attrs.hasUnsupportedUsage());
|
|
EXPECT_NE(attrs.getUnsupportedReason().find("score modifier"), std::string::npos);
|
|
// Nothing applied: no stats-related output tensor was created as a side effect.
|
|
EXPECT_EQ(attrs.get_max(), nullptr);
|
|
EXPECT_EQ(attrs.get_sum_exp(), nullptr);
|
|
}
|
|
|
|
TEST(TestSdpaAttributes, NativeSetUnfuseFmaSetsHintNotUnsupported)
|
|
{
|
|
SdpaAttributes attrs;
|
|
attrs.set_unfuse_fma(true);
|
|
EXPECT_TRUE(attrs.unfuse_fma_hint);
|
|
EXPECT_FALSE(attrs.hasUnsupportedUsage());
|
|
|
|
attrs.set_unfuse_fma(false);
|
|
EXPECT_FALSE(attrs.unfuse_fma_hint);
|
|
EXPECT_FALSE(attrs.hasUnsupportedUsage());
|
|
}
|