OpenVDB 9.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
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
27#include <unordered_map>
28
29namespace openvdb {
31namespace OPENVDB_VERSION_NAME {
32
33namespace ax {
34
35/// @brief This class stores a list of access names, types and their dependency
36/// connections.
37///
39{
40public:
41 using Ptr = std::shared_ptr<AttributeRegistry>;
42 using ConstPtr = std::shared_ptr<const AttributeRegistry>;
43
44 /// @brief Registered access details, including its name, type and whether
45 /// a write handle is required
46 ///
48 {
49 /// @brief Storage for access name, type and writesTo details
50 /// @param name The name of the access
51 /// @param type The typename of the access
52 /// @param readsFrom Whether the access is read from
53 /// @param writesTo Whether the access is written to
54 AccessData(const Name& name,
55 const ast::tokens::CoreType type,
56 const bool readsFrom,
57 const bool writesTo)
58 : mAttrib(name, type)
59 , mAccess(readsFrom, writesTo)
60 , mUses()
61 , mDependencies() {}
62
63 bool reads() const { return mAccess.first; }
64 bool writes() const { return mAccess.second; }
65 const std::string tokenname() const { return mAttrib.tokenname(); }
66 const std::string& name() const { return mAttrib.name(); }
67 ast::tokens::CoreType type() const { return mAttrib.type(); }
68 const std::vector<const AccessData*>& deps() const { return mDependencies; }
69 const std::vector<const AccessData*>& uses() const { return mUses; }
70
71 bool dependson(const AccessData* data) const {
72 assert(data);
73 for (auto& dep : mDependencies) {
74 if (dep == data) return true;
75 }
76 return false;
77 }
78
79 bool affectsothers() const {
80 for (auto& dep : mUses) {
81 if (dep != this) return true;
82 }
83 return false;
84 }
85
86 private:
87 friend AttributeRegistry;
88
89 const ast::Attribute mAttrib;
90 const std::pair<bool, bool> mAccess;
91 std::vector<const AccessData*> mUses; // Accesses which depend on this access
92 std::vector<const AccessData*> mDependencies; // Accesses which this access depends on
93 };
94
95 using AccessDataVec = std::vector<AccessData>;
96
97 inline static AttributeRegistry::Ptr create(const ast::Tree& tree);
98
99 inline bool isReadable(const std::string& name, const ast::tokens::CoreType type) const
100 {
101 return this->accessPattern(name, type).first;
102 }
103
104 /// @brief Returns whether or not an access is required to be written to.
105 /// If no access with this name has been registered, returns false
106 /// @param name The name of the access
107 /// @param type The type of the access
108 inline bool isWritable(const std::string& name, const ast::tokens::CoreType type) const
109 {
110 return this->accessPattern(name, type).second;
111 }
112
113 inline std::pair<bool,bool>
114 accessPattern(const std::string& name, const ast::tokens::CoreType type) const
115 {
116 auto* data = this->get(name, type);
117 if (!data) return std::pair<bool,bool>(false,false);
118 return data->mAccess;
119 }
120
121 /// @brief Returns whether or not an access is registered.
122 /// @param name The name of the access
123 /// @param type The type of the access
124 inline bool isRegistered(const std::string& name, const ast::tokens::CoreType type) const
125 {
126 return this->accessIndex(name, type) != -1;
127 }
128
129 /// @brief Returns whether or not an access is registered.
130 /// @param name The name of the access
131 /// @param type The type of the access
132 inline int64_t
133 accessIndex(const std::string& name,
134 const ast::tokens::CoreType type) const
135 {
136 int64_t i = 0;
137 for (const auto& data : mAccesses) {
138 if (data.type() == type && data.name() == name) {
139 return i;
140 }
141 ++i;
142 }
143 return -1;
144 }
145
146 const AccessData*
147 get(const std::string& name, const ast::tokens::CoreType type) const
148 {
149 for (const auto& data : mAccesses) {
150 if ((type == ast::tokens::UNKNOWN || data.type() == type)
151 && data.name() == name) {
152 return &data;
153 }
154 }
155 return nullptr;
156 }
157
158 /// @brief Returns a const reference to the vector of registered accesss
159 inline const AccessDataVec& data() const { return mAccesses; }
160
161 void print(std::ostream& os) const;
162
163private:
164 AttributeRegistry() : mAccesses() {}
165
166 /// @brief Add an access to the registry, returns an index into
167 /// the registry for that access
168 /// @param name The name of the access
169 /// @param type The typename of the access
170 /// @param writesTo Whether the access is required to be writeable
171 ///
172 inline void
173 addData(const Name& name,
174 const ast::tokens::CoreType type,
175 const bool readsfrom,
176 const bool writesto) {
177 mAccesses.emplace_back(name, type, readsfrom, writesto);
178 }
179
180 AccessDataVec mAccesses;
181};
182
183
184/////////////////////////////////////////////////////////////////////
185/////////////////////////////////////////////////////////////////////
186
187
188inline AttributeRegistry::Ptr AttributeRegistry::create(const ast::Tree& tree)
189{
191 std::vector<std::string> read, write, all;
193
194 size_t idx = 0;
195 std::unordered_map<std::string, size_t> indexmap;
196
197 auto dataBuilder =
198 [&](const std::vector<std::string>& attribs,
199 const bool readFlag,
200 const bool writeFlag)
201 {
202 std::string name, type;
203 for (const auto& attrib : attribs) {
204 ast::Attribute::nametypeFromToken(attrib, &name, &type);
205 const ast::tokens::CoreType typetoken =
207 registry->addData(name, typetoken, readFlag, writeFlag);
208 indexmap[attrib] = idx++;
209 }
210 };
211
212 // insert all data
213
214 dataBuilder(read, true, false);
215 dataBuilder(write, false, true);
216 dataBuilder(all, true, true);
217
218 auto depBuilder = [&](const std::vector<std::string>& attribs) {
219
220 std::string name, type;
221 for (const auto& attrib : attribs) {
222 ast::Attribute::nametypeFromToken(attrib, &name, &type);
223 const ast::tokens::CoreType typetoken =
225
226 std::vector<std::string> deps;
227 ast::attributeDependencyTokens(tree, name, typetoken, deps);
228 if (deps.empty()) continue;
229
230 assert(indexmap.find(attrib) != indexmap.cend());
231 const size_t index = indexmap.at(attrib);
232 AccessData& access = registry->mAccesses[index];
233 for (const std::string& dep : deps) {
234 assert(indexmap.find(dep) != indexmap.cend());
235 const size_t depindex = indexmap.at(dep);
236 access.mDependencies.emplace_back(&registry->mAccesses[depindex]);
237 }
238 }
239 };
240
241 // initialize dependencies
242
243 depBuilder(read);
244 depBuilder(write);
245 depBuilder(all);
246
247 // Update usage from deps
248
249 for (AccessData& access : registry->mAccesses) {
250 for (const AccessData& next : registry->mAccesses) {
251 // don't skip self depends as it may write to itself
252 // i.e. @a = @a + 1; should add a self usage
253 if (next.dependson(&access)) {
254 access.mUses.emplace_back(&next);
255 }
256 }
257 }
258
259 return registry;
260}
261
262inline void AttributeRegistry::print(std::ostream& os) const
263{
264 size_t idx = 0;
265 for (const auto& data : mAccesses) {
266 os << "Attribute: " << data.name() << ", type: " <<
267 ast::tokens::typeStringFromToken(data.type()) << '\n';
268 os << " " << "Index : " << idx << '\n';
269 os << std::boolalpha;
270 os << " " << "Reads From : " << data.reads() << '\n';
271 os << " " << "Writes To : " << data.writes() << '\n';
272 os << std::noboolalpha;
273 os << " " << "Dependencies : " << data.mDependencies.size() << '\n';
274 for (const auto& dep : data.mDependencies) {
275 os << " " << "Attribute: " << dep->name() << " type: " <<
276 ast::tokens::typeStringFromToken(dep->type()) << '\n';
277 }
278 os << " " << "Usage : " << data.mUses.size() << '\n';
279 for (const auto& dep : data.mUses) {
280 os << " " << "Attribute: " << dep->name() << " type: " <<
281 ast::tokens::typeStringFromToken(dep->type()) << '\n';
282 }
283 os << '\n';
284 ++idx;
285 }
286}
287
288} // namespace ax
289} // namespace OPENVDB_VERSION_NAME
290} // namespace openvdb
291
292#endif // OPENVDB_AX_COMPILER_TARGET_REGISTRY_HAS_BEEN_INCLUDED
293
This class stores a list of access names, types and their dependency connections.
Definition: AttributeRegistry.h:39
std::shared_ptr< AttributeRegistry > Ptr
Definition: AttributeRegistry.h:41
const AccessData * get(const std::string &name, const ast::tokens::CoreType type) const
Definition: AttributeRegistry.h:147
int64_t accessIndex(const std::string &name, const ast::tokens::CoreType type) const
Returns whether or not an access is registered.
Definition: AttributeRegistry.h:133
bool isReadable(const std::string &name, const ast::tokens::CoreType type) const
Definition: AttributeRegistry.h:99
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:108
bool isRegistered(const std::string &name, const ast::tokens::CoreType type) const
Returns whether or not an access is registered.
Definition: AttributeRegistry.h:124
std::vector< AccessData > AccessDataVec
Definition: AttributeRegistry.h:95
std::pair< bool, bool > accessPattern(const std::string &name, const ast::tokens::CoreType type) const
Definition: AttributeRegistry.h:114
const AccessDataVec & data() const
Returns a const reference to the vector of registered accesss.
Definition: AttributeRegistry.h:159
std::shared_ptr< const AttributeRegistry > ConstPtr
Definition: AttributeRegistry.h:42
static void read(std::istream &is, GridHandle< BufferT > &handle, Codec codec)
static fileSize_t write(std::ostream &os, const GridHandle< BufferT > &handle, Codec codec)
CoreType tokenFromTypeString(const std::string &type)
Definition: Tokens.h:66
std::string typeStringFromToken(const CoreType type)
Definition: Tokens.h:118
CoreType
Definition: Tokens.h:32
@ UNKNOWN
Definition: Tokens.h:63
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...
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.
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.
std::string Name
Definition: Name.h:17
Definition: Exceptions.h:13
Registered access details, including its name, type and whether a write handle is required.
Definition: AttributeRegistry.h:48
ast::tokens::CoreType type() const
Definition: AttributeRegistry.h:67
const std::string tokenname() const
Definition: AttributeRegistry.h:65
const std::string & name() const
Definition: AttributeRegistry.h:66
bool reads() const
Definition: AttributeRegistry.h:63
const std::vector< const AccessData * > & uses() const
Definition: AttributeRegistry.h:69
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:54
const std::vector< const AccessData * > & deps() const
Definition: AttributeRegistry.h:68
bool dependson(const AccessData *data) const
Definition: AttributeRegistry.h:71
bool affectsothers() const
Definition: AttributeRegistry.h:79
bool writes() const
Definition: AttributeRegistry.h:64
Attributes represent any access to a primitive value, typically associated with the '@' symbol syntax...
Definition: AST.h:1874
A Tree is the highest concrete (non-abstract) node in the entire AX AST hierarchy....
Definition: AST.h:562
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:116
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:202