1*89c4ff92SAndroid Build Coastguard Worker // 2*89c4ff92SAndroid Build Coastguard Worker // Copyright © 2017 Arm Ltd. All rights reserved. 3*89c4ff92SAndroid Build Coastguard Worker // SPDX-License-Identifier: MIT 4*89c4ff92SAndroid Build Coastguard Worker // 5*89c4ff92SAndroid Build Coastguard Worker 6*89c4ff92SAndroid Build Coastguard Worker #include <test/RuntimeTests.hpp> 7*89c4ff92SAndroid Build Coastguard Worker 8*89c4ff92SAndroid Build Coastguard Worker #include <LeakChecking.hpp> 9*89c4ff92SAndroid Build Coastguard Worker 10*89c4ff92SAndroid Build Coastguard Worker #include <backendsCommon/test/RuntimeTestImpl.hpp> 11*89c4ff92SAndroid Build Coastguard Worker #include <test/ProfilingTestUtils.hpp> 12*89c4ff92SAndroid Build Coastguard Worker #include <armnn/utility/IgnoreUnused.hpp> 13*89c4ff92SAndroid Build Coastguard Worker 14*89c4ff92SAndroid Build Coastguard Worker #include <doctest/doctest.h> 15*89c4ff92SAndroid Build Coastguard Worker 16*89c4ff92SAndroid Build Coastguard Worker #ifdef WITH_VALGRIND 17*89c4ff92SAndroid Build Coastguard Worker #include <valgrind/memcheck.h> 18*89c4ff92SAndroid Build Coastguard Worker #endif 19*89c4ff92SAndroid Build Coastguard Worker 20*89c4ff92SAndroid Build Coastguard Worker TEST_SUITE("ClRuntime") 21*89c4ff92SAndroid Build Coastguard Worker { 22*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("RuntimeValidateGpuDeviceSupportLayerNoFallback") 23*89c4ff92SAndroid Build Coastguard Worker { 24*89c4ff92SAndroid Build Coastguard Worker // build up the structure of the network 25*89c4ff92SAndroid Build Coastguard Worker armnn::INetworkPtr net(armnn::INetwork::Create()); 26*89c4ff92SAndroid Build Coastguard Worker 27*89c4ff92SAndroid Build Coastguard Worker armnn::IConnectableLayer* input = net->AddInputLayer(0); 28*89c4ff92SAndroid Build Coastguard Worker armnn::IConnectableLayer* output = net->AddOutputLayer(0); 29*89c4ff92SAndroid Build Coastguard Worker 30*89c4ff92SAndroid Build Coastguard Worker input->GetOutputSlot(0).Connect(output->GetInputSlot(0)); 31*89c4ff92SAndroid Build Coastguard Worker input->GetOutputSlot(0).SetTensorInfo(armnn::TensorInfo({ 1, 1, 4, 4 }, armnn::DataType::Float32)); 32*89c4ff92SAndroid Build Coastguard Worker 33*89c4ff92SAndroid Build Coastguard Worker armnn::IRuntime::CreationOptions options; 34*89c4ff92SAndroid Build Coastguard Worker armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options)); 35*89c4ff92SAndroid Build Coastguard Worker 36*89c4ff92SAndroid Build Coastguard Worker std::vector<armnn::BackendId> backends = { armnn::Compute::GpuAcc }; 37*89c4ff92SAndroid Build Coastguard Worker armnn::IOptimizedNetworkPtr optNet = armnn::Optimize(*net, backends, runtime->GetDeviceSpec()); 38*89c4ff92SAndroid Build Coastguard Worker CHECK(optNet); 39*89c4ff92SAndroid Build Coastguard Worker 40*89c4ff92SAndroid Build Coastguard Worker // Load it into the runtime. It should success. 41*89c4ff92SAndroid Build Coastguard Worker armnn::NetworkId netId; 42*89c4ff92SAndroid Build Coastguard Worker CHECK(runtime->LoadNetwork(netId, std::move(optNet)) == armnn::Status::Success); 43*89c4ff92SAndroid Build Coastguard Worker } 44*89c4ff92SAndroid Build Coastguard Worker 45*89c4ff92SAndroid Build Coastguard Worker #ifdef ARMNN_LEAK_CHECKING_ENABLED 46*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("RuntimeMemoryLeaksGpuAcc") 47*89c4ff92SAndroid Build Coastguard Worker { 48*89c4ff92SAndroid Build Coastguard Worker CHECK(ARMNN_LEAK_CHECKER_IS_ACTIVE()); 49*89c4ff92SAndroid Build Coastguard Worker armnn::IRuntime::CreationOptions options; 50*89c4ff92SAndroid Build Coastguard Worker armnn::RuntimeImpl runtime(options); 51*89c4ff92SAndroid Build Coastguard Worker armnn::RuntimeLoadedNetworksReserve(&runtime); 52*89c4ff92SAndroid Build Coastguard Worker 53*89c4ff92SAndroid Build Coastguard Worker std::vector<armnn::BackendId> backends = {armnn::Compute::GpuAcc}; 54*89c4ff92SAndroid Build Coastguard Worker { 55*89c4ff92SAndroid Build Coastguard Worker // Do a warmup of this so we make sure that all one-time 56*89c4ff92SAndroid Build Coastguard Worker // initialization happens before we do the leak checking. 57*89c4ff92SAndroid Build Coastguard Worker CreateAndDropDummyNetwork(backends, runtime); 58*89c4ff92SAndroid Build Coastguard Worker } 59*89c4ff92SAndroid Build Coastguard Worker 60*89c4ff92SAndroid Build Coastguard Worker { 61*89c4ff92SAndroid Build Coastguard Worker ARMNN_SCOPED_LEAK_CHECKER("LoadAndUnloadNetworkGpuAcc"); 62*89c4ff92SAndroid Build Coastguard Worker CHECK(ARMNN_NO_LEAKS_IN_SCOPE()); 63*89c4ff92SAndroid Build Coastguard Worker // In the second run we check for all remaining memory 64*89c4ff92SAndroid Build Coastguard Worker // in use after the network was unloaded. If there is any 65*89c4ff92SAndroid Build Coastguard Worker // then it will be treated as a memory leak. 66*89c4ff92SAndroid Build Coastguard Worker CreateAndDropDummyNetwork(backends, runtime); 67*89c4ff92SAndroid Build Coastguard Worker CHECK(ARMNN_NO_LEAKS_IN_SCOPE()); 68*89c4ff92SAndroid Build Coastguard Worker CHECK(ARMNN_BYTES_LEAKED_IN_SCOPE() == 0); 69*89c4ff92SAndroid Build Coastguard Worker CHECK(ARMNN_OBJECTS_LEAKED_IN_SCOPE() == 0); 70*89c4ff92SAndroid Build Coastguard Worker } 71*89c4ff92SAndroid Build Coastguard Worker } 72*89c4ff92SAndroid Build Coastguard Worker #endif 73*89c4ff92SAndroid Build Coastguard Worker 74*89c4ff92SAndroid Build Coastguard Worker // Note: this part of the code is due to be removed when we fully trust the gperftools based results. 75*89c4ff92SAndroid Build Coastguard Worker #if defined(WITH_VALGRIND) 76*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("RuntimeMemoryUsage") 77*89c4ff92SAndroid Build Coastguard Worker { 78*89c4ff92SAndroid Build Coastguard Worker // From documentation: 79*89c4ff92SAndroid Build Coastguard Worker 80*89c4ff92SAndroid Build Coastguard Worker // This means that no pointer to the block can be found. The block is classified as "lost", 81*89c4ff92SAndroid Build Coastguard Worker // because the programmer could not possibly have freed it at program exit, since no pointer to it exists. 82*89c4ff92SAndroid Build Coastguard Worker unsigned long leakedBefore = 0; 83*89c4ff92SAndroid Build Coastguard Worker unsigned long leakedAfter = 0; 84*89c4ff92SAndroid Build Coastguard Worker 85*89c4ff92SAndroid Build Coastguard Worker // A start-pointer or chain of start-pointers to the block is found. Since the block is still pointed at, 86*89c4ff92SAndroid Build Coastguard Worker // the programmer could, at least in principle, have freed it before program exit. 87*89c4ff92SAndroid Build Coastguard Worker // We want to test this in case memory is not freed as early as it could have been. 88*89c4ff92SAndroid Build Coastguard Worker unsigned long reachableBefore = 0; 89*89c4ff92SAndroid Build Coastguard Worker unsigned long reachableAfter = 0; 90*89c4ff92SAndroid Build Coastguard Worker 91*89c4ff92SAndroid Build Coastguard Worker // Needed as out params but we don't test them. 92*89c4ff92SAndroid Build Coastguard Worker unsigned long dubious = 0; 93*89c4ff92SAndroid Build Coastguard Worker unsigned long suppressed = 0; 94*89c4ff92SAndroid Build Coastguard Worker 95*89c4ff92SAndroid Build Coastguard Worker // Ensure that runtime is large enough before checking for memory leaks. 96*89c4ff92SAndroid Build Coastguard Worker // Otherwise, when loading the network, it will automatically reserve memory that won't be released 97*89c4ff92SAndroid Build Coastguard Worker // until destruction. 98*89c4ff92SAndroid Build Coastguard Worker armnn::NetworkId networkIdentifier; 99*89c4ff92SAndroid Build Coastguard Worker armnn::IRuntime::CreationOptions options; 100*89c4ff92SAndroid Build Coastguard Worker armnn::Runtime runtime(options); 101*89c4ff92SAndroid Build Coastguard Worker armnn::RuntimeLoadedNetworksReserve(&runtime); 102*89c4ff92SAndroid Build Coastguard Worker 103*89c4ff92SAndroid Build Coastguard Worker // Checks for leaks before we load the network and record them so that we can see the delta after unloading. 104*89c4ff92SAndroid Build Coastguard Worker VALGRIND_DO_QUICK_LEAK_CHECK; 105*89c4ff92SAndroid Build Coastguard Worker VALGRIND_COUNT_LEAKS(leakedBefore, dubious, reachableBefore, suppressed); 106*89c4ff92SAndroid Build Coastguard Worker 107*89c4ff92SAndroid Build Coastguard Worker // build a mock-network and load it into the runtime 108*89c4ff92SAndroid Build Coastguard Worker std::vector<armnn::BackendId> backends = {armnn::Compute::GpuAcc}; 109*89c4ff92SAndroid Build Coastguard Worker { 110*89c4ff92SAndroid Build Coastguard Worker armnn::TensorInfo inputTensorInfo(armnn::TensorShape({ 7, 7 }), armnn::DataType::Float32); 111*89c4ff92SAndroid Build Coastguard Worker armnn::TensorInfo outputTensorInfo(armnn::TensorShape({ 7, 7 }), armnn::DataType::Float32); 112*89c4ff92SAndroid Build Coastguard Worker 113*89c4ff92SAndroid Build Coastguard Worker armnn::INetworkPtr mockNetwork(armnn::INetwork::Create()); 114*89c4ff92SAndroid Build Coastguard Worker 115*89c4ff92SAndroid Build Coastguard Worker armnn::IConnectableLayer* input = mockNetwork->AddInputLayer(0, "input"); 116*89c4ff92SAndroid Build Coastguard Worker armnn::IConnectableLayer* layer = mockNetwork->AddActivationLayer(armnn::ActivationDescriptor(), "test"); 117*89c4ff92SAndroid Build Coastguard Worker armnn::IConnectableLayer* output = mockNetwork->AddOutputLayer(0, "output"); 118*89c4ff92SAndroid Build Coastguard Worker 119*89c4ff92SAndroid Build Coastguard Worker input->GetOutputSlot(0).Connect(layer->GetInputSlot(0)); 120*89c4ff92SAndroid Build Coastguard Worker layer->GetOutputSlot(0).Connect(output->GetInputSlot(0)); 121*89c4ff92SAndroid Build Coastguard Worker 122*89c4ff92SAndroid Build Coastguard Worker // Sets the tensors in the network. 123*89c4ff92SAndroid Build Coastguard Worker input->GetOutputSlot(0).SetTensorInfo(inputTensorInfo); 124*89c4ff92SAndroid Build Coastguard Worker layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo); 125*89c4ff92SAndroid Build Coastguard Worker 126*89c4ff92SAndroid Build Coastguard Worker // optimize the network 127*89c4ff92SAndroid Build Coastguard Worker armnn::IOptimizedNetworkPtr optNet = Optimize(*mockNetwork, backends, runtime.GetDeviceSpec()); 128*89c4ff92SAndroid Build Coastguard Worker 129*89c4ff92SAndroid Build Coastguard Worker runtime.LoadNetwork(networkIdentifier, std::move(optNet)); 130*89c4ff92SAndroid Build Coastguard Worker } 131*89c4ff92SAndroid Build Coastguard Worker 132*89c4ff92SAndroid Build Coastguard Worker runtime.UnloadNetwork(networkIdentifier); 133*89c4ff92SAndroid Build Coastguard Worker 134*89c4ff92SAndroid Build Coastguard Worker VALGRIND_DO_ADDED_LEAK_CHECK; 135*89c4ff92SAndroid Build Coastguard Worker VALGRIND_COUNT_LEAKS(leakedAfter, dubious, reachableAfter, suppressed); 136*89c4ff92SAndroid Build Coastguard Worker 137*89c4ff92SAndroid Build Coastguard Worker // If we're not running under Valgrind, these vars will have been initialised to 0, so this will always pass. 138*89c4ff92SAndroid Build Coastguard Worker CHECK(leakedBefore == leakedAfter); 139*89c4ff92SAndroid Build Coastguard Worker 140*89c4ff92SAndroid Build Coastguard Worker // Add resonable threshold after and before running valgrind with the ACL clear cache function. 141*89c4ff92SAndroid Build Coastguard Worker // TODO Threshold set to 80k until the root cause of the memory leakage is found and fixed. Revert threshold 142*89c4ff92SAndroid Build Coastguard Worker // value to 1024 when fixed. 143*89c4ff92SAndroid Build Coastguard Worker CHECK(static_cast<long>(reachableAfter) - static_cast<long>(reachableBefore) < 81920); 144*89c4ff92SAndroid Build Coastguard Worker 145*89c4ff92SAndroid Build Coastguard Worker // These are needed because VALGRIND_COUNT_LEAKS is a macro that assigns to the parameters 146*89c4ff92SAndroid Build Coastguard Worker // so they are assigned to, but still considered unused, causing a warning. 147*89c4ff92SAndroid Build Coastguard Worker IgnoreUnused(dubious); 148*89c4ff92SAndroid Build Coastguard Worker IgnoreUnused(suppressed); 149*89c4ff92SAndroid Build Coastguard Worker } 150*89c4ff92SAndroid Build Coastguard Worker #endif 151*89c4ff92SAndroid Build Coastguard Worker 152*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("ProfilingPostOptimisationStructureGpuAcc") 153*89c4ff92SAndroid Build Coastguard Worker { 154*89c4ff92SAndroid Build Coastguard Worker VerifyPostOptimisationStructureTestImpl(armnn::Compute::GpuAcc); 155*89c4ff92SAndroid Build Coastguard Worker } 156*89c4ff92SAndroid Build Coastguard Worker 157*89c4ff92SAndroid Build Coastguard Worker } 158