InvokeFunction invoke;
pp::LinearDocument internal;
+ const std::string data_varname = "data";
+
+ auto data_exp = [&data_varname](const GlobalOffset &off) {
+ return pp::fmt(data_varname, " + ", off);
+ };
+
// Record the subnet information
std::map<const ANNBinder *, SubnetInfo> subnet_ctx;
auto subnet_field_name = pp::fmt("_subnet_", subnet_ctx.size());
// Create global data variable
- auto emit_weight = [&global, &builder](const ann::OperandID &id, const ann::Operand *info) {
+ auto emit_weight = [&](const ann::OperandID &id, const ann::Operand *info) {
if (info->weight())
{
auto base = info->weight()->base();
auto size = info->weight()->size();
- auto gvar = global.constant(base, size);
+ auto off = global.constant(base, size);
- auto base_exp = pp::fmt("reinterpret_cast<const void *>(&", gvar, ")");
+ auto base_exp = pp::fmt("reinterpret_cast<const void *>(", data_exp(off), ")");
auto size_exp = pp::fmt(size);
builder.expr(info, base_exp, size_exp);
auto input = m->input()->at(n);
auto dims = as_dims(input->shape());
- auto name_var = global.constant(input->name());
- auto dims_var = global.constant<uint32_t>(dims);
+ auto name_off = global.constant(input->name());
+ auto name_exp = pp::fmt("reinterpret_cast<const char *>(", data_exp(name_off), ")");
+ auto dims_off = global.constant<uint32_t>(dims);
+ auto dims_exp = pp::fmt("reinterpret_cast<const unsigned *>(", data_exp(dims_off), ")");
- net_ctor.append("inputs.at(", n, ").name = ", name_var, ";");
+ net_ctor.append("inputs.at(", n, ").name = ", name_exp, ";");
net_ctor.append("inputs.at(", n, ").shape.rank = ", dims.size(), ";");
- net_ctor.append("inputs.at(", n, ").shape.dims = ", dims_var, ";");
+ net_ctor.append("inputs.at(", n, ").shape.dims = ", dims_exp, ";");
}
// Initialize output metadata
auto output = m->output()->at(n);
auto dims = as_dims(output->shape());
- auto name_var = global.constant(output->name());
- auto dims_name = global.constant<uint32_t>(dims);
+ auto name_off = global.constant(output->name());
+ auto name_exp = pp::fmt("reinterpret_cast<const char *>(", data_exp(name_off), ")");
+ auto dims_off = global.constant<uint32_t>(dims);
+ auto dims_exp = pp::fmt("reinterpret_cast<const unsigned *>(", data_exp(dims_off), ")");
- net_ctor.append("outputs.at(", n, ").name = ", name_var, ";");
+ net_ctor.append("outputs.at(", n, ").name = ", name_exp, ";");
net_ctor.append("outputs.at(", n, ").shape.rank = ", dims.size(), ";");
- net_ctor.append("outputs.at(", n, ").shape.dims = ", dims_name, ";");
+ net_ctor.append("outputs.at(", n, ").shape.dims = ", dims_exp, ";");
}
// TODO Implement this
source.append(includes);
source.append();
- source.append(global.content());
+ source.append("uint8_t ", data_varname, "[] = { ", global, " };");
source.append();
source.append("namespace");
namespace enco
{
-std::string Global::constant(const std::string &s)
+GlobalOffset Global::constant(const std::string &s)
{
- auto name = pp::fmt("g_", _count++);
-
- _content.append("const char *", name, " = \"", s, "\";");
-
- return name;
+ auto const base = reinterpret_cast<const uint8_t *>(s.c_str());
+ auto const size = s.size() + 1 /* NUL */;
+ return constant(base, size);
}
-template <> std::string Global::constant(const std::vector<uint32_t> &values)
+template <> GlobalOffset Global::constant(const std::vector<uint32_t> &values)
{
- auto name = pp::fmt("g_", _count++);
-
- std::stringstream ss;
-
- ss << "const uint32_t " << name << "[" << values.size() << "] = { ";
- ss << ::concat(", ", transform(u32_to_dec, values.begin(), values.end()));
- ss << " };";
-
- _content.append(ss.str());
-
- return name;
+ auto const base = reinterpret_cast<const uint8_t *>(values.data());
+ auto const size = sizeof(uint32_t) * values.size();
+ return constant(base, size);
}
-std::string Global::constant(const uint8_t *base, uint32_t size)
+GlobalOffset Global::constant(const uint8_t *base, uint32_t size)
{
- auto name = pp::fmt("g_", _count++);
+ uint32_t offset = _content.size();
- std::stringstream ss;
+ for (uint32_t n = 0; n < size; ++n)
+ {
+ _content.emplace_back(base[n]);
+ }
- ss << "const uint8_t " << name << "[" << size << "] = { ";
- ss << ::concat(", ", transform(u08_to_hex, base, base + size));
- ss << " };";
+ return offset;
+}
- _content.append(ss.str());
+void emit_as_initializer_list(std::ostream &os, const Global &global)
+{
+ if (global.size() > 0)
+ {
+ os << u08_to_hex(global.at(0));
- return name;
+ for (uint32_t n = 1; n < global.size(); ++n)
+ {
+ os << ", " << u08_to_hex(global.at(n));
+ }
+ }
}
} // namespace enco
#ifndef __ENCO_GLOBAL_H__
#define __ENCO_GLOBAL_H__
-#include <pp/LinearDocument.h>
-
#include <cstdint>
#include <string>
+#include <vector>
+#include <ostream>
namespace enco
{
+using GlobalOffset = uint32_t;
+
/**
* @brief Manage global variable declarations
*/
{
public:
// @brief Create a global constant string (const char *) literal, and return variable name
- std::string constant(const std::string &value);
+ GlobalOffset constant(const std::string &value);
// @brief Create a global constant array variable of type T
- template <typename T> std::string constant(const std::vector<T> &values);
+ template <typename T> GlobalOffset constant(const std::vector<T> &values);
// @brief Create a global constant array variable of byte (uint8_t) type
- std::string constant(const uint8_t *base, uint32_t size);
+ GlobalOffset constant(const uint8_t *base, uint32_t size);
public:
- const pp::MultiLineText &content(void) const { return _content; }
+ uint32_t size(void) const { return _content.size(); }
+ uint8_t at(uint32_t n) const { return _content.at(n); }
private:
- uint32_t _count = 0;
- pp::LinearDocument _content;
+ std::vector<uint8_t> _content;
};
+void emit_as_initializer_list(std::ostream &os, const Global &global);
+
} // namespace enco
+static inline std::ostream &operator<<(std::ostream &os, const enco::Global &global)
+{
+ emit_as_initializer_list(os, global);
+ return os;
+}
+
#endif // __ENCO_GLOBAL_H__