Skip to content
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

Check whether array element is fully specialized #6000

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

kaizhangNV
Copy link
Contributor

close #5776

When we start specialize a "specialize" IR, we should
make sure all the elements are fully specialized, but
we miss checking the elements of an array. This change
will check the it.

close shader-slang#5776

When we start specialize a "specialize" IR, we should
make sure all the elements are fully specialized, but
we miss checking the elements of an array. This change
will check the it.
@kaizhangNV kaizhangNV requested a review from a team as a code owner January 3, 2025 21:46
@kaizhangNV kaizhangNV added the pr: non-breaking PRs without breaking changes label Jan 3, 2025
@@ -123,6 +123,12 @@ struct SpecializationContext
}
return false;
}
case kIROp_ArrayType:
{
auto array = as<IRArrayType>(inst);
Copy link
Collaborator

Choose a reason for hiding this comment

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

I wonder why this case is necessary.
If we have an type that is T.Differential[N], then it shall be encoded as IRArrayType(IRLookupWitness(w, "Differential"), N), and since IRLookupWitness has operand w, it won't appear in global scope, and therefore the IRArrayType itself won't appear directly in the global scope, and therefore it won't be reported as true by the default case logic.

Basically, if the element type is not fully specialized, then the array type itself shouldn't appear in the global scope. What IR are you seeing?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, this case this necessary, the unit test can reproduce the case.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I ask this question because in theory this shouldn’t happen, otherwise we will have the same issue for Ptr type and all other kinds of wrapper types.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If you dump the IR from the unit test, you will find out:

Ptr(specialize(%84, specialize(%150, Float, 1 : Int, %168)))	= get_field_addr(%callx5Fdata, %result)

this could result as:

	struct %GradInBuffer	: Type
	{
		field(%gradx5Fin, specialize(%82, lookupWitness( witness_table_t(%IDifferentiable)(Array(Float, 1)),   %37)))
	}

and finally this lookup table will give us

Array(lookupWitness(%168, %37), %N6)

here is the case I need to handle.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I see. In this case we do need to also handle all other opcodes by recursively checking their operands. Because we could have PtrType(lookupWitness()), or ArrayType(int, lookupwitness()), etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I verified that vector<float, N> seems not having this problem, but not sure about pointer or matrix, etc.

Copy link
Collaborator

Choose a reason for hiding this comment

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

We need to at least include ptrType, AttributedType, all the texture and buffer types, etc.

Basically everything needs to bottleneck through areAllOperandsFullySpecialized. But doing so can be slow, due to redundant checks.

We probably need to refactor the code so we sweep the global scope once and insert all fully specialized insts into a hash set, and run the deep check if an inst isn't in the hash set.

Copy link
Collaborator

Choose a reason for hiding this comment

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

vector<T.Differential, N> should have the same problem, no?

Copy link
Collaborator

Choose a reason for hiding this comment

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

the case should be handled by calling:

return areAllOperandsFullySpecialized(inst);

this is because for array<T, N>, we should not only verify T, but also N.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pr: non-breaking PRs without breaking changes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Invalid HLSL generated for bwd_diff function
2 participants