[Beignet] [PATCH 2/6] Add the Serialization and DeSerialization logic to gbe::kernel and gbe::program

Yang, Rong R rong.r.yang at intel.com
Fri Aug 23 00:45:24 PDT 2013


Hi, Junyan,

  See my comment.

-----Original Message-----
From: beignet-bounces+rong.r.yang=intel.com at lists.freedesktop.org [mailto:beignet-bounces+rong.r.yang=intel.com at lists.freedesktop.org] On Behalf Of junyan.he at inbox.com
Sent: Thursday, August 22, 2013 4:19 PM
To: beignet at lists.freedesktop.org
Cc: Junyan He
Subject: [Beignet] [PATCH 2/6] Add the Serialization and DeSerialization logic to gbe::kernel and gbe::program

From: Junyan He <junyan.he at linux.intel.com<mailto:junyan.he at linux.intel.com>>

Signed-off-by: Junyan He <junyan.he at linux.intel.com<mailto:junyan.he at linux.intel.com>>
---
 backend/src/backend/program.cpp |  397 +++++++++++++++++++++++++++++++++++++++
 backend/src/backend/program.hpp |   61 +++++-
 backend/src/ir/constant.hpp     |    6 +
 backend/src/ir/image.hpp        |    3 +
 backend/src/ir/sampler.hpp      |    3 +
 backend/src/sys/platform.hpp    |   22 +++
 6 files changed, 489 insertions(+), 3 deletions(-)

diff --git a/backend/src/backend/program.cpp b/backend/src/backend/program.cpp index 35d3a7c..dec5ae4 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,402 @@ namespace gbe {
     return true;
   }

+#define OUT_UPDATE_SZ(elt) \
+  do { \
+      auto tmp_val = elt;\
+      souts.write((char *)(&tmp_val), sizeof(elt));  \
+      ret_size += sizeof(elt); \
+  } while(0)
+
+#define IN_UPDATE_SZ(elt) \
+  do { \
+      ins.read((char *)(&(elt)), sizeof(elt));  \
+      total_size -= sizeof(elt); \
+  } while(0)
+
+  size_t Program::serializeToBin(std::ostream& outs) {
+    size_t ret_size = 0;
+    std::ostringstream souts(std::ostringstream::binary);
+    unsigned int i;
+    size_t const_num = constantSet ? constantSet->getConstantNum() : 0;
+    size_t ker_num = kernels.size();
+    size_t global_data_sz = constantSet ? constantSet->getDataSize() :
+ 0;
+
+    OUT_UPDATE_SZ(magic_begin);
+    OUT_UPDATE_SZ(ker_num);
+    OUT_UPDATE_SZ(const_num);
+    OUT_UPDATE_SZ(global_data_sz);
+
[YangRong]: Is it better to let class ConstantSet and Constant extend from Serializable, and call ConstantSet.serializeToBin here? Just as Kernel.
+    if (global_data_sz > 0) {
+      char* mem = reinterpret_cast<char *>(::malloc(sizeof(char)*global_data_sz));
+      if (!mem)
+        return false;
+
+      getGlobalConstantData(mem);
+
+      for (i = 0; i < global_data_sz; i++)
+        OUT_UPDATE_SZ(mem[i]);
[YangRong]: Why not write global_data_sz once.
+
+      ::free(mem);
+    }
+
+    for (i = 0; i < const_num; i++) {
+      size_t bytes = sizeof(constantSet->getConstant(i).getName().size()) //name length
+          + constantSet->getConstant(i).getName().size()*sizeof(char) //name
+          + sizeof(constantSet->getConstant(i).getSize())  //size
+          + sizeof(constantSet->getConstant(i).getAlignment())  //alignment
+          + sizeof(constantSet->getConstant(i).getOffset())  //offset
+          + sizeof(constantSet->getConstant(i).getReg());  //reg
+      OUT_UPDATE_SZ(bytes);
+
+      OUT_UPDATE_SZ(constantSet->getConstant(i).getName().size());
+      outs.write(constantSet->getConstant(i).getName().c_str(),
+                 constantSet->getConstant(i).getName().size());
+      ret_size += sizeof(char)*constantSet->getConstant(i).getName().size();
+      OUT_UPDATE_SZ(constantSet->getConstant(i).getSize());
+      OUT_UPDATE_SZ(constantSet->getConstant(i).getAlignment());
+      OUT_UPDATE_SZ(constantSet->getConstant(i).getOffset());
+      OUT_UPDATE_SZ(constantSet->getConstant(i).getReg());
+    }
+
+    for (auto ker : kernels) {
+      size_t sz = ker.second->serializeToBin(souts);
+      if (!sz)
+        return 0;
+
+      ret_size += sz;
+    }
+
+    OUT_UPDATE_SZ(magic_end);
+
+    outs.write((char *)&ret_size, sizeof(ret_size));
[YangRong]: Why not append the total size to the end of outs to avoid two pass write, and check the read size whether equal to this size at last when deserializeFromBin?

+    outs.write(souts.str().c_str(), souts.str().size());
+    ret_size += sizeof(ret_size);
+    return ret_size;
+  }
+
+  size_t Program::deserializeFromBin(std::istream& ins) {
+    size_t total_size = 0;
+    size_t ret_size = 0;
+    uint32_t magic;
+    size_t ker_num;
+    size_t const_num;
+    size_t global_data_sz;
+
+    ins.read((char *)&total_size, sizeof(total_size));
+    ret_size = total_size + sizeof(total_size);
+
+    IN_UPDATE_SZ(magic);
+    if (magic != magic_begin)
+      return 0;
+
+    IN_UPDATE_SZ(ker_num);
+    IN_UPDATE_SZ(const_num);
+    IN_UPDATE_SZ(global_data_sz);
+
+    constantSet = new ir::ConstantSet;
+    if (const_num || global_data_sz) {
+      char tmp;
+      size_t const_bytes;
+      IN_UPDATE_SZ(const_bytes);
+
+      for (unsigned int i = 0; i < global_data_sz; i++) {
+        IN_UPDATE_SZ(tmp);
+        constantSet->data.push_back(tmp);
+      }
+
+      for (unsigned int i = 0; i < const_num; i++) {
+        size_t name_len;
+        IN_UPDATE_SZ(name_len);
+        char* c_name = new char[name_len];
+        ins.read(c_name, name_len);
+        total_size -= sizeof(char)*name_len;
+        uint32_t size, align, offset;
+        uint16_t reg;
+        IN_UPDATE_SZ(size);
+        IN_UPDATE_SZ(align);
+        IN_UPDATE_SZ(offset);
+        IN_UPDATE_SZ(reg);
+        std::string name(c_name);
+        delete[] c_name;
+
+        const ir::Constant constant(name, size, align, offset);
+        constantSet->constants.push_back(constant);
+
+        const_bytes -= sizeof(name_len) + name_len * sizeof(char)
+            + sizeof(size) + sizeof(align) + sizeof(offset) +
+ sizeof(reg);
+
+        if (const_bytes) {
+          return 0;
+        }
+      }
+    }
+
+    for (unsigned int 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;
+
+    if (total_size)
+      return 0;
+
+    return ret_size;
+  }
+
+  size_t Kernel::serializeToBin(std::ostream& outs) {
+    unsigned int i;
+    size_t ret_size = 0;
+    std::ostringstream souts(std::ostringstream::binary);
+
+    OUT_UPDATE_SZ(magic_begin);
+
+    OUT_UPDATE_SZ(name.size());
+    souts.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) {
+      OUT_UPDATE_SZ(samplerSet->samplerMap.size());
+      for (auto iter : samplerSet->samplerMap) {
+        OUT_UPDATE_SZ(iter.first);
+        OUT_UPDATE_SZ(iter.second.reg);
+        OUT_UPDATE_SZ(iter.second.slot);
+      }
+
+      OUT_UPDATE_SZ(samplerSet->regMap.size());
+      for (auto iter : samplerSet->regMap) {
+        OUT_UPDATE_SZ(iter.first);
+        OUT_UPDATE_SZ(iter.second.reg);
+        OUT_UPDATE_SZ(iter.second.slot);
+      }
+    }
+
+    /* images. */
+    if (imageSet) {
+      OUT_UPDATE_SZ(imageSet->regMap.size());
+      for (auto iter : imageSet->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);
+      }
[Yang Rong]: Because ImageInfo is a struct, maybe can read/write it once.
+
+      OUT_UPDATE_SZ(imageSet->indexMap.size());
+      for (auto iter : imageSet->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);
+      }
+    }
+
+    /* Code. */
+    const char * code = getCode();
+    OUT_UPDATE_SZ(getCodeSize());
+    for (i = 0; i < getCodeSize(); i++) {
+      OUT_UPDATE_SZ(code[i]);
+    }
[YangRong]: Also write code once?

+
+    OUT_UPDATE_SZ(magic_end);
+
+    outs.write((char *)&ret_size, sizeof(ret_size));
+    outs.write(souts.str().c_str(), souts.str().size());
+    ret_size += sizeof(ret_size);
+    return ret_size;
+  }
+
+  size_t Kernel::deserializeFromBin(std::istream& ins) {
+    size_t total_size = 0;
+    size_t ret_size = 0;
+    uint32_t magic = 0;
+    size_t patch_num = 0;
+    size_t image_map_sz = 0;
+    size_t sampler_map_sz = 0;
+    size_t code_size = 0;
+
+    ins.read((char *)&total_size, sizeof(total_size));
+    ret_size = total_size + sizeof(total_size);
+
+    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];
+    ins.read(c_name, name_len);
+    total_size -= sizeof(char)*name_len;
+
+    name = c_name;
+    delete[] c_name;
+
+    IN_UPDATE_SZ(argNum);
+    GBE_NEW_ARRAY_NO_ARG(KernelArgument, 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);
+
+    samplerSet = GBE_NEW(ir::SamplerSet);
+
+    IN_UPDATE_SZ(sampler_map_sz); //samplerMap
+    if (sampler_map_sz){
+      for (uint32_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);
+        samplerSet->samplerMap.insert(std::make_pair(key, reg_slot));
+      }
+    }
+
+    IN_UPDATE_SZ(sampler_map_sz);  //regMap
+    if (sampler_map_sz){
+      for (uint32_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);
+        samplerSet->regMap.insert(std::make_pair(key, reg_slot));
+      }
+    }
+
+    imageSet = GBE_NEW(ir::ImageSet);
+
+    IN_UPDATE_SZ(image_map_sz); //regMap
+    if (image_map_sz){
+      for (uint32_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);
+
+        imageSet->regMap.insert(std::make_pair(reg, img_info));
+      }
+    }
+
+    IN_UPDATE_SZ(image_map_sz); //indexMap
+    if (image_map_sz){
+      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);
+
+        imageSet->indexMap.insert(std::make_pair(index, img_info));
+      }
+    }
+
+    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;
+
+    if (total_size)
+      return 0;
+
+    return ret_size;
+  }
+
+#undef OUT_UPDATE_SZ
+#undef IN_UPDATE_SZ
+
+ /*********************** 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 f1ab20e..6d53253 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);
+
+
   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,6 +216,31 @@ 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 | kernel_number | constant_number |
+       const_data_size |
+       const_data |
+       constant_1_size |
+       constant_1 |
+       ........   |
+       constant_n_size |
+       constant_n |
+       kernel_1_size |
+       kernel_1   |
+       ........   |
+       kernel_n_size   |
+       kernel_n   |
+       magic_end
+    */
+
+    /*! Implements the serialization. */
+    virtual size_t serializeToBin(std::ostream& outs);
+    virtual size_t deserializeFromBin(std::istream& ins);
+
   protected:
     /*! Compile a kernel */
     virtual Kernel *compileKernel(const ir::Unit &unit, const std::string &name) = 0; diff --git a/backend/src/ir/constant.hpp b/backend/src/ir/constant.hpp index 0717391..a3eab64 100644
--- a/backend/src/ir/constant.hpp
+++ b/backend/src/ir/constant.hpp
@@ -28,6 +28,9 @@
 #include "sys/vector.hpp"

 namespace gbe {
+
+class Program;
+
 namespace ir {

   /*! Describe one constant (may be a scalar or an array) */ @@ -52,6 +55,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; } @@ -102,6 +107,7 @@ namespace ir {
       return *this;
     }
   private:
+    friend class gbe::Program;
     vector<char> data;         //!< The constant data serialized in one array
     vector<Constant> constants;//!< Each constant description
     GBE_CLASS(ConstantSet);
diff --git a/backend/src/ir/image.hpp b/backend/src/ir/image.hpp index 04e78e6..61d9426 100644
--- a/backend/src/ir/image.hpp
+++ b/backend/src/ir/image.hpp
@@ -32,6 +32,8 @@ extern "C" {
 }

 namespace gbe {
+  class Kernel;
+
 namespace ir {

   class Context;
@@ -61,6 +63,7 @@ namespace ir {
     ImageSet() {}
     ~ImageSet();
   private:
+    friend class gbe::Kernel;
     map<Register, struct ImageInfo *> regMap;
     map<uint32_t, struct ImageInfo *> indexMap;
     GBE_CLASS(ImageSet);
diff --git a/backend/src/ir/sampler.hpp b/backend/src/ir/sampler.hpp index f968299..bcb6c74 100644
--- a/backend/src/ir/sampler.hpp
+++ b/backend/src/ir/sampler.hpp
@@ -28,6 +28,8 @@
 #include "sys/map.hpp"

 namespace gbe {
+  class Kernel;
+
 namespace ir {

   /*! A sampler set is a set of global samplers which are defined as constant global @@ -67,6 +69,7 @@ namespace ir {
     SamplerSet(const SamplerSet& other) : samplerMap(other.samplerMap.begin(), other.samplerMap.end()) { }
     SamplerSet() {}
   private:
+    friend class gbe::Kernel;
     void appendReg(const Register reg, uint32_t key, Context *ctx);
     map<uint32_t, SamplerRegSlot> samplerMap;
     map<Register, SamplerRegSlot> regMap; diff --git a/backend/src/sys/platform.hpp b/backend/src/sys/platform.hpp index a665356..8b28b7b 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,25 @@ 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;
+
+  /* We do not want to be copied. */
+  INLINE Serializable(const Serializable&) = delete;  INLINE
+ Serializable& operator= (const Serializable&) = delete;
+
+  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. */} };
+
 ////////////////////////////////////////////////////////////////////////////////
 /// Disable some compiler warnings
 ////////////////////////////////////////////////////////////////////////////////
--
1.7.9.5

_______________________________________________
Beignet mailing list
Beignet at lists.freedesktop.org<mailto:Beignet at lists.freedesktop.org>
http://lists.freedesktop.org/mailman/listinfo/beignet

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/beignet/attachments/20130823/d8681477/attachment-0001.html>


More information about the Beignet mailing list