OpenVDB: AttributeRegistry.h Source File

OpenVDB 8.0.0

AttributeRegistry.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0/
3
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
25 #include <unordered_map>
26
27 namespace openvdb {
28 OPENVDB_USE_VERSION_NAMESPACE
29 namespace OPENVDB_VERSION_NAME {
30
31 namespace ax {
32
36 class AttributeRegistry
37 {
38 public:
39 using Ptr = std::shared_ptr<AttributeRegistry>;
40 using ConstPtr = std::shared_ptr<const AttributeRegistry>;
41
45 struct AccessData
46 {
52 AccessData(const Name& name,
53 const ast::tokens::CoreType type,
54 const bool readsFrom,
55 const bool writesTo)
56 : mAttrib(name, type)
57 , mAccess(readsFrom, writesTo)
58 , mUses()
59 , mDependencies() {}
60
61 bool reads() const { return mAccess.first; }
62 bool writes() const { return mAccess.second; }
63 const std::string tokenname() const { return mAttrib.tokenname(); }
64 const std::string& name() const { return mAttrib.name(); }
65 ast::tokens::CoreType type() const { return mAttrib.type(); }
66 const std::vector<const AccessData*>& deps() const { return mDependencies; }
67 const std::vector<const AccessData*>& uses() const { return mUses; }
68
69 bool dependson(const AccessData* data) const {
70 for (auto& dep : mDependencies) {
71 if (dep == data) return true;
72 }
73 return false;
74 }
75
76 bool affectsothers() const {
77 for (auto& dep : mUses) {
78 if (dep != this) return true;
79 }
80 return false;
81 }
82
83 private:
84 friend AttributeRegistry;
85
86 const ast::Attribute mAttrib;
87 const std::pair<bool, bool> mAccess;
88 std::vector<const AccessData*> mUses; // Accesses which depend on this access
89 std::vector<const AccessData*> mDependencies; // Accesses which this access depends on
90 };
91
92 using AccessDataVec = std::vector<AccessData>;
93
94 inline static AttributeRegistry::Ptr create(const ast::Tree& tree);
95
96 inline bool isReadable(const std::string& name, const ast::tokens::CoreType type) const
97 {
98 return this->accessPattern(name, type).first;
99 }
100
105 inline bool isWritable(const std::string& name, const ast::tokens::CoreType type) const
106 {
107 return this->accessPattern(name, type).second;
108 }
109
110 inline std::pair<bool,bool>
111 accessPattern(const std::string& name, const ast::tokens::CoreType type) const
112 {
113 for (const auto& data : mAccesses) {
114 if ((type == ast::tokens::UNKNOWN || data.type() == type)
115 && data.name() == name) {
116 return data.mAccess;
117 }
118 }
119 return std::pair<bool,bool>(false,false);
120 }
121
125 inline bool isRegistered(const std::string& name, const ast::tokens::CoreType type) const
126 {
127 return this->accessIndex(name, type) != -1;
128 }
129
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
148 inline const AccessDataVec& data() const { return mAccesses; }
149
150 void print(std::ostream& os) const;
151
152 private:
153 AttributeRegistry() : mAccesses() {}
154
161 inline void
162 addData(const Name& name,
163 const ast::tokens::CoreType type,
164 const bool readsfrom,
165 const bool writesto) {
166 mAccesses.emplace_back(name, type, readsfrom, writesto);
167 }
168
169 AccessDataVec mAccesses;
170 };
171
172
175
176
177 inline AttributeRegistry::Ptr AttributeRegistry::create(const ast::Tree& tree)
178 {
179 AttributeRegistry::Ptr registry(new AttributeRegistry());
180 std::vector<std::string> read, write, all;
181 ast::catalogueAttributeTokens(tree, &read, &write, &all);
182
183 size_t idx = 0;
184 std::unordered_map<std::string, size_t> indexmap;
185
186 auto dataBuilder =
187 [&](const std::vector<std::string>& attribs,
188 const bool readFlag,
189 const bool writeFlag)
190 {
191 std::string name, type;
192 for (const auto& attrib : attribs) {
193 ast::Attribute::nametypeFromToken(attrib, &name, &type);
194 const ast::tokens::CoreType typetoken =
195 ast::tokens::tokenFromTypeString(type);
196 registry->addData(name, typetoken, readFlag, writeFlag);
197 indexmap[attrib] = idx++;
198 }
199 };
200
201 // insert all data
202
203 dataBuilder(read, true, false);
204 dataBuilder(write, false, true);
205 dataBuilder(all, true, true);
206
207 auto depBuilder = [&](const std::vector<std::string>& attribs) {
208
209 std::string name, type;
210 for (const auto& attrib : attribs) {
211 ast::Attribute::nametypeFromToken(attrib, &name, &type);
212 const ast::tokens::CoreType typetoken =
213 ast::tokens::tokenFromTypeString(type);
214
215 std::vector<std::string> deps;
216 ast::attributeDependencyTokens(tree, name, typetoken, deps);
217 if (deps.empty()) continue;
218
219 assert(indexmap.find(attrib) != indexmap.cend());
220 const size_t index = indexmap.at(attrib);
221 AccessData& access = registry->mAccesses[index];
222 for (const std::string& dep : deps) {
223 assert(indexmap.find(dep) != indexmap.cend());
224 const size_t depindex = indexmap.at(dep);
225 access.mDependencies.emplace_back(&registry->mAccesses[depindex]);
226 }
227 }
228 };
229
230 // initialize dependencies
231
232 depBuilder(read);
233 depBuilder(write);
234 depBuilder(all);
235
236 // Update usage from deps
237
238 for (AccessData& access : registry->mAccesses) {
239 for (const AccessData& next : registry->mAccesses) {
240 // don't skip self depends as it may write to itself
241 // i.e. @a = @a + 1; should add a self usage
242 if (next.dependson(&access)) {
243 access.mUses.emplace_back(&next);
244 }
245 }
246 }
247
248 return registry;
249 }
250
251 inline void AttributeRegistry::print(std::ostream& os) const
252 {
253 size_t idx = 0;
254 for (const auto& data : mAccesses) {
255 os << "Attribute: " << data.name() << ", type: " <<
256 ast::tokens::typeStringFromToken(data.type()) << '\n';
257 os << " " << "Index : " << idx << '\n';
258 os << std::boolalpha;
259 os << " " << "Reads From : " << data.reads() << '\n';
260 os << " " << "Writes To : " << data.writes() << '\n';
261 os << std::noboolalpha;
262 os << " " << "Dependencies : " << data.mDependencies.size() << '\n';
263 for (const auto& dep : data.mDependencies) {
264 os << " " << "Attribute: " << dep->name() << " type: " <<
265 ast::tokens::typeStringFromToken(dep->type()) << '\n';
266 }
267 os << " " << "Usage : " << data.mUses.size() << '\n';
268 for (const auto& dep : data.mUses) {
269 os << " " << "Attribute: " << dep->name() << " type: " <<
270 ast::tokens::typeStringFromToken(dep->type()) << '\n';
271 }
272 os << '\n';
273 ++idx;
274 }
275 }
276
277 } // namespace ax
278 } // namespace OPENVDB_VERSION_NAME
279 } // namespace openvdb
280
281 #endif // OPENVDB_AX_COMPILER_TARGET_REGISTRY_HAS_BEEN_INCLUDED
282
openvdb::v8_2::ax::AttributeRegistry::isReadable
bool isReadable(const std::string &name, const ast::tokens::CoreType type) const
Definition: AttributeRegistry.h:96
openvdb::v8_2::ax::AttributeRegistry
This class stores a list of access names, types and their dependency connections.
Definition: AttributeRegistry.h:37
openvdb::v8_2::ax::AttributeRegistry::AccessData::type
ast::tokens::CoreType type() const
Definition: AttributeRegistry.h:65
openvdb::v8_2::ax::AttributeRegistry::isWritable
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:105
openvdb::v8_2::ax::AttributeRegistry::accessIndex
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
openvdb::v8_2::ax::ast::attributeDependencyTokens
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.
openvdb::v8_2::ax::AttributeRegistry::Ptr
std::shared_ptr< AttributeRegistry > Ptr
Definition: AttributeRegistry.h:39
openvdb::v8_2::ax::AttributeRegistry::AccessData::deps
const std::vector< const AccessData * > & deps() const
Definition: AttributeRegistry.h:66
openvdb::v8_2::ax::ast::Tree
A Tree is the highest concrete (non-abstract) node in the entire AX AST hierarchy....
Definition: AST.h:562
openvdb::v8_2::ax::ast::tokens::typeStringFromToken
std::string typeStringFromToken(const CoreType type)
Definition: Tokens.h:118
openvdb::v8_2::ax::AttributeRegistry::AccessDataVec
std::vector< AccessData > AccessDataVec
Definition: AttributeRegistry.h:92
version.h
Library and file format version numbers.
openvdb::v8_2::ax::AttributeRegistry::AccessData::tokenname
const std::string tokenname() const
Definition: AttributeRegistry.h:63
openvdb::v8_2::ax::ast::Attribute
Attributes represent any access to a primitive value, typically associated with the '@' symbol syntax...
Definition: AST.h:1874
openvdb::v8_2::ax::ast::catalogueAttributeTokens
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::v8_2::ax::AttributeRegistry::isRegistered
bool isRegistered(const std::string &name, const ast::tokens::CoreType type) const
Returns whether or not an access is registered.
Definition: AttributeRegistry.h:125
openvdb::v8_2::ax::ast::tokens::tokenFromTypeString
CoreType tokenFromTypeString(const std::string &type)
Definition: Tokens.h:66
openvdb::v8_2::ax::AttributeRegistry::data
const AccessDataVec & data() const
Returns a const reference to the vector of registered accesss.
Definition: AttributeRegistry.h:148
openvdb::v8_2::ax::AttributeRegistry::AccessData::name
const std::string & name() const
Definition: AttributeRegistry.h:64
openvdb::v8_2::ax::AttributeRegistry::AccessData::writes
bool writes() const
Definition: AttributeRegistry.h:62
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:153
openvdb::v8_2::ax::ast::tokens::CoreType
CoreType
Definition: Tokens.h:32
openvdb::v8_2::ax::AttributeRegistry::AccessData::dependson
bool dependson(const AccessData *data) const
Definition: AttributeRegistry.h:69
openvdb::v8_2::ax::AttributeRegistry::accessPattern
std::pair< bool, bool > accessPattern(const std::string &name, const ast::tokens::CoreType type) const
Definition: AttributeRegistry.h:111
openvdb::v8_2::ax::AttributeRegistry::AccessData::AccessData
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:52
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:101
openvdb::v8_2::ax::AttributeRegistry::AccessData
Registered access details, including its name, type and whether a write handle is required.
Definition: AttributeRegistry.h:46
openvdb
Definition: openvdb/Exceptions.h:13
openvdb::v8_2::ax::AttributeRegistry::AccessData::reads
bool reads() const
Definition: AttributeRegistry.h:61
openvdb::v8_2::ax::AttributeRegistry::ConstPtr
std::shared_ptr< const AttributeRegistry > ConstPtr
Definition: AttributeRegistry.h:40
openvdb::v8_2::ax::AttributeRegistry::AccessData::affectsothers
bool affectsothers() const
Definition: AttributeRegistry.h:76
openvdb::v8_2::ax::ast::tokens::UNKNOWN
@ UNKNOWN
Definition: Tokens.h:63
openvdb::v8_2::ax::AttributeRegistry::AccessData::uses
const std::vector< const AccessData * > & uses() const
Definition: AttributeRegistry.h:67
openvdb::v8_2::Name
std::string Name
Definition: Name.h:17
openvdb::v8_2::ax::ast::print
void print(const ast::Node &node, const bool numberStatements=true, std::ostream &os=std::cout, const char *indent=" ")
Writes a descriptive printout of a Node hierarchy into a target stream.