1 // 2 // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved. 3 // SPDX-License-Identifier: MIT 4 // 5 6 #include <armnn/backends/ICustomAllocator.hpp> 7 #include <armnn/BackendRegistry.hpp> 8 #include <armnn/Descriptors.hpp> 9 #include <armnn/Exceptions.hpp> 10 #include <armnn/IRuntime.hpp> 11 #include <armnn/backends/TensorHandle.hpp> 12 // Requires the OpenCl backend to be included (GpuAcc) 13 #include <cl/ClBackend.hpp> 14 #include <doctest/doctest.h> 15 #include <backendsCommon/DefaultAllocator.hpp> 16 #include <armnnTestUtils/MockBackend.hpp> 17 #include <cl/ClBackendDefaultAllocator.hpp> 18 19 using namespace armnn; 20 21 22 namespace 23 { 24 25 TEST_SUITE("DefaultAllocatorTests") 26 { 27 28 TEST_CASE("DefaultAllocatorTest") 29 { 30 float number = 3; 31 32 TensorInfo inputTensorInfo(TensorShape({1, 1}), DataType::Float32); 33 34 // Create ArmNN runtime 35 IRuntime::CreationOptions options; // default options 36 auto customAllocator = std::make_shared<DefaultAllocator>(); 37 options.m_CustomAllocatorMap = {{"GpuAcc", std::move(customAllocator)}}; 38 IRuntimePtr run = IRuntime::Create(options); 39 40 // Creates structures for input & output 41 unsigned int numElements = inputTensorInfo.GetNumElements(); 42 size_t totalBytes = numElements * sizeof(float); 43 44 void* alignedInputPtr = options.m_CustomAllocatorMap["GpuAcc"]->allocate(totalBytes, 0); 45 46 auto* inputPtr = reinterpret_cast<float*>(alignedInputPtr); 47 std::fill_n(inputPtr, numElements, number); 48 CHECK(inputPtr[0] == 3); 49 50 auto& backendRegistry = armnn::BackendRegistryInstance(); 51 backendRegistry.DeregisterAllocator(ClBackend::GetIdStatic()); 52 } 53 54 TEST_CASE("DefaultAllocatorTestMulti") 55 { 56 float number = 3; 57 58 TensorInfo inputTensorInfo(TensorShape({2, 1}), DataType::Float32); 59 60 // Create ArmNN runtime 61 IRuntime::CreationOptions options; // default options 62 auto customAllocator = std::make_shared<DefaultAllocator>(); 63 options.m_CustomAllocatorMap = {{"GpuAcc", std::move(customAllocator)}}; 64 IRuntimePtr run = IRuntime::Create(options); 65 66 // Creates structures for input & output 67 unsigned int numElements = inputTensorInfo.GetNumElements(); 68 size_t totalBytes = numElements * sizeof(float); 69 70 void* alignedInputPtr = options.m_CustomAllocatorMap["GpuAcc"]->allocate(totalBytes, 0); 71 void* alignedInputPtr2 = options.m_CustomAllocatorMap["GpuAcc"]->allocate(totalBytes, 0); 72 73 auto* inputPtr = reinterpret_cast<float*>(alignedInputPtr); 74 std::fill_n(inputPtr, numElements, number); 75 CHECK(inputPtr[0] == 3); 76 CHECK(inputPtr[1] == 3); 77 78 auto* inputPtr2 = reinterpret_cast<float*>(alignedInputPtr2); 79 std::fill_n(inputPtr2, numElements, number); 80 CHECK(inputPtr2[0] == 3); 81 CHECK(inputPtr2[1] == 3); 82 83 // No overlap 84 CHECK(inputPtr[0] == 3); 85 CHECK(inputPtr[1] == 3); 86 87 auto& backendRegistry = armnn::BackendRegistryInstance(); 88 backendRegistry.DeregisterAllocator(ClBackend::GetIdStatic()); 89 } 90 91 TEST_CASE("DefaultAllocatorTestMock") 92 { 93 // Create ArmNN runtime 94 IRuntime::CreationOptions options; // default options 95 IRuntimePtr run = IRuntime::Create(options); 96 97 // Initialize Mock Backend 98 MockBackendInitialiser initialiser; 99 auto factoryFun = BackendRegistryInstance().GetFactory(MockBackend().GetIdStatic()); 100 ARMNN_ASSERT(factoryFun != nullptr); 101 auto backend = factoryFun(); 102 auto defaultAllocator = backend->GetDefaultAllocator(); 103 104 // GetMemorySourceType 105 CHECK(defaultAllocator->GetMemorySourceType() == MemorySource::Malloc); 106 107 size_t totalBytes = 1 * sizeof(float); 108 // Allocate 109 void* ptr = defaultAllocator->allocate(totalBytes, 0); 110 111 // GetMemoryRegionAtOffset 112 CHECK(defaultAllocator->GetMemoryRegionAtOffset(ptr, 0, 0)); 113 114 // Free 115 defaultAllocator->free(ptr); 116 117 // Clean up 118 auto& backendRegistry = armnn::BackendRegistryInstance(); 119 backendRegistry.Deregister(MockBackend().GetIdStatic()); 120 backendRegistry.DeregisterAllocator(ClBackend::GetIdStatic()); 121 } 122 123 } 124 125 126 TEST_SUITE("ClDefaultAllocatorTests") 127 { 128 129 TEST_CASE("ClDefaultAllocatorTest") 130 { 131 float number = 3; 132 133 TensorInfo inputTensorInfo(TensorShape({1, 1}), DataType::Float32); 134 135 // Create ArmNN runtime 136 IRuntime::CreationOptions options; // default options 137 auto customAllocator = std::make_shared<ClBackendDefaultAllocator>(); 138 options.m_CustomAllocatorMap = {{"GpuAcc", std::move(customAllocator)}}; 139 IRuntimePtr run = IRuntime::Create(options); 140 141 // Creates structures for input & output 142 unsigned int numElements = inputTensorInfo.GetNumElements(); 143 size_t totalBytes = numElements * sizeof(float); 144 145 void* alignedInputPtr = options.m_CustomAllocatorMap["GpuAcc"]->allocate(totalBytes, 0); 146 147 auto* inputPtr = reinterpret_cast<float*>(alignedInputPtr); 148 std::fill_n(inputPtr, numElements, number); 149 CHECK(inputPtr[0] == 3); 150 151 auto& backendRegistry = armnn::BackendRegistryInstance(); 152 backendRegistry.DeregisterAllocator(ClBackend::GetIdStatic()); 153 } 154 155 TEST_CASE("ClDefaultAllocatorTestMulti") 156 { 157 float number = 3; 158 159 TensorInfo inputTensorInfo(TensorShape({2, 1}), DataType::Float32); 160 161 // Create ArmNN runtime 162 IRuntime::CreationOptions options; // default options 163 auto customAllocator = std::make_shared<ClBackendDefaultAllocator>(); 164 options.m_CustomAllocatorMap = {{"GpuAcc", std::move(customAllocator)}}; 165 IRuntimePtr run = IRuntime::Create(options); 166 167 // Creates structures for input & output 168 unsigned int numElements = inputTensorInfo.GetNumElements(); 169 size_t totalBytes = numElements * sizeof(float); 170 171 void* alignedInputPtr = options.m_CustomAllocatorMap["GpuAcc"]->allocate(totalBytes, 0); 172 void* alignedInputPtr2 = options.m_CustomAllocatorMap["GpuAcc"]->allocate(totalBytes, 0); 173 174 auto* inputPtr = reinterpret_cast<float*>(alignedInputPtr); 175 std::fill_n(inputPtr, numElements, number); 176 CHECK(inputPtr[0] == 3); 177 CHECK(inputPtr[1] == 3); 178 179 auto* inputPtr2 = reinterpret_cast<float*>(alignedInputPtr2); 180 std::fill_n(inputPtr2, numElements, number); 181 CHECK(inputPtr2[0] == 3); 182 CHECK(inputPtr2[1] == 3); 183 184 // No overlap 185 CHECK(inputPtr[0] == 3); 186 CHECK(inputPtr[1] == 3); 187 188 auto& backendRegistry = armnn::BackendRegistryInstance(); 189 backendRegistry.DeregisterAllocator(ClBackend::GetIdStatic()); 190 } 191 192 } 193 194 } // namespace armnn