aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXusong Wang <xusongw@google.com>2021-06-09 10:45:34 -0700
committerXusong Wang <xusongw@google.com>2021-06-09 11:01:09 -0700
commit7fd13ec3f3d6d9a8f98187e02987128001b8ee31 (patch)
tree24bc967e1b7ea44e9d8401625160507347254824
parent6d2180cdd897555ccff773f0e8a0cb2b3f5a2315 (diff)
downloadNeuralNetworks-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.cpp40
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);