diff options
author | Xusong Wang <xusongw@google.com> | 2021-06-09 10:45:34 -0700 |
---|---|---|
committer | Xusong Wang <xusongw@google.com> | 2021-06-09 11:01:09 -0700 |
commit | 7fd13ec3f3d6d9a8f98187e02987128001b8ee31 (patch) | |
tree | 24bc967e1b7ea44e9d8401625160507347254824 | |
parent | 6d2180cdd897555ccff773f0e8a0cb2b3f5a2315 (diff) | |
download | NeuralNetworks-7fd13ec3f3d6d9a8f98187e02987128001b8ee31.tar.gz |
Skip TestGpuNnapi if the device does not have enough GPU memory.
This CL modifies TestGpuNnapi to choose a heap that is large enough for
memory allocation and skip the test if none of them is suitable. Even if
we found a large enough heap, the device memory allocation may still
fail if the allocation size exceeds the upper limit of a single
allocation that the platform supports. In such a case, the test will
also be skipped.
This CL also fixes a bug when checking the supported extensions --
strcmp returns 0 on match and non-0 on mismatch.
Fixes: 190527027
Test: NNT_static
Change-Id: Iee829307a8cd95ea8701f23cbff279e21266aeb6
-rw-r--r-- | runtime/test/TestGpuNnapi.cpp | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/runtime/test/TestGpuNnapi.cpp b/runtime/test/TestGpuNnapi.cpp index 1d5ea3ddf..c527d7865 100644 --- a/runtime/test/TestGpuNnapi.cpp +++ b/runtime/test/TestGpuNnapi.cpp @@ -132,7 +132,7 @@ bool isExtensionSupported(const std::vector<VkExtensionProperties>& supportedExt const char* requestedExtension) { return std::any_of(supportedExtensions.begin(), supportedExtensions.end(), [requestedExtension](const auto& extension) { - return strcmp(extension.extensionName, requestedExtension); + return strcmp(extension.extensionName, requestedExtension) == 0; }); } @@ -183,19 +183,19 @@ DispatchSize chooseDispatchSize(const VkPhysicalDeviceLimits& limits) { // Find the first memory index that satisfies the requirements // See VkAndroidHardwareBufferPropertiesANDROID::memoryTypeBits for the semantics of // "memoryTypeBitsRequirement" -uint32_t findMemoryType(const VkPhysicalDeviceMemoryProperties& properties, - uint32_t memoryTypeBitsRequirement, VkFlags requirementsMask) { +std::optional<uint32_t> findMemoryType(const VkPhysicalDeviceMemoryProperties& properties, + uint32_t memoryTypeBitsRequirement, + VkDeviceSize sizeRequirement) { for (uint32_t memoryIndex = 0; memoryIndex < VK_MAX_MEMORY_TYPES; ++memoryIndex) { const uint32_t memoryTypeBits = (1 << memoryIndex); const bool isRequiredMemoryType = memoryTypeBitsRequirement & memoryTypeBits; - const bool satisfiesFlags = (properties.memoryTypes[memoryIndex].propertyFlags & - requirementsMask) == requirementsMask; - if (isRequiredMemoryType && satisfiesFlags) return memoryIndex; + const uint32_t heapIndex = properties.memoryTypes[memoryIndex].heapIndex; + const bool isLargeEnough = properties.memoryHeaps[heapIndex].size >= sizeRequirement; + if (isRequiredMemoryType && isLargeEnough) return memoryIndex; } // failed to find memory type. - CHECK(false); - return 0; + return std::nullopt; } void addBufferTransitionBarrier(VkCommandBuffer commandBuffer, VkBuffer buffer, @@ -545,6 +545,14 @@ class VulkanComputePipeline { }; ASSERT_EQ(vkCreateBuffer(mDevice, &bufferCreateInfo, nullptr, &mOutputBuffer), VK_SUCCESS); + // Find a proper memory type + const auto maybeMemoryTypeIndex = + findMemoryType(mPhysicalDeviceMemoryProperties, properties.memoryTypeBits, + properties.allocationSize); + if (!maybeMemoryTypeIndex.has_value()) { + GTEST_SKIP() << "None of the memory type is suitable for allocation"; + } + // Import the AHardwareBuffer memory const VkImportAndroidHardwareBufferInfoANDROID importMemoryAllocateInfo = { .sType = VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID, @@ -555,11 +563,17 @@ class VulkanComputePipeline { .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, .pNext = &importMemoryAllocateInfo, .allocationSize = properties.allocationSize, - .memoryTypeIndex = findMemoryType(mPhysicalDeviceMemoryProperties, - properties.memoryTypeBits, 0), - }; - ASSERT_EQ(vkAllocateMemory(mDevice, &memoryAllocInfo, nullptr, &mOutputBufferMemory), - VK_SUCCESS); + .memoryTypeIndex = maybeMemoryTypeIndex.value(), + }; + const auto allocationResult = + vkAllocateMemory(mDevice, &memoryAllocInfo, nullptr, &mOutputBufferMemory); + // Memory allocation may fail if the size exceeds the upper limit of a single allocation + // that the platform supports + if (allocationResult == VK_ERROR_OUT_OF_DEVICE_MEMORY) { + GTEST_SKIP() << "Unable to allocate device memory of " << properties.allocationSize + << " bytes"; + } + ASSERT_EQ(allocationResult, VK_SUCCESS); // Bind the memory with the buffer ASSERT_EQ(vkBindBufferMemory(mDevice, mOutputBuffer, mOutputBufferMemory, 0), VK_SUCCESS); |