LibTorch's save_to & load_from function - Model Archiving

I’m fairly new to LibTorch and it’s Model Archiving system.

At the moment, I’m trying to save my model configuration from one module, and load it a different module, but I’m raising an error in LibTorch that I don’t quite understand.

To do this, i’ve been reading the API documentation here: Class OutputArchive — PyTorch master documentation
which doesn’t seem to be all that helpful on the matter.

I’ve been trying utilise as much of LibTorch as possible here, but I’m suspecting a JSON or similar storage structure might infact be easier. I’m doing it this way (rather than using a .clone() or similar) as I intend to send the data at some point in the future.

I’ve simplified my code below;

torch::serialize::OutputArchive
NewModule::getArchive()
{
   torch::serialize::OutputArchive archive;
   auto params = named_parameters(true /*recurse*/);
   auto buffers = named_buffers(true /*recurse*/);
   
   for (const auto& val : params)
   {
      if (!is_empty(val.value()))
				archive.write(val.key(), val.value());
      // Same again with a write-buffers.
      return archive;
   }
}

This function aims to copy the contents to a torch::serialise::OutputArchive, which can then be saved to disk, passed into an ostream or “writer function”. It’s the last of these I’m struggling to get working successfully.

Torch specifies that the writer function must be of type std::function<size_t(const void*, size_t)> I’m assuming (as the docs don’t specify!) that the const void* is actually an array of bytes which length is determined by the second parameter, size_t I am unsure why the return value is also a size_t here.

My next block of code reads this data blob and attempts to read it using torch::serialise::InputArchive. Calling load_from here produces the error: “PytorchStreamReader failed reading zip archive: failed finding central directory”

Can anyone help resolve why this is the case?

Code below:

void
NewModule::LoadFromData(const char* data, size_t data_size)
{
   torch::serialize::InputArchive archive;
   archive.load_from(data, data_size);
   auto params = named_parameters(true);
   auto buffers = named_buffers(true);
   for (auto& val : params)
   {
      archive.read(val.key(), val.value());
   }
   // Same again with a copy buffers
}

torch::serialize::OutputArchive
NewModule::copyArchive()
{
   NewModule other_module;
   auto archive = getArchive();
   std::function<size_t(const void*, size_t)> writer_lambda = [this, other_module](const void* data, size_t size) mutable -> size_t {
      other_module.LoadFromData(reinterpret_cast<const char*>(data), size);
   }
   archive.save_to(writer_lambda);
}

Not sure exactly your need but have you seen this for saving to disk:

and this for transferring parameters between modules without saving:

Even if this might be a solution for the original poster, I’d be interested in understanding how archive.save_to(std::function<size_t(const void*, size_t)>) should be used. I would like to “save” the archive into a JSON object (Binary Values - JSON for Modern C++) for which I wanted to use the callback to convert the OutputArchive into an std::vector<std::uint8_t> and proceed with the JSON binary machinery. Any help is appreciated.