18 #if defined(__unix__) || defined(__APPLE__)
19 if (sharedObjectPath.empty())
21 throw RuntimeException(
"OpenHandle error: shared object path must not be empty");
24 void* sharedObjectHandle = dlopen(sharedObjectPath.c_str(), RTLD_LAZY);
25 if (!sharedObjectHandle)
30 return sharedObjectHandle;
39 #if defined(__unix__) || defined(__APPLE__)
40 if (!sharedObjectHandle)
45 dlclose(
const_cast<void*
>(sharedObjectHandle));
66 std::string DynamicBackendUtils::GetDlError()
68 #if defined(__unix__) || defined(__APPLE__)
69 const char* errorMessage = dlerror();
75 return std::string(errorMessage);
77 throw RuntimeException(
"Dynamic backends not supported on this platform");
84 if (!overrideBackendPath.empty())
88 ARMNN_LOG(
warning) <<
"WARNING: The given override path for dynamic backends \""
89 << overrideBackendPath <<
"\" is not valid";
94 return std::vector<std::string>{ overrideBackendPath };
106 if (backendPaths.empty())
113 std::unordered_set<std::string> uniqueBackendPaths;
114 std::vector<std::string> validBackendPaths;
119 for (
const std::string& path : tempBackendPaths)
128 auto it = uniqueBackendPaths.find(path);
129 if (it != uniqueBackendPaths.end())
136 uniqueBackendPaths.insert(path);
139 validBackendPaths.push_back(path);
142 return validBackendPaths;
153 #if !defined(ARMNN_DISABLE_FILESYSTEM)
154 fs::path fsPath(path);
156 if (!fs::exists(fsPath))
158 ARMNN_LOG(
warning) <<
"WARNING: The given backend path \"" << path <<
"\" does not exist";
162 if (!fs::is_directory(fsPath))
164 ARMNN_LOG(
warning) <<
"WARNING: The given backend path \"" << path <<
"\" is not a directory";
168 if (!fsPath.is_absolute())
170 ARMNN_LOG(
warning) <<
"WARNING: The given backend path \"" << path <<
"\" is not absolute";
173 #endif // !defined(ARMNN_DISABLE_FILESYSTEM)
180 std::unordered_set<std::string> uniqueSharedObjects;
181 std::vector<std::string> sharedObjects;
183 #if !defined(ARMNN_DISABLE_FILESYSTEM)
184 for (
const std::string& backendPath : backendPaths)
195 std::vector<path> backendPathFiles;
196 std::copy(directory_iterator(backendPath), directory_iterator(), std::back_inserter(backendPathFiles));
197 std::sort(backendPathFiles.begin(), backendPathFiles.end());
200 for (
const path& backendPathFile : backendPathFiles)
203 std::string filename = backendPathFile.filename().string();
205 if (filename.empty())
216 canonicalPath = canonical(backendPathFile);
218 catch (
const filesystem_error& e)
222 if (canonicalPath.empty())
231 const std::regex dynamicBackendRegex(
"^[a-zA-Z0-9]+_[a-zA-Z0-9]+_backend.so(\\.[0-9]+)*$");
233 bool filenameMatch =
false;
237 filenameMatch = std::regex_match(filename, dynamicBackendRegex);
239 catch (
const std::exception& e)
250 std::string validCanonicalPath = canonicalPath.string();
251 auto it = uniqueSharedObjects.find(validCanonicalPath);
252 if (it == uniqueSharedObjects.end())
255 sharedObjects.push_back(validCanonicalPath);
258 uniqueSharedObjects.insert(validCanonicalPath);
264 #endif // !defined(ARMNN_DISABLE_FILESYSTEM)
266 return sharedObjects;
272 std::vector<DynamicBackendPtr> dynamicBackends;
273 for (
const std::string& sharedObject : sharedObjects)
276 void* sharedObjectHandle =
nullptr;
284 << sharedObject <<
"\": " << e.
what();
287 if (!sharedObjectHandle)
289 ARMNN_LOG(
warning) <<
"Invalid handle to the shared object file \"" << sharedObject <<
"\"";
302 ARMNN_LOG(
warning) <<
"Cannot create a valid dynamic backend from the shared object file \""
303 << sharedObject <<
"\": " << e.
what();
308 ARMNN_LOG(
warning) <<
"Invalid dynamic backend object for the shared object file \""
309 << sharedObject <<
"\"";
314 dynamicBackends.push_back(std::move(dynamicBackend));
317 return dynamicBackends;
325 for (
const auto&
id : dynamicBackends)
342 const std::vector<DynamicBackendPtr>& dynamicBackends)
354 dynamicBackendId = dynamicBackend->GetBackendId();
359 <<
"an error has occurred when getting the backend id: " << e.
what();
362 if (dynamicBackendId.
IsEmpty() ||
365 ARMNN_LOG(
warning) <<
"Cannot register dynamic backend, invalid backend id: " << dynamicBackendId;
371 if (backendAlreadyRegistered)
373 ARMNN_LOG(
warning) <<
"Cannot register dynamic backend \"" << dynamicBackendId
374 <<
"\": backend already registered";
382 dynamicBackendFactoryFunction = dynamicBackend->GetFactoryFunction();
386 ARMNN_LOG(
warning) <<
"Cannot register dynamic backend \"" << dynamicBackendId
387 <<
"\": an error has occurred when getting the backend factory function: "
391 if (dynamicBackendFactoryFunction ==
nullptr)
393 ARMNN_LOG(
warning) <<
"Cannot register dynamic backend \"" << dynamicBackendId
394 <<
"\": invalid backend factory function";
401 backendRegistry.
Register(dynamicBackendId, dynamicBackendFactoryFunction);
405 ARMNN_LOG(
warning) <<
"An error has occurred when registering the dynamic backend \""
406 << dynamicBackendId <<
"\": " << e.
what();
411 registeredBackendIds.insert(dynamicBackendId);
414 return registeredBackendIds;