2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // See LICENSE file in the project root for full license information.
7 #include "armnn/Version.hpp"
9 #ifdef ARMCOMPUTECL_ENABLED
10 #include <arm_compute/core/CL/OpenCL.h>
11 #include <arm_compute/core/CL/CLKernelLibrary.h>
12 #include <arm_compute/runtime/CL/CLScheduler.h>
15 #include <boost/log/trivial.hpp>
16 #include <boost/polymorphic_cast.hpp>
18 using namespace armnn;
24 IRuntime* IRuntime::CreateRaw(const CreationOptions& options)
26 return new Runtime(options);
29 IRuntimePtr IRuntime::Create(const CreationOptions& options)
31 return IRuntimePtr(CreateRaw(options), &IRuntime::Destroy);
34 void IRuntime::Destroy(IRuntime* runtime)
36 delete boost::polymorphic_downcast<Runtime*>(runtime);
39 int Runtime::GenerateNetworkId()
41 return m_NetworkIdCounter++;
44 Status Runtime::LoadNetwork(NetworkId& networkIdOut, IOptimizedNetworkPtr inNetwork)
46 IOptimizedNetwork* rawNetwork = inNetwork.release();
47 unique_ptr<LoadedNetwork> loadedNetwork = LoadedNetwork::MakeLoadedNetwork(
48 std::unique_ptr<OptimizedNetwork>(boost::polymorphic_downcast<OptimizedNetwork*>(rawNetwork)),
53 return Status::Failure;
56 networkIdOut = GenerateNetworkId();
59 m_LoadedNetworks[networkIdOut] = std::move(loadedNetwork);
61 return Status::Success;
64 Status Runtime::UnloadNetwork(NetworkId networkId)
66 #ifdef ARMCOMPUTECL_ENABLED
67 if (arm_compute::CLScheduler::get().context()() != NULL)
69 arm_compute::CLScheduler::get().sync();
72 if (m_LoadedNetworks.erase(networkId) == 0)
74 BOOST_LOG_TRIVIAL(warning) << "WARNING: Runtime::UnloadNetwork(): " << networkId << " not found!";
75 return Status::Failure;
77 #ifdef ARMCOMPUTECL_ENABLED
78 if (arm_compute::CLScheduler::get().context()() != NULL && m_LoadedNetworks.empty())
80 m_WorkloadFactories.m_GpuAcc.get()->LoadOpenClRuntime();
83 BOOST_LOG_TRIVIAL(debug) << "Runtime::UnloadNetwork(): Unloaded network with ID: " << networkId;
84 return Status::Success;
87 Runtime::Runtime(const CreationOptions& options)
88 : m_NetworkIdCounter(0)
90 BOOST_LOG_TRIVIAL(info) << "ArmNN v" << ARMNN_VERSION << "\n";
91 BOOST_LOG_TRIVIAL(info) << "Using compute device: " << options.m_DefaultComputeDevice << "\n";
92 m_DeviceSpec.DefaultComputeDevice = options.m_DefaultComputeDevice;
94 // If useCpuRefAsFallback is false, the reference workload factory will be prevented from creating
95 // operation workloads, unless the default compute device is precisely the reference backend.
96 m_WorkloadFactories.m_CpuRef = make_shared<RefWorkloadFactory>(
97 options.m_DefaultComputeDevice == Compute::CpuRef ? true : options.m_UseCpuRefAsFallback);
98 m_WorkloadFactories.m_CpuAcc = make_shared<NeonWorkloadFactory>();
99 m_WorkloadFactories.m_GpuAcc = make_shared<ClWorkloadFactory>(options.m_ClTunedParameters);
101 if (options.m_DefaultComputeDevice == Compute::GpuAcc)
103 m_WorkloadFactories.m_GpuAcc.get()->LoadOpenClRuntime();
109 std::vector<int> networkIDs;
110 std::transform(m_LoadedNetworks.begin(), m_LoadedNetworks.end(),
111 std::back_inserter(networkIDs),
112 [](const auto &pair) { return pair.first; });
114 for (auto networkID : networkIDs)
116 UnloadNetwork(networkID);
120 TensorInfo Runtime::GetInputTensorInfo(NetworkId networkId, LayerBindingId layerId) const
122 LoadedNetwork* net = m_LoadedNetworks.at(networkId).get();
123 return net->GetInputTensorInfo(layerId);
126 TensorInfo Runtime::GetOutputTensorInfo(NetworkId networkId, LayerBindingId layerId) const
128 const LoadedNetwork* net = m_LoadedNetworks.at(networkId).get();
129 return net->GetOutputTensorInfo(layerId);
132 Status Runtime::EnqueueWorkload(NetworkId networkId,
133 const InputTensors& inputTensors,
134 const OutputTensors& outputTensors)
136 LoadedNetwork* loadedNetwork = m_LoadedNetworks.at(networkId).get();
137 return loadedNetwork->EnqueueWorkload(inputTensors, outputTensors, m_WorkloadFactories);