Line data Source code
1 : // Copyright 2024, UChicago Argonne, LLC
2 : // All Rights Reserved
3 : // Software Name: NEML2 -- the New Engineering material Model Library, version 2
4 : // By: Argonne National Laboratory
5 : // OPEN SOURCE LICENSE (MIT)
6 : //
7 : // Permission is hereby granted, free of charge, to any person obtaining a copy
8 : // of this software and associated documentation files (the "Software"), to deal
9 : // in the Software without restriction, including without limitation the rights
10 : // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 : // copies of the Software, and to permit persons to whom the Software is
12 : // furnished to do so, subject to the following conditions:
13 : //
14 : // The above copyright notice and this permission notice shall be included in
15 : // all copies or substantial portions of the Software.
16 : //
17 : // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 : // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 : // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 : // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 : // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 : // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 : // THE SOFTWARE.
24 :
25 : #include <dlfcn.h>
26 : #include <fstream>
27 :
28 : #include "neml2/base/Registry.h"
29 : #include "neml2/base/OptionSet.h"
30 : #include "neml2/base/NEML2Object.h"
31 : #include "neml2/misc/assertions.h"
32 :
33 : namespace neml2
34 : {
35 : Registry &
36 5953 : Registry::get()
37 : {
38 5953 : static Registry registry_singleton;
39 5953 : return registry_singleton;
40 : }
41 :
42 : void
43 2 : Registry::load(const std::filesystem::path & lib)
44 : {
45 : namespace fs = std::filesystem;
46 :
47 : // Check that the library exists
48 2 : neml_assert(fs::exists(lib), "Runtime library file " + lib.string() + " does not exist.");
49 :
50 : // Check that the library file is readable
51 2 : std::ifstream try_open(lib.string().c_str(), std::ifstream::in);
52 2 : neml_assert(
53 2 : !try_open.fail(),
54 4 : "Runtime library file " + lib.string() +
55 : " exists but could not be opened. Check to make sure that you have read permission.");
56 2 : try_open.close();
57 :
58 : // Load the library
59 2 : void * const lib_handle = dlopen(fs::absolute(lib).c_str(), RTLD_LAZY);
60 2 : neml_assert(lib_handle != nullptr,
61 : "Runtime library file ",
62 2 : lib.string(),
63 : " exists and can be opened, but cannot by dynamically loaded. This generally means "
64 : "that the loader was unable to load one or more of the dependencies (see otool or "
65 : "ldd). Error: \n",
66 2 : dlerror());
67 2 : }
68 :
69 : const std::map<std::string, NEML2ObjectInfo> &
70 2 : Registry::info()
71 : {
72 2 : return get()._info;
73 : }
74 :
75 : const NEML2ObjectInfo &
76 5079 : Registry::info(const std::string & name)
77 : {
78 5079 : const auto & reg = get();
79 5079 : neml_assert(
80 5079 : reg._info.count(name) > 0,
81 : name,
82 : " is not a registered object. Did you forget to register it with register_NEML2_object?");
83 5079 : return reg._info.at(name);
84 : }
85 :
86 : void
87 871 : Registry::add_inner(const std::string & name,
88 : const std::string & type,
89 : const OptionSet & options,
90 : BuildPtr build_ptr)
91 : {
92 871 : auto & reg = get();
93 871 : neml_assert(reg._info.count(name) == 0,
94 : "Duplicate registration found. Object of type ",
95 : name,
96 : " is being registered multiple times.");
97 871 : reg._info[name] = NEML2ObjectInfo{type, options, build_ptr};
98 871 : }
99 : } // namespace neml2
|