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

Add vulkanMemoryModel #965

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

omarahmed1111
Copy link
Contributor

@omarahmed1111 omarahmed1111 commented Nov 28, 2022

PR Changes

  • Add vulkan-memory-model option to clspv
  • Generate VulkanMemoryModel shaders from clspv
  • Change memorySemantics for atomics on VulkanMemoryModel
  • Remove Coherent decoration on VulkanMemoryModel as it is not supported and replace it with relevant Available and Visible on read and write instructions

Related issue

This contribution is being made by Codeplay on behalf of Samsung.

Copy link
Collaborator

@alan-baker alan-baker left a comment

Choose a reason for hiding this comment

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

What about places where we insert spirv ops earlier in the flow? I feel like there may be cases of missed operands.

lib/Compiler.cpp Outdated
Comment on lines 754 to 757
if (clspv::Option::VulkanMemoryModel() &&
clspv::Option::SpvVersion() < clspv::Option::SPIRVVersion::SPIRV_1_5) {
llvm::errs() << "vulkan memory model is not supported for spirv versions "
"less that 1.5\n";
return -1;
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

The OpExtension is required prior to 1.5, but the functionality is available so this error can be dropped.

;

if (clspv::Option::VulkanMemoryModel()) {
addSPIRVInst<kExtensions>(spv::OpExtension, "SPV_KHR_vulkan_memory_model");
Copy link
Collaborator

Choose a reason for hiding this comment

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

The extension is only required if the version is < 1.5

@@ -6300,6 +6402,22 @@ bool SPIRVProducerPassImpl::isPointerUniform(Value *ptr) {
return uniformPointer;
}

bool SPIRVProducerPassImpl::isCoherentResource(Value *Ptr) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This seems like it will fail if the address calculation includes a phi, select, or function parameter. Previously those cases would all have been covered by the coherent decoration.

Comment on lines 3090 to 3091
addSPIRVInst<kCapabilities>(spv::OpCapability,
spv::CapabilityVulkanMemoryModelDeviceScopeKHR);
Copy link
Collaborator

Choose a reason for hiding this comment

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

It's not clear to me that we'd want device scope by default. I think QueueFamily is probably more appropriate. I'd suggest you take a look at clvk, but I expect it doesn't use different families.

This could be an extra command line option. Probably you'd want to introduce a helper function to get the right scope.

// CHECK-NOT: OpDecorate {{.*}} Coherent
// CHECK: [[uint:%[_a-zA-Z0-9]+]] = OpTypeInt 32 0
// CHECK: [[DEVICE_SCOPE:%[_a-zA-Z0-9]+]] = OpConstant [[uint]] 1
// CHECK: {{.*}} = OpLoad [[uint]] {{.*}} MakePointerVisible|NonPrivatePointer [[DEVICE_SCOPE]]
Copy link
Collaborator

Choose a reason for hiding this comment

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

What about the store in bar. If x is selected it should be coherent.

Comment on lines 3475 to 3484
const auto coherent =
unsigned(dyn_cast<ConstantInt>(
Call->getArgOperand(ClspvOperand::kResourceCoherent))
->getZExtValue());

if (clspv::Option::VulkanMemoryModel() && coherent == 1) {
Ops << (spv::MemoryAccessNonPrivatePointerMask |
spv::MemoryAccessMakePointerVisibleMask)
<< getSPIRVInt32Constant(spv::ScopeDevice);
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this is always unnecessary. These loads occur for samplers and images. Those handle loads come from UniformConstant and the handles themselves are never modified.


bool isCoherent = isCoherentResource(Call->getArgOperand(0));

if (clspv::Option::VulkanMemoryModel() && isCoherent) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't see any coverage of this in the tests. In fact, I'm not sure clspv can generate a coherent image right now. That is likely a bug since where this functionality wasn't updated for read_write images. It would need a change in descriptor allocation. Please either fix that or file an issue to address it.

Separately, this could be tested using IR only. Take a look at the tests in Spv1p4 for how to run SPIRVProducer only tests.


bool isCoherent = isCoherentResource(Call->getArgOperand(0));

if (clspv::Option::VulkanMemoryModel() && isCoherent) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same as above, please add unit test coverage.

@hernanponcedeleon
Copy link

Is there a plan to move forward with this PR?

I am working on a tool to verify SPIRV wrt the vulkan memory model and having clspv generate such kind of code would be super useful.

I wanted to test the code in this PR, but unfortunately it does not build for me.

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

Successfully merging this pull request may close these issues.

5 participants