/*
 * Copyright (c) 2025-2026 The Khronos Group Inc.
 * Copyright (C) 2025 Arm Limited.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 */

#include "layer_validation_tests.h"
#include "pipeline_helper.h"
#include "descriptor_helper.h"
#include "data_graph_objects.h"
#include "generated/pnext_chain_extraction.h"
#include "layers/utils/vk_struct_compare.h"
#include <vector>

class NegativeDataGraph : public DataGraphTest {};

TEST_F(NegativeDataGraph, CreateDataGraphPipelinesFeatureNotEnabled) {
    TEST_DESCRIPTION("Try to create a DataGraphPipeline when the dataGraph feature is not enabled");
    // add all the requirements of InitBasicDataGraph except dataGraph
    SetTargetApiVersion(VK_API_VERSION_1_4);
    AddRequiredExtensions(VK_ARM_TENSORS_EXTENSION_NAME);
    AddRequiredExtensions(VK_ARM_DATA_GRAPH_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::tensors);
    AddRequiredFeature(vkt::Feature::dataGraphShaderModule);
    AddRequiredFeature(vkt::Feature::shaderTensorAccess);
    AddRequiredFeature(vkt::Feature::vulkanMemoryModel);
    AddRequiredFeature(vkt::Feature::shaderInt8);
    RETURN_IF_SKIP(Init());

    // this error is generated by the spirv verification, which runs already in the constructor
    m_errorMonitor->SetAllowedFailureMsg("VUID-VkShaderModuleCreateInfo-pCode-08740");
    vkt::dg::DataGraphPipelineHelper pipeline(*this);

    m_errorMonitor->SetDesiredError("VUID-vkCreateDataGraphPipelinesARM-dataGraph-09760");
    pipeline.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, CreateDataGraphPipelinesDeferredOperationNotNull) {
    TEST_DESCRIPTION("Try to create a DataGraphPipeline when deferredOperation is not VK_NULL_HANDLE");
    AddRequiredExtensions(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME);
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline_helper(*this);
    VkDeferredOperationKHR deferred_operation;
    vk::CreateDeferredOperationKHR(*m_device, nullptr, &deferred_operation);
    VkPipeline pipeline;
    m_errorMonitor->SetDesiredError("VUID-vkCreateDataGraphPipelinesARM-deferredOperation-09761");
    vk::CreateDataGraphPipelinesARM(*m_device, deferred_operation, VK_NULL_HANDLE, 1, &pipeline_helper.pipeline_ci_, nullptr,
                                    &pipeline);
    m_errorMonitor->VerifyFound();
    vk::DestroyDeferredOperationKHR(*m_device, deferred_operation, nullptr);
}

TEST_F(NegativeDataGraph, CreateDataGraphPipelinesDeferredOperationWrongFlags) {
    TEST_DESCRIPTION("Try to create a DataGraphPipeline with deferredOperation and invalid pipeline flags");
    AddRequiredExtensions(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::pipelineCreationCacheControl);
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline_helper(*this);
    VkDeferredOperationKHR deferred_operation;
    vk::CreateDeferredOperationKHR(*m_device, nullptr, &deferred_operation);
    VkPipeline pipeline;

    // set the wrong flags in the pipeline create info
    pipeline_helper.pipeline_ci_.flags |= VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT;

    m_errorMonitor->SetDesiredError("VUID-vkCreateDataGraphPipelinesARM-deferredOperation-09916");
    // this is also triggered because deferredOperations currently MUST be NULL
    m_errorMonitor->SetDesiredError("VUID-vkCreateDataGraphPipelinesARM-deferredOperation-09761");
    vk::CreateDataGraphPipelinesARM(*m_device, deferred_operation, VK_NULL_HANDLE, 1, &pipeline_helper.pipeline_ci_, nullptr,
                                    &pipeline);
    m_errorMonitor->VerifyFound();
    vk::DestroyDeferredOperationKHR(*m_device, deferred_operation, nullptr);
}

TEST_F(NegativeDataGraph, CreateDataGraphPipelinesInvalidFlags) {
    TEST_DESCRIPTION("Try to create a DataGraphPipeline with invalid flags in create_info");
    RETURN_IF_SKIP(InitBasicDataGraph());

    auto set_info = [](vkt::dg::DataGraphPipelineHelper& pipeline) {
        pipeline.pipeline_ci_.flags = VK_PIPELINE_CREATE_2_VIEW_INDEX_FROM_DEVICE_INDEX_BIT_KHR;
    };
    vkt::dg::DataGraphPipelineHelper::OneshotTest(*this, set_info, 0, "VUID-VkDataGraphPipelineCreateInfoARM-flags-09764");
}

TEST_F(NegativeDataGraph, CreateDataGraphPipelinesNoProtectedAccessButFeatureNotEnabled) {
    TEST_DESCRIPTION(
        "Try to create a DataGraphPipeline where flags include VK_PIPELINE_CREATE_2_NO_PROTECTED_ACCESS_BIT_EXT but "
        "pipelineProtectedAccess is not enabled");
    RETURN_IF_SKIP(InitBasicDataGraph());

    auto set_info = [](vkt::dg::DataGraphPipelineHelper& pipeline) {
        pipeline.pipeline_ci_.flags = VK_PIPELINE_CREATE_2_NO_PROTECTED_ACCESS_BIT_EXT;
    };
    vkt::dg::DataGraphPipelineHelper::OneshotTest(*this, set_info, 0,
                                                  "VUID-VkDataGraphPipelineCreateInfoARM-pipelineProtectedAccess-09772");
}

TEST_F(NegativeDataGraph, CreateDataGraphPipelinesProtectedAccessOnlyButFeatureNotEnabled) {
    TEST_DESCRIPTION(
        "Try to create a DataGraphPipeline where flags include VK_PIPELINE_CREATE_2_PROTECTED_ACCESS_ONLY_BIT_EXT but "
        "pipelineProtectedAccess is not enabled");
    RETURN_IF_SKIP(InitBasicDataGraph());

    auto set_info = [](vkt::dg::DataGraphPipelineHelper& pipeline) {
        pipeline.pipeline_ci_.flags = VK_PIPELINE_CREATE_2_PROTECTED_ACCESS_ONLY_BIT_EXT;
    };
    vkt::dg::DataGraphPipelineHelper::OneshotTest(*this, set_info, 0,
                                                  "VUID-VkDataGraphPipelineCreateInfoARM-pipelineProtectedAccess-09772");
}

TEST_F(NegativeDataGraph, CreateDataGraphPipelinesBothProtectedAccessBits) {
    TEST_DESCRIPTION(
        "Try to create a DataGraphPipeline where flags include both VK_PIPELINE_CREATE_2_NO_PROTECTED_ACCESS_BIT_EXT and "
        "VK_PIPELINE_CREATE_2_PROTECTED_ACCESS_ONLY_BIT_EXT");
    AddRequiredExtensions(VK_EXT_PIPELINE_PROTECTED_ACCESS_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::pipelineProtectedAccess);
    RETURN_IF_SKIP(InitBasicDataGraph());

    auto set_info = [](vkt::dg::DataGraphPipelineHelper& pipeline) {
        pipeline.pipeline_ci_.flags =
            VK_PIPELINE_CREATE_2_NO_PROTECTED_ACCESS_BIT_EXT | VK_PIPELINE_CREATE_2_PROTECTED_ACCESS_ONLY_BIT_EXT;
    };
    vkt::dg::DataGraphPipelineHelper::OneshotTest(*this, set_info, 0, "VUID-VkDataGraphPipelineCreateInfoARM-flags-09773");
}

TEST_F(NegativeDataGraph, CreateDataGraphPipelinesStageCreationFeedbackCountNotZero) {
    TEST_DESCRIPTION(
        "Try to create a DataGraphPipeline where pNext contains a VkPipelineCreationFeedbackCreateInfo structure but the "
        "pipelineStageCreationFeedbackCount is not 0");
    RETURN_IF_SKIP(InitBasicDataGraph());

    VkPipelineCreationFeedback creation_feedback;
    VkPipelineCreationFeedbackCreateInfo creation_feedback_create_info = vku::InitStructHelper();
    creation_feedback_create_info.pPipelineCreationFeedback = &creation_feedback;
    creation_feedback_create_info.pipelineStageCreationFeedbackCount = 1;
    creation_feedback_create_info.pPipelineStageCreationFeedbacks = &creation_feedback;
    auto set_info = [&](vkt::dg::DataGraphPipelineHelper& pipeline) {
        pipeline.shader_module_ci_.pNext = &creation_feedback_create_info;
    };
    vkt::dg::DataGraphPipelineHelper::OneshotTest(*this, set_info, 0, "VUID-VkDataGraphPipelineCreateInfoARM-pNext-09804");
}

TEST_F(NegativeDataGraph, CreateDataGraphPipelinesPushConstantCountNotZero) {
    TEST_DESCRIPTION(
        "Try to create a DataGraphPipeline where the layout was created with a non-zero pushConstantRangeCount and non-NULL "
        "pushConstRange");
    RETURN_IF_SKIP(InitBasicDataGraph());

    std::vector<VkPushConstantRange> pcr = {{VK_SHADER_STAGE_ALL, 0, sizeof(uint32_t)}};
    auto set_info = [&](vkt::dg::DataGraphPipelineHelper& pipeline) { pipeline.CreatePipelineLayout(pcr); };
    vkt::dg::DataGraphPipelineHelper::OneshotTest(*this, set_info, 0, "VUID-VkDataGraphPipelineCreateInfoARM-layout-09767");
}

TEST_F(NegativeDataGraph, CreateDataGraphPipelinesUpdateAfterBindFeatureNotEnabled) {
    TEST_DESCRIPTION(
        "Try to create a DataGraphPipeline where the descriptorSetLayout used sets the BIND_AFTER_USE_BIT but the "
        "dataGraphUpdateAfterBind is not enabled");
    RETURN_IF_SKIP(InitBasicDataGraph());

    auto set_info = [&](vkt::dg::DataGraphPipelineHelper& pipeline) {
        pipeline.descriptor_set_.reset(new OneOffDescriptorSet(pipeline.device_, pipeline.descriptor_set_layout_bindings_,
                                                               VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT, nullptr,
                                                               VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT));
        pipeline.CreatePipelineLayout();
    };
    vkt::dg::DataGraphPipelineHelper::OneshotTest(*this, set_info, 0,
                                                  "VUID-VkDataGraphPipelineCreateInfoARM-dataGraphUpdateAfterBind-09768");
}

TEST_F(NegativeDataGraph, CreateDataGraphPipelinesMutableDescriptor) {
    TEST_DESCRIPTION("Try to create a DataGraphPipeline with a MUTABLE descriptor (not allowed in datagraph)");
    AddRequiredExtensions(VK_EXT_MUTABLE_DESCRIPTOR_TYPE_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::mutableDescriptorType);
    RETURN_IF_SKIP(InitBasicDataGraph());

    VkDescriptorType types[] = {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE};
    VkMutableDescriptorTypeListEXT mutable_descriptor_type_list = {1, types};

    VkMutableDescriptorTypeCreateInfoEXT mutable_descriptor_info = vku::InitStructHelper();
    mutable_descriptor_info.mutableDescriptorTypeListCount = 1;
    mutable_descriptor_info.pMutableDescriptorTypeLists = &mutable_descriptor_type_list;

    auto set_info = [&](vkt::dg::DataGraphPipelineHelper& pipeline) {
        pipeline.descriptor_set_layout_bindings_[0].descriptorType =
            VK_DESCRIPTOR_TYPE_MUTABLE_EXT;  // the pipeline sets this to tensor
        pipeline.descriptor_set_.reset(
            new OneOffDescriptorSet(pipeline.device_, pipeline.descriptor_set_layout_bindings_, 0, &mutable_descriptor_info));
        pipeline.CreatePipelineLayout();
    };
    vkt::dg::DataGraphPipelineHelper::OneshotTest(*this, set_info, 0, "VUID-VkDataGraphPipelineCreateInfoARM-pSetLayouts-09770");
}

TEST_F(NegativeDataGraph, CreateDataGraphPipelinesEarlyReturnFlagCacheControlNotEnabled) {
    TEST_DESCRIPTION(
        "Try to create a DataGraphPipeline when flags contains VK_PIPELINE_CREATE_2_EARLY_RETURN_ON_FAILURE_BIT_KHR but the "
        "pipelineCreationCacheControl feature is not enabled");
    RETURN_IF_SKIP(InitBasicDataGraph());

    auto set_info = [](vkt::dg::DataGraphPipelineHelper& pipeline) {
        pipeline.pipeline_ci_.flags = VK_PIPELINE_CREATE_2_EARLY_RETURN_ON_FAILURE_BIT_KHR;
    };
    vkt::dg::DataGraphPipelineHelper::OneshotTest(*this, set_info, 0,
                                                  "VUID-VkDataGraphPipelineCreateInfoARM-pipelineCreationCacheControl-09871");
}

TEST_F(NegativeDataGraph, CreateDataGraphPipelinesFailOnPipelineCompileFlagCacheControlNotEnabled) {
    TEST_DESCRIPTION(
        "Try to create a DataGraphPipeline when flags contains VK_PIPELINE_CREATE_2_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_KHR but "
        "the pipelineCreationCacheControl feature is not enabled");
    RETURN_IF_SKIP(InitBasicDataGraph());

    auto set_info = [](vkt::dg::DataGraphPipelineHelper& pipeline) {
        pipeline.pipeline_ci_.flags = VK_PIPELINE_CREATE_2_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_KHR;
    };
    vkt::dg::DataGraphPipelineHelper::OneshotTest(*this, set_info, 0,
                                                  "VUID-VkDataGraphPipelineCreateInfoARM-pipelineCreationCacheControl-09871");
}

TEST_F(NegativeDataGraph, CreateDataGraphPipelinesTypeMismatch) {
    TEST_DESCRIPTION(
        "Try to create a DataGraphPipeline where the descriptor slot in layout does not match the resource item used in the Shader "
        "Module");
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::HelperParameters params;
    params.desc_type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;  // should be tensor
    vkt::dg::DataGraphPipelineHelper pipeline(*this, params);
    // 2 tensors, 2 errors
    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineCreateInfoARM-layout-09769");
    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineCreateInfoARM-layout-09769");
    pipeline.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

static void InitDefaultComputePipeline(CreateComputePipelineHelper& pipeline, VkRenderFramework* framework) {
    std::vector<VkDescriptorSetLayoutBinding> bindings = {
        {0, VK_DESCRIPTOR_TYPE_TENSOR_ARM, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
        {1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}};

    pipeline.cs_ = VkShaderObj::CreateFromGLSL(framework, kMinimalTensorGlsl, VK_SHADER_STAGE_COMPUTE_BIT);
    pipeline.dsl_bindings_.resize(bindings.size());
    memcpy(pipeline.dsl_bindings_.data(), bindings.data(), bindings.size() * sizeof(VkDescriptorSetLayoutBinding));
    pipeline.CreateComputePipeline();
}

TEST_F(NegativeDataGraph, GetDataGraphPipelinePropertiesPipelineNotCreatedWithCreateDataGraphPipeline) {
    TEST_DESCRIPTION(
        "Try to get the datagraph pipeline properties for a pipeline not created with vkCreateDataGraphPipelinesARM (i.e. created "
        "with vkCreateComputePipeline)");
    RETURN_IF_SKIP(InitBasicDataGraph());

    CreateComputePipelineHelper pipeline(*m_device);
    InitDefaultComputePipeline(pipeline, this);
    VkDataGraphPipelineInfoARM pipeline_info = vku::InitStructHelper();
    pipeline_info.dataGraphPipeline = pipeline;

    // query with `pData` null, to get back the required `dataSize`. Enough to trigger the VUID
    VkDataGraphPipelinePropertyQueryResultARM query_result;
    query_result = vku::InitStructHelper();
    query_result.property = VK_DATA_GRAPH_PIPELINE_PROPERTY_CREATION_LOG_ARM;
    query_result.pData = nullptr;
    query_result.dataSize = 0;
    uint32_t prop_count = 1;
    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineInfoARM-dataGraphPipeline-09803");
    vk::GetDataGraphPipelinePropertiesARM(m_device->handle(), &pipeline_info, prop_count, &query_result);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, GetDataGraphPipelinePropertiesDuplicatedProperty) {
    TEST_DESCRIPTION("Duplicate property in datagraph pipeline properties request");
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    pipeline.CreateDataGraphPipeline();

    // query with `pData` null, to get back the required `dataSize`. Enough to trigger the VUID
    VkDataGraphPipelineInfoARM pipeline_info = vku::InitStructHelper();
    pipeline_info.dataGraphPipeline = pipeline;
    std::array<VkDataGraphPipelinePropertyQueryResultARM, 3> query_results;
    // properties 0 and 2 are the same: error
    query_results[0] = vku::InitStructHelper();
    query_results[0].property = VK_DATA_GRAPH_PIPELINE_PROPERTY_CREATION_LOG_ARM;
    query_results[0].pData = nullptr;
    query_results[0].dataSize = 0;
    query_results[1] = vku::InitStructHelper();
    query_results[1].property = VK_DATA_GRAPH_PIPELINE_PROPERTY_IDENTIFIER_ARM;
    query_results[1].pData = nullptr;
    query_results[1].dataSize = 0;
    query_results[2] = vku::InitStructHelper();
    query_results[2].property = VK_DATA_GRAPH_PIPELINE_PROPERTY_CREATION_LOG_ARM;
    query_results[2].pData = nullptr;
    query_results[2].dataSize = 0;

    m_errorMonitor->SetDesiredError("VUID-vkGetDataGraphPipelinePropertiesARM-pProperties-09889");
    vk::GetDataGraphPipelinePropertiesARM(m_device->handle(), &pipeline_info, query_results.size(), query_results.data());
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, SessionCreateInfoInvalidGraphPipeline) {
    TEST_DESCRIPTION(
        "Try to create a DataGraphPipelineSession where the dataGraphPipeline member of VkDataGraphPipelineSessionCreateInfoARM "
        "was "
        "not created by vkCreateDataGraphPipelinesARM");
    RETURN_IF_SKIP(InitBasicDataGraph());

    CreateComputePipelineHelper pipeline(*m_device);
    InitDefaultComputePipeline(pipeline, this);

    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
    session_ci.dataGraphPipeline = pipeline;

    VkDataGraphPipelineSessionARM session;
    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineSessionCreateInfoARM-dataGraphPipeline-09781");
    vk::CreateDataGraphPipelineSessionARM(*m_device, &session_ci, nullptr, &session);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, SessionCreateInfoProtectedMemoryFeatureNotEnabled) {
    TEST_DESCRIPTION(
        "Try to create a DataGraphPipelineSession where the flags member of VkDataGraphPipelineSessionCreateInfoARM contains "
        "VK_DATA_GRAPH_PIPELINE_SESSION_CREATE_PROTECTED_BIT_ARM but the protectedMemory feature is not enabled");
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    pipeline.CreateDataGraphPipeline();

    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
    session_ci.dataGraphPipeline = pipeline;
    session_ci.flags = VK_DATA_GRAPH_PIPELINE_SESSION_CREATE_PROTECTED_BIT_ARM;

    VkDataGraphPipelineSessionARM session;
    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineSessionCreateInfoARM-protectedMemory-09782");
    vk::CreateDataGraphPipelineSessionARM(*m_device, &session_ci, nullptr, &session);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, SessionGetMemoryRequirementsBindPointNotGottenPrior) {
    TEST_DESCRIPTION(
        "Try to get the memory requirements for a session without a prior call to "
        "vkGetDataGraphPipelineSessionBindPointRequirementsARM");
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    pipeline.CreateDataGraphPipeline();

    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
    session_ci.dataGraphPipeline = pipeline;

    vkt::DataGraphPipelineSession session(*m_device, session_ci, vkt::no_mem);

    VkDataGraphPipelineSessionMemoryRequirementsInfoARM session_mem_reqs = vku::InitStructHelper();
    session_mem_reqs.session = session;
    session_mem_reqs.bindPoint = VK_DATA_GRAPH_PIPELINE_SESSION_BIND_POINT_TRANSIENT_ARM;

    VkMemoryRequirements2 mem_reqs = vku::InitStructHelper();

    m_errorMonitor->SetDesiredError("VUID-vkGetDataGraphPipelineSessionMemoryRequirementsARM-bindPoint-09784");
    vk::GetDataGraphPipelineSessionMemoryRequirementsARM(*m_device, &session_mem_reqs, &mem_reqs);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, BindSessionTwice) {
    TEST_DESCRIPTION("Try to create a bind DataGraphPipelineSession on the same bindpoint twice");
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    pipeline.CreateDataGraphPipeline();

    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
    session_ci.dataGraphPipeline = pipeline;
    vkt::DataGraphPipelineSession session(*m_device, session_ci);

    std::vector<vkt::DeviceMemory> device_mem(session.BindPointsCount());
    session.AllocSessionMem(device_mem);

    auto session_bind_infos = InitSessionBindInfo(session, device_mem);
    vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data());

    // bind again to trigger error
    m_errorMonitor->SetDesiredError("VUID-VkBindDataGraphPipelineSessionMemoryInfoARM-session-09785");
    vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data());
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, BindSessionMemoryOffsetLargerThanSize) {
    TEST_DESCRIPTION(
        "Try to create a bind DataGraphPipelineSession to DeviceMemory at an offset which is larger than the allocated memory "
        "size");
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    pipeline.CreateDataGraphPipeline();

    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
    session_ci.dataGraphPipeline = pipeline;
    vkt::DataGraphPipelineSession session(*m_device, session_ci);

    std::vector<vkt::DeviceMemory> device_mem(session.BindPointsCount());
    session.AllocSessionMem(device_mem);

    auto session_bind_infos = InitSessionBindInfo(session, device_mem);
    auto& mem_req = session.MemReqs()[0];
    session_bind_infos[0].memoryOffset = mem_req.memoryRequirements.size + 2 * mem_req.memoryRequirements.alignment;

    m_errorMonitor->SetDesiredError("VUID-VkBindDataGraphPipelineSessionMemoryInfoARM-memoryOffset-09787");
    vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data());
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, BindSessionMemoryInvalidMemoryBits) {
    TEST_DESCRIPTION(
        "Try to create a bind DataGraphPipelineSession on a memory type who's memoryTypeBits is incompatible with the required "
        "bits");
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    pipeline.CreateDataGraphPipeline();

    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
    session_ci.dataGraphPipeline = pipeline;
    vkt::DataGraphPipelineSession session(*m_device, session_ci);

    std::vector<vkt::DeviceMemory> device_mem(session.BindPointsCount());
    auto& bind_point_reqs = session.BindPointReqs();
    auto& mem_reqs = session.MemReqs();
    for (uint32_t i = 0; i < bind_point_reqs.size(); i++) {
        if (bind_point_reqs[i].bindPointType != VK_DATA_GRAPH_PIPELINE_SESSION_BIND_POINT_TYPE_MEMORY_ARM) {
            continue;
        }

        VkMemoryAllocateInfo session_alloc_info = vku::InitStructHelper();
        session_alloc_info.allocationSize = mem_reqs[i].memoryRequirements.size;
        if (!m_device->Physical().SetMemoryType(~mem_reqs[i].memoryRequirements.memoryTypeBits, &session_alloc_info, 0)) {
            GTEST_SKIP() << "Memory type not found";
        }
        device_mem[i] = vkt::DeviceMemory(*m_device, session_alloc_info);
    }

    auto session_bind_infos = InitSessionBindInfo(session, device_mem);
    m_errorMonitor->SetDesiredError("VUID-VkBindDataGraphPipelineSessionMemoryInfoARM-memory-09788");
    vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data());
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, BindSessionMemoryInvalidOffsetAlignment) {
    TEST_DESCRIPTION(
        "Try to create a bind DataGraphPipelineSession at an offset which is not an integer multiple of the required alignment");
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    pipeline.CreateDataGraphPipeline();

    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
    session_ci.dataGraphPipeline = pipeline;
    vkt::DataGraphPipelineSession session(*m_device, session_ci);

    std::vector<vkt::DeviceMemory> device_mem(session.BindPointsCount());
    session.AllocSessionMem(device_mem, false, 2);

    auto session_bind_infos = InitSessionBindInfo(session, device_mem);
    auto& mem_reqs = session.MemReqs();
    session_bind_infos[0].memoryOffset = mem_reqs[0].memoryRequirements.alignment - 1;

    m_errorMonitor->SetDesiredError("VUID-VkBindDataGraphPipelineSessionMemoryInfoARM-memoryOffset-09789");
    vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data());
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, BindSessionMemoryTooSmall) {
    TEST_DESCRIPTION("Try to create a bind DataGraphPipelineSession to device memory which is too small");
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    pipeline.CreateDataGraphPipeline();

    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
    session_ci.dataGraphPipeline = pipeline;
    vkt::DataGraphPipelineSession session(*m_device, session_ci);

    std::vector<vkt::DeviceMemory> device_mem(session.BindPointsCount());
    session.AllocSessionMem(device_mem, false, 1, -1);
    auto session_bind_infos = InitSessionBindInfo(session, device_mem);

    m_errorMonitor->SetDesiredError("VUID-VkBindDataGraphPipelineSessionMemoryInfoARM-size-09790");
    vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data());
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, BindProtectedSessionToUnprotectedMemory) {
    TEST_DESCRIPTION("Try to bind a protected DataGraphPipelineSession to unprotected memory");
    AddRequiredFeature(vkt::Feature::protectedMemory);
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    pipeline.CreateDataGraphPipeline();

    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
    session_ci.flags = VK_DATA_GRAPH_PIPELINE_SESSION_CREATE_PROTECTED_BIT_ARM;
    session_ci.dataGraphPipeline = pipeline;
    vkt::DataGraphPipelineSession session(*m_device, session_ci);

    // allocate unprotected memory
    std::vector<vkt::DeviceMemory> device_mem(session.BindPointsCount());
    auto& mem_reqs = session.MemReqs();
    for (uint32_t i = 0; i < mem_reqs.size(); i++) {
        VkMemoryAllocateInfo session_alloc_info = vku::InitStructHelper();
        session_alloc_info.allocationSize = mem_reqs[i].memoryRequirements.size;
        auto memoryTypeBits = mem_reqs[i].memoryRequirements.memoryTypeBits;
        if (!m_device->Physical().SetMemoryType(memoryTypeBits, &session_alloc_info, 0, VK_MEMORY_PROPERTY_PROTECTED_BIT)) {
            GTEST_SKIP() << "Memory type not found";
        }
        device_mem[i] = vkt::DeviceMemory(*m_device, session_alloc_info);
    }

    auto session_bind_infos = InitSessionBindInfo(session, device_mem);
    m_errorMonitor->SetDesiredError("VUID-VkBindDataGraphPipelineSessionMemoryInfoARM-session-09791");
    // we are using a different memory type from the session, which also causes an error with memoryBits
    m_errorMonitor->SetAllowedFailureMsg("VUID-VkBindDataGraphPipelineSessionMemoryInfoARM-memory-09788");
    vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data());
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, BindUnprotectedSessionToProtectedMemory) {
    TEST_DESCRIPTION("Try to bind an unprotected DataGraphPipelineSession to protected memory");
    AddRequiredFeature(vkt::Feature::protectedMemory);
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    pipeline.CreateDataGraphPipeline();

    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
    session_ci.dataGraphPipeline = pipeline;
    vkt::DataGraphPipelineSession session(*m_device, session_ci);

    // allocate protected memory
    std::vector<vkt::DeviceMemory> device_mem(session.BindPointsCount());
    auto& mem_reqs = session.MemReqs();
    for (uint32_t i = 0; i < mem_reqs.size(); i++) {
        VkMemoryAllocateInfo session_alloc_info = vku::InitStructHelper();
        session_alloc_info.allocationSize = mem_reqs[i].memoryRequirements.size;
        auto memoryTypeBits = mem_reqs[i].memoryRequirements.memoryTypeBits;
        if (!m_device->Physical().SetMemoryType(memoryTypeBits, &session_alloc_info, VK_MEMORY_PROPERTY_PROTECTED_BIT)) {
            GTEST_SKIP() << "Memory type not found";
        }
        device_mem[i] = vkt::DeviceMemory(*m_device, session_alloc_info);
    }

    auto session_bind_infos = InitSessionBindInfo(session, device_mem);
    m_errorMonitor->SetDesiredError("VUID-VkBindDataGraphPipelineSessionMemoryInfoARM-session-09792");
    // we are using a different memory type from the session, which also causes an error with memoryBits
    m_errorMonitor->SetAllowedFailureMsg("VUID-VkBindDataGraphPipelineSessionMemoryInfoARM-memory-09788");
    vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data());
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, BindSessionObjectIndexTooLarge) {
    TEST_DESCRIPTION(
        "Try to bind a DataGraphPipelineSession when the resource index is larger than the numObjects for the bindPoint");
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    pipeline.CreateDataGraphPipeline();

    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
    session_ci.dataGraphPipeline = pipeline;
    vkt::DataGraphPipelineSession session(*m_device, session_ci);

    std::vector<vkt::DeviceMemory> device_mem(session.BindPointsCount());
    session.AllocSessionMem(device_mem);

    auto session_bind_infos = InitSessionBindInfo(session, device_mem);
    session_bind_infos[0].objectIndex = session.BindPointReqs()[0].numObjects + 1;

    m_errorMonitor->SetDesiredError("VUID-VkBindDataGraphPipelineSessionMemoryInfoARM-objectIndex-09805");
    vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data());
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, BindSessionObjectWrongBindPoint) {
    TEST_DESCRIPTION("Try to bind a DataGraphPipelineSession with the wrong bindpoint");
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    pipeline.CreateDataGraphPipeline();

    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
    session_ci.dataGraphPipeline = pipeline;
    vkt::DataGraphPipelineSession session(*m_device, session_ci);

    std::vector<vkt::DeviceMemory> device_mem(session.BindPointsCount());
    session.AllocSessionMem(device_mem);

    auto session_bind_infos = InitSessionBindInfo(session, device_mem);
    session_bind_infos[0].bindPoint =
        static_cast<VkDataGraphPipelineSessionBindPointARM>(VK_DATA_GRAPH_PIPELINE_SESSION_BIND_POINT_MAX_ENUM_ARM - 1);

    m_errorMonitor->SetDesiredError("VUID-VkBindDataGraphPipelineSessionMemoryInfoARM-bindPoint-09786");
    // VK_DATA_GRAPH_PIPELINE_SESSION_BIND_POINT_TRANSIENT_ARM is the only legal value for bindPoint, so whatever we
    // put in place of it, we also trigger this implicit check:
    m_errorMonitor->SetAllowedFailureMsg("VUID-VkBindDataGraphPipelineSessionMemoryInfoARM-bindPoint-parameter");
    vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data());
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, DestroySessionInUse) {
    TEST_DESCRIPTION("Try destroying a datagraph pipeline session while it is in use");
    SetTargetApiVersion(VK_API_VERSION_1_4);
    AddRequiredFeature(vkt::Feature::timelineSemaphore);
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    pipeline.CreateDataGraphPipeline();

    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
    session_ci.dataGraphPipeline = pipeline;
    vkt::DataGraphPipelineSession session(*m_device, session_ci);

    std::vector<vkt::DeviceMemory> device_mem(session.BindPointsCount());
    session.AllocSessionMem(device_mem);
    auto session_bind_infos = InitSessionBindInfo(session, device_mem);
    vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data());

    pipeline.descriptor_set_->WriteDescriptorTensorInfo(0, &pipeline.tensor_views_[0]->handle(), 0);
    pipeline.descriptor_set_->WriteDescriptorTensorInfo(1, &pipeline.tensor_views_[1]->handle(), 0);
    pipeline.descriptor_set_->UpdateDescriptorSets();

    m_command_buffer.Begin();
    vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline);
    vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline.pipeline_layout_, 0, 1,
                              &pipeline.descriptor_set_.get()->set_, 0, nullptr);
    vk::CmdDispatchDataGraphARM(m_command_buffer, session, nullptr);
    m_command_buffer.End();

    VkSemaphoreTypeCreateInfo sem_type = vku::InitStructHelper();
    sem_type.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE;
    sem_type.initialValue = 0;
    VkSemaphoreCreateInfo create_sem = vku::InitStructHelper(&sem_type);

    vkt::Semaphore sem(*m_device, create_sem);
    VkTimelineSemaphoreSubmitInfo timeline_info = vku::InitStructHelper();
    const uint64_t wait_value = 1;
    timeline_info.waitSemaphoreValueCount = 1;
    timeline_info.pWaitSemaphoreValues = &wait_value;

    VkPipelineStageFlags dst_stage_mask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;

    VkSubmitInfo submit_info = vku::InitStructHelper(&timeline_info);
    submit_info.waitSemaphoreCount = 1;
    submit_info.pWaitSemaphores = &sem.handle();
    submit_info.pWaitDstStageMask = &dst_stage_mask;
    submit_info.commandBufferCount = 1;
    submit_info.pCommandBuffers = &m_command_buffer.handle();

    vk::QueueSubmit(m_default_queue->handle(), 1, &submit_info, VK_NULL_HANDLE);

    m_errorMonitor->SetDesiredError("VUID-vkDestroyDataGraphPipelineSessionARM-session-09793");
    vk::DestroyDataGraphPipelineSessionARM(*m_device, session, nullptr);
    m_errorMonitor->VerifyFound();

    VkSemaphoreSignalInfo signal_sem = vku::InitStructHelper();
    signal_sem.semaphore = sem;
    signal_sem.value = 1;
    vk::SignalSemaphore(*m_device, &signal_sem);

    m_default_queue->Wait();
}

TEST_F(NegativeDataGraph, DestroySessionCreatedWithDestroyWithoutCallbacks) {
    TEST_DESCRIPTION("Try destroying without callbacks a datagraph pipeline session with callbacks");
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    pipeline.CreateDataGraphPipeline();

    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
    session_ci.dataGraphPipeline = pipeline;

    VkDataGraphPipelineSessionARM session;
    vk::CreateDataGraphPipelineSessionARM(*m_device, &session_ci, vkt::DefaultAllocator(), &session);

    m_errorMonitor->SetDesiredError("VUID-vkDestroyDataGraphPipelineSessionARM-session-09794");
    vk::DestroyDataGraphPipelineSessionARM(*m_device, session, nullptr);
    m_errorMonitor->VerifyFound();

    vk::DestroyDataGraphPipelineSessionARM(*m_device, session, vkt::DefaultAllocator());

    vk::CreateDataGraphPipelineSessionARM(*m_device, &session_ci, nullptr, &session);

    m_errorMonitor->SetDesiredError("VUID-vkDestroyDataGraphPipelineSessionARM-session-09795");
    vk::DestroyDataGraphPipelineSessionARM(*m_device, session, vkt::DefaultAllocator());
    m_errorMonitor->VerifyFound();

    vk::DestroyDataGraphPipelineSessionARM(*m_device, session, nullptr);
}

TEST_F(NegativeDataGraph, DestroySessionCreatedWithoutDestroyWithCallbacks) {
    TEST_DESCRIPTION("Try destroying with callbacks a datagraph pipeline session without callbacks");
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    pipeline.CreateDataGraphPipeline();

    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
    session_ci.dataGraphPipeline = pipeline;

    VkDataGraphPipelineSessionARM session;
    vk::CreateDataGraphPipelineSessionARM(*m_device, &session_ci, nullptr, &session);

    m_errorMonitor->SetDesiredError("VUID-vkDestroyDataGraphPipelineSessionARM-session-09795");
    vk::DestroyDataGraphPipelineSessionARM(*m_device, session, vkt::DefaultAllocator());
    m_errorMonitor->VerifyFound();

    vk::DestroyDataGraphPipelineSessionARM(*m_device, session, nullptr);
}

TEST_F(NegativeDataGraph, CmdDispatchPipelineNotBound) {
    TEST_DESCRIPTION(
        "Try to add a CmdDispatchDataGraphARM to a command buffer when the pipeline was not bound to "
        "VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM");
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    pipeline.CreateDataGraphPipeline();

    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
    session_ci.dataGraphPipeline = pipeline;
    vkt::DataGraphPipelineSession session(*m_device, session_ci);

    std::vector<vkt::DeviceMemory> device_mem(session.BindPointsCount());
    session.AllocSessionMem(device_mem);
    auto session_bind_infos = InitSessionBindInfo(session, device_mem);
    vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data());

    pipeline.descriptor_set_->WriteDescriptorTensorInfo(0, &pipeline.tensor_views_[0]->handle(), 0);
    pipeline.descriptor_set_->WriteDescriptorTensorInfo(1, &pipeline.tensor_views_[1]->handle(), 0);
    pipeline.descriptor_set_->UpdateDescriptorSets();

    m_command_buffer.Begin();
    vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline.pipeline_layout_, 0, 1,
                              &pipeline.descriptor_set_.get()->set_, 0, nullptr);
    m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchDataGraphARM-None-08606");
    vk::CmdDispatchDataGraphARM(m_command_buffer, session, nullptr);
    m_errorMonitor->VerifyFound();
    m_command_buffer.End();
}

TEST_F(NegativeDataGraph, CmdDispatchDescriptorSetNotBound) {
    TEST_DESCRIPTION("Try to dispatch a datagraph when the required descriptor set is not bound");
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    pipeline.CreateDataGraphPipeline();

    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
    session_ci.dataGraphPipeline = pipeline;
    vkt::DataGraphPipelineSession session(*m_device, session_ci);

    std::vector<vkt::DeviceMemory> device_mem(session.BindPointsCount());
    session.AllocSessionMem(device_mem);
    auto session_bind_infos = InitSessionBindInfo(session, device_mem);
    vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data());

    pipeline.descriptor_set_->WriteDescriptorTensorInfo(0, &pipeline.tensor_views_[0]->handle(), 0);
    pipeline.descriptor_set_->WriteDescriptorTensorInfo(1, &pipeline.tensor_views_[1]->handle(), 0);
    pipeline.descriptor_set_->UpdateDescriptorSets();

    m_command_buffer.Begin();
    vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline);
    m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchDataGraphARM-None-08600");
    vk::CmdDispatchDataGraphARM(m_command_buffer, session, nullptr);
    m_errorMonitor->VerifyFound();
    m_command_buffer.End();
}

TEST_F(NegativeDataGraph, CmdDispatchSessionNotBound) {
    TEST_DESCRIPTION("Try dispatching a graph command when not all required session resources have been bound");
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    pipeline.CreateDataGraphPipeline();

    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
    session_ci.dataGraphPipeline = pipeline;
    vkt::DataGraphPipelineSession session(*m_device, session_ci);

    pipeline.descriptor_set_->WriteDescriptorTensorInfo(0, &pipeline.tensor_views_[0]->handle(), 0);
    pipeline.descriptor_set_->WriteDescriptorTensorInfo(1, &pipeline.tensor_views_[1]->handle(), 0);
    pipeline.descriptor_set_->UpdateDescriptorSets();

    m_command_buffer.Begin();
    vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline);
    vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline.pipeline_layout_, 0, 1,
                              &pipeline.descriptor_set_.get()->set_, 0, nullptr);
    m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchDataGraphARM-session-09796");
    vk::CmdDispatchDataGraphARM(m_command_buffer, session, nullptr);
    m_errorMonitor->VerifyFound();
    m_command_buffer.End();
}

TEST_F(NegativeDataGraph, CmdDispatchSessionPartiallyBound) {
    TEST_DESCRIPTION("Dispatch a graph command buffer but bind only some of the required session resources");

    AddRequiredExtensions(VK_ARM_DATA_GRAPH_NEURAL_ACCELERATOR_STATISTICS_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::dataGraphNeuralAcceleratorStatistics);
    RETURN_IF_SKIP(InitBasicDataGraph());

    // Use NX statistics, so the session requires at least two bind points (transient + nx stats)
    // Execute twice, each time binding only one of the bind points

    for (auto bind_point : {VK_DATA_GRAPH_PIPELINE_SESSION_BIND_POINT_NEURAL_ACCELERATOR_STATISTICS_ARM,
                            VK_DATA_GRAPH_PIPELINE_SESSION_BIND_POINT_TRANSIENT_ARM}) {
        VkDataGraphPipelineNeuralStatisticsCreateInfoARM ne_stats_info = vku::InitStructHelper();
        ne_stats_info.allowNeuralStatistics = VK_TRUE;
        vkt::dg::DataGraphPipelineHelper pipeline(*this);
        vvl::PnextChainAdd(&pipeline.pipeline_ci_, &ne_stats_info);

        pipeline.CreateDataGraphPipeline();

        // include a SessionNeuralStatisticsCreateInfo to collect the neural stats
        VkDataGraphPipelineSessionNeuralStatisticsCreateInfoARM session_ne_stats_info = vku::InitStructHelper();
        session_ne_stats_info.mode = VkNeuralAcceleratorStatisticsModeARM::VK_NEURAL_ACCELERATOR_STATISTICS_MODE_STATISTICS0_ARM;
        VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper(&session_ne_stats_info);
        session_ci.dataGraphPipeline = pipeline;
        vkt::DataGraphPipelineSession session(*m_device, session_ci);

        std::vector<vkt::DeviceMemory> device_mem(session.BindPointsCount());
        session.AllocSessionMem(device_mem);

        std::vector<VkBindDataGraphPipelineSessionMemoryInfoARM> session_bind_infos;
        for (uint32_t i = 0; i < session.BindPointsCount(); i++) {
            VkDataGraphPipelineSessionBindPointRequirementARM bind_point_req = session.BindPointReqs()[i];

            if (bind_point_req.bindPoint != bind_point) {
                continue;
            }

            session_bind_infos.resize(bind_point_req.numObjects);

            for (uint32_t j = 0; j < bind_point_req.numObjects; j++) {
                session_bind_infos[j] = vku::InitStructHelper();
                session_bind_infos[j].session = session;
                session_bind_infos[j].memory = device_mem[i];
                session_bind_infos[j].bindPoint = bind_point_req.bindPoint;
                session_bind_infos[j].objectIndex = j;
            }

            break;
        }

        vk::BindDataGraphPipelineSessionMemoryARM(*m_device, static_cast<uint32_t>(session_bind_infos.size()),
                                                  session_bind_infos.data());

        pipeline.descriptor_set_->WriteDescriptorTensorInfo(0, &pipeline.tensor_views_[0]->handle(), 0);
        pipeline.descriptor_set_->WriteDescriptorTensorInfo(1, &pipeline.tensor_views_[1]->handle(), 0);
        pipeline.descriptor_set_->UpdateDescriptorSets();

        m_command_buffer.Begin();
        vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline);
        vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline.pipeline_layout_, 0, 1,
                                  &pipeline.descriptor_set_.get()->set_, 0, nullptr);
        VkDataGraphPipelineDispatchInfoARM disp_info = vku::InitStructHelper();
        m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchDataGraphARM-session-09796");
        vk::CmdDispatchDataGraphARM(m_command_buffer, session, &disp_info);
        m_errorMonitor->VerifyFound();
        m_command_buffer.End();
    };
}

TEST_F(NegativeDataGraph, CmdDispatchProtectedNoFaultUnsupportedUnprotectedCmdBufferProtectedTensor) {
    TEST_DESCRIPTION(
        "Try dispatching a datagraph with protected resources - bound pipeline tensors have VK_TENSOR_CREATE_PROTECTED_BIT_ARM set "
        "- to an unprotected command buffer when protectedNoFault is not supported");
    AddRequiredFeature(vkt::Feature::protectedMemory);
    RETURN_IF_SKIP(InitBasicDataGraph());

    VkPhysicalDeviceProtectedMemoryProperties protected_memory_properties = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(protected_memory_properties);
    if (protected_memory_properties.protectedNoFault) {
        GTEST_SKIP() << "protectedNoFault is supported";
    }

    vkt::dg::HelperParameters params;
    params.protected_tensors = true;
    vkt::dg::DataGraphPipelineHelper pipeline(*this, params);
    pipeline.CreateDataGraphPipeline();

    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
    session_ci.dataGraphPipeline = pipeline;
    vkt::DataGraphPipelineSession session(*m_device, session_ci);

    std::vector<vkt::DeviceMemory> device_mem(session.BindPointsCount());
    session.AllocSessionMem(device_mem);
    auto session_bind_infos = InitSessionBindInfo(session, device_mem);
    vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data());

    pipeline.descriptor_set_->WriteDescriptorTensorInfo(0, &pipeline.tensor_views_[0]->handle(), 0);
    pipeline.descriptor_set_->WriteDescriptorTensorInfo(1, &pipeline.tensor_views_[1]->handle(), 0);
    pipeline.descriptor_set_->UpdateDescriptorSets();

    m_command_buffer.Begin();
    vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline);
    vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline.pipeline_layout_, 0, 1,
                              &pipeline.descriptor_set_.get()->set_, 0, nullptr);
    m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchDataGraphARM-commandBuffer-09800");
    m_errorMonitor->SetDesiredError(
        "VUID-vkCmdDispatchDataGraphARM-commandBuffer-09800");  // We are using 2 protected resources in this unprotected command
                                                                // buffer and so need to log the error twice
    vk::CmdDispatchDataGraphARM(m_command_buffer, session, nullptr);
    m_errorMonitor->VerifyFound();
    m_command_buffer.End();
}

TEST_F(NegativeDataGraph, CmdDispatchProtectedNoFaultUnsupportedProtectedCmdBufferUnprotectedTensor) {
    TEST_DESCRIPTION(
        "Try dispatching a datagraph with unprotected resources to a protected command buffer - command buffer created with "
        "VK_COMMAND_POOL_CREATE_PROTECTED_BIT set -  when protectedNoFault is not supported");
    SetTargetApiVersion(VK_API_VERSION_1_4);
    AddRequiredExtensions(VK_ARM_TENSORS_EXTENSION_NAME);
    AddRequiredExtensions(VK_ARM_DATA_GRAPH_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::tensors);
    AddRequiredFeature(vkt::Feature::dataGraph);
    AddRequiredFeature(vkt::Feature::dataGraphShaderModule);
    AddRequiredFeature(vkt::Feature::shaderTensorAccess);
    AddRequiredFeature(vkt::Feature::vulkanMemoryModel);
    AddRequiredFeature(vkt::Feature::shaderInt8);
    AddRequiredFeature(vkt::Feature::protectedMemory);
    RETURN_IF_SKIP(InitFramework());
    RETURN_IF_SKIP(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_PROTECTED_BIT));

    VkPhysicalDeviceProtectedMemoryProperties protected_memory_properties = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(protected_memory_properties);
    if (protected_memory_properties.protectedNoFault) {
        GTEST_SKIP() << "protectedNoFault is supported";
    }

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    pipeline.CreateDataGraphPipeline();

    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
    session_ci.dataGraphPipeline = pipeline;
    vkt::DataGraphPipelineSession session(*m_device, session_ci);
    std::vector<vkt::DeviceMemory> device_mem(session.BindPointsCount());
    session.AllocSessionMem(device_mem);

    auto session_bind_infos = InitSessionBindInfo(session, device_mem);
    vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data());

    pipeline.descriptor_set_->WriteDescriptorTensorInfo(0, &pipeline.tensor_views_[0]->handle(), 0);
    pipeline.descriptor_set_->WriteDescriptorTensorInfo(1, &pipeline.tensor_views_[1]->handle(), 0);
    pipeline.descriptor_set_->UpdateDescriptorSets();

    m_command_buffer.Begin();
    vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline);
    vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline.pipeline_layout_, 0, 1,
                              &pipeline.descriptor_set_.get()->set_, 0, nullptr);
    m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchDataGraphARM-commandBuffer-09801");
    m_errorMonitor->SetDesiredError(
        "VUID-vkCmdDispatchDataGraphARM-commandBuffer-09801");  // We are using 2 unprotected resources in this protected command
                                                                // buffer and so need to log the error twice
    vk::CmdDispatchDataGraphARM(m_command_buffer, session, nullptr);
    m_errorMonitor->VerifyFound();
    m_command_buffer.End();
}

TEST_F(NegativeDataGraph, CmdDispatchInvalidDescriptorNoUpdate) {
    TEST_DESCRIPTION("Try dispatching a datagraph but the descriptor has not been updated");
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    pipeline.CreateDataGraphPipeline();

    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
    session_ci.dataGraphPipeline = pipeline;
    vkt::DataGraphPipelineSession session(*m_device, session_ci);
    auto& bind_point_reqs = session.BindPointReqs();
    std::vector<vkt::DeviceMemory> device_mem(bind_point_reqs.size());
    session.AllocSessionMem(device_mem);
    auto session_bind_infos = InitSessionBindInfo(session, device_mem);
    vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data());

    // update only 1 of 2 descriptors
    pipeline.descriptor_set_->WriteDescriptorTensorInfo(0, &pipeline.tensor_views_[0]->handle(), 0);
    pipeline.descriptor_set_->UpdateDescriptorSets();

    m_command_buffer.Begin();
    vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline);
    vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline.pipeline_layout_, 0, 1,
                              &pipeline.descriptor_set_.get()->set_, 0, nullptr);
    m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchDataGraphARM-None-08114");
    vk::CmdDispatchDataGraphARM(m_command_buffer, session, nullptr);
    m_errorMonitor->VerifyFound();
    m_command_buffer.End();
}

TEST_F(NegativeDataGraph, CmdDispatchInvalidDescriptorDeletedObject) {
    TEST_DESCRIPTION("Try dispatching a datagraph but the tensor or the view are destroyed before dispatch");
    RETURN_IF_SKIP(InitBasicDataGraph());

    // 2 runs: 1st time delete the tensor, 2nd the view, both make the descriptor invalid
    for (uint32_t i = 0; i < 2; i++) {
        vkt::dg::DataGraphPipelineHelper pipeline(*this);
        pipeline.CreateDataGraphPipeline();

        VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
        session_ci.dataGraphPipeline = pipeline;
        vkt::DataGraphPipelineSession session(*m_device, session_ci);

        auto& bind_point_reqs = session.BindPointReqs();
        std::vector<vkt::DeviceMemory> device_mem(bind_point_reqs.size());
        session.AllocSessionMem(device_mem);
        auto session_bind_infos = InitSessionBindInfo(session, device_mem);
        vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data());

        pipeline.descriptor_set_->WriteDescriptorTensorInfo(0, &pipeline.tensor_views_[0]->handle(), 0);
        pipeline.descriptor_set_->WriteDescriptorTensorInfo(1, &pipeline.tensor_views_[1]->handle(), 0);
        pipeline.descriptor_set_->UpdateDescriptorSets();

        // deleting either of these 2 invalidates the descriptor
        if (i == 0) {
            pipeline.tensors_[0]->Destroy();
        } else {
            pipeline.tensor_views_[0]->Destroy();
        }

        m_command_buffer.Begin();
        vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline);
        vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline.pipeline_layout_, 0, 1,
                                  &pipeline.descriptor_set_.get()->set_, 0, nullptr);
        m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchDataGraphARM-None-08114");
        vk::CmdDispatchDataGraphARM(m_command_buffer, session, nullptr);
        m_errorMonitor->VerifyFound();
        m_command_buffer.End();
    }
}

TEST_F(NegativeDataGraph, CmdDispatchInvalidDescriptorBufferBit) {
    TEST_DESCRIPTION(
        "Try dispatching a datagraph with VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT set, but using descriptor sets.");
    AddRequiredFeature(vkt::Feature::dataGraphDescriptorBuffer);
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    pipeline.pipeline_ci_.flags |= VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT;
    pipeline.CreateDataGraphPipeline();

    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
    session_ci.dataGraphPipeline = pipeline;
    vkt::DataGraphPipelineSession session(*m_device, session_ci);
    auto& bind_point_reqs = session.BindPointReqs();
    std::vector<vkt::DeviceMemory> device_mem(bind_point_reqs.size());
    session.AllocSessionMem(device_mem);
    auto session_bind_infos = InitSessionBindInfo(session, device_mem);
    vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data());

    pipeline.descriptor_set_->WriteDescriptorTensorInfo(0, &pipeline.tensor_views_[0]->handle(), 0);
    pipeline.descriptor_set_->WriteDescriptorTensorInfo(1, &pipeline.tensor_views_[1]->handle(), 0);
    pipeline.descriptor_set_->UpdateDescriptorSets();

    m_command_buffer.Begin();
    vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline);
    vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline.pipeline_layout_, 0, 1,
                              &pipeline.descriptor_set_.get()->set_, 0, nullptr);
    m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchDataGraphARM-None-08115");
    vk::CmdDispatchDataGraphARM(m_command_buffer, session, nullptr);
    m_errorMonitor->VerifyFound();
    m_command_buffer.End();
}

TEST_F(NegativeDataGraph, CmdDispatchMissingDescriptorBufferBit) {
    TEST_DESCRIPTION(
        "Try dispatching a datagraph with descriptor buffers but without the VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT.");
    SetTargetApiVersion(VK_API_VERSION_1_4);
    AddRequiredExtensions(VK_EXT_DESCRIPTOR_BUFFER_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::descriptorBuffer);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    AddRequiredFeature(vkt::Feature::dataGraphDescriptorBuffer);
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);

    // create a pipeline layout with the required flags
    VkDescriptorSetLayoutCreateInfo dslci = vku::InitStructHelper();
    dslci.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT;
    dslci.bindingCount = pipeline.descriptor_set_layout_bindings_.size();
    dslci.pBindings = pipeline.descriptor_set_layout_bindings_.data();

    vkt::DescriptorSetLayout dsl(*m_device, dslci);
    vkt::PipelineLayout pipeline_layout(*m_device, {&dsl});
    ASSERT_TRUE(pipeline_layout.initialized());

    // set layout for descriptor buffer, but not the flags
    // pipeline.pipeline_ci_.flags |= VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT;
    pipeline.pipeline_ci_.layout = pipeline_layout;
    pipeline.CreateDataGraphPipeline();

    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
    session_ci.dataGraphPipeline = pipeline;
    vkt::DataGraphPipelineSession session(*m_device, session_ci);
    auto& bind_point_reqs = session.BindPointReqs();
    std::vector<vkt::DeviceMemory> device_mem(bind_point_reqs.size());
    session.AllocSessionMem(device_mem);
    auto session_bind_infos = InitSessionBindInfo(session, device_mem);
    vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data());

    pipeline.descriptor_set_->WriteDescriptorTensorInfo(0, &pipeline.tensor_views_[0]->handle(), 0);
    pipeline.descriptor_set_->WriteDescriptorTensorInfo(1, &pipeline.tensor_views_[1]->handle(), 0);
    pipeline.descriptor_set_->UpdateDescriptorSets();

    m_command_buffer.Begin();
    vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline);

    vkt::Buffer buffer(*m_device, 4096, VK_BUFFER_USAGE_SAMPLER_DESCRIPTOR_BUFFER_BIT_EXT, vkt::device_address);
    VkDescriptorBufferBindingInfoEXT dbbi = vku::InitStructHelper();
    dbbi.address = buffer.Address();
    dbbi.usage = VK_BUFFER_USAGE_SAMPLER_DESCRIPTOR_BUFFER_BIT_EXT;

    vk::CmdBindDescriptorBuffersEXT(m_command_buffer, 1, &dbbi);

    uint32_t index = 0;
    VkDeviceSize offset = 0;
    vk::CmdSetDescriptorBufferOffsetsEXT(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline_layout, 0, 1, &index,
                                         &offset);

    m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchDataGraphARM-None-08117");
    m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchDataGraphARM-None-08600");
    vk::CmdDispatchDataGraphARM(m_command_buffer, session, nullptr);
    m_errorMonitor->VerifyFound();
    m_command_buffer.End();
}

TEST_F(NegativeDataGraph, ShaderModuleCreateInfoInvalidConstantID) {
    TEST_DESCRIPTION(
        "Try creating a datagraph pipeline where the VkDataGraphPipelineShaderModuleCreateInfoARM has a "
        "VkDataGraphPipelineConstantARM whose id member is not valid");
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    VkDataGraphPipelineConstantARM graph_pipeline_constant = vku::InitStructHelper();
    graph_pipeline_constant.id = 42;  // Arbitrary value not used by OpGraphConstantARM in shader module
    int constant_data = 42;
    graph_pipeline_constant.pConstantData = &constant_data;
    pipeline.shader_module_ci_.constantCount = 1;
    pipeline.shader_module_ci_.pConstants = &graph_pipeline_constant;
    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09921");
    pipeline.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, TensorSparsitySuppliedMissingDescription) {
    TEST_DESCRIPTION(
        "Try creating a datagraph pipeline with a tensor sparsity structure but missing a tensor description structure");
    RETURN_IF_SKIP(InitBasicDataGraph());

    const std::string& spirv_string = vkt::dg::DataGraphPipelineHelper::GetSpirvConstantDataGraph();

    vkt::dg::HelperParameters params;
    params.spirv_source = spirv_string.c_str();
    vkt::dg::DataGraphPipelineHelper pipeline(*this, params);

    VkDataGraphPipelineConstantTensorSemiStructuredSparsityInfoARM tensor_sparsity = vku::InitStructHelper();
    tensor_sparsity.groupSize = 1;

    // GetConstant puts the correct description in the pNext, by overwriting it we lose the description and cause the error
    VkDataGraphPipelineConstantARM constant = GetConstant();
    constant.pNext = &tensor_sparsity;
    pipeline.shader_module_ci_.constantCount = 1;
    pipeline.shader_module_ci_.pConstants = &constant;

    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineConstantARM-pNext-09775");
    // 9921 will also be triggered since we need a description for this
    // Graph Constant ID and we are intentionally not passing one
    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09921");
    pipeline.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, TensorSparsityDimensionTooLarge) {
    TEST_DESCRIPTION(
        "Try creating a datagraph pipeline with a tensor sparsity structure but the supplied dimension is larger than the "
        "dimensionCount in the tensor description supplied");
    RETURN_IF_SKIP(InitBasicDataGraph());

    const std::string& spirv_string = vkt::dg::DataGraphPipelineHelper::GetSpirvConstantDataGraph();

    vkt::dg::HelperParameters params;
    params.spirv_source = spirv_string.c_str();
    vkt::dg::DataGraphPipelineHelper pipeline(*this, params);

    VkTensorDescriptionARM constant_tensor_desc = DefaultConstantTensorDesc();

    VkDataGraphPipelineConstantTensorSemiStructuredSparsityInfoARM tensor_sparsity = vku::InitStructHelper();
    tensor_sparsity.groupSize = 1;
    tensor_sparsity.dimension = constant_tensor_desc.dimensionCount + 1;
    constant_tensor_desc.pNext = &tensor_sparsity;

    VkDataGraphPipelineConstantARM constant = GetConstant(constant_tensor_desc);
    pipeline.shader_module_ci_.constantCount = 1;
    pipeline.shader_module_ci_.pConstants = &constant;

    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineConstantARM-pNext-09776");
    pipeline.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, TensorSparsityDescriptionDimensionNotMultipleOfSparsityGroupSize) {
    TEST_DESCRIPTION(
        "Try creating a datagraph pipeline with a tensor sparsity structure but dimension[sparsity->dimension] is not a multiple "
        "of sparsity->groupSize");
    RETURN_IF_SKIP(InitBasicDataGraph());

    const std::string& spirv_string = vkt::dg::DataGraphPipelineHelper::GetSpirvConstantDataGraph();

    vkt::dg::HelperParameters params;
    params.spirv_source = spirv_string.c_str();
    vkt::dg::DataGraphPipelineHelper pipeline(*this, params);

    VkTensorDescriptionARM constant_tensor_desc = DefaultConstantTensorDesc();

    VkDataGraphPipelineConstantTensorSemiStructuredSparsityInfoARM tensor_sparsity = vku::InitStructHelper();
    tensor_sparsity.dimension = 2;
    int64_t dim_2 = constant_tensor_desc.pDimensions[tensor_sparsity.dimension];
    ASSERT_TRUE((dim_2 >= 1) && (dim_2 <= static_cast<int64_t>(UINT32_MAX)));
    tensor_sparsity.groupSize =
        static_cast<uint32_t>(dim_2 - 1);  // ensure that dim_2 (the sparsity dimension) is NOT a multiple of groupSize
    constant_tensor_desc.pNext = &tensor_sparsity;

    VkDataGraphPipelineConstantARM constant = GetConstant(constant_tensor_desc);
    pipeline.shader_module_ci_.constantCount = 1;
    pipeline.shader_module_ci_.pConstants = &constant;

    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineConstantARM-pNext-09777");
    pipeline.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, TensorSparsityDoubleDefinition) {
    TEST_DESCRIPTION("Try creating a datagraph pipeline with a tensor sparsity defined twice for the same dimension");
    RETURN_IF_SKIP(InitBasicDataGraph());

    const std::string& spirv_string = vkt::dg::DataGraphPipelineHelper::GetSpirvConstantDataGraph();

    vkt::dg::HelperParameters params;
    params.spirv_source = spirv_string.c_str();
    vkt::dg::DataGraphPipelineHelper pipeline(*this, params);

    VkTensorDescriptionARM constant_tensor_desc = DefaultConstantTensorDesc();

    // add 3 sparsity structures but 2 are for the same dimension -> ERROR
    VkDataGraphPipelineConstantTensorSemiStructuredSparsityInfoARM tensor_sparsity0 = vku::InitStructHelper();
    tensor_sparsity0.groupSize = 1;
    tensor_sparsity0.dimension = 2;
    constant_tensor_desc.pNext = &tensor_sparsity0;
    VkDataGraphPipelineConstantTensorSemiStructuredSparsityInfoARM tensor_sparsity1 = vku::InitStructHelper();
    tensor_sparsity1.groupSize = 2;
    tensor_sparsity1.dimension = 3;
    tensor_sparsity0.pNext = &tensor_sparsity1;
    VkDataGraphPipelineConstantTensorSemiStructuredSparsityInfoARM tensor_sparsity2 = vku::InitStructHelper();
    tensor_sparsity2.groupSize = 2;
    tensor_sparsity2.dimension = 2;
    tensor_sparsity1.pNext = &tensor_sparsity2;

    VkDataGraphPipelineConstantARM constant = GetConstant(constant_tensor_desc);
    pipeline.shader_module_ci_.constantCount = 1;
    pipeline.shader_module_ci_.pConstants = &constant;

    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineConstantARM-pNext-09870");
    pipeline.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, GraphConstantTensorWrongID) {
    TEST_DESCRIPTION("Try creating a datagraph pipeline with a constant that has an id different from the spirv definition");
    RETURN_IF_SKIP(InitBasicDataGraph());

    const std::string& spirv_string = vkt::dg::DataGraphPipelineHelper::GetSpirvConstantDataGraph();

    vkt::dg::HelperParameters params;
    params.spirv_source = spirv_string.c_str();
    vkt::dg::DataGraphPipelineHelper pipeline(*this, params);

    VkTensorDescriptionARM desc = DefaultConstantTensorDesc();
    VkDataGraphPipelineConstantARM constant = GetConstant(desc);
    constant.id = 42;
    pipeline.shader_module_ci_.constantCount = 1;
    pipeline.shader_module_ci_.pConstants = &constant;

    // 9921 triggered 2 times:
    // - Vulkan pConstants[x].id = 42 has no correspondence in the spirv code
    // - spirv OpGraphConstantARM has no correspondence in the Vulkan pConstants
    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09921");
    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09921");
    pipeline.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, GraphConstantTensorWrongRank) {
    TEST_DESCRIPTION(
        "Try creating a datagraph pipeline with a constant based on a tensor with rank different from the spirv definition");
    RETURN_IF_SKIP(InitBasicDataGraph());

    const std::string& spirv_string = vkt::dg::DataGraphPipelineHelper::GetSpirvConstantDataGraph();

    vkt::dg::HelperParameters params;
    params.spirv_source = spirv_string.c_str();
    vkt::dg::DataGraphPipelineHelper pipeline(*this, params);

    // define a tensor with rank 3, the spirv has rank 4
    VkTensorDescriptionARM desc = vku::InitStructHelper();
    const std::vector<int64_t> dimensions{1, 2, 4};
    desc.tiling = VK_TENSOR_TILING_LINEAR_ARM;
    desc.format = VK_FORMAT_R32_SINT;
    desc.dimensionCount = dimensions.size();
    desc.pDimensions = dimensions.data();
    desc.usage = VK_TENSOR_USAGE_DATA_GRAPH_BIT_ARM;

    VkDataGraphPipelineConstantARM constant = GetConstant(desc);
    pipeline.shader_module_ci_.constantCount = 1;
    pipeline.shader_module_ci_.pConstants = &constant;

    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09921");
    pipeline.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, GraphConstantTensorWrongDimensions) {
    TEST_DESCRIPTION(
        "Try creating a datagraph pipeline with a constant based on a tensor with dimensions different from the spirv definition");
    RETURN_IF_SKIP(InitBasicDataGraph());

    const std::string& spirv_string = vkt::dg::DataGraphPipelineHelper::GetSpirvConstantDataGraph();

    vkt::dg::HelperParameters params;
    params.spirv_source = spirv_string.c_str();
    vkt::dg::DataGraphPipelineHelper pipeline(*this, params);

    // dim[3] is different from the spirv (4)
    VkTensorDescriptionARM desc = vku::InitStructHelper();
    const std::vector<int64_t> dimensions{1, 2, 4, 1};  // dim[3] is 4 in the spirv
    desc.tiling = VK_TENSOR_TILING_LINEAR_ARM;
    desc.format = VK_FORMAT_R32_SINT;
    desc.dimensionCount = dimensions.size();
    desc.pDimensions = dimensions.data();
    desc.usage = VK_TENSOR_USAGE_DATA_GRAPH_BIT_ARM;

    VkDataGraphPipelineConstantARM constant = GetConstant(desc);
    pipeline.shader_module_ci_.constantCount = 1;
    pipeline.shader_module_ci_.pConstants = &constant;

    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09921");
    pipeline.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, GraphConstantTensorWrongFormat) {
    TEST_DESCRIPTION(
        "Try creating a datagraph pipeline with a constant based on a tensor with format different from the spirv definition");
    RETURN_IF_SKIP(InitBasicDataGraph());

    const std::string& spirv_string = vkt::dg::DataGraphPipelineHelper::GetSpirvConstantDataGraph();

    vkt::dg::HelperParameters params;
    params.spirv_source = spirv_string.c_str();

    // try a few different formats, different for bit width, float encoding and type
    // compatible VK_FORMAT_R32_SINT and VK_FORMAT_R32_UINT also included
    for (auto format : {VK_FORMAT_R32_UINT, VK_FORMAT_R32_SINT, VK_FORMAT_R8_SINT, VK_FORMAT_R8_BOOL_ARM, VK_FORMAT_R32_SFLOAT,
                        VK_FORMAT_R8_SFLOAT_FPENCODING_FLOAT8E4M3_ARM}) {
        vkt::dg::DataGraphPipelineHelper pipeline(*this, params);

        VkTensorDescriptionARM desc = DefaultConstantTensorDesc();
        desc.format = format;
        VkDataGraphPipelineConstantARM constant = GetConstant(desc);
        pipeline.shader_module_ci_.constantCount = 1;
        pipeline.shader_module_ci_.pConstants = &constant;

        // SPIRV is signless, so both VK_FORMAT_R32_SINT and VK_FORMAT_R32_UINT must not trigger the error
        if (format == VK_FORMAT_R32_SINT || format == VK_FORMAT_R32_UINT) {
            pipeline.CreateDataGraphPipeline();
        } else {
            m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09921");
            pipeline.CreateDataGraphPipeline();
            m_errorMonitor->VerifyFound();
        }
    }
}

TEST_F(NegativeDataGraph, GraphConstantTensorMissingDescription) {
    TEST_DESCRIPTION("Try creating a datagraph pipeline with a constant that is missing the tensor description");
    RETURN_IF_SKIP(InitBasicDataGraph());

    const std::string& spirv_string = vkt::dg::DataGraphPipelineHelper::GetSpirvConstantDataGraph();

    vkt::dg::HelperParameters params;
    params.spirv_source = spirv_string.c_str();
    vkt::dg::DataGraphPipelineHelper pipeline(*this, params);

    // GetConstant puts the correct description in the pNext, remove it to cause the error
    VkDataGraphPipelineConstantARM constant = GetConstant();
    constant.pNext = nullptr;
    pipeline.shader_module_ci_.constantCount = 1;
    pipeline.shader_module_ci_.pConstants = &constant;

    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09921");
    pipeline.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, GraphConstantTensorWrongTiling) {
    TEST_DESCRIPTION("Try creating a datagraph pipeline with a constant which corresponds to a tensor with the incorrect tiling");
    RETURN_IF_SKIP(InitBasicDataGraph());

    const std::string& spirv_string = vkt::dg::DataGraphPipelineHelper::GetSpirvConstantDataGraph();

    vkt::dg::HelperParameters params;
    params.spirv_source = spirv_string.c_str();
    vkt::dg::DataGraphPipelineHelper pipeline(*this, params);

    VkTensorDescriptionARM desc = DefaultConstantTensorDesc();
    desc.tiling = VK_TENSOR_TILING_OPTIMAL_ARM;  // should be VK_TENSOR_TILING_LINEAR_ARM
    VkDataGraphPipelineConstantARM constant = GetConstant(desc);
    pipeline.shader_module_ci_.constantCount = 1;
    pipeline.shader_module_ci_.pConstants = &constant;

    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineConstantARM-pNext-09917");
    pipeline.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, GraphConstantTensorMissingUsageFlags) {
    TEST_DESCRIPTION("Try creating a datagraph pipeline with a constant based on a tensor with the incorrect usage flags");
    RETURN_IF_SKIP(InitBasicDataGraph());

    const std::string& spirv_string = vkt::dg::DataGraphPipelineHelper::GetSpirvConstantDataGraph();

    vkt::dg::HelperParameters params;
    params.spirv_source = spirv_string.c_str();
    vkt::dg::DataGraphPipelineHelper pipeline(*this, params);

    VkTensorDescriptionARM desc = DefaultConstantTensorDesc();
    desc.usage = VK_TENSOR_USAGE_SHADER_BIT_ARM;  // should be VK_TENSOR_USAGE_DATA_GRAPH_BIT_ARM
    VkDataGraphPipelineConstantARM constant = GetConstant(desc);
    pipeline.shader_module_ci_.constantCount = 1;
    pipeline.shader_module_ci_.pConstants = &constant;

    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineConstantARM-id-09850");
    pipeline.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, ResourceTensorWrongDescriptorSet) {
    TEST_DESCRIPTION("Try creating a datagraph pipeline with a resource with descriptorSet different from the spirv definition");
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);

    // incorrect descriptorSet on one resource
    pipeline.resources_[0].descriptorSet = 42;

    // 9923 triggered 2 times:
    // - Vulkan pResourceInfos[x].descriptorSet = 42 has no correspondence in the spirv code
    // - spirv OpVariable has no correspondence in the Vulkan pResourceInfos
    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923");
    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923");
    pipeline.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, ResourceTensorWrongBinding) {
    TEST_DESCRIPTION("Try creating a datagraph pipeline with a resource with binding different from the spirv definition");
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);

    // incorrect binding on one resource
    pipeline.resources_[0].binding = 42;

    // 9923 triggered 2 times:
    // - Vulkan pResourceInfos[x].binding = 42 has no correspondence in the spirv code
    // - spirv OpVariable has no correspondence in the Vulkan pResourceInfos
    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923");
    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923");
    pipeline.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, ResourceTensorArrayElementNotZero) {
    TEST_DESCRIPTION("Try creating a datagraph pipeline with a resource with arrayElement greater than zero");
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);

    // incorrect arrayElement on one resource
    pipeline.resources_[0].arrayElement = 42;

    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923");
    pipeline.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, ResourceTensorWrongRank) {
    TEST_DESCRIPTION(
        "Try creating a datagraph pipeline with a resource based on a tensor with rank different from the spirv definition");
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);

    // define a tensor with rank 3, the spirv has rank 4
    auto* desc =
        const_cast<VkTensorDescriptionARM*>(vku::FindStructInPNextChain<VkTensorDescriptionARM>(pipeline.resources_[0].pNext));
    const std::vector<int64_t> dimensions{1, 4, 16};
    desc->dimensionCount = dimensions.size();
    desc->pDimensions = dimensions.data();

    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923");
    pipeline.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, ResourceTensorWrongDimensions) {
    TEST_DESCRIPTION(
        "Try creating a datagraph pipeline with a resource based on a tensor with dimensions different from the spirv definition");
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);

    // dim[3] is different from the spirv (4)
    auto* desc =
        const_cast<VkTensorDescriptionARM*>(vku::FindStructInPNextChain<VkTensorDescriptionARM>(pipeline.resources_[0].pNext));
    const std::vector<int64_t> dimensions{1, 8, 16, 1};  // dim[3] is 4 in the spirv
    desc->dimensionCount = dimensions.size();
    desc->pDimensions = dimensions.data();

    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923");
    pipeline.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, ResourceTensorWrongFormat) {
    TEST_DESCRIPTION(
        "Try creating a datagraph pipeline with a resource based on a tensor with format different from the spirv definition");
    RETURN_IF_SKIP(InitBasicDataGraph());

    // try a few different formats, different for bit width, type and float encoding
    // NOTE: VK_FORMAT_R8_SINT included as a sanity check: it is different only by sign from the actual format,
    // meaning it is compatible, and it must NOT trigger the VU
    for (auto format : {VK_FORMAT_R8_SINT, VK_FORMAT_R8_BOOL_ARM, VK_FORMAT_R32_SINT, VK_FORMAT_R32_SFLOAT,
                        VK_FORMAT_R8_SFLOAT_FPENCODING_FLOAT8E4M3_ARM}) {
        vkt::dg::DataGraphPipelineHelper pipeline(*this);

        auto* desc =
            const_cast<VkTensorDescriptionARM*>(vku::FindStructInPNextChain<VkTensorDescriptionARM>(pipeline.resources_[0].pNext));
        desc->format = format;

        if (format == VK_FORMAT_R8_SINT) {
            // INT check must not consider the sign, as required by TOSA function specifications
            pipeline.CreateDataGraphPipeline();
        } else {
            m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923");
            pipeline.CreateDataGraphPipeline();
            m_errorMonitor->VerifyFound();
        }
    }
}

TEST_F(NegativeDataGraph, ResourceTensorMissingDescription) {
    TEST_DESCRIPTION("Try creating a datagraph pipeline with a resource missing the tensor description");
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);

    // cut the connection to the tensor description
    pipeline.resources_[0].pNext = nullptr;

    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923");
    pipeline.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, ResourceTensorInvalidUsage) {
    TEST_DESCRIPTION(
        "Try creating a datagraph pipeline when the VkTensorDescriptionARM struct in the pNext of resources in resourceInfo do "
        "not have a valid Usage member");
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);

    // set an incorrect usage in the tensor description
    auto* desc =
        const_cast<VkTensorDescriptionARM*>(vku::FindStructInPNextChain<VkTensorDescriptionARM>(pipeline.resources_[0].pNext));
    desc->usage = VK_TENSOR_USAGE_SHADER_BIT_ARM;  // should be VK_TENSOR_USAGE_DATA_GRAPH_BIT_ARM
    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineResourceInfoARM-descriptorSet-09851");
    pipeline.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, ResourceInfoImageLayoutsNoUnifiedImageLayouts) {
    TEST_DESCRIPTION(
        "Try dispatching a datagraph with image resources without image layout info when unifiedImageLayouts is disabled");
    RETURN_IF_SKIP(InitBasicDataGraph(true));

    // Need to create a data graph with image resources instead of the usual tensors, so use optical flow.
    vkt::dg::OpticalFlowHelper optical_flow(*this);
    /* Fail to chain a VkDataGraphPipelineResourceInfoImageLayoutARM structure. Since the unifiedImageLayouts feature is not
     * enabled this is invalid usage. */
    optical_flow.dg_pipeline_.resources_[0].pNext = nullptr;
    optical_flow.CreateDataGraphPipeline();
    optical_flow.SetupImageDescriptors();

    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
    session_ci.dataGraphPipeline = optical_flow.dg_pipeline_;
    vkt::DataGraphPipelineSession session(*m_device, session_ci);
    std::vector<vkt::DeviceMemory> device_mem(session.BindPointReqs().size());
    session.AllocSessionMem(device_mem);
    std::vector<VkBindDataGraphPipelineSessionMemoryInfoARM> session_bind_infos =
        DataGraphTest::InitSessionBindInfo(session, device_mem);
    vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data());

    VkDataGraphPipelineOpticalFlowDispatchInfoARM optical_flow_di = vku::InitStructHelper();
    VkDataGraphPipelineDispatchInfoARM pipeline_di = vku::InitStructHelper(&optical_flow_di);

    m_command_buffer.Begin();
    vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, optical_flow.dg_pipeline_);
    vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, optical_flow.dg_pipeline_.pipeline_layout_,
                              0, 1, &optical_flow.dg_pipeline_.descriptor_set_.get()->set_, 0, nullptr);

    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineResourceInfoARM-descriptorSet-09962");
    vk::CmdDispatchDataGraphARM(m_command_buffer, session, &pipeline_di);
    m_errorMonitor->VerifyFound();

    m_command_buffer.End();
}

TEST_F(NegativeDataGraph, SessionGetMemoryRequirementsIndexTooLarge) {
    TEST_DESCRIPTION("Try to get the memory requirements for a session with an out-of-bounds value for objectIndex");
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    pipeline.CreateDataGraphPipeline();

    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
    session_ci.dataGraphPipeline = pipeline;

    vkt::DataGraphPipelineSession session(*m_device, session_ci, vkt::no_mem);

    uint32_t bind_point_req_count = 0;
    VkDataGraphPipelineSessionBindPointRequirementsInfoARM bind_point_req_info = vku::InitStructHelper();
    bind_point_req_info.session = session;
    vk::GetDataGraphPipelineSessionBindPointRequirementsARM(*m_device, &bind_point_req_info, &bind_point_req_count, nullptr);
    if (bind_point_req_count == 0) {
        GTEST_FAIL() << "No bind points, test incorrect. Possible causes: incorrect spirv, or inconsistency between spirv and "
                        "tensor/constant declarations\n";
    }
    std::vector<VkDataGraphPipelineSessionBindPointRequirementARM> bind_point_reqs(bind_point_req_count);
    for (auto& bp_req : bind_point_reqs) {
        bp_req = vku::InitStructHelper();
    }
    vk::GetDataGraphPipelineSessionBindPointRequirementsARM(*m_device, &bind_point_req_info, &bind_point_req_count,
                                                            bind_point_reqs.data());

    VkDataGraphPipelineSessionMemoryRequirementsInfoARM session_mem_reqs = vku::InitStructHelper();
    session_mem_reqs.session = session;
    session_mem_reqs.bindPoint = bind_point_reqs[0].bindPoint;
    session_mem_reqs.objectIndex = bind_point_reqs[0].numObjects;  // one over the limit

    VkMemoryRequirements2 mem_reqs = vku::InitStructHelper();

    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineSessionMemoryRequirementsInfoARM-objectIndex-09855");
    vk::GetDataGraphPipelineSessionMemoryRequirementsARM(*m_device, &session_mem_reqs, &mem_reqs);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, ShaderUsesSpecConstantsFeatureNotEnabled) {
    TEST_DESCRIPTION(
        "Try to create a datagraph with a VkSpecializationInfo used in the shader module when the feature is not enabled");
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    const VkSpecializationMapEntry entry = {
        0,                // id
        0,                // offset
        sizeof(uint32_t)  // size
    };
    uint32_t data = 0;
    const VkSpecializationInfo specialization_info = {
        1,
        &entry,
        1 * sizeof(uint32_t),
        &data,
    };
    pipeline.shader_module_ci_.pSpecializationInfo = &specialization_info;
    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineShaderModuleCreateInfoARM-dataGraphSpecializationConstants-09849");
    pipeline.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, ShaderSpirvUsesOpSpecFeatureNotEnabled) {
    TEST_DESCRIPTION(
        "Try to create a datagraph with a shader module which contains OpSpec commands when the feature is not enabled");
    RETURN_IF_SKIP(InitBasicDataGraph());

    // inject a dummy line in the spirv to trigger the error
    vkt::dg::ModifiableShaderParameters spirv_params;
    spirv_params.types = R"(%dummy_spec_constant = OpSpecConstant %uint 3)";
    const std::string& spirv_string = vkt::dg::DataGraphPipelineHelper::GetSpirvModifyableDataGraph(spirv_params);

    // ShaderModule in VkDataGraphPipelineShaderModuleCreateInfoARM::module
    {
        vkt::dg::HelperParameters params;
        params.spirv_source = spirv_string.c_str();
        vkt::dg::DataGraphPipelineHelper pipeline(*this, params);

        m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineShaderModuleCreateInfoARM-dataGraphSpecializationConstants-09849");
        pipeline.CreateDataGraphPipeline();
        m_errorMonitor->VerifyFound();
    }

    // ShaderModule in the pNext chain of VkDataGraphPipelineCreateInfoARM
    {
        spvtools::SpirvTools tools{SPV_ENV_UNIVERSAL_1_6};
        std::vector<uint32_t> spirv_binary;
        if (!tools.Assemble(spirv_string, &spirv_binary)) {
            Monitor().SetError("Failed to compile SPIRV shader module");
            return;
        }
        VkShaderModuleCreateInfo shader_module_create_info = vku::InitStructHelper();
        shader_module_create_info.codeSize = spirv_binary.size() * sizeof(uint32_t);
        shader_module_create_info.pCode = spirv_binary.data();

        vkt::dg::DataGraphPipelineHelper pipeline(*this);
        // the helper constructor adds the shader module as VkDataGraphPipelineShaderModuleCreateInfoARM::module, get rid of it
        pipeline.shader_module_ci_.module = VK_NULL_HANDLE;
        // add the shader info in pNext chain
        vvl::PnextChainAdd(&pipeline.pipeline_ci_, &shader_module_create_info);

        m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineShaderModuleCreateInfoARM-dataGraphSpecializationConstants-09849");
        pipeline.CreateDataGraphPipeline();
        m_errorMonitor->VerifyFound();
    }
}

TEST_F(NegativeDataGraph, DataGraphShaderModuleCreateInfoIncorrectName) {
    TEST_DESCRIPTION(
        "Create a datagraph pipeline where VkDataGraphPipelineShaderModuleCreateInfoARM::pName doesn't match the name in the spirv "
        "code.");
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    pipeline.shader_module_ci_.pName = "NOT_the_correct_name";
    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineShaderModuleCreateInfoARM-pName-09872");
    pipeline.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, DataGraphShaderModuleCreateInfoHasModuleAndShaderModuleCreateInfo) {
    TEST_DESCRIPTION(
        "Create a datagraph pipeline where VkDataGraphPipelineShaderModuleCreateInfoARM::module is not null, but it also includes "
        "a VkShaderModuleCreateInfo structure in its pNext chain.");
    RETURN_IF_SKIP(InitBasicDataGraph());

    // the pipeline constructor adds the shader module in the "normal" way, as VkDataGraphPipelineShaderModuleCreateInfoARM::module
    vkt::dg::DataGraphPipelineHelper pipeline(*this);

    // also add the same ShaderModule in the pNext chain
    spvtools::SpirvTools tools{SPV_ENV_UNIVERSAL_1_6};
    const std::string& spirv_source = vkt::dg::DataGraphPipelineHelper::GetSpirvBasicDataGraph();
    std::vector<uint32_t> spirv_binary;
    if (!tools.Assemble(spirv_source, &spirv_binary)) {
        Monitor().SetError("Failed to compile SPIRV shader module");
        return;
    }
    VkShaderModuleCreateInfo shader_module_create_info = vku::InitStructHelper();
    shader_module_create_info.codeSize = spirv_binary.size() * sizeof(uint32_t);
    shader_module_create_info.pCode = spirv_binary.data();

    // add the shader info in VkDataGraphPipelineShaderModuleCreateInfoARM::pNext
    {
        pipeline.shader_module_ci_.pNext = &shader_module_create_info;

        m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineShaderModuleCreateInfoARM-pNext-09873");
        pipeline.CreateDataGraphPipeline();
        m_errorMonitor->VerifyFound();
    }

    // add the shader info in VkDataGraphPipelineCreateInfoARM::pNext
    {
        // rearrange the pNext chain, we should get the same result
        pipeline.shader_module_ci_.pNext = nullptr;
        pipeline.pipeline_ci_.pNext = &shader_module_create_info;
        shader_module_create_info.pNext = &pipeline.shader_module_ci_;

        m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineShaderModuleCreateInfoARM-pNext-09873");
        pipeline.CreateDataGraphPipeline();
        m_errorMonitor->VerifyFound();
    }
}

TEST_F(NegativeDataGraph, DataGraphShaderModuleCreateInfoInvalidModule) {
    TEST_DESCRIPTION(
        "Create a datagraph pipeline where VkDataGraphPipelineShaderModuleCreateInfoARM::module is NULL and there is no "
        "VkShaderModuleCreateInfo structure in its pNext chain.");
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    pipeline.shader_module_ci_.module = VK_NULL_HANDLE;
    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineShaderModuleCreateInfoARM-pNext-09874");
    pipeline.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, DataGraphShaderModuleCreateInfoDescriptorBufferNoFeature) {
    TEST_DESCRIPTION("Create a datagraph pipeline with the flag for descriptor buffers but the feature is not enabled.");
    // NOT adding vkt::Feature::dataGraphDescriptorBuffer
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    pipeline.pipeline_ci_.flags |= VK_PIPELINE_CREATE_2_DESCRIPTOR_BUFFER_BIT_EXT;
    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineCreateInfoARM-dataGraphDescriptorBuffer-09885");
    pipeline.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, DataGraphShaderModuleNoFeature) {
    TEST_DESCRIPTION("Try to create a datagraph without the dataGraphShaderModule feature.");
    // add all the requirements of InitBasicDataGraph except dataGraphShaderModule
    SetTargetApiVersion(VK_API_VERSION_1_4);
    AddRequiredExtensions(VK_ARM_TENSORS_EXTENSION_NAME);
    AddRequiredExtensions(VK_ARM_DATA_GRAPH_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::tensors);
    AddRequiredFeature(vkt::Feature::dataGraph);
    AddRequiredFeature(vkt::Feature::shaderTensorAccess);
    AddRequiredFeature(vkt::Feature::vulkanMemoryModel);
    AddRequiredFeature(vkt::Feature::shaderInt8);
    RETURN_IF_SKIP(Init());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineCreateInfoARM-dataGraphShaderModule-09886");
    pipeline.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, DataGraphWrongCreateInfoStructs) {
    TEST_DESCRIPTION("None or too many of the required info structures passed in pNext of vkCreateDataGraphPipelinesARM.");
    AddRequiredFeature(vkt::Feature::pipelineCreationCacheControl);
    RETURN_IF_SKIP(InitBasicDataGraph());

    // none of the structs included
    {
        vkt::dg::DataGraphPipelineHelper pipeline(*this);
        pipeline.pipeline_ci_.pNext = nullptr;
        m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineCreateInfoARM-pNext-09977");
        pipeline.CreateDataGraphPipeline();
        m_errorMonitor->VerifyFound();
    }

    // too many of the structs included
    {
        vkt::dg::DataGraphPipelineHelper pipeline(*this);
        // a VkDataGraphPipelineShaderModuleCreateInfoARM is already included by the helper, add also
        // a VkDataGraphPipelineIdentifierCreateInfoARM (can't have both)
        VkDataGraphPipelineIdentifierCreateInfoARM pipeline_id = vku::InitStructHelper();
        constexpr uint8_t dummy_data = 1;
        pipeline_id.identifierSize = 1;
        pipeline_id.pIdentifier = &dummy_data;
        vvl::PnextChainAdd(&pipeline.pipeline_ci_, &pipeline_id);
        pipeline.pipeline_ci_.flags |= VK_PIPELINE_CREATE_2_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;
        pipeline.pipeline_ci_.pResourceInfos = nullptr;
        pipeline.pipeline_ci_.resourceInfoCount = 0;

        VkPipelineCache pipeline_cache;
        VkPipelineCacheCreateInfo cache_create_info = vku::InitStructHelper();
        cache_create_info.initialDataSize = 0;
        VkResult err = vk::CreatePipelineCache(device(), &cache_create_info, nullptr, &pipeline_cache);
        ASSERT_EQ(VK_SUCCESS, err);

        m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineCreateInfoARM-pNext-09977");
        pipeline.CreateDataGraphPipeline(pipeline_cache);
        m_errorMonitor->VerifyFound();
        vk::DestroyPipelineCache(device(), pipeline_cache, nullptr);
    }
}

TEST_F(NegativeDataGraph, DataGraphShaderModuleSpirvArrayWrongSize) {
    TEST_DESCRIPTION("Create a datagraph with Vulkan resource arrays not matching the spirv.");
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::HelperParameters params;
    params.graph_variant = vkt::dg::GraphVariant::AddTensorArraySpirv;
    vkt::dg::DataGraphPipelineHelper pipeline(*this, params);

    // override the DataGraphPipelineHelper constructor: set the wrong array length and recreate the layout
    pipeline.descriptor_set_layout_bindings_[0].descriptorCount = 1;  // ERROR 9934: the spirv code defines an array of 2
    pipeline.descriptor_set_.reset(new OneOffDescriptorSet(pipeline.device_, pipeline.descriptor_set_layout_bindings_));
    pipeline.CreatePipelineLayout();

    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineCreateInfoARM-layout-09934");
    // tensor arrays also triggers VU 9923s (2 tensors, 2 errors)
    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923");
    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923");
    pipeline.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, DataGraphShaderModuleSpirvRuntimeArraySizeZero) {
    TEST_DESCRIPTION("Create a datagraph where a Vulkan resource is a runtime array with count 0.");
    SetTargetApiVersion(VK_API_VERSION_1_4);
    AddRequiredFeature(vkt::Feature::runtimeDescriptorArray);
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::HelperParameters params;
    params.graph_variant = vkt::dg::GraphVariant::AddRuntimeTensorArraySpirv;
    vkt::dg::DataGraphPipelineHelper pipeline(*this, params);

    // override the DataGraphPipelineHelper constructor: set the wrong array length and recreate the layout
    pipeline.descriptor_set_layout_bindings_[0].descriptorCount = 0;  // ERROR 9934: OpTypeRuntimeArray needs > 0
    pipeline.descriptor_set_.reset(new OneOffDescriptorSet(pipeline.device_, pipeline.descriptor_set_layout_bindings_));
    pipeline.CreatePipelineLayout();

    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineCreateInfoARM-layout-09934");
    // tensor arrays also triggers VU 9923s (2 tensors, 2 errors)
    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923");
    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923");
    pipeline.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, DataGraphTensorNoShape) {
    TEST_DESCRIPTION("Create a datagraph using tensors without shape.");
    RETURN_IF_SKIP(InitBasicDataGraph());

    // input and output variables are tensors without a shape, rank only (%tensor_r4)
    static const char* tensorNoShapeDataGraphSpirv = R"spirv(
                            OpCapability GraphARM
                            OpCapability TensorsARM
                            OpCapability Int8
                            OpCapability Shader
                            OpCapability VulkanMemoryModel
                            OpCapability Matrix
                            OpExtension "SPV_ARM_graph"
                            OpExtension "SPV_ARM_tensors"
                            OpExtension "SPV_KHR_vulkan_memory_model"
                    %tosa = OpExtInstImport "TOSA.001000.1"
                            OpMemoryModel Logical Vulkan
                            OpName %main_arg_0 "main_arg_0"
                            OpName %main_res_0 "main_res_0"
                            OpDecorate %main_arg_0 Binding 0
                            OpDecorate %main_arg_0 DescriptorSet 0
                            OpDecorate %main_res_0 Binding 1
                            OpDecorate %main_res_0 DescriptorSet 0
                      %i8 = OpTypeInt 8 0
                     %i32 = OpTypeInt 32 0
                   %i32_0 = OpConstant %i32 0
                   %i32_1 = OpConstant %i32 1
                   %i32_2 = OpConstant %i32 2
                   %i32_4 = OpConstant %i32 4
               %i32_arr_1 = OpTypeArray %i32 %i32_1
               %i32_arr_4 = OpTypeArray %i32 %i32_4
             %i32_arr_1_2 = OpConstantComposite %i32_arr_1 %i32_2
             %i32_arr_1_4 = OpConstantComposite %i32_arr_1 %i32_4
            %i32_2_tensor = OpTypeTensorARM %i32 %i32_1 %i32_arr_1_2
            %i32_4_tensor = OpTypeTensorARM %i32 %i32_1 %i32_arr_1_4
               %tensor_r4 = OpTypeTensorARM %i8 %i32_4
           %ptr_tensor_r4 = OpTypePointer UniformConstant %tensor_r4
        %i32_2_tensor_2_2 = OpConstantComposite %i32_2_tensor %i32_2 %i32_2
    %i32_4_tensor_0_0_0_0 = OpConstantComposite %i32_4_tensor %i32_0 %i32_0 %i32_0 %i32_0
              %main_arg_0 = OpVariable %ptr_tensor_r4 UniformConstant
              %main_res_0 = OpVariable %ptr_tensor_r4 UniformConstant
              %graph_type = OpTypeGraphARM 1 %tensor_r4 %tensor_r4
                            OpGraphEntryPointARM %graph_0 "main" %main_arg_0 %main_res_0
                 %graph_0 = OpGraphARM %graph_type
                    %in_0 = OpGraphInputARM %tensor_r4 %i32_0
                    %op_0 = OpExtInst %tensor_r4 %tosa MAX_POOL2D  %i32_2_tensor_2_2 %i32_2_tensor_2_2 %i32_4_tensor_0_0_0_0 %i32_0 %in_0
                    %op_1 = OpExtInst %tensor_r4 %tosa MAX_POOL2D  %i32_2_tensor_2_2 %i32_2_tensor_2_2 %i32_4_tensor_0_0_0_0 %i32_0 %op_0
                            OpGraphSetOutputARM %op_1 %i32_0
                            OpGraphEndARM
)spirv";

    vkt::dg::HelperParameters params;
    params.spirv_source = tensorNoShapeDataGraphSpirv;
    vkt::dg::DataGraphPipelineHelper pipeline(*this, params);

    // 2 tensors, 2 errors
    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09919");
    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09919");
    pipeline.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, DataGraphPipelineIdentifierNoFlag) {
    TEST_DESCRIPTION("Create a datagraph with the ARM cache but the wrong flags.");
    AddRequiredFeature(vkt::Feature::pipelineCreationCacheControl);
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    VkDataGraphPipelineIdentifierCreateInfoARM pipeline_id = vku::InitStructHelper();
    constexpr uint8_t dummy_data = 1;
    pipeline_id.identifierSize = 1;
    pipeline_id.pIdentifier = &dummy_data;
    // replace the pNext chain, to remove the VkDataGraphPipelineShaderModuleCreateInfoARM added in the helper constructor
    pipeline.pipeline_ci_.pNext = &pipeline_id;
    // NOT setting VK_PIPELINE_CREATE_2_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT in the flags: ERROR
    pipeline.pipeline_ci_.pResourceInfos = nullptr;
    pipeline.pipeline_ci_.resourceInfoCount = 0;

    VkPipelineCache pipeline_cache;
    VkPipelineCacheCreateInfo cache_create_info = vku::InitStructHelper();
    cache_create_info.initialDataSize = 0;
    VkResult err = vk::CreatePipelineCache(device(), &cache_create_info, nullptr, &pipeline_cache);
    ASSERT_EQ(VK_SUCCESS, err);

    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineCreateInfoARM-None-11840");
    pipeline.CreateDataGraphPipeline(pipeline_cache);
    m_errorMonitor->VerifyFound();
    vk::DestroyPipelineCache(device(), pipeline_cache, nullptr);
}

TEST_F(NegativeDataGraph, DataGraphPipelineIdentifierHasResources) {
    TEST_DESCRIPTION("Create a datagraph with the ARM cache but resources info still included.");
    AddRequiredFeature(vkt::Feature::pipelineCreationCacheControl);
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    VkDataGraphPipelineIdentifierCreateInfoARM pipeline_id = vku::InitStructHelper();
    constexpr uint8_t dummy_data = 1;
    pipeline_id.identifierSize = 1;
    pipeline_id.pIdentifier = &dummy_data;
    // replace the pNext chain, to remove the VkDataGraphPipelineShaderModuleCreateInfoARM added in the helper constructor
    pipeline.pipeline_ci_.pNext = &pipeline_id;
    // set the correct flags, but leave pResourceInfos
    pipeline.pipeline_ci_.flags |= VK_PIPELINE_CREATE_2_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;

    VkPipelineCache pipeline_cache;
    VkPipelineCacheCreateInfo cache_create_info = vku::InitStructHelper();
    cache_create_info.initialDataSize = 0;
    VkResult err = vk::CreatePipelineCache(device(), &cache_create_info, nullptr, &pipeline_cache);
    ASSERT_EQ(VK_SUCCESS, err);

    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineCreateInfoARM-None-12363");
    pipeline.CreateDataGraphPipeline(pipeline_cache);
    m_errorMonitor->VerifyFound();
    vk::DestroyPipelineCache(device(), pipeline_cache, nullptr);
}

TEST_F(NegativeDataGraph, DataGraphCreateInfoResourceCountZero) {
    TEST_DESCRIPTION("Create a datagraph with the ARM cache, resource count is zero, but resource pointer is not null.");
    AddRequiredFeature(vkt::Feature::pipelineCreationCacheControl);
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    VkDataGraphPipelineIdentifierCreateInfoARM pipeline_id = vku::InitStructHelper();
    constexpr uint8_t dummy_data = 1;
    pipeline_id.identifierSize = 1;
    pipeline_id.pIdentifier = &dummy_data;
    // replace the pNext chain, to remove the VkDataGraphPipelineShaderModuleCreateInfoARM added in the helper constructor
    pipeline.pipeline_ci_.pNext = &pipeline_id;
    // set the correct flags, set resourceInfoCount to 0, but leave pResourceInfos
    pipeline.pipeline_ci_.flags |= VK_PIPELINE_CREATE_2_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;
    pipeline.pipeline_ci_.resourceInfoCount = 0;

    VkPipelineCache pipeline_cache;
    VkPipelineCacheCreateInfo cache_create_info = vku::InitStructHelper();
    cache_create_info.initialDataSize = 0;
    VkResult err = vk::CreatePipelineCache(device(), &cache_create_info, nullptr, &pipeline_cache);
    ASSERT_EQ(VK_SUCCESS, err);

    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineCreateInfoARM-resourceInfoCount-12364");
    pipeline.CreateDataGraphPipeline(pipeline_cache);
    m_errorMonitor->VerifyFound();
    vk::DestroyPipelineCache(device(), pipeline_cache, nullptr);
}

TEST_F(NegativeDataGraph, DataGraphCreateInfoNullResources) {
    TEST_DESCRIPTION("Create a datagraph but resource count is zero.");
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    pipeline.pipeline_ci_.pResourceInfos = nullptr;  // this is to avoid VU 12364
    pipeline.pipeline_ci_.resourceInfoCount = 0;

    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineCreateInfoARM-None-12365");
    // we also get 2x this because the spirv still includes 2 resources
    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923");
    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923");
    pipeline.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, DataGraphPipelineIdentifierNoCache) {
    TEST_DESCRIPTION("Create a datagraph using the cache identifier but without a valid cache object.");
    AddRequiredFeature(vkt::Feature::pipelineCreationCacheControl);
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);

    // add the cache identifier object
    VkDataGraphPipelineIdentifierCreateInfoARM pipeline_id = vku::InitStructHelper();
    constexpr uint8_t dummy_data = 1;
    pipeline_id.identifierSize = 1;
    pipeline_id.pIdentifier = &dummy_data;
    vvl::PnextChainAdd(&pipeline.pipeline_ci_, &pipeline_id);
    pipeline.pipeline_ci_.flags |= VK_PIPELINE_CREATE_2_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;

    // ... but pass a NULL handle for the cache object
    VkPipelineCache pipeline_cache = VK_NULL_HANDLE;

    m_errorMonitor->SetDesiredError("VUID-vkCreateDataGraphPipelinesARM-pNext-09928");
    pipeline.CreateDataGraphPipeline(pipeline_cache);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, DataGraphOpGraphConstantARMNoShape) {
    TEST_DESCRIPTION("Try to create a datagraph with an OpGraphConstantARM defined on a tensor without shape");
    RETURN_IF_SKIP(InitBasicDataGraph());

    // inject in the spirv a constant based on a shapeless tensor
    vkt::dg::ModifiableShaderParameters spirv_params;
    spirv_params.types = R"(
    %i32_1_2_4_4_tensor = OpTypeTensorARM %uint %uint_4 %uint_arr_4_1_2_4_4
    %tensor_r4 = OpTypeTensorARM %uint %uint_4
    %constant_no_shape = OpGraphConstantARM %tensor_r4 0)";
    spirv_params.instructions = R"(
    %i32_op_1 = OpExtInst %i32_1_2_4_4_tensor %tosa CAST %op_1
    %dummy = OpExtInst %i32_1_2_4_4_tensor %tosa ADD %i32_op_1 %constant_no_shape)";

    const std::string& spirv_string = vkt::dg::DataGraphPipelineHelper::GetSpirvModifyableDataGraph(spirv_params);

    vkt::dg::HelperParameters params;
    params.spirv_source = spirv_string.c_str();
    vkt::dg::DataGraphPipelineHelper pipeline(*this, params);

    VkDataGraphPipelineConstantARM constant = GetConstant();
    pipeline.shader_module_ci_.constantCount = 1;
    pipeline.shader_module_ci_.pConstants = &constant;

    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09920");
    pipeline.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, DataGraphNoConstant) {
    TEST_DESCRIPTION("Try to create a datagraph without a required constant.");
    RETURN_IF_SKIP(InitBasicDataGraph());

    // spirv has a constant, but we don't define it in Vulkan
    const std::string spirv_string = vkt::dg::DataGraphPipelineHelper::GetSpirvConstantDataGraph();

    vkt::dg::HelperParameters params;
    params.spirv_source = spirv_string.c_str();
    // helper constructor does NOT initialize the constant
    vkt::dg::DataGraphPipelineHelper pipeline(*this, params);
    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09921");
    pipeline.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, DataGraphOpGraphConstantARMNotTensor) {
    TEST_DESCRIPTION("Try to create a datagraph with an OpGraphConstantARM that is not a tensor");
    RETURN_IF_SKIP(InitBasicDataGraph());

    // inject in the spirv constants based on a scalar, not tensors
    vkt::dg::ModifiableShaderParameters spirv_params;
    spirv_params.types = R"(%constant_scalar_min = OpGraphConstantARM %uint 0
                %constant_scalar_max = OpGraphConstantARM %uint 128)";
    spirv_params.instructions =
        "%dummy = OpExtInst %uchar_1_2_4_4_tensor %tosa CLAMP %op_1 %constant_scalar_min %constant_scalar_max %uint_2";
    const std::string& spirv_string = vkt::dg::DataGraphPipelineHelper::GetSpirvModifyableDataGraph(spirv_params);

    vkt::dg::HelperParameters params;
    params.spirv_source = spirv_string.c_str();

    m_errorMonitor->SetDesiredError("VUID-VkShaderModuleCreateInfo-pCode-08737");
    VkShaderObj shader(*m_device, spirv_string.c_str(), VK_SHADER_STAGE_COMPUTE_BIT, SPV_ENV_VULKAN_1_4, SPV_SOURCE_ASM);
    m_errorMonitor->VerifyFound();
}

// NOTE: This is meant as a positive test for tensor arrays.
// Right now they are illegal, but they will be legal at some point.
// When this happens, remove the SetDesiredError and move to data_graph_positive.cpp
TEST_F(NegativeDataGraph, DataGraphShaderModuleSpirvArray) {
    TEST_DESCRIPTION("Create a datagraph using a tensor array as input.");
    RETURN_IF_SKIP(InitBasicDataGraph());

    // currently tensor arrays are banned by VU 9923. The mock ICD doesn't create a pipeline, so we can still test
    // successfully if we ignore it, but a real driver will actually try to create something illegal, and likely crash
    if (!IsPlatformMockICD()) {
        GTEST_SKIP() << "Test only supported by MockICD";
    }

    vkt::dg::HelperParameters params;
    params.graph_variant = vkt::dg::GraphVariant::AddTensorArraySpirv;
    vkt::dg::DataGraphPipelineHelper pipeline(*this, params);

    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923");
    m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923");
    pipeline.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

// NOTE: This is meant as a positive test for tensor arrays.
// Right now they are illegal, but they will be legal at some point.
// When this happens, remove the SetDesiredError and move to data_graph_positive.cpp
TEST_F(NegativeDataGraph, DataGraphShaderModuleSpirvRuntimeArray) {
    TEST_DESCRIPTION("Create a datagraph using a tensor runtime array as input.");
    SetTargetApiVersion(VK_API_VERSION_1_4);
    AddRequiredFeature(vkt::Feature::runtimeDescriptorArray);
    RETURN_IF_SKIP(InitBasicDataGraph());

    // currently tensor arrays are banned by VU 9923. The mock ICD doesn't create a pipeline, so we can still test
    // successfully if we ignore it, but a real driver will actually try to create something illegal, and likely crash
    if (!IsPlatformMockICD()) {
        GTEST_SKIP() << "Test only supported by MockICD";
    }

    {
        // the helper constructs a layout with descriptorCount == 2, matching the size of the spirv array
        vkt::dg::HelperParameters params;
        params.graph_variant = vkt::dg::GraphVariant::AddRuntimeTensorArraySpirv;
        vkt::dg::DataGraphPipelineHelper pipeline(*this, params);

        // tensor arrays triggers VU 9923, we need to suppress it (2 tensors, 2 errors)
        m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923");
        m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923");
        pipeline.CreateDataGraphPipeline();
        m_errorMonitor->VerifyFound();
    }
    {
        vkt::dg::HelperParameters params;
        params.graph_variant = vkt::dg::GraphVariant::AddRuntimeTensorArraySpirv;
        vkt::dg::DataGraphPipelineHelper pipeline(*this, params);

        // override the DataGraphPipelineHelper constructor: set a bigger element count, runtime array will handle this
        pipeline.descriptor_set_layout_bindings_[0].descriptorCount = 3;
        pipeline.descriptor_set_.reset(new OneOffDescriptorSet(pipeline.device_, pipeline.descriptor_set_layout_bindings_));
        pipeline.CreatePipelineLayout();

        // tensor arrays triggers VU 9923, we need to suppress it (2 tensors, 2 errors)
        m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923");
        m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923");
        pipeline.CreateDataGraphPipeline();
        m_errorMonitor->VerifyFound();
    }
}

TEST_F(NegativeDataGraph, CmdDispatchWrongPipeline) {
    TEST_DESCRIPTION("Try to create a datagraph where session and command buffer are bound to different pipelines.");
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    pipeline.CreateDataGraphPipeline();

    // make a _copy_ of the command buffer pipeline, so everything else checks out, but it's NOT the same object
    VkDataGraphPipelineCreateInfoARM pipeline_ci = pipeline.pipeline_ci_;
    vkt::Pipeline pipeline_copy(*m_device, pipeline_ci);

    // bind the session to the _copy_ pipeline
    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
    session_ci.dataGraphPipeline = pipeline_copy;
    vkt::DataGraphPipelineSession session(*m_device, session_ci);
    // setup the command buffer with the _default_ pipeline, as usual.
    auto& bind_point_reqs = session.BindPointReqs();
    std::vector<vkt::DeviceMemory> device_mem(bind_point_reqs.size());
    session.AllocSessionMem(device_mem);
    auto session_bind_infos = InitSessionBindInfo(session, device_mem);
    vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data());

    pipeline.descriptor_set_->WriteDescriptorTensorInfo(0, &pipeline.tensor_views_[0]->handle(), 0);
    pipeline.descriptor_set_->WriteDescriptorTensorInfo(1, &pipeline.tensor_views_[1]->handle(), 0);
    pipeline.descriptor_set_->UpdateDescriptorSets();

    m_command_buffer.Begin();
    vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline);
    vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline.pipeline_layout_, 0, 1,
                              &pipeline.descriptor_set_.get()->set_, 0, nullptr);

    m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchDataGraphARM-dataGraphPipeline-09951");
    vk::CmdDispatchDataGraphARM(m_command_buffer, session, nullptr);
    m_command_buffer.End();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, CmdDispatchWrongTensorUsage) {
    TEST_DESCRIPTION("Create and execute a datagraph where tensors have the wrong usage flag");
    RETURN_IF_SKIP(InitBasicDataGraph());

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    pipeline.CreateDataGraphPipeline();

    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
    session_ci.dataGraphPipeline = pipeline;
    vkt::DataGraphPipelineSession session(*m_device, session_ci);
    auto& bind_point_reqs = session.BindPointReqs();
    std::vector<vkt::DeviceMemory> device_mem(bind_point_reqs.size());
    session.AllocSessionMem(device_mem);
    auto session_bind_infos = InitSessionBindInfo(session, device_mem);
    vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data());

    // pass a tensor with the wrong usage into the pipeline
    VkTensorDescriptionARM wrong_desc = pipeline.GetTensorDesc(vkt::dg::TensorType::BASIC_SPIRV_IN);
    wrong_desc.usage = VK_TENSOR_USAGE_SHADER_BIT_ARM;  // should be VK_TENSOR_USAGE_DATA_GRAPH_BIT_ARM
    vkt::Tensor wrong_tensor;
    vkt::TensorView wrong_view;
    pipeline.InitTensor(wrong_tensor, wrong_view, wrong_desc);

    pipeline.descriptor_set_->WriteDescriptorTensorInfo(0, &wrong_view.handle(), 0);
    pipeline.descriptor_set_->WriteDescriptorTensorInfo(1, &pipeline.tensor_views_[1]->handle(), 0);
    pipeline.descriptor_set_->UpdateDescriptorSets();

    m_command_buffer.Begin();
    vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline);
    vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline.pipeline_layout_, 0, 1,
                              &pipeline.descriptor_set_.get()->set_, 0, nullptr);

    m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchDataGraphARM-pDescription-09900");
    vk::CmdDispatchDataGraphARM(m_command_buffer, session, nullptr);
    m_errorMonitor->VerifyFound();
    m_command_buffer.End();
}

TEST_F(NegativeDataGraph, BindPipelineCommandPoolFromWrongQueue) {
    TEST_DESCRIPTION("Try to bind a datagraph pipeline with a command buffer using the wrong queue");
    RETURN_IF_SKIP(InitBasicDataGraph());
    InitRenderTarget();

    // find a queue that doesn't support datagraph. Also require supporting either graphics
    // or compute, to avoid "VUID-vkCmdBindPipeline-commandBuffer-cmdpool"
    uint32_t queueFamilyIndex_no_datagraph_support = vvl::kU32Max;
    const auto q_props = m_device->Physical().queue_properties_;
    for (uint32_t i = 0; i < (uint32_t)q_props.size(); i++) {
        if ((q_props[i].queueFlags & VK_QUEUE_DATA_GRAPH_BIT_ARM) == 0 &&
            (q_props[i].queueFlags & (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT))) {
            queueFamilyIndex_no_datagraph_support = i;
            break;
        }
    }
    if (queueFamilyIndex_no_datagraph_support == vvl::kU32Max) {
        GTEST_SKIP() << "No queue found that doesn't support VK_QUEUE_DATA_GRAPH_BIT_ARM";
    }
    vkt::CommandPool commandPool(*m_device, queueFamilyIndex_no_datagraph_support);
    vkt::CommandBuffer commandBuffer(*m_device, commandPool);

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    pipeline.CreateDataGraphPipeline();

    commandBuffer.Begin();
    m_errorMonitor->SetDesiredError("VUID-vkCmdBindPipeline-pipelineBindPoint-09910");
    vk::CmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline);
    m_errorMonitor->VerifyFound();
    commandBuffer.End();
}

TEST_F(NegativeDataGraph, BindWrongBindPoint) {
    TEST_DESCRIPTION("Try to bind a graphics pipeline to the datagraph bind point");
    RETURN_IF_SKIP(InitBasicDataGraph());

    InitRenderTarget();
    CreatePipelineHelper pipeline(*this);
    pipeline.CreateGraphicsPipeline();

    m_command_buffer.Begin();
    m_errorMonitor->SetDesiredError("VUID-vkCmdBindPipeline-pipelineBindPoint-09911");
    vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, CmdDispatchWrongQueue) {
    TEST_DESCRIPTION("Try to create a datagraph where the command buffer is allocated on a queue that does not support TOSA 1.0");
    RETURN_IF_SKIP(InitBasicDataGraph());

    // find a queue family that does NOT support TOSA
    const VkQueueFamilyDataGraphPropertiesARM tosa_1_0_property{
        VK_STRUCTURE_TYPE_QUEUE_FAMILY_DATA_GRAPH_PROPERTIES_ARM,
        nullptr,
        {VK_PHYSICAL_DEVICE_DATA_GRAPH_PROCESSING_ENGINE_TYPE_DEFAULT_ARM, false},
        {VK_PHYSICAL_DEVICE_DATA_GRAPH_OPERATION_TYPE_SPIRV_EXTENDED_INSTRUCTION_SET_ARM, "TOSA.001000.1", 0}};
    uint32_t queue_without_tosa_1_0_idx = UINT32_MAX;
    uint32_t n_queue_families;
    vk::GetPhysicalDeviceQueueFamilyProperties(Gpu(), &n_queue_families, nullptr);
    const auto q_props = m_device->Physical().queue_properties_;
    for (uint32_t qfi = 0; qfi < n_queue_families; qfi++) {
        // the queue must support datagraph
        if ((q_props[qfi].queueFlags & VK_QUEUE_DATA_GRAPH_BIT_ARM) == 0) {
            continue;
        }

        uint32_t n_properties;
        vk::GetPhysicalDeviceQueueFamilyDataGraphPropertiesARM(Gpu(), qfi, &n_properties, nullptr);
        std::vector<VkQueueFamilyDataGraphPropertiesARM> properties(n_properties,
                                                                    {VK_STRUCTURE_TYPE_QUEUE_FAMILY_DATA_GRAPH_PROPERTIES_ARM});
        vk::GetPhysicalDeviceQueueFamilyDataGraphPropertiesARM(Gpu(), qfi, &n_properties, properties.data());

        bool queue_supports_tosa_1_0 = false;
        for (const auto& p : properties) {
            if (CompareVkQueueFamilyDataGraphPropertiesARM(tosa_1_0_property, p)) {
                queue_supports_tosa_1_0 = true;
                break;
            }
        }
        if (!queue_supports_tosa_1_0) {
            queue_without_tosa_1_0_idx = qfi;
            break;
        }
    }

    // TODO: setup the queues so that we don't skip here

    if (UINT32_MAX == queue_without_tosa_1_0_idx) {
        GTEST_SKIP() << "All the queues supporting datagraph also support TOSA, impossible to create the error condition, skip.";
    }

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    pipeline.CreateDataGraphPipeline();

    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
    session_ci.dataGraphPipeline = pipeline;
    vkt::DataGraphPipelineSession session(*m_device, session_ci);
    auto& bind_point_reqs = session.BindPointReqs();
    std::vector<vkt::DeviceMemory> device_mem(bind_point_reqs.size());
    session.AllocSessionMem(device_mem);
    auto session_bind_infos = InitSessionBindInfo(session, device_mem);
    vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data());

    pipeline.descriptor_set_->WriteDescriptorTensorInfo(0, &pipeline.tensor_views_[0]->handle(), 0);
    pipeline.descriptor_set_->WriteDescriptorTensorInfo(1, &pipeline.tensor_views_[1]->handle(), 0);
    pipeline.descriptor_set_->UpdateDescriptorSets();

    // run the graph on the wrong queue family (command pool, buffer)
    vkt::CommandPool command_pool;
    vkt::CommandBuffer command_buffer;
    command_pool.Init(*m_device, queue_without_tosa_1_0_idx);
    command_buffer.Init(*m_device, command_pool);
    command_buffer.Begin();
    vk::CmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline);
    vk::CmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline.pipeline_layout_, 0, 1,
                              &pipeline.descriptor_set_.get()->set_, 0, nullptr);
    m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchDataGraphARM-commandBuffer-09941");
    vk::CmdDispatchDataGraphARM(command_buffer, session, nullptr);
    m_errorMonitor->VerifyFound();
    command_buffer.End();
}

TEST_F(NegativeDataGraph, OpticalFlowWrongImageFormat) {
    TEST_DESCRIPTION("Try to create an optical flow data graph pipeline with an unsupported input image format");

    RETURN_IF_SKIP(InitBasicDataGraph(true));

    vkt::dg::OpticalFlowHelper optical_flow(*this);

    /* Set an unsupported imageFormat. ASTC are block formats, incompatible with optical flow operations. */
    optical_flow.optical_flow_ci_.imageFormat = VK_FORMAT_ASTC_4x4_UNORM_BLOCK;

    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineOpticalFlowCreateInfoARM-imageFormat-09968");
    (void)optical_flow.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, OpticalFlowWrongFlowVectorFormat) {
    TEST_DESCRIPTION("Try to create an optical flow data graph pipeline with an unsupported flow vector image format");

    RETURN_IF_SKIP(InitBasicDataGraph(true));

    vkt::dg::OpticalFlowHelper optical_flow(*this);

    /* Set an unsupported flowVectorFormat. ASTC are block formats, incompatible with optical flow operations. */
    optical_flow.optical_flow_ci_.flowVectorFormat = VK_FORMAT_ASTC_4x4_UNORM_BLOCK;

    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineOpticalFlowCreateInfoARM-flowVectorFormat-09969");
    (void)optical_flow.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, OpticalFlowWrongCostFormat) {
    TEST_DESCRIPTION("Try to create an optical flow data graph pipeline with an unsupported cost image format");

    RETURN_IF_SKIP(InitBasicDataGraph(true));

    auto opt_flow_properties = vkt::dg::OpticalFlowHelper::QueryOpticalFlowProperties(*this, DefaultQueue()->family_index);
    if (!opt_flow_properties.costSupported) {
        GTEST_SKIP() << "Cost not supported, skip.";
    }

    vkt::dg::OpticalFlowHelper optical_flow(*this);
    /* Set an unsupported costFormat. ASTC are block formats, incompatible with optical flow operations. */
    optical_flow.optical_flow_ci_.costFormat = VK_FORMAT_ASTC_4x4_UNORM_BLOCK;

    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineOpticalFlowCreateInfoARM-costFormat-09970");
    (void)optical_flow.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, OpticalFlowWrongHint) {
    TEST_DESCRIPTION("Execute optical flow with a wrong meanFlowL1NormHint value");
    RETURN_IF_SKIP(InitBasicDataGraph(true));

    auto opt_flow_properties = vkt::dg::OpticalFlowHelper::QueryOpticalFlowProperties(*this, DefaultQueue()->family_index);
    if (!opt_flow_properties.hintSupported) {
        GTEST_SKIP() << "Hint not supported, skip.";
    }

    vkt::dg::OpticalFlowHelper optical_flow(*this);
    optical_flow.CreateDataGraphPipeline();
    optical_flow.SetupImageDescriptors();

    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
    session_ci.dataGraphPipeline = optical_flow.dg_pipeline_;
    vkt::DataGraphPipelineSession session(*m_device, session_ci);

    auto& bind_point_reqs = session.BindPointReqs();
    std::vector<vkt::DeviceMemory> device_mem(bind_point_reqs.size());
    session.AllocSessionMem(device_mem);
    auto session_bind_infos = InitSessionBindInfo(session, device_mem);
    vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data());

    // set a hint that is too high
    VkDataGraphPipelineOpticalFlowDispatchInfoARM optical_flow_di = vku::InitStructHelper();
    optical_flow_di.meanFlowL1NormHint = optical_flow.optical_flow_ci_.height + 1;
    VkDataGraphPipelineDispatchInfoARM pipeline_di = vku::InitStructHelper(&optical_flow_di);

    m_command_buffer.Begin();
    vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, optical_flow.dg_pipeline_);
    vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, optical_flow.PipelineLayout(), 0, 1,
                              optical_flow.DescriptorSet(), 0, nullptr);
    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineOpticalFlowDispatchInfoARM-meanFlowL1NormHint-09976");
    vk::CmdDispatchDataGraphARM(m_command_buffer, session, &pipeline_di);
    m_errorMonitor->VerifyFound();
    m_command_buffer.End();
}

TEST_F(NegativeDataGraph, OpticalFlowNoCacheSession) {
    TEST_DESCRIPTION("Dispatch an optical flow pipeline with flags that require cache, but without cache");
    RETURN_IF_SKIP(InitBasicDataGraph(true));

    vkt::dg::OpticalFlowHelper optical_flow(*this);
    optical_flow.CreateDataGraphPipeline();
    optical_flow.SetupImageDescriptors();

    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
    session_ci.dataGraphPipeline = optical_flow.dg_pipeline_;

    vkt::DataGraphPipelineSession session(*m_device, session_ci);
    std::vector<vkt::DeviceMemory> device_mem(session.BindPointReqs().size());
    session.AllocSessionMem(device_mem);
    std::vector<VkBindDataGraphPipelineSessionMemoryInfoARM> session_bind_infos =
        DataGraphTest::InitSessionBindInfo(session, device_mem);
    vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data());

    VkDataGraphPipelineOpticalFlowDispatchInfoARM optical_flow_di = vku::InitStructHelper();
    // Set one of the disallowed bits
    optical_flow_di.flags = VK_DATA_GRAPH_OPTICAL_FLOW_EXECUTE_REFERENCE_UNCHANGED_BIT_ARM;

    m_command_buffer.Begin();
    vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, optical_flow.dg_pipeline_);
    vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, optical_flow.dg_pipeline_.pipeline_layout_,
                              0, 1, &optical_flow.dg_pipeline_.descriptor_set_.get()->set_, 0, nullptr);

    m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchDataGraphARM-pInfo-09964");
    VkDataGraphPipelineDispatchInfoARM pipeline_di = vku::InitStructHelper(&optical_flow_di);
    vk::CmdDispatchDataGraphARM(m_command_buffer, session, &pipeline_di);
    m_errorMonitor->VerifyFound();

    m_command_buffer.End();
}

TEST_F(NegativeDataGraph, OpticalFlowDispatchWithoutOpticalFlowCreateInfo) {
    TEST_DESCRIPTION("Dispatch an optical flow pipeline without including an optical flow create info");
    RETURN_IF_SKIP(InitBasicDataGraph(true));

    vkt::dg::DataGraphPipelineHelper pipeline(*this);
    pipeline.CreateDataGraphPipeline();

    pipeline.descriptor_set_->WriteDescriptorTensorInfo(0, &pipeline.tensor_views_[0]->handle(), 0);
    pipeline.descriptor_set_->WriteDescriptorTensorInfo(1, &pipeline.tensor_views_[1]->handle(), 0);
    pipeline.descriptor_set_->UpdateDescriptorSets();

    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
    session_ci.dataGraphPipeline = pipeline;

    vkt::DataGraphPipelineSession session(*m_device, session_ci);
    std::vector<vkt::DeviceMemory> device_mem(session.BindPointReqs().size());
    session.AllocSessionMem(device_mem);

    std::vector<VkBindDataGraphPipelineSessionMemoryInfoARM> session_bind_infos =
        DataGraphTest::InitSessionBindInfo(session, device_mem);

    vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data());

    // Set optical flow dispatch info for `pipeline` which was not created with optical flow create info.
    VkDataGraphPipelineOpticalFlowDispatchInfoARM optical_flow_di = vku::InitStructHelper();
    VkDataGraphPipelineDispatchInfoARM pipeline_di = vku::InitStructHelper(&optical_flow_di);

    m_command_buffer.Begin();
    vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline);
    vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline.pipeline_layout_, 0, 1,
                              &pipeline.descriptor_set_.get()->set_, 0, nullptr);

    m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchDataGraphARM-nodeType-09980");
    vk::CmdDispatchDataGraphARM(m_command_buffer, session, &pipeline_di);
    m_errorMonitor->VerifyFound();

    m_command_buffer.End();
}

TEST_F(NegativeDataGraph, OpticalFlowConnectionsImageLayoutsNoUnifiedImageLayouts) {
    TEST_DESCRIPTION(
        "Dispatch an optical flow pipeline with a layout definition that require the unifiedImageLayouts feature, but the feature "
        "is disabled");
    RETURN_IF_SKIP(InitBasicDataGraph(true));

    vkt::dg::OpticalFlowHelper optical_flow(*this);
    // Set the resource info image layout to VK_IMAGE_LAYOUT_GENERAL, where the connection references a descriptor in the
    // VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL layout. Since unifiedImageLayouts feature is not enabled this is invalid usage.
    optical_flow.image_layouts_[0].layout = VK_IMAGE_LAYOUT_GENERAL;

    optical_flow.CreateDataGraphPipeline();
    optical_flow.SetupImageDescriptors();

    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
    session_ci.dataGraphPipeline = optical_flow.dg_pipeline_;

    vkt::DataGraphPipelineSession session(*m_device, session_ci);
    std::vector<vkt::DeviceMemory> device_mem(session.BindPointReqs().size());
    session.AllocSessionMem(device_mem);
    std::vector<VkBindDataGraphPipelineSessionMemoryInfoARM> session_bind_infos =
        DataGraphTest::InitSessionBindInfo(session, device_mem);
    vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data());

    VkDataGraphPipelineOpticalFlowDispatchInfoARM optical_flow_di = vku::InitStructHelper();
    VkDataGraphPipelineDispatchInfoARM pipeline_di = vku::InitStructHelper(&optical_flow_di);

    m_command_buffer.Begin();
    vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, optical_flow.dg_pipeline_);
    vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, optical_flow.dg_pipeline_.pipeline_layout_,
                              0, 1, &optical_flow.dg_pipeline_.descriptor_set_.get()->set_, 0, nullptr);

    m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchDataGraphARM-nodeType-09981");
    vk::CmdDispatchDataGraphARM(m_command_buffer, session, &pipeline_di);
    m_errorMonitor->VerifyFound();

    m_command_buffer.End();
}

TEST_F(NegativeDataGraph, OpticalFlowConnectionsImageLayoutsUnifiedImageLayouts) {
    TEST_DESCRIPTION("Dispatch an optical flow pipeline with an incorrect layout definition for the unifiedImageLayouts feature");
    AddRequiredFeature(vkt::Feature::unifiedImageLayouts);
    RETURN_IF_SKIP(InitBasicDataGraph(true));

    vkt::dg::OpticalFlowHelper optical_flow(*this);
    // Set the resource info image layout to VK_IMAGE_LAYOUT_UNDEFINED, where the connection references a descriptor in the
    // VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL layout.
    optical_flow.image_layouts_[0].layout = VK_IMAGE_LAYOUT_UNDEFINED;
    optical_flow.CreateDataGraphPipeline();
    optical_flow.SetupImageDescriptors();

    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
    session_ci.dataGraphPipeline = optical_flow.dg_pipeline_;

    vkt::DataGraphPipelineSession session(*m_device, session_ci);
    std::vector<vkt::DeviceMemory> device_mem(session.BindPointReqs().size());
    session.AllocSessionMem(device_mem);
    std::vector<VkBindDataGraphPipelineSessionMemoryInfoARM> session_bind_infos =
        DataGraphTest::InitSessionBindInfo(session, device_mem);
    vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data());

    VkDataGraphPipelineOpticalFlowDispatchInfoARM optical_flow_di = vku::InitStructHelper();
    VkDataGraphPipelineDispatchInfoARM pipeline_di = vku::InitStructHelper(&optical_flow_di);

    m_command_buffer.Begin();
    vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, optical_flow.dg_pipeline_);
    vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, optical_flow.dg_pipeline_.pipeline_layout_,
                              0, 1, &optical_flow.dg_pipeline_.descriptor_set_.get()->set_, 0, nullptr);

    m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchDataGraphARM-nodeType-09981");
    vk::CmdDispatchDataGraphARM(m_command_buffer, session, &pipeline_di);
    m_errorMonitor->VerifyFound();

    m_command_buffer.End();
}

TEST_F(NegativeDataGraph, OpticalFlowMissingOpticalFlowCreateInfo) {
    TEST_DESCRIPTION("Try to create an optical flow datagraph without a VkDataGraphPipelineOpticalFlowCreateInfoARM structure");
    RETURN_IF_SKIP(InitBasicDataGraph(true));

    vkt::dg::OpticalFlowHelper optical_flow(*this);

    // pipeline_ci_.pNext points to optical_flow_ci_: skip one link to remove it from the chain
    optical_flow.dg_pipeline_.pipeline_ci_.pNext = optical_flow.optical_flow_ci_.pNext;

    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineSingleNodeCreateInfoARM-nodeType-09963");
    ASSERT_EQ(VK_ERROR_VALIDATION_FAILED, optical_flow.dg_pipeline_.CreateDataGraphPipeline());
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, OpticalFlowWrongNumberOfInputs) {
    TEST_DESCRIPTION("Try to create an optical flow datagraph with a missing or too many input connections");
    RETURN_IF_SKIP(InitBasicDataGraph(true));

    for (uint32_t n : {0, 2}) {
        vkt::dg::OfHelperParameters params;
        params.n_inputs = n;
        vkt::dg::OpticalFlowHelper optical_flow(*this, params);

        m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineSingleNodeCreateInfoARM-nodeType-09978");
        ASSERT_EQ(VK_ERROR_VALIDATION_FAILED, optical_flow.dg_pipeline_.CreateDataGraphPipeline());
        m_errorMonitor->VerifyFound();
    }
}

TEST_F(NegativeDataGraph, OpticalFlowWrongNumberOfReferences) {
    TEST_DESCRIPTION("Try to create an optical flow datagraph with a missing or too many reference connections");
    RETURN_IF_SKIP(InitBasicDataGraph(true));

    for (uint32_t n : {0, 2}) {
        vkt::dg::OfHelperParameters params;
        params.n_references = n;
        vkt::dg::OpticalFlowHelper optical_flow(*this, params);

        m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineSingleNodeCreateInfoARM-nodeType-09978");
        ASSERT_EQ(VK_ERROR_VALIDATION_FAILED, optical_flow.dg_pipeline_.CreateDataGraphPipeline());
        m_errorMonitor->VerifyFound();
    }
}

TEST_F(NegativeDataGraph, OpticalFlowWrongNumberOfOutputs) {
    TEST_DESCRIPTION("Try to create an optical flow datagraph with a missing or too many output connections");
    RETURN_IF_SKIP(InitBasicDataGraph(true));

    for (uint32_t n : {0, 2}) {
        vkt::dg::OfHelperParameters params;
        params.n_outputs = n;
        vkt::dg::OpticalFlowHelper optical_flow(*this, params);

        m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineSingleNodeCreateInfoARM-nodeType-09978");
        ASSERT_EQ(VK_ERROR_VALIDATION_FAILED, optical_flow.dg_pipeline_.CreateDataGraphPipeline());
        m_errorMonitor->VerifyFound();
    }
}

TEST_F(NegativeDataGraph, OpticalFlowWrongNumberOfHints) {
    TEST_DESCRIPTION("Try to create an optical flow datagraph with hintGridSize > 0 but missing or too many hint connections");
    RETURN_IF_SKIP(InitBasicDataGraph(true));

    uint32_t queue_index = DefaultQueue()->family_index;

    auto opt_flow_properties = vkt::dg::OpticalFlowHelper::QueryOpticalFlowProperties(*this, queue_index);
    if (!opt_flow_properties.hintSupported) {
        GTEST_SKIP() << "Hint not supported, skip.";
    }
    uint32_t hint_grid_size = vkt::dg::OpticalFlowHelper::GetAnyOpticalFlowGridSize(opt_flow_properties);

    for (uint32_t n : {0, 2}) {
        vkt::dg::OfHelperParameters params;
        params.n_hints = n;  // force the wrong number of hint images
        params.hintGridSize = hint_grid_size;
        vkt::dg::OpticalFlowHelper optical_flow(*this, params);

        m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineSingleNodeCreateInfoARM-nodeType-09979");
        ASSERT_EQ(VK_ERROR_VALIDATION_FAILED, optical_flow.dg_pipeline_.CreateDataGraphPipeline());
        m_errorMonitor->VerifyFound();
    }
}

TEST_F(NegativeDataGraph, OpticalFlowNoHint) {
    TEST_DESCRIPTION("Try to create an optical flow datagraph using a hint image but the feature is not supported");
    RETURN_IF_SKIP(InitBasicDataGraph(true));

    uint32_t n_queue_families;
    vk::GetPhysicalDeviceQueueFamilyProperties(Gpu(), &n_queue_families, nullptr);
    uint32_t no_hint_index = UINT32_MAX;
    const auto q_props = m_device->Physical().queue_properties_;
    for (uint32_t qfi = 0; qfi < n_queue_families; qfi++) {
        // the queue must support datagraph
        if ((q_props[qfi].queueFlags & VK_QUEUE_DATA_GRAPH_BIT_ARM) == 0) {
            continue;
        }
        // and optical flow
        auto of_support_property = vkt::dg::OpticalFlowHelper::GetOpticalFlowSupportProperty(*this, qfi);
        if (std::nullopt == of_support_property) {
            continue;
        }

        VkQueueFamilyDataGraphOpticalFlowPropertiesARM op_flow_properties = vku::InitStructHelper();
        ASSERT_EQ(VK_SUCCESS,
                  vk::GetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM(
                      Gpu(), qfi, &of_support_property.value(), reinterpret_cast<VkBaseOutStructure*>(&op_flow_properties)));
        if (!op_flow_properties.hintSupported) {
            no_hint_index = qfi;
            break;
        }
    }
    if (UINT32_MAX == no_hint_index) {
        GTEST_SKIP() << "All the queues that support datagraph also support optical flow hint, impossible to create the error "
                        "condition, skip.";
    }

    // TODO: use queue with index no_hint_index
    vkt::dg::OpticalFlowHelper optical_flow(*this);

    // force the hint flag
    optical_flow.optical_flow_ci_.flags |= VK_DATA_GRAPH_OPTICAL_FLOW_CREATE_ENABLE_HINT_BIT_ARM;

    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineOpticalFlowCreateInfoARM-flags-09974");
    ASSERT_EQ(VK_ERROR_VALIDATION_FAILED, optical_flow.CreateDataGraphPipeline());
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, OpticalFlowNoCost) {
    TEST_DESCRIPTION("Try to create an optical flow datagraph using a cost image but the feature is not supported");
    RETURN_IF_SKIP(InitBasicDataGraph(true));

    uint32_t n_queue_families;
    vk::GetPhysicalDeviceQueueFamilyProperties(Gpu(), &n_queue_families, nullptr);
    uint32_t no_cost_index = UINT32_MAX;
    const auto q_props = m_device->Physical().queue_properties_;
    for (uint32_t qfi = 0; qfi < n_queue_families; qfi++) {
        // the queue must support datagraph
        if ((q_props[qfi].queueFlags & VK_QUEUE_DATA_GRAPH_BIT_ARM) == 0) {
            continue;
        }
        // and optical flow
        auto of_support_property = vkt::dg::OpticalFlowHelper::GetOpticalFlowSupportProperty(*this, qfi);
        if (std::nullopt == of_support_property) {
            continue;
        }

        VkQueueFamilyDataGraphOpticalFlowPropertiesARM op_flow_properties = vku::InitStructHelper();
        ASSERT_EQ(VK_SUCCESS,
                  vk::GetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM(
                      Gpu(), qfi, &of_support_property.value(), reinterpret_cast<VkBaseOutStructure*>(&op_flow_properties)));
        if (!op_flow_properties.costSupported) {
            no_cost_index = qfi;
            break;
        }
    }
    if (UINT32_MAX == no_cost_index) {
        GTEST_SKIP() << "All the queues that support datagraph also support optical flow cost, impossible to create the error "
                        "condition, skip.";
    }

    // TODO: use queue with index no_cost_index
    vkt::dg::OpticalFlowHelper optical_flow(*this);

    // force the cost flag, and also a format to avoid 9970
    optical_flow.optical_flow_ci_.flags |= VK_DATA_GRAPH_OPTICAL_FLOW_CREATE_ENABLE_COST_BIT_ARM;
    optical_flow.optical_flow_ci_.costFormat =
        optical_flow.GetAnyOpticalFlowFormat(VK_DATA_GRAPH_OPTICAL_FLOW_IMAGE_USAGE_COST_BIT_ARM);

    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineOpticalFlowCreateInfoARM-flags-09975");
    ASSERT_EQ(VK_ERROR_VALIDATION_FAILED, optical_flow.CreateDataGraphPipeline());
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, OpticalFlowUnequalGridSizes) {
    TEST_DESCRIPTION("Try to create an optical flow datagraph with non-zero hintGridSize not equal to outputGridSize");
    RETURN_IF_SKIP(InitBasicDataGraph(true));

    // Set different output and hint grid sizes
    uint32_t queue_index = DefaultQueue()->family_index;
    auto opt_flow_properties = vkt::dg::OpticalFlowHelper::QueryOpticalFlowProperties(*this, queue_index);
    vkt::dg::OfHelperParameters params;
    params.outputGridSize = vkt::dg::OpticalFlowHelper::GetAnyOpticalFlowGridSize(opt_flow_properties);
    params.hintGridSize = vkt::dg::OpticalFlowHelper::GetAnyOpticalFlowGridSize(
        opt_flow_properties, static_cast<VkDataGraphOpticalFlowGridSizeFlagBitsARM>(params.outputGridSize + 1));
    vkt::dg::OpticalFlowHelper optical_flow(*this, params);

    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineOpticalFlowCreateInfoARM-hintGridSize-09973");
    optical_flow.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, OpticalFlowWrongOutputGridSize) {
    TEST_DESCRIPTION("Try to create an optical flow datagraph with a wrong output grid size");
    RETURN_IF_SKIP(InitBasicDataGraph(true));

    // Set a wrong output grid size that is correct for hint grid size
    vkt::dg::OfHelperParameters params;
    params.outputGridSize = VK_DATA_GRAPH_OPTICAL_FLOW_GRID_SIZE_UNKNOWN_ARM;
    params.hintGridSize = VK_DATA_GRAPH_OPTICAL_FLOW_GRID_SIZE_UNKNOWN_ARM;
    vkt::dg::OpticalFlowHelper optical_flow(*this, params);
    optical_flow.optical_flow_ci_.flags &= ~VK_DATA_GRAPH_OPTICAL_FLOW_CREATE_ENABLE_HINT_BIT_ARM;

    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineOpticalFlowCreateInfoARM-outputGridSize-09971");
    optical_flow.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, OpticalFlowWrongHintGridSize) {
    TEST_DESCRIPTION("Try to create an optical flow datagraph with a wrong hint grid size");
    RETURN_IF_SKIP(InitBasicDataGraph(true));

    // Set a wrong hint grid size that is correct for output grid size
    uint32_t queue_index = DefaultQueue()->family_index;
    auto opt_flow_properties = vkt::dg::OpticalFlowHelper::QueryOpticalFlowProperties(*this, queue_index);
    vkt::dg::OfHelperParameters params;
    params.outputGridSize = vkt::dg::OpticalFlowHelper::GetAnyOpticalFlowGridSize(opt_flow_properties);
    params.hintGridSize = params.outputGridSize;
    vkt::dg::OpticalFlowHelper optical_flow(*this, params);
    optical_flow.optical_flow_ci_.flags &= ~VK_DATA_GRAPH_OPTICAL_FLOW_CREATE_ENABLE_HINT_BIT_ARM;

    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineOpticalFlowCreateInfoARM-hintGridSize-09972");
    optical_flow.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, OpticalFlowWrongWidthHeight) {
    TEST_DESCRIPTION("Try to create an optical flow datagraph with wrong image sizes");
    RETURN_IF_SKIP(InitBasicDataGraph(true));

    uint32_t queue_index = DefaultQueue()->family_index;
    auto opt_flow_properties = vkt::dg::OpticalFlowHelper::QueryOpticalFlowProperties(*this, queue_index);
    vkt::dg::OfHelperParameters params;

    // Set widths and heights that are too low or too high
    uint32_t good_width = params.width;
    uint32_t good_height = params.height;
    uint32_t under_width = opt_flow_properties.minWidth - 1;
    uint32_t over_width = opt_flow_properties.maxWidth + 1;
    uint32_t under_height = opt_flow_properties.minHeight - 1;
    uint32_t over_height = opt_flow_properties.maxHeight + 1;

    for (uint32_t w : {under_width, good_width, over_width}) {
        for (uint32_t h : {under_height, good_height, over_height}) {
            params.width = w;
            params.height = h;
            vkt::dg::OpticalFlowHelper optical_flow(*this, params);
            if (w != good_width) {
                m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineOpticalFlowCreateInfoARM-width-09966");
            }
            if (h != good_height) {
                m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineOpticalFlowCreateInfoARM-height-09967");
            }
            optical_flow.CreateDataGraphPipeline();
            m_errorMonitor->VerifyFound();
        }
    }
}

TEST_F(NegativeDataGraph, ProcessingEnginesGetPropertiesWrongQueue) {
    TEST_DESCRIPTION("Request Processing Engine operation properties on a different queue family that does not support them");
    RETURN_IF_SKIP(InitBasicDataGraph(true /*optical_flow*/));

    // get the available properties on the default queue
    uint32_t queue_index = DefaultQueue()->family_index;
    uint32_t n_properties = 0;
    ASSERT_EQ(VK_SUCCESS, vk::GetPhysicalDeviceQueueFamilyDataGraphPropertiesARM(Gpu(), queue_index, &n_properties, nullptr));
    std::vector<VkQueueFamilyDataGraphPropertiesARM> data_graph_queue_family_properties(
        n_properties, vku::InitStruct<VkQueueFamilyDataGraphPropertiesARM>());
    ASSERT_EQ(VK_SUCCESS, vk::GetPhysicalDeviceQueueFamilyDataGraphPropertiesARM(Gpu(), queue_index, &n_properties,
                                                                                 data_graph_queue_family_properties.data()));

    // same on a different queue
    if (SecondQueue() == nullptr) {
        GTEST_SKIP() << "Two queue families needed, skip test.";
    }
    uint32_t other_queue_index = SecondQueue()->family_index;
    n_properties = 0;
    ASSERT_EQ(VK_SUCCESS, vk::GetPhysicalDeviceQueueFamilyDataGraphPropertiesARM(Gpu(), other_queue_index, &n_properties, nullptr));
    std::vector<VkQueueFamilyDataGraphPropertiesARM> other_queue_family_data_graph_properties(
        n_properties, vku::InitStruct<VkQueueFamilyDataGraphPropertiesARM>());
    ASSERT_EQ(VK_SUCCESS, vk::GetPhysicalDeviceQueueFamilyDataGraphPropertiesARM(Gpu(), other_queue_index, &n_properties,
                                                                                 other_queue_family_data_graph_properties.data()));

    // now ask on the second queue for properties that are present only on the first queue
    bool found_unique_property = false;
    for (auto& prop : data_graph_queue_family_properties) {
        // skip prop if also present in the other queue
        if (std::any_of(other_queue_family_data_graph_properties.begin(), other_queue_family_data_graph_properties.end(),
                        [prop](const auto& other_prop) { return CompareVkQueueFamilyDataGraphPropertiesARM(prop, other_prop); })) {
            continue;
        }

        // The 2 properties that can be supported by the default engine.
        // TODO: add more properties for other engines
        static constexpr VkPhysicalDeviceDataGraphOperationSupportARM tosa_operation{
            VK_PHYSICAL_DEVICE_DATA_GRAPH_OPERATION_TYPE_SPIRV_EXTENDED_INSTRUCTION_SET_ARM, "TOSA.001000.1", 0};
        static constexpr VkPhysicalDeviceDataGraphOperationSupportARM optical_flow_operation{
            VK_PHYSICAL_DEVICE_DATA_GRAPH_OPERATION_TYPE_OPTICAL_FLOW_ARM, "OpticalFlow", 1};

        // get the values for the 2 properties supported in the default processing engine.
        VkQueueFamilyDataGraphOpticalFlowPropertiesARM op_flow_properties = vku::InitStructHelper();
        VkQueueFamilyDataGraphTOSAPropertiesARM tosa_properties = vku::InitStructHelper();
        VkBaseOutStructure* pProperties = nullptr;
        if (prop.operation.operationType == optical_flow_operation.operationType &&
            strcmp(prop.operation.name, optical_flow_operation.name) == 0) {
            pProperties = reinterpret_cast<VkBaseOutStructure*>(&op_flow_properties);
        } else if (prop.operation.operationType == tosa_operation.operationType &&
                   strcmp(prop.operation.name, tosa_operation.name) == 0) {
            pProperties = reinterpret_cast<VkBaseOutStructure*>(&tosa_properties);
        } else {
            // some other property that we haven't considered (other engine? Add)
            continue;
        }

        m_errorMonitor->SetDesiredError(
            "VUID-vkGetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM-pQueueFamilyDataGraphProperties-09957");
        ASSERT_EQ(VK_ERROR_VALIDATION_FAILED, vk::GetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM(
                                                  Gpu(), other_queue_index, &prop, pProperties));
        m_errorMonitor->VerifyFound();
        found_unique_property = true;
    }
    if (!found_unique_property) {
        GTEST_SKIP() << "No queue-family-specific data graph properties available.";
    }
}

TEST_F(NegativeDataGraph, ProcessingEnginesGetPropertiesWrongEngine) {
    TEST_DESCRIPTION("Request Processing Engine operation properties with the wrong engine");
    RETURN_IF_SKIP(InitBasicDataGraph(true /*optical_flow*/));

    // get the available properties on the default queue
    uint32_t queue_index = DefaultQueue()->family_index;
    uint32_t n_properties = 0;
    ASSERT_EQ(VK_SUCCESS, vk::GetPhysicalDeviceQueueFamilyDataGraphPropertiesARM(Gpu(), queue_index, &n_properties, nullptr));
    std::vector<VkQueueFamilyDataGraphPropertiesARM> data_graph_queue_family_properties(
        n_properties, vku::InitStruct<VkQueueFamilyDataGraphPropertiesARM>());
    ASSERT_EQ(VK_SUCCESS, vk::GetPhysicalDeviceQueueFamilyDataGraphPropertiesARM(Gpu(), queue_index, &n_properties,
                                                                                 data_graph_queue_family_properties.data()));

    // ask for properties, but switch the engine
    bool test_executed = false;
    for (auto& prop : data_graph_queue_family_properties) {
        // switch the engine in prop
        if (prop.engine.type == VK_PHYSICAL_DEVICE_DATA_GRAPH_PROCESSING_ENGINE_TYPE_DEFAULT_ARM) {
            prop.engine = {VK_PHYSICAL_DEVICE_DATA_GRAPH_PROCESSING_ENGINE_TYPE_COMPUTE_QCOM, true};
        } else {
            prop.engine = {VK_PHYSICAL_DEVICE_DATA_GRAPH_PROCESSING_ENGINE_TYPE_DEFAULT_ARM, false};
        }

        // The 2 properties that can be supported by the default engine.
        // TODO: add more properties for other engines
        static constexpr VkPhysicalDeviceDataGraphOperationSupportARM tosa_operation{
            VK_PHYSICAL_DEVICE_DATA_GRAPH_OPERATION_TYPE_SPIRV_EXTENDED_INSTRUCTION_SET_ARM, "TOSA.001000.1", 0};
        static constexpr VkPhysicalDeviceDataGraphOperationSupportARM optical_flow_operation{
            VK_PHYSICAL_DEVICE_DATA_GRAPH_OPERATION_TYPE_OPTICAL_FLOW_ARM, "OpticalFlow", 1};

        // get the values for the 2 properties supported in the default processing engine.
        VkQueueFamilyDataGraphOpticalFlowPropertiesARM op_flow_properties = vku::InitStructHelper();
        VkQueueFamilyDataGraphTOSAPropertiesARM tosa_properties = vku::InitStructHelper();
        VkBaseOutStructure* pProperties = nullptr;
        if (prop.operation.operationType == optical_flow_operation.operationType &&
            strcmp(prop.operation.name, optical_flow_operation.name) == 0) {
            pProperties = reinterpret_cast<VkBaseOutStructure*>(&op_flow_properties);
        } else if (prop.operation.operationType == tosa_operation.operationType &&
                   strcmp(prop.operation.name, tosa_operation.name) == 0) {
            pProperties = reinterpret_cast<VkBaseOutStructure*>(&tosa_properties);
        } else {
            // some other property that we haven't considered (other engine? Add)
            continue;
        }

        m_errorMonitor->SetDesiredError(
            "VUID-vkGetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM-pQueueFamilyDataGraphProperties-09957");
        ASSERT_EQ(VK_ERROR_VALIDATION_FAILED,
                  vk::GetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM(Gpu(), queue_index, &prop, pProperties));
        m_errorMonitor->VerifyFound();
        test_executed = true;
    }
    if (!test_executed) {
        GTEST_SKIP() << "No queue-family-specific data graph properties available.";
    }
}

TEST_F(NegativeDataGraph, ProcessingEnginesGetPropertiesWrongType) {
    TEST_DESCRIPTION("Request the Processing Engine properties using the wrong structure");
    RETURN_IF_SKIP(InitBasicDataGraph(true));

    // get the available properties
    uint32_t queue_index = DefaultQueue()->family_index;
    uint32_t n_properties = 0;
    ASSERT_EQ(VK_SUCCESS, vk::GetPhysicalDeviceQueueFamilyDataGraphPropertiesARM(Gpu(), queue_index, &n_properties, nullptr));
    if (n_properties == 0) {
        GTEST_SKIP() << "The physical device does not support any datagraph properties, skip.";
    }
    std::vector<VkQueueFamilyDataGraphPropertiesARM> data_graph_queue_family_properties(
        n_properties, vku::InitStruct<VkQueueFamilyDataGraphPropertiesARM>());
    ASSERT_EQ(VK_SUCCESS, vk::GetPhysicalDeviceQueueFamilyDataGraphPropertiesARM(Gpu(), queue_index, &n_properties,
                                                                                 data_graph_queue_family_properties.data()));

    VkQueueFamilyDataGraphPropertiesARM properties = vku::InitStructHelper();  // WRONG structure!
    VkBaseOutStructure* pProperties = reinterpret_cast<VkBaseOutStructure*>(&properties);
    m_errorMonitor->SetDesiredError("VUID-vkGetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM-pProperties-09958");
    ASSERT_EQ(VK_ERROR_VALIDATION_FAILED, vk::GetPhysicalDeviceQueueFamilyDataGraphEngineOperationPropertiesARM(
                                              Gpu(), queue_index, &data_graph_queue_family_properties[0], pProperties));
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, ProtectedAccessOnlyWithNeuralStatistics) {
    TEST_DESCRIPTION(
        "Try to create a protected DataGraphPipeline (VK_PIPELINE_CREATE_2_PROTECTED_ACCESS_ONLY_BIT_EXT) with incompatible neural "
        "statistics (VkDataGraphPipelineNeuralStatisticsCreateInfoARM)");

    AddRequiredExtensions(VK_ARM_DATA_GRAPH_NEURAL_ACCELERATOR_STATISTICS_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::dataGraphNeuralAcceleratorStatistics);
    AddRequiredFeature(vkt::Feature::protectedMemory);
    AddRequiredExtensions(VK_EXT_PIPELINE_PROTECTED_ACCESS_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::pipelineProtectedAccess);
    RETURN_IF_SKIP(InitBasicDataGraph());

    // enable protected access and ask for neural stats: invalid because no data can be returned with protected access
    VkDataGraphPipelineNeuralStatisticsCreateInfoARM ne_stats_info = vku::InitStructHelper();
    ne_stats_info.allowNeuralStatistics = VK_TRUE;
    vkt::dg::DataGraphPipelineHelper helper(*this);
    helper.pipeline_ci_.flags = VK_PIPELINE_CREATE_2_PROTECTED_ACCESS_ONLY_BIT_EXT;
    vvl::PnextChainAdd(&helper.pipeline_ci_, &ne_stats_info);
    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineCreateInfoARM-flags-09848");
    helper.CreateDataGraphPipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, ProtectedSessionWithNeuralStatistics) {
    TEST_DESCRIPTION("Try to request neural statistics in a protected DataGraphPipelineSession (can't return any data)");
    AddRequiredExtensions(VK_ARM_DATA_GRAPH_NEURAL_ACCELERATOR_STATISTICS_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::dataGraphNeuralAcceleratorStatistics);
    AddRequiredFeature(vkt::Feature::protectedMemory);
    RETURN_IF_SKIP(InitBasicDataGraph());

    // create a protected session and ask for neural stats: invalid because no data can be returned with protected access
    VkDataGraphPipelineNeuralStatisticsCreateInfoARM ne_stats_info = vku::InitStructHelper();
    ne_stats_info.allowNeuralStatistics = VK_TRUE;
    vkt::dg::DataGraphPipelineHelper helper(*this);
    vvl::PnextChainAdd(&helper.pipeline_ci_, &ne_stats_info);
    helper.CreateDataGraphPipeline();

    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper();
    session_ci.dataGraphPipeline = helper;
    session_ci.flags = VK_DATA_GRAPH_PIPELINE_SESSION_CREATE_PROTECTED_BIT_ARM;

    VkDataGraphPipelineSessionARM session;
    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineSessionCreateInfoARM-flags-09853");
    vk::CreateDataGraphPipelineSessionARM(*m_device, &session_ci, nullptr, &session);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, SessionWithNeuralStatisticsCreateInfoInvalid) {
    TEST_DESCRIPTION("Try to create a DataGraphPipelineSession with an invalid NeuralStatisticsCreateInfo");
    AddRequiredExtensions(VK_ARM_DATA_GRAPH_NEURAL_ACCELERATOR_STATISTICS_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::dataGraphNeuralAcceleratorStatistics);
    RETURN_IF_SKIP(InitBasicDataGraph());

    // pass an INCORRECT request for neural statistics (allowNeuralStatistics == false)
    VkDataGraphPipelineNeuralStatisticsCreateInfoARM ne_stats_info = vku::InitStructHelper();
    ne_stats_info.allowNeuralStatistics = VK_FALSE;  // MUST be true
    vkt::dg::DataGraphPipelineHelper helper(*this);
    vvl::PnextChainAdd(&helper.pipeline_ci_, &ne_stats_info);
    helper.CreateDataGraphPipeline();

    // initialize a SessionCreateInfo including a SessionNeuralStatisticsCreateInfo
    VkDataGraphPipelineSessionNeuralStatisticsCreateInfoARM session_ne_stats_info = vku::InitStructHelper();
    session_ne_stats_info.mode = VkNeuralAcceleratorStatisticsModeARM::VK_NEURAL_ACCELERATOR_STATISTICS_MODE_STATISTICS0_ARM;
    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper(&session_ne_stats_info);
    session_ci.dataGraphPipeline = helper;

    VkDataGraphPipelineSessionARM session = VK_NULL_HANDLE;
    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineSessionCreateInfoARM-pNext-09852");
    vk::CreateDataGraphPipelineSessionARM(*m_device, &session_ci, nullptr, &session);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, SessionWithNeuralStatisticsCreateInfoMissing) {
    TEST_DESCRIPTION("Try to create Session Neural statistics without initializing (basic) Neural statistics");
    AddRequiredExtensions(VK_ARM_DATA_GRAPH_NEURAL_ACCELERATOR_STATISTICS_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::dataGraphNeuralAcceleratorStatistics);
    RETURN_IF_SKIP(InitBasicDataGraph());

    // create a pipeline WITHOUT a VkDataGraphPipelineNeuralStatisticsCreateInfoARM in the pNext chain (see previous test)
    vkt::dg::DataGraphPipelineHelper helper(*this);
    helper.CreateDataGraphPipeline();

    // initialize a SessionCreateInfo including a SessionNeuralStatisticsCreateInfo
    VkDataGraphPipelineSessionNeuralStatisticsCreateInfoARM session_ne_stats_info = vku::InitStructHelper();
    session_ne_stats_info.mode = VkNeuralAcceleratorStatisticsModeARM::VK_NEURAL_ACCELERATOR_STATISTICS_MODE_STATISTICS0_ARM;
    VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper(&session_ne_stats_info);
    session_ci.dataGraphPipeline = helper;

    VkDataGraphPipelineSessionARM session = VK_NULL_HANDLE;
    m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineSessionCreateInfoARM-pNext-09852");
    vk::CreateDataGraphPipelineSessionARM(*m_device, &session_ci, nullptr, &session);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, QueryNeuralStatisticsMissingCreateInfo) {
    TEST_DESCRIPTION("Try to query the neural statistics property but the property has not been enabled (missing create_info)");
    AddRequiredExtensions(VK_ARM_DATA_GRAPH_NEURAL_ACCELERATOR_STATISTICS_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::dataGraphNeuralAcceleratorStatistics);
    RETURN_IF_SKIP(InitBasicDataGraph());
    // create pipeline, WITHOUT a create info for the neural statistics
    vkt::dg::DataGraphPipelineHelper helper(*this);
    helper.CreateDataGraphPipeline();
    // query the neural stats
    VkDataGraphPipelineInfoARM pipeline_info = vku::InitStructHelper();
    pipeline_info.dataGraphPipeline = helper;

    /* query with `pData` null, to get back the required `dataSize`. Enough to trigger the VUID
       NOTE: passing an array, to make sure the check is implemented correctly */
    std::array<VkDataGraphPipelinePropertyQueryResultARM, 2> query_result;
    query_result[0] = vku::InitStructHelper();
    query_result[0].property = VK_DATA_GRAPH_PIPELINE_PROPERTY_CREATION_LOG_ARM;
    query_result[0].pData = nullptr;
    query_result[0].dataSize = 0;
    query_result[1] = vku::InitStructHelper();
    query_result[1].property = VK_DATA_GRAPH_PIPELINE_PROPERTY_NEURAL_ACCELERATOR_STATISTICS_INFO_ARM;
    query_result[1].pData = nullptr;
    query_result[1].dataSize = 0;

    uint32_t prop_count = query_result.size();
    m_errorMonitor->SetDesiredError("VUID-vkGetDataGraphPipelinePropertiesARM-pProperties-09856");
    vk::GetDataGraphPipelinePropertiesARM(device(), &pipeline_info, prop_count, query_result.data());
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDataGraph, QueryNeuralStatisticsAllowedFalse) {
    TEST_DESCRIPTION(
        "Try to query the neural statistics property but the property has not been enabled (create_info exists but "
        "allowNeuralStatistics is false)");
    AddRequiredExtensions(VK_ARM_DATA_GRAPH_NEURAL_ACCELERATOR_STATISTICS_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::dataGraphNeuralAcceleratorStatistics);
    RETURN_IF_SKIP(InitBasicDataGraph());

    // add the neural stats create info but DISABLE stats
    VkDataGraphPipelineNeuralStatisticsCreateInfoARM ne_stats_info = vku::InitStructHelper();
    ne_stats_info.allowNeuralStatistics = VK_FALSE;  // this MUST be true to get the stats
    vkt::dg::DataGraphPipelineHelper helper(*this);
    vvl::PnextChainAdd(&helper.pipeline_ci_, &ne_stats_info);
    helper.CreateDataGraphPipeline();
    // query the neural stats
    VkDataGraphPipelineInfoARM pipeline_info = vku::InitStructHelper();
    pipeline_info.dataGraphPipeline = helper;
    VkDataGraphPipelinePropertyQueryResultARM query_result = vku::InitStructHelper();
    // query with pData null, to get back the required dataSize. Enough to trigger the VUID
    query_result.property = VK_DATA_GRAPH_PIPELINE_PROPERTY_NEURAL_ACCELERATOR_STATISTICS_INFO_ARM;
    query_result.pData = nullptr;
    query_result.dataSize = 0;
    uint32_t prop_count = 1;
    m_errorMonitor->SetDesiredError("VUID-vkGetDataGraphPipelinePropertiesARM-pProperties-09856");
    vk::GetDataGraphPipelinePropertiesARM(m_device->handle(), &pipeline_info, prop_count, &query_result);
    m_errorMonitor->VerifyFound();
}
