Skip to content

Trying to not make a big deal of Marshalling

Peter Doak edited this page Apr 30, 2020 · 2 revisions

In thinking about how to not break encapsulation and minimize dependency introduced by serialization of walker elements for serialization. This is a simple concern requiring the object to be marshaled models the concept of "serializable" Which I crudely define as begin able to return two closures one able to add memory segments the other being able to remove them.

Here's a sketch.

  using MemorySegments = std::vector<std::pair<T*,T*>>;
  using SerializeFunction = std::function<void(MemorySegments&)>
  
  template<typename T>
  class WalkerElementsBuffer
  {
    void writeWalker()
    {
     //write a header cataloging the segments
     //copy segments into buffer
     //reserve can happen in one step. If the buffer has been used its already the right size.
    }

    template<class SF, class ...WFEs>
    void writeWalker(SerializationFunction serialize_f, WFEs... walker_elements)
    {
      serialize_f(segments_);
      writeWalker(walker_elements...);
    }

    void readWalker()
    {
     //read header cataloging the segments
    }

    template<class SF, class ...WFEs>
    void readWalker(SerializationFunction deserialize_f, WFEs... walker_elements)
    {
      readWalker(walker_elements...);
      deserialize_f(segments_);
    }

    T* getPtr() { return buffer_.data(); }
    size_t size() { return buffer_.size(); }
  private:
    std::vector<std::pair<T*,T*>> segments_;
    std::vector<T> buffer_;
  }

  class A_WFE
  {
    //...

    // return closures
    SerializationFunction serialize() { return [this](MemorySegments& mem_seg){
				mem_seg.push_back(std::pair<T*,T*>(something1.data(),something1.data()+something1.size()));
				mem_seg.push_back(std::pair<T*,T*>(something2...));
				//...
				  };
    };
    SerializationFunction deserialize() { return [this](MemorySegments& mem_seg){
						   ...
						   something2.copyIn(mem_seg.pop_back());
						   something1.copyIn(mem_seg.pop_back());
						 };
    };
    //...
  };


  ...

  mpi_buffer.writeWalker(walker.serialize(), walker_twf.serialize(), walker_ham.serialize())
  //mpi3 understands I'm returning a T*
  comm.isend_n(mpi_buffer.getPtr(),mpi_buffer.size(),dest);

  comm.irecieve_n(mpi_buffer.getPtr(),mpi_buffer.size(),sender);
  mpi_buffer.readWalker(walker.deserialize(), walker_twf.deserialize(), walker_ham.deserialize())

Clone this wiki locally