};
/** @brief Return a set of Bag to be allocated */
+// NOTE An input/output bag may be included in the retrun set of "intermediates"
std::set<coco::Bag *> intermediates(const enco::Code *code)
{
// NOTE The current implementation may allocate unnecessary buffers (such as weight)
{
auto bag = code->module()->entity()->bag()->at(n);
- if (!bag->isInput() && !bag->isOutput())
+ // TODO Remove unnecessary indentation
{
if (accessed_by_host(bag))
{
// Set dedicated memory reigion for intermediate buffer(s)
for (const auto &bag : intermediates(_code))
{
+ // Skip if a bag is already allocated
+ if (mem.member(bag))
+ {
+ continue;
+ }
+
auto name = invoke.local();
invoke.head.append("auto ", name, " = new uint8_t[", bag->size() * sizeof(float), "];");
#include "MemoryContext.h"
+#include <cassert>
+
namespace enco
{
+bool MemoryContext::member(const coco::Bag *bag) const
+{
+ // NOTE _base and _size SHOULD BE consistent
+ if (_base.find(bag) != _base.end())
+ {
+ assert(_size.find(bag) != _size.end());
+ return true;
+ }
+
+ assert(_size.find(bag) == _size.end());
+ return false;
+}
+
void MemoryContext::base(const coco::Bag *bag, const std::string &exp) { _base[bag] = exp; }
void MemoryContext::size(const coco::Bag *bag, const std::string &exp) { _size[bag] = exp; }
class MemoryContext
{
public:
+ /**
+ * @brief Check whether a base/size expression for a given bag
+ */
+ bool member(const coco::Bag *bag) const;
+
+public:
void base(const coco::Bag *bag, const std::string &exp);
void size(const coco::Bag *bag, const std::string &exp);