Skip to content

Conversation

@joaosaffran
Copy link
Collaborator

@joaosaffran joaosaffran commented Nov 7, 2025

This patch is adding array operator long vector test to HLK. There are 3 scenarios that were identified when doing those tests:

  • Dynamic Element Access: the generated dxil uses a GEP instruction to calculate the correct address to access.
  • Static element access: the code uses extracelement and insertelement.

Closes: #7618

@damyanp
Copy link
Member

damyanp commented Nov 10, 2025

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@joaosaffran joaosaffran marked this pull request as ready for review November 14, 2025 22:18
Comment on lines 4194 to 4195
OutputVector[IndexList[i]] = Input1[IndexList[i]];
uint index = (uint)(IndexList[i]);
Copy link
Contributor

Choose a reason for hiding this comment

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

Did you mean this? Otherwise index is not used.

Suggested change
OutputVector[IndexList[i]] = Input1[IndexList[i]];
uint index = (uint)(IndexList[i]);
uint index = (uint)(IndexList[i]);
OutputVector[index] = Input1[index];

Comment on lines 4199 to 4200
uint Modifier = (uint) Input2[0];
uint IndexList[6] = {0 + Modifier, OutNum - 1 + Modifier, 1 + Modifier, OutNum - 2 + Modifier, OutNum / 2 + Modifier, OutNum / 2 + 1 + Modifier};
Copy link
Contributor

Choose a reason for hiding this comment

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

Typically you can use the name Zero for clarity. Also, if you add this Zero to the initialization of index below instead of the init list, the code would be a bit simpler, and equivalent. Then it's easier to compare IndexList between static/dynamic cases. If you had a common location, you could even share the code.

#if IS_UNARY_OP
#if TEST_ARRAY_OPERATOR_STATIC_ACCESS
uint IndexList[6] = {0, OutNum - 1, 1, OutNum - 2, OutNum / 2, OutNum / 2 + 1};
Copy link
Contributor

Choose a reason for hiding this comment

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

The count could be a constant, then used later instead of 6 for clarity.
Plus the IndexList could be const and formatted to make it easier to see the pattern.

Suggested change
uint IndexList[6] = {0, OutNum - 1, 1, OutNum - 2, OutNum / 2, OutNum / 2 + 1};
const uint IndexCount = 6;
const uint IndexList[IndexCount] = {
0, OutNum - 1,
1, OutNum - 2,
OutNum / 2, OutNum / 2 + 1
};

vector<OUT_TYPE, OutNum> OutputVector = 0;
uint End = min(OutNum, 6);
[unroll]for(uint i = 0; i < 6; ++i) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Loop uses 6 instead of End.

Suggested change
[unroll]for(uint i = 0; i < 6; ++i) {
[unroll]for(uint i = 0; i < End; ++i) {

HLSLBool_t() : Val(0) {}
HLSLBool_t(int32_t Val) : Val(Val) {}
HLSLBool_t(bool Val) : Val(Val) {}
explicit HLSLBool_t(float Val) : Val(Val) {}
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is adding this operator necessary? I don't see where it's used.


size_t IndexList[6] = {
0, VectorSize - 1, 1, VectorSize - 2, VectorSize / 2, VectorSize / 2 + 1};
for (size_t i = 0; i < 6; ++i)
Copy link
Contributor

Choose a reason for hiding this comment

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

I suppose if you're going to use min(VectorSize, 6) in HLSL for the loop count, you should do so here too. The only difference for vectors of length 3 to 5 is redundant operations on short vectors. If you use a vector length of 1 or 2, this will index out-of-bounds at VectorSize - 2 for length 1 and VectorSize / 2 + 1 for lengths 1 and 2.

Copy link
Member

@damyanp damyanp left a comment

Choose a reason for hiding this comment

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

I think this LGTM. It took me quite a while to try and figure out what these tests were doing. I wonder if there are some short, directed, comments that could help explain things?

@joaosaffran joaosaffran requested a review from tex3d November 17, 2025 20:48
@joaosaffran joaosaffran requested a review from damyanp November 17, 2025 21:30
Copy link
Contributor

@alsepkow alsepkow left a comment

Choose a reason for hiding this comment

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

LGTM. A few minor nits and a suggestion to avoid comparing a bunch of extra zeros.

size_t IndexList[IndexCount] = {
0, VectorSize - 1, 1, VectorSize - 2, VectorSize / 2, VectorSize / 2 + 1};
size_t End = std::min(VectorSize, IndexCount);
for (size_t i = 0; i < End; ++i)
Copy link
Contributor

Choose a reason for hiding this comment

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

casing, i should be I

#if TEST_ARRAY_OPERATOR
// This test case is for testing array operator [].
// It tests static array access with a compile time constant index array.
// And dynamic access, by introducing a runtime dependency that prevents the
Copy link
Contributor

Choose a reason for hiding this comment

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

very minor nit: Change 'And' to 'Or' to further clarify its one or the other at a time.

Suggested change
// And dynamic access, by introducing a runtime dependency that prevents the
// Or dynamic access, by introducing a runtime dependency that prevents the

uint End = min(OutNum, IndexCount);
#if DYNAMIC_ACCESS
uint Zero = (uint) Input2[0];
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: const

static std::vector<T> buildExpectedArrayAccess(const InputSets<T> &Inputs) {
const size_t VectorSize = Inputs[0].size();
std::vector<T> Expected;
Expected.resize(VectorSize);
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a reason you opted to zero an expected vector for the elements we aren't testing vs just setting the expected output size to 6?

You could avoid verifying a bunch of zeros by doing that. And if I recall correctly, all you will need to do is set the size of Expected to 6 here. The framework we built dispatches calls to other functions based on the number of elements in the Expected vector. And you can set OutNum in the shader to 6 with logic similar to how it's changed for the reduction op.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The test read and write at different indexes on which vector size. This is done to provide GEP instruction with index to access at the beginning, middle and end of vector. Forcing that to be 6 means we will need to store the that at I always, making the storing of elements to always be static.

I could make the IndexVector to be 0 to 5, but that reduces the scope where we test GEP calc for larger vectors

Copy link
Contributor

Choose a reason for hiding this comment

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

Great point! I wasn't considering the storing portion when I asked that. I wonder if a comment saying that is helpful for a little documentation on that being the intent.

Copy link
Contributor

@tex3d tex3d left a comment

Choose a reason for hiding this comment

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

LGTM!

@joaosaffran
Copy link
Collaborator Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@joaosaffran
Copy link
Collaborator Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

Copy link
Contributor

@alsepkow alsepkow left a comment

Choose a reason for hiding this comment

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

lgtm

@joaosaffran joaosaffran merged commit 10a4f01 into microsoft:main Nov 20, 2025
12 checks passed
@github-project-automation github-project-automation bot moved this from New to Done in HLSL Roadmap Nov 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Long Vector Execution Tests: Array Operator

4 participants