[Beignet] [V3 PATCH 1/4] Add the serialization support for backend

Zhigang Gong zhigang.gong at linux.intel.com
Thu Sep 12 01:15:53 PDT 2013


Pushed the whole patchset. Thanks for the contribution.

On Wed, Sep 11, 2013 at 06:07:39PM +0800, junyan.he at inbox.com wrote:
> From: Junyan He <junyan.he at linux.intel.com>
> 
> The Serializable class define the interface of serialize_to/deserialize_from
> functions for internal binary and llvm binary. And also a print status
> function for debugging.
> The class which may need the serializaion support need to derive from it,
> these classes including: Program, Kernel, ConstantSet, ImageSet and SamplerSet.
> This patch just add serialize_to/deserialize_from internal binary support for
> all these classes.
> 
> Signed-off-by: Junyan He <junyan.he at linux.intel.com>
> ---
>  backend/src/backend/gen_program.cpp |   27 +++
>  backend/src/backend/gen_program.hpp |   10 +-
>  backend/src/backend/program.cpp     |  316 +++++++++++++++++++++++++++++++++++
>  backend/src/backend/program.hpp     |   59 ++++++-
>  backend/src/ir/constant.cpp         |  101 +++++++++++
>  backend/src/ir/constant.hpp         |   28 +++-
>  backend/src/ir/image.cpp            |  139 +++++++++++++++
>  backend/src/ir/image.hpp            |   25 ++-
>  backend/src/ir/sampler.cpp          |   98 +++++++++++
>  backend/src/ir/sampler.hpp          |   25 ++-
>  backend/src/sys/platform.hpp        |   42 +++++
>  11 files changed, 862 insertions(+), 8 deletions(-)
> 
> diff --git a/backend/src/backend/gen_program.cpp b/backend/src/backend/gen_program.cpp
> index 3d7bedd..bdd3441 100644
> --- a/backend/src/backend/gen_program.cpp
> +++ b/backend/src/backend/gen_program.cpp
> @@ -27,12 +27,15 @@
>  #include "backend/gen_program.hpp"
>  #include "backend/gen_context.hpp"
>  #include "backend/gen_defs.hpp"
> +#include "backend/gen/gen_mesa_disasm.h"
>  #include "backend/gen_reg_allocation.hpp"
>  #include "ir/unit.hpp"
>  #include "llvm/llvm_to_gen.hpp"
>  
>  #include <cstring>
>  #include <memory>
> +#include <iostream>
> +#include <fstream>
>  
>  namespace gbe {
>  
> @@ -41,8 +44,32 @@ namespace gbe {
>    {}
>    GenKernel::~GenKernel(void) { GBE_SAFE_DELETE_ARRAY(insns); }
>    const char *GenKernel::getCode(void) const { return (const char*) insns; }
> +  const void GenKernel::setCode(const char * ins, size_t size) {
> +    insns = (GenInstruction *)ins;
> +    insnNum = size / sizeof(GenInstruction);
> +  }
>    size_t GenKernel::getCodeSize(void) const { return insnNum * sizeof(GenInstruction); }
>  
> +  void GenKernel::printStatus(int indent, std::ostream& outs) {
> +    Kernel::printStatus(indent, outs);
> +
> +    FILE *f = fopen("/dev/null", "w");
> +    char *buf = new char[4096];
> +    setbuffer(f, buf, 4096);
> +
> +    for (uint32_t i = 0; i < insnNum; i++) {
> +      gen_disasm(f, insns+i);
> +      outs << buf;
> +      fflush(f);
> +      setbuffer(f, NULL, 0);
> +      setbuffer(f, buf, 4096);
> +    }
> +
> +    setbuffer(f, NULL, 0);
> +    delete [] buf;
> +    fclose(f);
> +  }
> +
>    GenProgram::GenProgram(void) {}
>    GenProgram::~GenProgram(void) {}
>  
> diff --git a/backend/src/backend/gen_program.hpp b/backend/src/backend/gen_program.hpp
> index 68b0427..f78e324 100644
> --- a/backend/src/backend/gen_program.hpp
> +++ b/backend/src/backend/gen_program.hpp
> @@ -42,8 +42,12 @@ namespace gbe
>      virtual ~GenKernel(void);
>      /*! Implements base class */
>      virtual const char *getCode(void) const;
> -    /*! Implements base class */
> +    /*! Set the instruction stream (to be implemented) */
> +    virtual const void setCode(const char *, size_t size);
> +    /*! Implements get the code size */
>      virtual size_t getCodeSize(void) const;
> +    /*! Implements printStatus*/
> +    virtual void printStatus(int indent, std::ostream& outs);
>      GenInstruction *insns; //!< Instruction stream
>      uint32_t insnNum;      //!< Number of instructions
>      GBE_CLASS(GenKernel);  //!< Use custom allocators
> @@ -59,6 +63,10 @@ namespace gbe
>      virtual ~GenProgram(void);
>      /*! Implements base class */
>      virtual Kernel *compileKernel(const ir::Unit &unit, const std::string &name);
> +    /*! Allocate an empty kernel. */
> +    virtual Kernel *allocateKernel(const std::string &name) {
> +      return GBE_NEW(GenKernel, name);
> +    }
>      /*! Use custom allocators */
>      GBE_CLASS(GenProgram);
>    };
> diff --git a/backend/src/backend/program.cpp b/backend/src/backend/program.cpp
> index 35d3a7c..68bb17e 100644
> --- a/backend/src/backend/program.cpp
> +++ b/backend/src/backend/program.cpp
> @@ -37,6 +37,7 @@
>  #include <fstream>
>  #include <dlfcn.h>
>  #include <sstream>
> +#include <iostream>
>  #include <unistd.h>
>  
>  /* Not defined for LLVM 3.0 */
> @@ -124,6 +125,321 @@ namespace gbe {
>      return true;
>    }
>  
> +#define OUT_UPDATE_SZ(elt) SERIALIZE_OUT(elt, outs, ret_size)
> +#define IN_UPDATE_SZ(elt) DESERIALIZE_IN(elt, ins, total_size)
> +
> +  size_t Program::serializeToBin(std::ostream& outs) {
> +    size_t ret_size = 0;
> +    size_t ker_num = kernels.size();
> +    int has_constset = 0;
> +
> +    OUT_UPDATE_SZ(magic_begin);
> +
> +    if (constantSet) {
> +      has_constset = 1;
> +      OUT_UPDATE_SZ(has_constset);
> +      size_t sz = constantSet->serializeToBin(outs);
> +      if (!sz)
> +        return 0;
> +
> +      ret_size += sz;
> +    } else {
> +      OUT_UPDATE_SZ(has_constset);
> +    }
> +
> +    OUT_UPDATE_SZ(ker_num);
> +    for (auto ker : kernels) {
> +      size_t sz = ker.second->serializeToBin(outs);
> +      if (!sz)
> +        return 0;
> +
> +      ret_size += sz;
> +    }
> +
> +    OUT_UPDATE_SZ(magic_end);
> +
> +    OUT_UPDATE_SZ(ret_size);
> +    return ret_size;
> +  }
> +
> +  size_t Program::deserializeFromBin(std::istream& ins) {
> +    size_t total_size = 0;
> +    int has_constset = 0;
> +    size_t ker_num;
> +    uint32_t magic;
> +
> +    IN_UPDATE_SZ(magic);
> +    if (magic != magic_begin)
> +      return 0;
> +
> +    IN_UPDATE_SZ(has_constset);
> +    if(has_constset) {
> +      constantSet = new ir::ConstantSet;
> +      size_t sz = constantSet->deserializeFromBin(ins);
> +
> +      if (sz == 0) {
> +        return 0;
> +      }
> +
> +      total_size += sz;
> +    }
> +
> +    IN_UPDATE_SZ(ker_num);
> +
> +    for (size_t i = 0; i < ker_num; i++) {
> +      size_t ker_serial_sz;
> +      std::string ker_name; // Just a empty name here.
> +      Kernel* ker = allocateKernel(ker_name);
> +
> +      if(!(ker_serial_sz = ker->deserializeFromBin(ins)))
> +        return 0;
> +
> +      kernels.insert(std::make_pair(ker->getName(), ker));
> +      total_size += ker_serial_sz;
> +    }
> +
> +    IN_UPDATE_SZ(magic);
> +    if (magic != magic_end)
> +      return 0;
> +
> +    size_t total_bytes;
> +    IN_UPDATE_SZ(total_bytes);
> +    if (total_bytes + sizeof(total_size) != total_size)
> +      return 0;
> +
> +    return total_size;
> +  }
> +
> +  size_t Kernel::serializeToBin(std::ostream& outs) {
> +    unsigned int i;
> +    size_t ret_size = 0;
> +    int has_samplerset = 0;
> +    int has_imageset = 0;
> +
> +    OUT_UPDATE_SZ(magic_begin);
> +
> +    OUT_UPDATE_SZ(name.size());
> +    outs.write(name.c_str(), name.size());
> +    ret_size += sizeof(char)*name.size();
> +
> +    OUT_UPDATE_SZ(argNum);
> +    for (i = 0; i < argNum; i++) {
> +      KernelArgument& arg = args[i];
> +      OUT_UPDATE_SZ(arg.type);
> +      OUT_UPDATE_SZ(arg.size);
> +      OUT_UPDATE_SZ(arg.bufSize);
> +    }
> +
> +    OUT_UPDATE_SZ(patches.size());
> +    for (auto patch : patches) {
> +      unsigned int tmp;
> +      tmp = patch.type;
> +      OUT_UPDATE_SZ(tmp);
> +      tmp = patch.subType;
> +      OUT_UPDATE_SZ(tmp);
> +      tmp = patch.offset;
> +      OUT_UPDATE_SZ(tmp);
> +    }
> +
> +    OUT_UPDATE_SZ(curbeSize);
> +    OUT_UPDATE_SZ(simdWidth);
> +    OUT_UPDATE_SZ(stackSize);
> +    OUT_UPDATE_SZ(useSLM);
> +
> +    /* samplers. */
> +    if (samplerSet) {
> +      has_samplerset = 1;
> +      OUT_UPDATE_SZ(has_samplerset);
> +      size_t sz = samplerSet->serializeToBin(outs);
> +      if (!sz)
> +        return 0;
> +
> +      ret_size += sz;
> +    } else {
> +      OUT_UPDATE_SZ(has_samplerset);
> +    }
> +
> +    /* images. */
> +    if (imageSet) {
> +      has_imageset = 1;
> +      OUT_UPDATE_SZ(has_imageset);
> +      size_t sz = imageSet->serializeToBin(outs);
> +      if (!sz)
> +        return 0;
> +
> +      ret_size += sz;
> +    } else {
> +      OUT_UPDATE_SZ(has_imageset);
> +    }
> +
> +    /* Code. */
> +    const char * code = getCode();
> +    OUT_UPDATE_SZ(getCodeSize());
> +    outs.write(code, getCodeSize()*sizeof(char));
> +    ret_size += getCodeSize()*sizeof(char);
> +
> +    OUT_UPDATE_SZ(magic_end);
> +
> +    OUT_UPDATE_SZ(ret_size);
> +    return ret_size;
> +  }
> +
> +  size_t Kernel::deserializeFromBin(std::istream& ins) {
> +    size_t total_size = 0;
> +    int has_samplerset = 0;
> +    int has_imageset = 0;
> +    size_t code_size = 0;
> +    uint32_t magic = 0;
> +    size_t patch_num = 0;
> +
> +    IN_UPDATE_SZ(magic);
> +    if (magic != magic_begin)
> +      return 0;
> +
> +    size_t name_len;
> +    IN_UPDATE_SZ(name_len);
> +    char* c_name = new char[name_len+1];
> +    ins.read(c_name, name_len*sizeof(char));
> +    total_size += sizeof(char)*name_len;
> +    c_name[name_len] = 0;
> +    name = c_name;
> +    delete[] c_name;
> +
> +    IN_UPDATE_SZ(argNum);
> +    args = GBE_NEW_ARRAY_NO_ARG(KernelArgument, argNum);
> +    for (uint32_t i = 0; i < argNum; i++) {
> +      KernelArgument& arg = args[i];
> +      IN_UPDATE_SZ(arg.type);
> +      IN_UPDATE_SZ(arg.size);
> +      IN_UPDATE_SZ(arg.bufSize);
> +    }
> +
> +    IN_UPDATE_SZ(patch_num);
> +    for (uint32_t i = 0; i < patch_num; i++) {
> +      unsigned int tmp;
> +      PatchInfo patch;
> +      IN_UPDATE_SZ(tmp);
> +      patch.type = tmp;
> +      IN_UPDATE_SZ(tmp);
> +      patch.subType = tmp;
> +      IN_UPDATE_SZ(tmp);
> +      patch.offset = tmp;
> +
> +      patches.push_back(patch);
> +    }
> +
> +    IN_UPDATE_SZ(curbeSize);
> +    IN_UPDATE_SZ(simdWidth);
> +    IN_UPDATE_SZ(stackSize);
> +    IN_UPDATE_SZ(useSLM);
> +
> +    IN_UPDATE_SZ(has_samplerset);
> +    if (has_samplerset) {
> +      samplerSet = GBE_NEW(ir::SamplerSet);
> +      size_t sz = samplerSet->deserializeFromBin(ins);
> +      if (sz == 0) {
> +        return 0;
> +      }
> +
> +      total_size += sz;
> +    }
> +
> +    IN_UPDATE_SZ(has_imageset);
> +    if (has_imageset) {
> +      imageSet = GBE_NEW(ir::ImageSet);
> +      size_t sz = imageSet->deserializeFromBin(ins);
> +      if (sz == 0) {
> +        return 0;
> +      }
> +
> +      total_size += sz;
> +    }
> +
> +    IN_UPDATE_SZ(code_size);
> +    if (code_size) {
> +      char* code = GBE_NEW_ARRAY_NO_ARG(char, code_size);
> +      ins.read(code, code_size*sizeof(char));
> +      total_size += sizeof(char)*code_size;
> +      setCode(code, code_size);
> +    }
> +
> +    IN_UPDATE_SZ(magic);
> +    if (magic != magic_end)
> +      return 0;
> +
> +    size_t total_bytes;
> +    IN_UPDATE_SZ(total_bytes);
> +    if (total_bytes + sizeof(total_size) != total_size)
> +      return 0;
> +
> +    return total_size;
> +  }
> +
> +#undef OUT_UPDATE_SZ
> +#undef IN_UPDATE_SZ
> +
> +  void Program::printStatus(int indent, std::ostream& outs) {
> +    using namespace std;
> +    string spaces = indent_to_str(indent);
> +
> +    outs << spaces << "=============== Begin Program ===============" << "\n";
> +
> +    if (constantSet) {
> +      constantSet->printStatus(indent + 4, outs);
> +    }
> +
> +    for (auto ker : kernels) {
> +      ker.second->printStatus(indent + 4, outs);
> +    }
> +
> +    outs << spaces << "================ End Program ================" << "\n";
> +  }
> +
> +  void Kernel::printStatus(int indent, std::ostream& outs) {
> +    using namespace std;
> +    string spaces = indent_to_str(indent);
> +    string spaces_nl = indent_to_str(indent + 4);
> +    int num;
> +
> +    outs << spaces << "+++++++++++ Begin Kernel +++++++++++" << "\n";
> +    outs << spaces_nl << "Kernel Name: " << name << "\n";
> +    outs << spaces_nl << "  curbeSize: " << curbeSize << "\n";
> +    outs << spaces_nl << "  simdWidth: " << simdWidth << "\n";
> +    outs << spaces_nl << "  stackSize: " << stackSize << "\n";
> +    outs << spaces_nl << "  useSLM: " << useSLM << "\n";
> +
> +    outs << spaces_nl << "  Argument Number is " << argNum << "\n";
> +    for (uint32_t i = 0; i < argNum; i++) {
> +      KernelArgument& arg = args[i];
> +      outs << spaces_nl << "  Arg " << i << ":\n";
> +      outs << spaces_nl << "      type value: "<< arg.type << "\n";
> +      outs << spaces_nl << "      size: "<< arg.size << "\n";
> +      outs << spaces_nl << "      bufSize: "<< arg.bufSize << "\n";
> +    }
> +
> +    outs << spaces_nl << "  Patches Number is " << patches.size() << "\n";
> +    num = 0;
> +    for (auto patch : patches) {
> +      num++;
> +      outs << spaces_nl << "  patch " << num << ":\n";
> +      outs << spaces_nl << "      type value: "<< patch.type << "\n";
> +      outs << spaces_nl << "      subtype value: "<< patch.subType << "\n";
> +      outs << spaces_nl << "      offset: "<< patch.offset << "\n";
> +    }
> +
> +    if (samplerSet) {
> +      samplerSet->printStatus(indent + 4, outs);
> +    }
> +
> +    if (imageSet) {
> +      imageSet->printStatus(indent + 4, outs);
> +    }
> +
> +    outs << spaces << "++++++++++++ End Kernel ++++++++++++" << "\n";
> +  }
> +
> +  /*********************** End of Program class member function *************************/
> +
>    static void programDelete(gbe_program gbeProgram) {
>      gbe::Program *program = (gbe::Program*)(gbeProgram);
>      GBE_SAFE_DELETE(program);
> diff --git a/backend/src/backend/program.hpp b/backend/src/backend/program.hpp
> index 83aaab8..28a792d 100644
> --- a/backend/src/backend/program.hpp
> +++ b/backend/src/backend/program.hpp
> @@ -67,7 +67,7 @@ namespace gbe {
>    }
>  
>    /*! Describe a compiled kernel */
> -  class Kernel : public NonCopyable
> +  class Kernel : public NonCopyable, public Serializable
>    {
>    public:
>      /*! Create an empty kernel with the given name */
> @@ -76,6 +76,8 @@ namespace gbe {
>      virtual ~Kernel(void);
>      /*! Return the instruction stream (to be implemented) */
>      virtual const char *getCode(void) const = 0;
> +    /*! Set the instruction stream.*/
> +    virtual const void setCode(const char *, size_t size) = 0;
>      /*! Return the instruction stream size (to be implemented) */
>      virtual size_t getCodeSize(void) const = 0;
>      /*! Get the kernel name */
> @@ -128,9 +130,37 @@ namespace gbe {
>      size_t getImageSize(void) const { return imageSet->getDataSize(); }
>      /*! Get defined image value array */
>      void getImageData(ImageInfo *images) const { imageSet->getData(images); }
> +
> +    static const uint32_t magic_begin = TO_MAGIC('K', 'E', 'R', 'N');
> +    static const uint32_t magic_end = TO_MAGIC('N', 'R', 'E', 'K');
> +
> +    /* format:
> +       magic_begin       |
> +       name_size         |
> +       name              |
> +       arg_num           |
> +       args              |
> +       PatchInfo_num     |
> +       PatchInfo         |
> +       curbeSize         |
> +       simdWidth         |
> +       stackSize         |
> +       useSLM            |
> +       samplers          |
> +       images            |
> +       code_size         |
> +       code              |
> +       magic_end
> +    */
> +
> +    /*! Implements the serialization. */
> +    virtual size_t serializeToBin(std::ostream& outs);
> +    virtual size_t deserializeFromBin(std::istream& ins);
> +    virtual void printStatus(int indent, std::ostream& outs);
> +
>    protected:
>      friend class Context;      //!< Owns the kernels
> -    const std::string name;    //!< Kernel name
> +    std::string name;    //!< Kernel name
>      KernelArgument *args;      //!< Each argument
>      vector<PatchInfo> patches; //!< Indicates how to build the curbe
>      uint32_t argNum;           //!< Number of function arguments
> @@ -146,7 +176,7 @@ namespace gbe {
>    };
>  
>    /*! Describe a compiled program */
> -  class Program : public NonCopyable
> +  class Program : public NonCopyable, public Serializable
>    {
>    public:
>      /*! Create an empty program */
> @@ -186,9 +216,32 @@ namespace gbe {
>      size_t getGlobalConstantSize(void) const { return constantSet->getDataSize(); }
>      /*! Get the content of global constant arrays */
>      void getGlobalConstantData(char *mem) const { constantSet->getData(mem); }
> +
> +    static const uint32_t magic_begin = TO_MAGIC('P', 'R', 'O', 'G');
> +    static const uint32_t magic_end = TO_MAGIC('G', 'O', 'R', 'P');
> +
> +    /* format:
> +       magic_begin       |
> +       constantSet_flag  |
> +       constSet_data     |
> +       kernel_num        |
> +       kernel_1          |
> +       ........          |
> +       kernel_n          |
> +       magic_end         |
> +       total_size
> +    */
> +
> +    /*! Implements the serialization. */
> +    virtual size_t serializeToBin(std::ostream& outs);
> +    virtual size_t deserializeFromBin(std::istream& ins);
> +    virtual void printStatus(int indent, std::ostream& outs);
> +
>    protected:
>      /*! Compile a kernel */
>      virtual Kernel *compileKernel(const ir::Unit &unit, const std::string &name) = 0;
> +    /*! Allocate an empty kernel. */
> +    virtual Kernel *allocateKernel(const std::string &name) = 0;
>      /*! Kernels sorted by their name */
>      hash_map<std::string, Kernel*> kernels;
>      /*! Global (constants) outside any kernel */
> diff --git a/backend/src/ir/constant.cpp b/backend/src/ir/constant.cpp
> index c9f5bfe..7a8f80f 100644
> --- a/backend/src/ir/constant.cpp
> +++ b/backend/src/ir/constant.cpp
> @@ -40,6 +40,107 @@ namespace ir {
>      for (uint32_t i = 0; i < size; ++i) this->data.push_back(data[i]);
>    }
>  
> +#define OUT_UPDATE_SZ(elt) SERIALIZE_OUT(elt, outs, ret_size)
> +#define IN_UPDATE_SZ(elt) DESERIALIZE_IN(elt, ins, total_size)
> +
> +  size_t ConstantSet::serializeToBin(std::ostream& outs) {
> +    size_t ret_size = 0;
> +
> +    OUT_UPDATE_SZ(magic_begin);
> +
> +    /* output the const data. */
> +    OUT_UPDATE_SZ((data.size()*sizeof(char)));
> +    if(data.size() > 0) {
> +      outs.write(data.data(), data.size()*sizeof(char));
> +      ret_size += data.size()*sizeof(char);
> +    }
> +
> +    OUT_UPDATE_SZ(constants.size());
> +    for (auto const &cnst : constants) {
> +      size_t bytes = sizeof(cnst.getName().size())        //name length self
> +                     + cnst.getName().size()*sizeof(char) //name
> +                     + sizeof(cnst.getSize())             //size
> +                     + sizeof(cnst.getAlignment())        //alignment
> +                     + sizeof(cnst.getOffset())	          //offset
> +                     + sizeof(cnst.getReg());             //reg
> +      OUT_UPDATE_SZ(bytes);
> +
> +      OUT_UPDATE_SZ(cnst.getName().size());
> +      outs.write(cnst.getName().c_str(), cnst.getName().size());
> +      ret_size += sizeof(char)*cnst.getName().size();
> +      OUT_UPDATE_SZ(cnst.getSize());
> +      OUT_UPDATE_SZ(cnst.getAlignment());
> +      OUT_UPDATE_SZ(cnst.getOffset());
> +      OUT_UPDATE_SZ(cnst.getReg());
> +    }
> +
> +    OUT_UPDATE_SZ(magic_end);
> +    OUT_UPDATE_SZ(ret_size);
> +
> +    return ret_size;
> +  }
> +
> +  size_t ConstantSet::deserializeFromBin(std::istream& ins) {
> +    size_t total_size = 0;
> +    size_t global_data_sz = 0;
> +    size_t const_num;
> +    uint32_t magic;
> +
> +    IN_UPDATE_SZ(magic);
> +    if (magic != magic_begin)
> +      return 0;
> +
> +    IN_UPDATE_SZ(global_data_sz);
> +    for (size_t i = 0; i < global_data_sz; i++) {
> +      char elt;
> +      IN_UPDATE_SZ(elt);
> +      data.push_back(elt);
> +    }
> +
> +    IN_UPDATE_SZ(const_num);
> +    for (size_t i = 0; i < const_num; i++) {
> +      size_t bytes;
> +      IN_UPDATE_SZ(bytes);
> +
> +      size_t name_len;
> +      IN_UPDATE_SZ(name_len);
> +
> +      char* c_name = new char[name_len+1];
> +      ins.read(c_name, name_len);
> +      total_size += sizeof(char)*name_len;
> +      c_name[name_len] = 0;
> +
> +      uint32_t size, align, offset;
> +      uint16_t reg;
> +      IN_UPDATE_SZ(size);
> +      IN_UPDATE_SZ(align);
> +      IN_UPDATE_SZ(offset);
> +      IN_UPDATE_SZ(reg);
> +
> +      ir::Constant constant(c_name, size, align, offset);
> +      constant.setReg(reg);
> +      constants.push_back(constant);
> +
> +      delete[] c_name;
> +
> +      /* Saint check */
> +      if (bytes != sizeof(name_len) + sizeof(char)*name_len + sizeof(size)
> +              + sizeof(align) + sizeof(offset) + sizeof(reg))
> +        return 0;
> +    }
> +
> +    IN_UPDATE_SZ(magic);
> +    if (magic != magic_end)
> +      return 0;
> +
> +    size_t total_bytes;
> +    IN_UPDATE_SZ(total_bytes);
> +    if (total_bytes + sizeof(total_size) != total_size)
> +      return 0;
> +
> +    return total_size;
> +  }
> +
>  } /* namespace ir */
>  } /* namespace gbe */
>  
> diff --git a/backend/src/ir/constant.hpp b/backend/src/ir/constant.hpp
> index 0717391..4bb549e 100644
> --- a/backend/src/ir/constant.hpp
> +++ b/backend/src/ir/constant.hpp
> @@ -52,6 +52,8 @@ namespace ir {
>      /*! Nothing happens here */
>      INLINE ~Constant(void) {}
>      const std::string& getName(void) const { return name; }
> +    uint32_t getSize (void) const { return size; }
> +    uint32_t getAlignment (void) const { return alignment; }
>      uint32_t getOffset(void) const { return offset; }
>      uint16_t getReg(void) const { return reg; }
>      void setReg(uint16_t reg) { this->reg = reg; }
> @@ -67,7 +69,7 @@ namespace ir {
>    /*! A constant set is a set of immutable data associated to a compilation
>     *  unit
>     */
> -  class ConstantSet
> +  class ConstantSet : public Serializable
>    {
>    public:
>      /*! Append a new constant in the constant set */
> @@ -93,7 +95,8 @@ namespace ir {
>          mem[i] = data[i];
>      }
>      ConstantSet() {}
> -    ConstantSet(const ConstantSet& other) : data(other.data), constants(other.constants) {}
> +    ConstantSet(const ConstantSet& other) : Serializable(other),
> +                data(other.data), constants(other.constants) {}
>      ConstantSet & operator = (const ConstantSet& other) {
>        if (&other != this) {
>          data = other.data;
> @@ -101,6 +104,27 @@ namespace ir {
>        }
>        return *this;
>      }
> +
> +    static const uint32_t magic_begin = TO_MAGIC('C', 'N', 'S', 'T');
> +    static const uint32_t magic_end = TO_MAGIC('T', 'S', 'N', 'C');
> +
> +    /* format:
> +       magic_begin     |
> +       const_data_size |
> +       const_data      |
> +       constant_1_size |
> +       constant_1      |
> +       ........        |
> +       constant_n_size |
> +       constant_n      |
> +       magic_end       |
> +       total_size
> +    */
> +
> +    /*! Implements the serialization. */
> +    virtual size_t serializeToBin(std::ostream& outs);
> +    virtual size_t deserializeFromBin(std::istream& ins);
> +
>    private:
>      vector<char> data;         //!< The constant data serialized in one array
>      vector<Constant> constants;//!< Each constant description
> diff --git a/backend/src/ir/image.cpp b/backend/src/ir/image.cpp
> index 486fde1..b901a12 100644
> --- a/backend/src/ir/image.cpp
> +++ b/backend/src/ir/image.cpp
> @@ -110,5 +110,144 @@ namespace ir {
>        GBE_DELETE(it.second);
>    }
>  
> +#define OUT_UPDATE_SZ(elt) SERIALIZE_OUT(elt, outs, ret_size)
> +#define IN_UPDATE_SZ(elt) DESERIALIZE_IN(elt, ins, total_size)
> +
> +  /*! Implements the serialization. */
> +  size_t ImageSet::serializeToBin(std::ostream& outs) {
> +    size_t ret_size = 0;
> +
> +    OUT_UPDATE_SZ(magic_begin);
> +
> +    OUT_UPDATE_SZ(regMap.size());
> +    for (auto iter : regMap) {
> +      OUT_UPDATE_SZ(iter.first);
> +      OUT_UPDATE_SZ(iter.second->arg_idx);
> +      OUT_UPDATE_SZ(iter.second->idx);
> +      OUT_UPDATE_SZ(iter.second->wSlot);
> +      OUT_UPDATE_SZ(iter.second->hSlot);
> +      OUT_UPDATE_SZ(iter.second->depthSlot);
> +      OUT_UPDATE_SZ(iter.second->dataTypeSlot);
> +      OUT_UPDATE_SZ(iter.second->channelOrderSlot);
> +      OUT_UPDATE_SZ(iter.second->dimOrderSlot);
> +    }
> +
> +    OUT_UPDATE_SZ(indexMap.size());
> +    for (auto iter : indexMap) {
> +      OUT_UPDATE_SZ(iter.first);
> +      OUT_UPDATE_SZ(iter.second->arg_idx);
> +      OUT_UPDATE_SZ(iter.second->idx);
> +      OUT_UPDATE_SZ(iter.second->wSlot);
> +      OUT_UPDATE_SZ(iter.second->hSlot);
> +      OUT_UPDATE_SZ(iter.second->depthSlot);
> +      OUT_UPDATE_SZ(iter.second->dataTypeSlot);
> +      OUT_UPDATE_SZ(iter.second->channelOrderSlot);
> +      OUT_UPDATE_SZ(iter.second->dimOrderSlot);
> +    }
> +
> +    OUT_UPDATE_SZ(magic_end);
> +    OUT_UPDATE_SZ(ret_size);
> +
> +    return ret_size;
> +  }
> +
> +  size_t ImageSet::deserializeFromBin(std::istream& ins) {
> +    size_t total_size = 0;
> +    uint32_t magic;
> +    size_t image_map_sz = 0;
> +
> +    IN_UPDATE_SZ(magic);
> +    if (magic != magic_begin)
> +      return 0;
> +
> +    IN_UPDATE_SZ(image_map_sz); //regMap
> +    for (size_t i = 0; i < image_map_sz; i++) {
> +      ir::Register reg;
> +      ImageInfo *img_info = GBE_NEW(struct ImageInfo);;
> +
> +      IN_UPDATE_SZ(reg);
> +      IN_UPDATE_SZ(img_info->arg_idx);
> +      IN_UPDATE_SZ(img_info->idx);
> +      IN_UPDATE_SZ(img_info->wSlot);
> +      IN_UPDATE_SZ(img_info->hSlot);
> +      IN_UPDATE_SZ(img_info->depthSlot);
> +      IN_UPDATE_SZ(img_info->dataTypeSlot);
> +      IN_UPDATE_SZ(img_info->channelOrderSlot);
> +      IN_UPDATE_SZ(img_info->dimOrderSlot);
> +
> +      regMap.insert(std::make_pair(reg, img_info));
> +    }
> +
> +    IN_UPDATE_SZ(image_map_sz); //indexMap
> +    for (uint32_t i = 0; i < image_map_sz; i++) {
> +      uint32_t index;
> +      ImageInfo *img_info = GBE_NEW(struct ImageInfo);;
> +
> +      IN_UPDATE_SZ(index);
> +      IN_UPDATE_SZ(img_info->arg_idx);
> +      IN_UPDATE_SZ(img_info->idx);
> +      IN_UPDATE_SZ(img_info->wSlot);
> +      IN_UPDATE_SZ(img_info->hSlot);
> +      IN_UPDATE_SZ(img_info->depthSlot);
> +      IN_UPDATE_SZ(img_info->dataTypeSlot);
> +      IN_UPDATE_SZ(img_info->channelOrderSlot);
> +      IN_UPDATE_SZ(img_info->dimOrderSlot);
> +
> +      indexMap.insert(std::make_pair(index, img_info));
> +    }
> +
> +    IN_UPDATE_SZ(magic);
> +    if (magic != magic_end)
> +      return 0;
> +
> +    size_t total_bytes;
> +    IN_UPDATE_SZ(total_bytes);
> +    if (total_bytes + sizeof(total_size) != total_size)
> +      return 0;
> +
> +    return total_size;
> +  }
> +
> +  void ImageSet::printStatus(int indent, std::ostream& outs) {
> +    using namespace std;
> +    string spaces = indent_to_str(indent);
> +    string spaces_nl = indent_to_str(indent + 4);
> +
> +    outs << spaces << "------------ Begin ImageSet ------------" << "\n";
> +
> +    outs << spaces_nl  << "  ImageSet Map: [reg, arg_idx, idx, wSlot, hSlot, depthSlot, "
> +                "dataTypeSlot, channelOrderSlot, dimOrderSlot]\n";
> +    outs << spaces_nl << "     regMap size: " << regMap.size() << "\n";
> +    for (auto iter : regMap) {
> +      outs << spaces_nl << "         [" << iter.first << ", "
> +           << iter.second->arg_idx << ", "
> +           << iter.second->idx << ", "
> +           << iter.second->wSlot << ", "
> +           << iter.second->hSlot << ", "
> +           << iter.second->depthSlot << ", "
> +           << iter.second->dataTypeSlot << ", "
> +           << iter.second->channelOrderSlot << ", "
> +           << iter.second->dimOrderSlot << "]" << "\n";
> +   }
> +
> +   outs << spaces_nl << "  ImageSet Map: [index, arg_idx, idx, wSlot, hSlot, depthSlot, "
> +           "dataTypeSlot, channelOrderSlot, dimOrderSlot]\n";
> +   outs << spaces_nl << "     regMap size: " << indexMap.size() << "\n";
> +   for (auto iter : indexMap) {
> +     outs << spaces_nl << "         [" << iter.first << ", "
> +          << iter.second->arg_idx << ", "
> +          << iter.second->idx << ", "
> +          << iter.second->wSlot << ", "
> +          << iter.second->hSlot << ", "
> +          << iter.second->depthSlot << ", "
> +          << iter.second->dataTypeSlot << ", "
> +          << iter.second->channelOrderSlot << ", "
> +          << iter.second->dimOrderSlot << ", " << "\n";
> +   }
> +
> +   outs << spaces << "------------- End ImageSet -------------" << "\n";
> +  }
> +
> +
>  } /* namespace ir */
>  } /* namespace gbe */
> diff --git a/backend/src/ir/image.hpp b/backend/src/ir/image.hpp
> index 04e78e6..c084c7d 100644
> --- a/backend/src/ir/image.hpp
> +++ b/backend/src/ir/image.hpp
> @@ -40,7 +40,7 @@ namespace ir {
>     *  for each individual image. And that individual image could be used
>     *  at backend to identify this image's location.
>     */
> -  class ImageSet
> +  class ImageSet : public Serializable
>    {
>    public:
>      /*! Append an image argument. */
> @@ -60,6 +60,29 @@ namespace ir {
>      ImageSet(const ImageSet& other) : regMap(other.regMap.begin(), other.regMap.end()) { }
>      ImageSet() {}
>      ~ImageSet();
> +
> +    static const uint32_t magic_begin = TO_MAGIC('I', 'M', 'A', 'G');
> +    static const uint32_t magic_end = TO_MAGIC('G', 'A', 'M', 'I');
> +
> +    /* format:
> +       magic_begin     |
> +       regMap_size     |
> +       element_1       |
> +       ........        |
> +       element_n       |
> +       indexMap_size   |
> +       element_1       |
> +       ........        |
> +       element_n       |
> +       magic_end       |
> +       total_size
> +    */
> +
> +    /*! Implements the serialization. */
> +    virtual size_t serializeToBin(std::ostream& outs);
> +    virtual size_t deserializeFromBin(std::istream& ins);
> +    virtual void printStatus(int indent, std::ostream& outs);
> +
>    private:
>      map<Register, struct ImageInfo *> regMap;
>      map<uint32_t, struct ImageInfo *> indexMap;
> diff --git a/backend/src/ir/sampler.cpp b/backend/src/ir/sampler.cpp
> index 62bdc16..cff1012 100644
> --- a/backend/src/ir/sampler.cpp
> +++ b/backend/src/ir/sampler.cpp
> @@ -74,5 +74,103 @@ namespace ir {
>      appendReg(samplerReg, SAMPLER_ID(id), ctx);
>    }
>  
> +
> +#define OUT_UPDATE_SZ(elt) SERIALIZE_OUT(elt, outs, ret_size)
> +#define IN_UPDATE_SZ(elt) DESERIALIZE_IN(elt, ins, total_size)
> +
> +  /*! Implements the serialization. */
> +  size_t SamplerSet::serializeToBin(std::ostream& outs) {
> +    size_t ret_size = 0;
> +
> +    OUT_UPDATE_SZ(magic_begin);
> +
> +    OUT_UPDATE_SZ(samplerMap.size());
> +    for (auto iter : samplerMap) {
> +      OUT_UPDATE_SZ(iter.first);
> +      OUT_UPDATE_SZ(iter.second.reg);
> +      OUT_UPDATE_SZ(iter.second.slot);
> +    }
> +
> +    OUT_UPDATE_SZ(regMap.size());
> +    for (auto iter : regMap) {
> +      OUT_UPDATE_SZ(iter.first);
> +      OUT_UPDATE_SZ(iter.second.reg);
> +      OUT_UPDATE_SZ(iter.second.slot);
> +    }
> +
> +    OUT_UPDATE_SZ(magic_end);
> +    OUT_UPDATE_SZ(ret_size);
> +
> +    return ret_size;
> +  }
> +
> +  size_t SamplerSet::deserializeFromBin(std::istream& ins) {
> +    size_t total_size = 0;
> +    uint32_t magic;
> +    size_t sampler_map_sz = 0;
> +
> +    IN_UPDATE_SZ(magic);
> +    if (magic != magic_begin)
> +      return 0;
> +
> +    IN_UPDATE_SZ(sampler_map_sz);
> +    for (size_t i = 0; i < sampler_map_sz; i++) {
> +      uint32_t key;
> +      ir::SamplerRegSlot reg_slot;
> +
> +      IN_UPDATE_SZ(key);
> +      IN_UPDATE_SZ(reg_slot.reg);
> +      IN_UPDATE_SZ(reg_slot.slot);
> +      samplerMap.insert(std::make_pair(key, reg_slot));
> +    }
> +
> +    IN_UPDATE_SZ(sampler_map_sz);
> +    for (size_t i = 0; i < sampler_map_sz; i++) {
> +      ir::Register key;
> +      ir::SamplerRegSlot reg_slot;
> +
> +      IN_UPDATE_SZ(key);
> +      IN_UPDATE_SZ(reg_slot.reg);
> +      IN_UPDATE_SZ(reg_slot.slot);
> +      regMap.insert(std::make_pair(key, reg_slot));
> +    }
> +
> +    IN_UPDATE_SZ(magic);
> +    if (magic != magic_end)
> +      return 0;
> +
> +    size_t total_bytes;
> +    IN_UPDATE_SZ(total_bytes);
> +    if (total_bytes + sizeof(total_size) != total_size)
> +      return 0;
> +
> +    return total_size;
> +  }
> +
> +  void SamplerSet::printStatus(int indent, std::ostream& outs) {
> +    using namespace std;
> +    string spaces = indent_to_str(indent);
> +    string spaces_nl = indent_to_str(indent + 4);
> +
> +    outs << spaces << "------------ Begin SamplerSet ------------" << "\n";
> +
> +    outs << spaces_nl << "  SamplerSet Map: [index, sampler_reg, sampler_slot]\n";
> +    outs << spaces_nl << "     samplerMap size: " << samplerMap.size() << "\n";
> +
> +    for (auto iter : samplerMap) {
> +      outs << spaces_nl <<  "     [" << iter.first << ", "
> +           << iter.second.reg << ", " << iter.second.slot << "]\n";
> +    }
> +
> +    outs << spaces_nl << "  SamplerSet Map: [reg, sampler_reg, sampler_slot]\n";
> +    outs << spaces_nl << "     regMap size: " << regMap.size() << "\n";
> +    for (auto iter : regMap) {
> +      outs << spaces_nl << "     [" << iter.first << ", "
> +           << iter.second.reg << ", " << iter.second.slot << "]\n";
> +    }
> +
> +    outs << spaces << "------------- End SamplerSet -------------" << "\n";
> +  }
> +
>  } /* namespace ir */
>  } /* namespace gbe */
> diff --git a/backend/src/ir/sampler.hpp b/backend/src/ir/sampler.hpp
> index f968299..3c72e3e 100644
> --- a/backend/src/ir/sampler.hpp
> +++ b/backend/src/ir/sampler.hpp
> @@ -41,7 +41,7 @@ namespace ir {
>      uint32_t slot;
>    };
>  
> -  class SamplerSet
> +  class SamplerSet : public Serializable
>    {
>    public:
>      /*! Append the specified sampler and return the allocated offset.
> @@ -66,6 +66,29 @@ namespace ir {
>  
>      SamplerSet(const SamplerSet& other) : samplerMap(other.samplerMap.begin(), other.samplerMap.end()) { }
>      SamplerSet() {}
> +
> +    static const uint32_t magic_begin = TO_MAGIC('S', 'A', 'M', 'P');
> +    static const uint32_t magic_end = TO_MAGIC('P', 'M', 'A', 'S');
> +
> +    /* format:
> +       magic_begin     |
> +       samplerMap_size |
> +       element_1       |
> +       ........        |
> +       element_n       |
> +       regMap_size     |
> +       element_1       |
> +       ........        |
> +       element_n       |
> +       magic_end       |
> +       total_size
> +    */
> +
> +    /*! Implements the serialization. */
> +    virtual size_t serializeToBin(std::ostream& outs);
> +    virtual size_t deserializeFromBin(std::istream& ins);
> +    virtual void printStatus(int indent, std::ostream& outs);
> +
>    private:
>      void appendReg(const Register reg, uint32_t key, Context *ctx);
>      map<uint32_t, SamplerRegSlot> samplerMap;
> diff --git a/backend/src/sys/platform.hpp b/backend/src/sys/platform.hpp
> index a665356..783b665 100644
> --- a/backend/src/sys/platform.hpp
> +++ b/backend/src/sys/platform.hpp
> @@ -24,6 +24,9 @@
>  #include <cstdlib>
>  #include <cstdio>
>  #include <iostream>
> +#include <ostream>
> +#include <istream>
> +#include <string>
>  #include <cassert>
>  #include <new>
>  
> @@ -323,6 +326,45 @@ private:
>    INLINE NonCopyable& operator= (const NonCopyable&) {return *this;}
>  };
>  
> +#define TO_MAGIC(A, B, C, D)  (A<<24 | B<<16 | C<<8 | D)
> +
> +class Serializable
> +{
> +public:
> +  INLINE Serializable(void) = default;
> +  INLINE Serializable(const Serializable&) = default;
> +  INLINE Serializable& operator= (const Serializable&) = default;
> +
> +  virtual size_t serializeToBin(std::ostream& outs) = 0;
> +  virtual size_t deserializeFromBin(std::istream& ins) = 0;
> +
> +  /* These two will follow LLVM's ABI. */
> +  virtual size_t serializeToLLVM(void) { return 0;/* not implemented now. */}
> +  virtual size_t deserializeFromLLVM(void) { return 0;/* not implemented now. */}
> +
> +  virtual void printStatus(int indent = 0, std::ostream& outs = std::cout) { }
> +
> +protected:
> +  static std::string indent_to_str(int indent) {
> +    std::string ind(indent, ' ');
> +    return ind;
> +  }
> +};
> +
> +/* Help Macro for serialization. */
> +#define SERIALIZE_OUT(elt, out, sz)			\
> +     do {						\
> +	  auto tmp_val = elt;				\
> +	  out.write((char *)(&tmp_val), sizeof(elt));	\
> +	  sz += sizeof(elt);				\
> +     } while(0)
> +
> +#define DESERIALIZE_IN(elt, in, sz)			\
> +     do {						\
> +	  in.read((char *)(&(elt)), sizeof(elt));	\
> +	  sz += sizeof(elt);				\
> +     } while(0)
> +
>  ////////////////////////////////////////////////////////////////////////////////
>  /// Disable some compiler warnings
>  ////////////////////////////////////////////////////////////////////////////////
> -- 
> 1.7.9.5
> 
> _______________________________________________
> Beignet mailing list
> Beignet at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/beignet


More information about the Beignet mailing list