Lagrange
Loading...
Searching...
No Matches
IndexedAttributeManager.h
1/*
2 * Copyright 2020 Adobe. All rights reserved.
3 * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License. You may obtain a copy
5 * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 *
7 * Unless required by applicable law or agreed to in writing, software distributed under
8 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 * OF ANY KIND, either express or implied. See the License for the specific language
10 * governing permissions and limitations under the License.
11 */
12#pragma once
13
14#include <map>
15#include <string>
16
17#include <lagrange/Logger.h>
18#include <lagrange/common.h>
19#include <lagrange/experimental/IndexedAttribute.h>
20#include <lagrange/utils/assert.h>
21
22namespace lagrange {
23namespace experimental {
24
26{
27public:
28 std::vector<std::string> get_names() const
29 {
30 std::vector<std::string> names;
31 for (const auto& itr : m_data) {
32 names.push_back(itr.first);
33 }
34 return names;
35 }
36
37 size_t get_size() const { return m_data.size(); }
38
39 bool has(const std::string& name) const { return m_data.find(name) != m_data.end(); }
40
41 void add(const std::string& name)
42 {
43 m_data.emplace(name, std::make_unique<IndexedAttribute>());
44 }
45
46 template <typename ValueDerived, typename IndexDerived>
47 void add(const std::string& name, ValueDerived&& values, IndexDerived&& indices)
48 {
49 auto attr = std::make_unique<IndexedAttribute>(
50 std::forward<ValueDerived>(values),
51 std::forward<IndexDerived>(indices));
52 m_data.emplace(name, std::move(attr));
53 }
54
55 template <typename ValueDerived, typename IndexDerived>
56 void set(const std::string& name, ValueDerived&& values, IndexDerived&& indices)
57 {
58 auto itr = m_data.find(name);
59 la_runtime_assert(itr != m_data.end(), "Indexed attribute " + name + " does not exist.");
60 if (itr->second == nullptr) {
61 itr->second = std::make_unique<IndexedAttribute>(
62 std::forward<ValueDerived>(values),
63 std::forward<IndexDerived>(indices));
64 } else {
65 itr->second->set_values(std::forward<ValueDerived>(values));
66 itr->second->set_indices(std::forward<IndexDerived>(indices));
67 }
68 }
69
70 IndexedAttribute* get(const std::string& name)
71 {
72 auto itr = m_data.find(name);
73 la_runtime_assert(itr != m_data.end(), "Indexed attribute " + name + " does not exist.");
74 return itr->second.get();
75 }
76
77 const IndexedAttribute* get(const std::string& name) const
78 {
79 auto itr = m_data.find(name);
80 la_runtime_assert(itr != m_data.end(), "Indexed attribute " + name + " does not exist.");
81 return itr->second.get();
82 }
83
84 template <typename Derived>
85 decltype(auto) get_values(const std::string& name)
86 {
87 auto ptr = get(name);
88 la_runtime_assert(ptr != nullptr, "Attribute " + name + " is null.");
89 return ptr->get_values<Derived>();
90 }
91
92 template <typename Derived>
93 decltype(auto) get_values(const std::string& name) const
94 {
95 const auto ptr = get(name);
96 la_runtime_assert(ptr != nullptr, "Attribute " + name + " is null.");
97 return ptr->get_values<Derived>();
98 }
99
100 template <typename Derived>
101 decltype(auto) get_indices(const std::string& name)
102 {
103 auto ptr = get(name);
104 la_runtime_assert(ptr != nullptr, "Attribute " + name + " is null.");
105 return ptr->get_indices<Derived>();
106 }
107
108 template <typename Derived>
109 decltype(auto) get_indices(const std::string& name) const
110 {
111 const auto ptr = get(name);
112 la_runtime_assert(ptr != nullptr, "Attribute " + name + " is null.");
113 return ptr->get_indices<Derived>();
114 }
115
116 template <typename Derived>
117 decltype(auto) view_values(const std::string& name)
118 {
119 auto ptr = get(name);
120 la_runtime_assert(ptr != nullptr, "Attribute " + name + " is null.");
121 return ptr->view_values<Derived>();
122 }
123
124 template <typename Derived>
125 decltype(auto) view_values(const std::string& name) const
126 {
127 const auto ptr = get(name);
128 la_runtime_assert(ptr != nullptr, "Attribute " + name + " is null.");
129 return ptr->view_values<Derived>();
130 }
131
132 template <typename Derived>
133 decltype(auto) view_indices(const std::string& name)
134 {
135 auto ptr = get(name);
136 la_runtime_assert(ptr != nullptr, "Attribute " + name + " is null.");
137 return ptr->view_indices<Derived>();
138 }
139
140 template <typename Derived>
141 decltype(auto) view_indices(const std::string& name) const
142 {
143 const auto ptr = get(name);
144 la_runtime_assert(ptr != nullptr, "Attribute " + name + " is null.");
145 return ptr->view_indices<Derived>();
146 }
147
148 template <typename ValueDerived, typename IndexDerived>
149 void import_data(const std::string& name, ValueDerived&& values, IndexDerived&& indices)
150 {
151 set(name, std::move(values.derived()), std::move(indices.derived()));
152 }
153
154 template <typename ValueDerived, typename IndexDerived>
155 void export_data(
156 const std::string& name,
157 Eigen::PlainObjectBase<ValueDerived>& values,
158 Eigen::PlainObjectBase<IndexDerived>& indices)
159 {
160 auto attr = get(name);
161 la_runtime_assert(attr != nullptr, "Attribute " + name + " is null.");
162 auto value_array = attr->get_values();
163 auto index_array = attr->get_indices();
164 la_runtime_assert(value_array != nullptr);
165 la_runtime_assert(index_array != nullptr);
166
167#ifndef NDEBUG
168 bool validate = true;
169 void* value_ptr = value_array->data();
170 void* index_ptr = index_array->data();
171#endif
172 try {
173 ValueDerived& value_matrix = value_array->template get<ValueDerived>();
174 IndexDerived& index_matrix = index_array->template get<IndexDerived>();
175 values.swap(value_matrix);
176 indices.swap(index_matrix);
177 } catch (std::runtime_error& e) {
178 // It seems ValueDerived or IndexDerived are not exact match to the
179 // Eigen type used for creating the attribute. A copy is necessary.
180 logger().warn("Export cannot be done without coping: {}", e.what());
181 values = value_array->view<ValueDerived>();
182 indices = index_array->view<IndexDerived>();
183#ifndef NDEBUG
184 validate = false;
185#endif
186 }
187
188#ifndef NDEBUG
189 if (validate) {
190 la_runtime_assert(value_ptr == values.data(), "Export values fall back to copying.");
191 la_runtime_assert(index_ptr == indices.data(), "Export indices fall back to copying.");
192 }
193#endif
194 }
195
196 void remove(const std::string& name)
197 {
198 auto itr = m_data.find(name);
199 la_runtime_assert(itr != m_data.end(), "Attribute " + name + " does not exist.");
200 m_data.erase(itr);
201 }
202
203 template <typename Archive>
204 void serialize_impl(Archive& ar)
205 {
207 enum { DATA = 0 };
208 ar.object([&](auto& ar) { ar("data", DATA) & m_data; });
209 LA_IGNORE_SHADOW_WARNING_END
210 }
211
212private:
213 std::map<std::string, std::unique_ptr<IndexedAttribute>> m_data;
214};
215
217
218template <typename Archive>
219void serialize(std::pair<std::string, IndexedAttribute>& entry, Archive& ar)
220{
221 enum { KEY = 0, VALUE = 1 };
222
223 ar.object([&](auto& ar) {
224 ar("key", KEY) & entry.first;
225 ar("value", VALUE) & entry.second;
226 });
227}
228
229template <typename Archive>
230void serialize(std::map<std::string, std::unique_ptr<IndexedAttribute>>& attrs, Archive& ar)
231{
232 std::vector<std::pair<std::string, ::lagrange::experimental::IndexedAttribute>> data;
233 if (!ar.is_input()) {
234 for (auto& itr : attrs) {
235 data.emplace_back(itr.first, *itr.second);
236 }
237 }
238
239 serialize(data, ar);
240
241 if (ar.is_input()) {
242 attrs.clear();
243 for (const auto& itr : data) {
244 attrs[itr.first] = std::make_unique<IndexedAttribute>(itr.second);
245 }
246 }
247}
248
249template <typename Archive>
250void serialize(IndexedAttributeManager& attributes, Archive& ar)
251{
252 attributes.serialize_impl(ar);
253}
254
255LA_IGNORE_SHADOW_WARNING_END
256
257} // namespace experimental
258} // namespace lagrange
Definition IndexedAttribute.h:22
Definition IndexedAttributeManager.h:26
Smart pointer with value semantics.
Definition value_ptr.h:134
LA_CORE_API spdlog::logger & logger()
Retrieves the current logger.
Definition Logger.cpp:40
#define la_runtime_assert(...)
Runtime assertion check.
Definition assert.h:174
#define LA_IGNORE_SHADOW_WARNING_BEGIN
Ignore shadow warnings.
Definition warning.h:68
Main namespace for Lagrange.