OpenVDB 12.0.0
 
Loading...
Searching...
No Matches
AttributeRegistry.h
Go to the documentation of this file.
1// Copyright Contributors to the OpenVDB Project
2// SPDX-License-Identifier: Apache-2.0/
3
4/// @file compiler/AttributeRegistry.h
5///
6/// @authors Nick Avramoussis, Francisco Gochez
7///
8/// @brief These classes contain lists of expected attributes and volumes
9/// which are populated by compiler during its internal code generation.
10/// These will then be requested from the inputs to the executable
11/// when execute is called. In this way, accesses are requested at
12/// execution time, allowing the executable objects to be shared and
13/// stored.
14///
15
16#ifndef OPENVDB_AX_COMPILER_TARGET_REGISTRY_HAS_BEEN_INCLUDED
17#define OPENVDB_AX_COMPILER_TARGET_REGISTRY_HAS_BEEN_INCLUDED
18
19#include "../ast/AST.h"
20#include "../ast/Tokens.h"
21#include "../ast/Scanners.h"
22
23#include <openvdb/version.h>
24#include <openvdb/Types.h>
25#include <openvdb/util/Name.h>
26#include <openvdb/util/Assert.h>
27
28#include <unordered_map>
29
30namespace openvdb {
32namespace OPENVDB_VERSION_NAME {
33
34namespace ax {
35
36/// @brief This class stores a list of access names, types and their dependency
37/// connections.
38///
39class AttributeRegistry
40{
41public:
42 using Ptr = std::shared_ptr<AttributeRegistry>;
43 using ConstPtr = std::shared_ptr<const AttributeRegistry>;
44
45 /// @brief Registered access details, including its name, type and whether
46 /// a write handle is required
47 ///
49 {
50 /// @brief Storage for access name, type and writesTo details
51 /// @param name The name of the access
52 /// @param type The typename of the access
53 /// @param readsFrom Whether the access is read from
54 /// @param writesTo Whether the access is written to
57 const bool readsFrom,
58 const bool writesTo)
59 : mAttrib(name, type)
60 , mAccess(readsFrom, writesTo)
61 , mUses()
62 , mDependencies() {}
63
64 bool reads() const { return mAccess.first; }
65 bool writes() const { return mAccess.second; }
66 const std::string tokenname() const { return mAttrib.tokenname(); }
67 const std::string& name() const { return mAttrib.name(); }
68 ast::tokens::CoreType type() const { return mAttrib.type(); }
69 const std::vector<const AccessData*>& deps() const { return mDependencies; }
70 const std::vector<const AccessData*>& uses() const { return mUses; }
71
72 bool dependson(const AccessData* data) const {
74 for (auto& dep : mDependencies) {
75 if (dep == data) return true;
76 }
77 return false;
78 }
79
80 bool affectsothers() const {
81 for (auto& dep : mUses) {
82 if (dep != this) return true;
83 }
84 return false;
85 }
86
87 private:
88 friend AttributeRegistry;
89
90 const ast::Attribute mAttrib;
91 const std::pair<bool, bool> mAccess;
92 std::vector<const AccessData*> mUses; // Accesses which depend on this access
93 std::vector<const AccessData*> mDependencies; // Accesses which this access depends on
94 };
95
96 using AccessDataVec = std::vector<AccessData>;
97
98 inline static AttributeRegistry::Ptr create(const ast::Tree& tree);
99
100 inline bool isReadable(const std::string& name, const ast::tokens::CoreType type) const
101 {
102 return this->accessPattern(name, type).first;
103 }
104
105 /// @brief Returns whether or not an access is required to be written to.
106 /// If no access with this name has been registered, returns false
107 /// @param name The name of the access
108 /// @param type The type of the access
109 inline bool isWritable(const std::string& name, const ast::tokens::CoreType type) const
110 {
111 return this->accessPattern(name, type).second;
112 }
113
114 inline std::pair<bool,bool>
115 accessPattern(const std::string& name, const ast::tokens::CoreType type) const
116 {
117 auto* data = this->get(name, type);
118 if (!data) return std::pair<bool,bool>(false,false);
119 return data->mAccess;
120 }
121
122 /// @brief Returns whether or not an access is registered.
123 /// @param name The name of the access
124 /// @param type The type of the access
125 inline bool isRegistered(const std::string& name, const ast::tokens::CoreType type) const
126 {
127 return this->accessIndex(name, type) != -1;
128 }
129
130 /// @brief Returns whether or not an access is registered.
131 /// @param name The name of the access
132 /// @param type The type of the access
133 inline int64_t
134 accessIndex(const std::string& name,
135 const ast::tokens::CoreType type) const
136 {
137 int64_t i = 0;
138 for (const auto& data : mAccesses) {
139 if (data.type() == type && data.name() == name) {
140 return i;
141 }
142 ++i;
143 }
144 return -1;
145 }
146
147 const AccessData*
148 get(const std::string& name, const ast::tokens::CoreType type) const
149 {
150 for (const auto& data : mAccesses) {
151 if ((type == ast::tokens::UNKNOWN || data.type() == type)
152 && data.name() == name) {
153 return &data;
154 }
155 }
156 return nullptr;
157 }
158
159 /// @brief Returns a const reference to the vector of registered accesss
160 inline const AccessDataVec& data() const { return mAccesses; }
161
162 void print(std::ostream& os) const;
163
164private:
165 AttributeRegistry() : mAccesses() {}
166
167 /// @brief Add an access to the registry, returns an index into
168 /// the registry for that access
169 /// @param name The name of the access
170 /// @param type The typename of the access
171 /// @param writesTo Whether the access is required to be writeable
172 ///
173 inline void
174 addData(const Name& name,
175 const ast::tokens::CoreType type,
176 const bool readsfrom,
177 const bool writesto) {
178 mAccesses.emplace_back(name, type, readsfrom, writesto);
179 }
180
181 AccessDataVec mAccesses;
182};
183
184
185/////////////////////////////////////////////////////////////////////
186/////////////////////////////////////////////////////////////////////
187
188
190{
191 AttributeRegistry::Ptr registry(new AttributeRegistry());
192 std::vector<std::string> read, write, all;
193 ast::catalogueAttributeTokens(tree, &read, &write, &all);
194
195 size_t idx = 0;
196 std::unordered_map<std::string, size_t> indexmap;
197
198 auto dataBuilder =
199 [&](const std::vector<std::string>& attribs,
200 const bool readFlag,
201 const bool writeFlag)
202 {
203 std::string name, type;
204 for (const auto& attrib : attribs) {
205 ast::Attribute::nametypeFromToken(attrib, &name, &type);
206 const ast::tokens::CoreType typetoken =
208 registry->addData(name, typetoken, readFlag, writeFlag);
209 indexmap[attrib] = idx++;
210 }
211 };
212
213 // insert all data
214
215 dataBuilder(read, true, false);
216 dataBuilder(write, false, true);
217 dataBuilder(all, true, true);
218
219 auto depBuilder = [&](const std::vector<std::string>& attribs) {
220
221 std::string name, type;
222 for (const auto& attrib : attribs) {
223 ast::Attribute::nametypeFromToken(attrib, &name, &type);
224 const ast::tokens::CoreType typetoken =
226
227 std::vector<std::string> deps;
228 ast::attributeDependencyTokens(tree, name, typetoken, deps);
229 if (deps.empty()) continue;
230
231 OPENVDB_ASSERT(indexmap.find(attrib) != indexmap.cend());
232 const size_t index = indexmap.at(attrib);
233 AccessData& access = registry->mAccesses[index];
234 for (const std::string& dep : deps) {
235 OPENVDB_ASSERT(indexmap.find(dep) != indexmap.cend());
236 const size_t depindex = indexmap.at(dep);
237 access.mDependencies.emplace_back(&registry->mAccesses[depindex]);
238 }
239 }
240 };
241
242 // initialize dependencies
243
244 depBuilder(read);
245 depBuilder(write);
246 depBuilder(all);
247
248 // Update usage from deps
249
250 for (AccessData& access : registry->mAccesses) {
251 for (const AccessData& next : registry->mAccesses) {
252 // don't skip self depends as it may write to itself
253 // i.e. @a = @a + 1; should add a self usage
254 if (next.dependson(&access)) {
255 access.mUses.emplace_back(&next);
256 }
257 }
258 }
259
260 return registry;
261}
262
263inline void AttributeRegistry::print(std::ostream& os) const
264{
265 size_t idx = 0;
266 for (const auto& data : mAccesses) {
267 os << "Attribute: " << data.name() << ", type: " <<
269 os << " " << "Index : " << idx << '\n';
270 os << std::boolalpha;
271 os << " " << "Reads From : " << data.reads() << '\n';
272 os << " " << "Writes To : " << data.writes() << '\n';
273 os << std::noboolalpha;
274 os << " " << "Dependencies : " << data.mDependencies.size() << '\n';
275 for (const auto& dep : data.mDependencies) {
276 os << " " << "Attribute: " << dep->name() << " type: " <<
277 ast::tokens::typeStringFromToken(dep->type()) << '\n';
278 }
279 os << " " << "Usage : " << data.mUses.size() << '\n';
280 for (const auto& dep : data.mUses) {
281 os << " " << "Attribute: " << dep->name() << " type: " <<
282 ast::tokens::typeStringFromToken(dep->type()) << '\n';
283 }
284 os << '\n';
285 ++idx;
286 }
287}
288
289} // namespace ax
290} // namespace OPENVDB_VERSION_NAME
291} // namespace openvdb
292
293#endif // OPENVDB_AX_COMPILER_TARGET_REGISTRY_HAS_BEEN_INCLUDED
294
Provides the definition for every abstract and concrete derived class which represent a particular ab...
#define OPENVDB_ASSERT(X)
Definition Assert.h:41
Retrieve intrinsic information from AX AST by performing various traversal algorithms.
Various function and operator tokens used throughout the AST and code generation.
This class stores a list of access names, types and their dependency connections.
Definition AttributeRegistry.h:40
std::shared_ptr< AttributeRegistry > Ptr
Definition AttributeRegistry.h:42
const AccessData * get(const std::string &name, const ast::tokens::CoreType type) const
Definition AttributeRegistry.h:148
int64_t accessIndex(const std::string &name, const ast::tokens::CoreType type) const
Returns whether or not an access is registered.
Definition AttributeRegistry.h:134
bool isReadable(const std::string &name, const ast::tokens::CoreType type) const
Definition AttributeRegistry.h:100
bool isWritable(const std::string &name, const ast::tokens::CoreType type) const
Returns whether or not an access is required to be written to. If no access with this name has been r...
Definition AttributeRegistry.h:109
bool isRegistered(const std::string &name, const ast::tokens::CoreType type) const
Returns whether or not an access is registered.
Definition AttributeRegistry.h:125
std::vector< AccessData > AccessDataVec
Definition AttributeRegistry.h:96
std::pair< bool, bool > accessPattern(const std::string &name, const ast::tokens::CoreType type) const
Definition AttributeRegistry.h:115
static AttributeRegistry::Ptr create(const ast::Tree &tree)
Definition AttributeRegistry.h:189
void print(std::ostream &os) const
Definition AttributeRegistry.h:263
const AccessDataVec & data() const
Returns a const reference to the vector of registered accesss.
Definition AttributeRegistry.h:160
std::shared_ptr< const AttributeRegistry > ConstPtr
Definition AttributeRegistry.h:43
std::string typeStringFromToken(const CoreType type)
Definition Tokens.h:118
CoreType tokenFromTypeString(const std::string &type)
Definition Tokens.h:66
CoreType
Definition Tokens.h:32
@ UNKNOWN
Definition Tokens.h:63
OPENVDB_AX_API void catalogueAttributeTokens(const ast::Node &node, std::vector< std::string > *readOnly, std::vector< std::string > *writeOnly, std::vector< std::string > *readWrite)
Parse all attributes into three unique vectors which represent how they are accessed within the synta...
OPENVDB_AX_API void attributeDependencyTokens(const ast::Tree &tree, const std::string &name, const tokens::CoreType type, std::vector< std::string > &dependencies)
Populate a list of attribute names which the given attribute depends on.
Definition PointDataGrid.h:170
std::string Name
Definition Name.h:19
Definition Exceptions.h:13
Registered access details, including its name, type and whether a write handle is required.
Definition AttributeRegistry.h:49
ast::tokens::CoreType type() const
Definition AttributeRegistry.h:68
const std::string tokenname() const
Definition AttributeRegistry.h:66
const std::string & name() const
Definition AttributeRegistry.h:67
bool reads() const
Definition AttributeRegistry.h:64
const std::vector< const AccessData * > & uses() const
Definition AttributeRegistry.h:70
AccessData(const Name &name, const ast::tokens::CoreType type, const bool readsFrom, const bool writesTo)
Storage for access name, type and writesTo details.
Definition AttributeRegistry.h:55
const std::vector< const AccessData * > & deps() const
Definition AttributeRegistry.h:69
bool dependson(const AccessData *data) const
Definition AttributeRegistry.h:72
bool affectsothers() const
Definition AttributeRegistry.h:80
bool writes() const
Definition AttributeRegistry.h:65
Attributes represent any access to a primitive value, typically associated with the '@' symbol syntax...
Definition AST.h:1875
static bool nametypeFromToken(const std::string &token, std::string *name, std::string *type)
Static method which splits a valid attribute token into its name and type counterparts....
Definition AST.h:1975
A Tree is the highest concrete (non-abstract) node in the entire AX AST hierarchy....
Definition AST.h:563
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:218