Skip to content

Update LongVector Execution tests to now use XML #7393

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 15 commits into
base: staging-sm6.9
Choose a base branch
from

Conversation

alsepkow
Copy link
Contributor

@alsepkow alsepkow commented Apr 28, 2025

This change is mainly focused on swapping to use the XML and statically defined values. Opting to stage this for review in smaller chunk while I iterate on adding the additional test cases.

  1. Update the LongVector exec tests to use the ShaderOpArithTable.xml TAEF table file for test entry points. This aligns with existing HLK tests.
  2. Some light code cleanup.
  3. Hard coded value sets in LongVectorTestData.h. Value sets give us a simple way to generate larger arrays from a smaller set of statically defined values. At a later point we can add logic to produce value sets at build time in this same header by consuming from a YAML file used in the offload test suite.

Copy link
Contributor

github-actions bot commented Apr 28, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@damyanp
Copy link
Member

damyanp commented Apr 29, 2025

I'm guessing that the submodule changes aren't meant to be a part of this change?

@alsepkow
Copy link
Contributor Author

I'm guessing that the submodule changes aren't meant to be a part of this change?

They are not. Accidentally grabbed those when I added the clang-format. Will fix.

LongVectorOpType_Clamp,
LongVectorOpType_Initialize,
LongVectorOpType_UnInitialized
enum LongVectorBinaryOpType {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just want to note here that for subsequent PR's that add more tests cases I'm going to split these enums up by category instead of unary vs binary.
HLSLOperators, trigonometric, math, etc. And then I'll also have some child classes that inherit from LongVectorTestConfig for these various categories to help split out the logic by category and avoid large switch statements.

if (Src== Ref) {
return true;
}
if (std::isnan(Src)) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if Src is not nan and Ref is nan?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question :). I coped the pattern from other functions here but I'm not sure what would happen. I'll debug that case to see and report back.

if (fsrc == fref)
// Compare as floats to handle when we have '0 == -0' which should be true
// but won't be true if we compare as uint16_t.
if (ConvertFloat16ToFloat32(fsrc) == ConvertFloat16ToFloat32(fref))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious, is there a ConvertUInt16ToFloat32 variant? Should that be created, or is the implementation of this conversion function identical to what would be done to convert uint16s?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That helper doesn't exist in this code. There is no float16 type in c++ (well, there actually is in c++23, but we don't use that yet). So float16 was implemented in a DX header in the Windows SDK.

So, this function name is a little confusing IMHO.

A little more context......
The two Convert* functions defined in HlslTestUtils reference their respective conversion functions in that DX SDK header. 'XMConvertHalfToFloat' and 'XMConvertFloatToHalf'. DirectX::PackedVector::HALF is aliased as a uint16_t in that header. And that uint16_t is used to store the bits of a 16-bit float. The DX header provides the functions to convert those bits into a floating-point value via the conversion functions, but because C++ had no float16 we use a float but the values are effectively clamped to the range of a 16 bit float.

The take-away is that we store and pass around float16 values as uint16_t's, but when it comes time to do comparisons we use the helper functions to interpret that uint16_t bit pattern as a float value.

Here's a link to the mentioned header if you're curious: DirectXPackedVector

{L"DataType", TableParameter::STRING, true},
{L"OpTypeEnum", TableParameter::STRING, true},
{L"InputValueSetName1", TableParameter::STRING, false},
{L"InputArgsName", TableParameter::STRING, false},
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Surprised BinaryOpParameters doesn't need something like InputArgsName.

Copy link
Contributor Author

@alsepkow alsepkow May 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will eventually. None of the binary intrinsics added up to this point have required input arguments. Although, there might be a better name to use here. The 'InputArgNames' are used for additional arguments like the min/max values in clamp. Distinct from the unary, binary, or ternary operands.

LongVectorOpTestDispatchByVectorSize<double>(OpType, Handler);
else
VERIFY_FAIL(
String().Format(L"DataType: %s is not recognized.", DataType.c_str()));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would this need to use %ls for wide strings or something of the sort?

}

LOG_ERROR_FMT_THROW(
L"RunShaderOpTest CallBack. Unexpected Resource Name: %S", Name);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is %ls needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Name is an explicit LPCSTR (long pointer to a char). And we're formatting that into a wide character string. So, in this case %S is what we want.

This gets confusing because there are functions in Windows that can compile down to either a narrow (char*) or wide (wchar*) depending on the environment (ANSI vs Unicode). The format specifier characters can have different meanings based on which variant they end up in. This is helpful for writing portable code where the type of the string (wide or narrow) and the type of the string expected by the function could change based on the environment. When the types could change you want to use %S and %s

This is why windows API functions have things like 'CreateFile', 'CreateFileA', and 'CreateFileW'.

%ls will interpret the argument as a wide character string in both printf and wprintf.
%s is a char* in printf, but a wchar_t* in wprintf
%S is a wchar_t* in printf, but a char* in wprintf

Strings are 'fun' :).

// on the seed value and are deterministic for any given seed.
std::mt19937 Generator;
inline bool DoValuesMatch(HLSLBool_t A, HLSLBool_t B, [[maybe_unused]] float Tolerance, [[maybe_unused]] LongVector::ValidationType ValidationType) {
return A == B;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why doesn't this use the Tolerance and ValidationType args? Is it possible to just remove those 2 args?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an artifact of the templated functions. Theres a compiler warning enabled as a failure for unused function parameters. If I modify the calling location to only include these arguments based on the type it doesn't really solve much. It's called by DoArraysMatch a few lines below.

If you have a cleaner suggestion I'm open!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not necessarily better, but this is another way I think to silence the warning:

DoValuesMatch(HLSLBool_t A, HLSLBool_t B, float, LongVector::ValidationType) {

template <typename T, std::size_t N>
void LogLongVector(const std::array<T, N> &Values, const std::wstring &Name) {
WEX::Logging::Log::Comment(
WEX::Common::String().Format(L"LongVector Name: %s", Name.c_str()));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

%ls?


template <typename T> void LogScalar(const T &Value, const std::wstring &Name) {
WEX::Logging::Log::Comment(
WEX::Common::String().Format(L"Scalar Name: %s", Name.c_str()));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

%ls?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: New
Development

Successfully merging this pull request may close these issues.

3 participants