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
160 lines
5.6 KiB
C++
160 lines
5.6 KiB
C++
// Copyright Advanced Micro Devices, Inc., or its affiliates.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
#include <rocRoller/Expression.hpp>
|
|
|
|
#include <catch2/catch_test_macros.hpp>
|
|
#include <catch2/generators/catch_generators.hpp>
|
|
|
|
#include <common/SourceMatcher.hpp>
|
|
|
|
#include "TestContext.hpp"
|
|
|
|
using namespace rocRoller;
|
|
|
|
namespace SubDwordExpressionTest
|
|
{
|
|
TEST_CASE("code generation of basic sub-dword expressions", "[expression][codegen]")
|
|
{
|
|
auto context = TestContext::ForDefaultTarget();
|
|
|
|
SECTION("cannot get bitfield from a literal")
|
|
{
|
|
auto literal = Register::Value::Literal(42);
|
|
CHECK_THROWS_AS(literal->bitfield(8, 8), FatalError);
|
|
}
|
|
|
|
SECTION("bitOffset cannot be greater than the number of bits in a Value")
|
|
{
|
|
auto r = std::make_shared<Register::Value>(
|
|
context.get(), Register::Type::Vector, DataType::UInt32, 1);
|
|
CHECK_THROWS_AS(r->bitfield(32, 8), FatalError);
|
|
}
|
|
|
|
SECTION("bitwidth cannot be zero")
|
|
{
|
|
auto r = std::make_shared<Register::Value>(
|
|
context.get(), Register::Type::Vector, DataType::UInt32, 1);
|
|
CHECK_THROWS_AS(r->bitfield(8, 0), FatalError);
|
|
}
|
|
|
|
SECTION("bitwidth cannot be greater than the number of bits in a register")
|
|
{
|
|
auto r = std::make_shared<Register::Value>(
|
|
context.get(), Register::Type::Vector, DataType::UInt32, 1);
|
|
CHECK_THROWS_AS(r->bitfield(8, 32), FatalError);
|
|
}
|
|
|
|
SECTION("indices must refer to adjacent elements")
|
|
{
|
|
auto r = std::make_shared<Register::Value>(
|
|
context.get(), Register::Type::Vector, DataType::UInt8x4, 1);
|
|
CHECK_THROWS_AS(r->segment({0, 2}), FatalError);
|
|
}
|
|
|
|
SECTION("generate from expression with bitfields")
|
|
{
|
|
Register::ValuePtr dest;
|
|
|
|
auto ra = std::make_shared<Register::Value>(
|
|
context.get(), Register::Type::Vector, DataType::UInt32, 1);
|
|
ra->setName("ra");
|
|
ra->allocateNow();
|
|
|
|
auto rb = std::make_shared<Register::Value>(
|
|
context.get(), Register::Type::Vector, DataType::UInt32, 4);
|
|
rb->setName("rb");
|
|
rb->allocateNow();
|
|
|
|
auto rc = std::make_shared<Register::Value>(
|
|
context.get(), Register::Type::Vector, DataType::UInt32, 1);
|
|
rc->setName("rc");
|
|
rc->allocateNow();
|
|
|
|
auto raByte1 = ra->bitfield(8, 8);
|
|
auto rbReg2Byte1 = rb->bitfield(72, 16);
|
|
auto rcByte2 = rc->bitfield(16, 8);
|
|
|
|
auto a = raByte1->expression();
|
|
auto b = rbReg2Byte1->expression();
|
|
auto c = rcByte2->expression();
|
|
|
|
auto expr1 = a + b;
|
|
auto expr2 = expr1 * c;
|
|
|
|
context.get()->schedule(Expression::generate(dest, expr2, context.get()));
|
|
|
|
std::string expected = R"(
|
|
v_bfe_u32 v6, v0, 8, 8
|
|
v_bfe_u32 v7, v3, 8, 16
|
|
v_add_u32 v8, v6, v7
|
|
v_bfe_u32 v6, v5, 16, 8
|
|
v_mul_lo_u32 v7, v8, v6
|
|
)";
|
|
|
|
CHECK(NormalizedSource(context.output()) == NormalizedSource(expected));
|
|
}
|
|
}
|
|
|
|
TEST_CASE("code generation of sub-dword expressions of packed types", "[expression][codegen]")
|
|
{
|
|
|
|
auto dataType = GENERATE(DataType::Halfx2,
|
|
DataType::BFloat16x2,
|
|
DataType::FP8x4,
|
|
DataType::BF8x4,
|
|
DataType::Int8x4,
|
|
DataType::UInt8x4,
|
|
DataType::FP6x16,
|
|
DataType::BF6x16,
|
|
DataType::FP4x8);
|
|
SECTION("for each packed datatype")
|
|
{
|
|
auto info = DataTypeInfo::Get(dataType);
|
|
auto const index = (info.packing > 2) ? 2 : 1;
|
|
auto const bitWidth = info.elementBits / info.packing;
|
|
auto const bitOffset = index * bitWidth;
|
|
|
|
std::string codeForA, codeForB;
|
|
|
|
{
|
|
auto ctx = TestContext::ForDefaultTarget().get();
|
|
|
|
auto ra
|
|
= std::make_shared<Register::Value>(ctx, Register::Type::Vector, dataType, 1);
|
|
ra->setName("ra");
|
|
ra->allocateNow();
|
|
|
|
auto A = ra->bitfield(bitOffset, bitWidth)->expression();
|
|
|
|
Register::ValuePtr dest = std::make_shared<Register::Value>(
|
|
ctx, Register::Type::Vector, info.segmentVariableType.dataType, 1);
|
|
dest->allocateNow();
|
|
ctx->schedule(Expression::generate(dest, A, ctx));
|
|
|
|
codeForA = ctx->instructions()->toString();
|
|
}
|
|
|
|
{
|
|
auto ctx = TestContext::ForDefaultTarget().get();
|
|
|
|
auto rb
|
|
= std::make_shared<Register::Value>(ctx, Register::Type::Vector, dataType, 1);
|
|
rb->setName("rb");
|
|
rb->allocateNow();
|
|
|
|
auto B = rb->segment({index})->expression();
|
|
|
|
Register::ValuePtr dest = std::make_shared<Register::Value>(
|
|
ctx, Register::Type::Vector, info.segmentVariableType.dataType, 1);
|
|
dest->allocateNow();
|
|
ctx->schedule(Expression::generate(dest, B, ctx));
|
|
|
|
codeForB = ctx->instructions()->toString();
|
|
}
|
|
|
|
CHECK(NormalizedSource(codeForA) == NormalizedSource(codeForB));
|
|
}
|
|
}
|
|
}
|