<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Exchange Server">
<!-- converted from rtf -->
<style><!-- .EmailQuote { margin-left: 1pt; padding-left: 4pt; border-left: #800000 2px solid; } --></style>
</head>
<body>
<font face="Calibri" size="2"><span style="font-size:10.5pt;">
<div>Hi, Junyan,</div>
<div> </div>
<div>  See my comment.</div>
<div><font face="Times New Roman"> </font></div>
<div>-----Original Message-----<br>

From: beignet-bounces+rong.r.yang=intel.com@lists.freedesktop.org [<a href="mailto:beignet-bounces+rong.r.yang=intel.com@lists.freedesktop.org">mailto:beignet-bounces+rong.r.yang=intel.com@lists.freedesktop.org</a>] On Behalf Of junyan.he@inbox.com<br>

Sent: Thursday, August 22, 2013 4:19 PM<br>

To: beignet@lists.freedesktop.org<br>

Cc: Junyan He<br>

Subject: [Beignet] [PATCH 2/6] Add the Serialization and DeSerialization logic to gbe::kernel and gbe::program</div>
<div><font face="Times New Roman"> </font></div>
<div>From: Junyan He <<a href="mailto:junyan.he@linux.intel.com">junyan.he@linux.intel.com</a>></div>
<div> </div>
<div>Signed-off-by: Junyan He <<a href="mailto:junyan.he@linux.intel.com">junyan.he@linux.intel.com</a>></div>
<div>---</div>
<div> backend/src/backend/program.cpp |  397 +++++++++++++++++++++++++++++++++++++++</div>
<div> backend/src/backend/program.hpp |   61 +++++-</div>
<div> backend/src/ir/constant.hpp     |    6 +</div>
<div> backend/src/ir/image.hpp        |    3 +</div>
<div> backend/src/ir/sampler.hpp      |    3 +</div>
<div> backend/src/sys/platform.hpp    |   22 +++</div>
<div> 6 files changed, 489 insertions(+), 3 deletions(-)</div>
<div> </div>
<div>diff --git a/backend/src/backend/program.cpp b/backend/src/backend/program.cpp index 35d3a7c..dec5ae4 100644</div>
<div>--- a/backend/src/backend/program.cpp</div>
<div>+++ b/backend/src/backend/program.cpp</div>
<div>@@ -37,6 +37,7 @@</div>
<div> #include <fstream></div>
<div> #include <dlfcn.h></div>
<div> #include <sstream></div>
<div>+#include <iostream></div>
<div> #include <unistd.h></div>
<div> </div>
<div> /* Not defined for LLVM 3.0 */</div>
<div>@@ -124,6 +125,402 @@ namespace gbe {</div>
<div>     return true;</div>
<div>   }</div>
<div> </div>
<div>+#define OUT_UPDATE_SZ(elt) \</div>
<div>+  do { \</div>
<div>+      auto tmp_val = elt;\</div>
<div>+      souts.write((char *)(&tmp_val), sizeof(elt));  \</div>
<div>+      ret_size += sizeof(elt); \</div>
<div>+  } while(0)</div>
<div>+</div>
<div>+#define IN_UPDATE_SZ(elt) \</div>
<div>+  do { \</div>
<div>+      ins.read((char *)(&(elt)), sizeof(elt));  \</div>
<div>+      total_size -= sizeof(elt); \</div>
<div>+  } while(0)</div>
<div>+</div>
<div>+  size_t Program::serializeToBin(std::ostream& outs) {</div>
<div>+    size_t ret_size = 0;</div>
<div>+    std::ostringstream souts(std::ostringstream::binary);</div>
<div>+    unsigned int i;</div>
<div>+    size_t const_num = constantSet ? constantSet->getConstantNum() : 0;</div>
<div>+    size_t ker_num = kernels.size();</div>
<div>+    size_t global_data_sz = constantSet ? constantSet->getDataSize() : </div>
<div>+ 0;</div>
<div>+</div>
<div>+    OUT_UPDATE_SZ(magic_begin);</div>
<div>+    OUT_UPDATE_SZ(ker_num);</div>
<div>+    OUT_UPDATE_SZ(const_num);</div>
<div>+    OUT_UPDATE_SZ(global_data_sz);</div>
<div>+</div>
<div><font color="#1F497D">[YangRong]: Is it better to let class ConstantSet and Constant extend from Serializable, and call ConstantSet<font face="Courier New">.</font>serializeToBin here? Just as Kernel.</font></div>
<div>+    if (global_data_sz > 0) {</div>
<div>+      char* mem = reinterpret_cast<char *>(::malloc(sizeof(char)*global_data_sz));</div>
<div>+      if (!mem)</div>
<div>+        return false;</div>
<div>+</div>
<div>+      getGlobalConstantData(mem);</div>
<div>+</div>
<div>+      for (i = 0; i < global_data_sz; i++)</div>
<div>+        OUT_UPDATE_SZ(mem[i]);</div>
<div><font color="#1F497D">[YangRong]: Why not write global_data_sz once<font face="Courier New">.</font></font></div>
<div>+</div>
<div>+      ::free(mem);</div>
<div>+    }</div>
<div>+</div>
<div>+    for (i = 0; i < const_num; i++) {</div>
<div>+      size_t bytes = sizeof(constantSet->getConstant(i).getName().size()) //name length</div>
<div>+          + constantSet->getConstant(i).getName().size()*sizeof(char) //name</div>
<div>+          + sizeof(constantSet->getConstant(i).getSize())  //size</div>
<div>+          + sizeof(constantSet->getConstant(i).getAlignment())  //alignment</div>
<div>+          + sizeof(constantSet->getConstant(i).getOffset())  //offset</div>
<div>+          + sizeof(constantSet->getConstant(i).getReg());  //reg</div>
<div>+      OUT_UPDATE_SZ(bytes);</div>
<div>+</div>
<div>+      OUT_UPDATE_SZ(constantSet->getConstant(i).getName().size());</div>
<div>+      outs.write(constantSet->getConstant(i).getName().c_str(),</div>
<div>+                 constantSet->getConstant(i).getName().size());</div>
<div>+      ret_size += sizeof(char)*constantSet->getConstant(i).getName().size();</div>
<div>+      OUT_UPDATE_SZ(constantSet->getConstant(i).getSize());</div>
<div>+      OUT_UPDATE_SZ(constantSet->getConstant(i).getAlignment());</div>
<div>+      OUT_UPDATE_SZ(constantSet->getConstant(i).getOffset());</div>
<div>+      OUT_UPDATE_SZ(constantSet->getConstant(i).getReg());</div>
<div>+    }</div>
<div>+</div>
<div>+    for (auto ker : kernels) {</div>
<div>+      size_t sz = ker.second->serializeToBin(souts);</div>
<div>+      if (!sz)</div>
<div>+        return 0;</div>
<div>+</div>
<div>+      ret_size += sz;</div>
<div>+    }</div>
<div>+</div>
<div>+    OUT_UPDATE_SZ(magic_end);</div>
<div>+</div>
<div>+    outs.write((char *)&ret_size, sizeof(ret_size));</div>
<div><font color="#1F497D">[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?</font></div>
<div><font face="Times New Roman"> </font></div>
<div>+    outs.write(souts.str().c_str(), souts.str().size());</div>
<div>+    ret_size += sizeof(ret_size);</div>
<div>+    return ret_size;</div>
<div>+  }</div>
<div>+</div>
<div>+  size_t Program::deserializeFromBin(std::istream& ins) {</div>
<div>+    size_t total_size = 0;</div>
<div>+    size_t ret_size = 0;</div>
<div>+    uint32_t magic;</div>
<div>+    size_t ker_num;</div>
<div>+    size_t const_num;</div>
<div>+    size_t global_data_sz;</div>
<div>+</div>
<div>+    ins.read((char *)&total_size, sizeof(total_size));</div>
<div>+    ret_size = total_size + sizeof(total_size);</div>
<div>+</div>
<div>+    IN_UPDATE_SZ(magic);</div>
<div>+    if (magic != magic_begin)</div>
<div>+      return 0;</div>
<div>+</div>
<div>+    IN_UPDATE_SZ(ker_num);</div>
<div>+    IN_UPDATE_SZ(const_num);</div>
<div>+    IN_UPDATE_SZ(global_data_sz);</div>
<div>+</div>
<div>+    constantSet = new ir::ConstantSet;</div>
<div>+    if (const_num || global_data_sz) {</div>
<div>+      char tmp;</div>
<div>+      size_t const_bytes;</div>
<div>+      IN_UPDATE_SZ(const_bytes);</div>
<div>+</div>
<div>+      for (unsigned int i = 0; i < global_data_sz; i++) {</div>
<div>+        IN_UPDATE_SZ(tmp);</div>
<div>+        constantSet->data.push_back(tmp);</div>
<div>+      }</div>
<div>+</div>
<div>+      for (unsigned int i = 0; i < const_num; i++) {</div>
<div>+        size_t name_len;</div>
<div>+        IN_UPDATE_SZ(name_len);</div>
<div>+        char* c_name = new char[name_len];</div>
<div>+        ins.read(c_name, name_len);</div>
<div>+        total_size -= sizeof(char)*name_len;</div>
<div>+        uint32_t size, align, offset;</div>
<div>+        uint16_t reg;</div>
<div>+        IN_UPDATE_SZ(size);</div>
<div>+        IN_UPDATE_SZ(align);</div>
<div>+        IN_UPDATE_SZ(offset);</div>
<div>+        IN_UPDATE_SZ(reg);</div>
<div>+        std::string name(c_name);</div>
<div>+        delete[] c_name;</div>
<div>+</div>
<div>+        const ir::Constant constant(name, size, align, offset);</div>
<div>+        constantSet->constants.push_back(constant);</div>
<div>+</div>
<div>+        const_bytes -= sizeof(name_len) + name_len * sizeof(char)</div>
<div>+            + sizeof(size) + sizeof(align) + sizeof(offset) + </div>
<div>+ sizeof(reg);</div>
<div>+</div>
<div>+        if (const_bytes) {</div>
<div>+          return 0;</div>
<div>+        }</div>
<div>+      }</div>
<div>+    }</div>
<div>+</div>
<div>+    for (unsigned int i = 0; i < ker_num; i++) {</div>
<div>+      size_t ker_serial_sz;</div>
<div>+      std::string ker_name; // Just a empty name here.</div>
<div>+      Kernel* ker = allocateKernel(ker_name);</div>
<div>+      if(!(ker_serial_sz = ker->deserializeFromBin(ins)))</div>
<div>+        return 0;</div>
<div>+</div>
<div>+      kernels.insert(std::make_pair(ker->getName(), ker));</div>
<div>+      total_size -= ker_serial_sz;</div>
<div>+    }</div>
<div>+</div>
<div>+    IN_UPDATE_SZ(magic);</div>
<div>+    if (magic != magic_end)</div>
<div>+      return 0;</div>
<div>+</div>
<div>+    if (total_size)</div>
<div>+      return 0;</div>
<div>+</div>
<div>+    return ret_size;</div>
<div>+  }</div>
<div>+</div>
<div>+  size_t Kernel::serializeToBin(std::ostream& outs) {</div>
<div>+    unsigned int i;</div>
<div>+    size_t ret_size = 0;</div>
<div>+    std::ostringstream souts(std::ostringstream::binary);</div>
<div>+</div>
<div>+    OUT_UPDATE_SZ(magic_begin);</div>
<div>+</div>
<div>+    OUT_UPDATE_SZ(name.size());</div>
<div>+    souts.write(name.c_str(), name.size());</div>
<div>+    ret_size += sizeof(char)*name.size();</div>
<div>+</div>
<div>+    OUT_UPDATE_SZ(argNum);</div>
<div>+    for (i = 0; i < argNum; i++) {</div>
<div>+      KernelArgument& arg = args[i];</div>
<div>+      OUT_UPDATE_SZ(arg.type);</div>
<div>+      OUT_UPDATE_SZ(arg.size);</div>
<div>+      OUT_UPDATE_SZ(arg.bufSize);</div>
<div>+    }</div>
<div>+</div>
<div>+    OUT_UPDATE_SZ(patches.size());</div>
<div>+    for (auto patch : patches) {</div>
<div>+      unsigned int tmp;</div>
<div>+      tmp = patch.type;</div>
<div>+      OUT_UPDATE_SZ(tmp);</div>
<div>+      tmp = patch.subType;</div>
<div>+      OUT_UPDATE_SZ(tmp);</div>
<div>+      tmp = patch.offset;</div>
<div>+      OUT_UPDATE_SZ(tmp);</div>
<div>+    }</div>
<div>+</div>
<div>+    OUT_UPDATE_SZ(curbeSize);</div>
<div>+    OUT_UPDATE_SZ(simdWidth);</div>
<div>+    OUT_UPDATE_SZ(stackSize);</div>
<div>+    OUT_UPDATE_SZ(useSLM);</div>
<div>+</div>
<div>+    /* samplers. */</div>
<div>+    if (samplerSet) {</div>
<div>+      OUT_UPDATE_SZ(samplerSet->samplerMap.size());</div>
<div>+      for (auto iter : samplerSet->samplerMap) {</div>
<div>+        OUT_UPDATE_SZ(iter.first);</div>
<div>+        OUT_UPDATE_SZ(iter.second.reg);</div>
<div>+        OUT_UPDATE_SZ(iter.second.slot);</div>
<div>+      }</div>
<div>+</div>
<div>+      OUT_UPDATE_SZ(samplerSet->regMap.size());</div>
<div>+      for (auto iter : samplerSet->regMap) {</div>
<div>+        OUT_UPDATE_SZ(iter.first);</div>
<div>+        OUT_UPDATE_SZ(iter.second.reg);</div>
<div>+        OUT_UPDATE_SZ(iter.second.slot);</div>
<div>+      }</div>
<div>+    }</div>
<div>+</div>
<div>+    /* images. */</div>
<div>+    if (imageSet) {</div>
<div>+      OUT_UPDATE_SZ(imageSet->regMap.size());</div>
<div>+      for (auto iter : imageSet->regMap) {</div>
<div>+        OUT_UPDATE_SZ(iter.first);</div>
<div>+        OUT_UPDATE_SZ(iter.second->arg_idx);</div>
<div>+        OUT_UPDATE_SZ(iter.second->idx);</div>
<div>+        OUT_UPDATE_SZ(iter.second->wSlot);</div>
<div>+        OUT_UPDATE_SZ(iter.second->hSlot);</div>
<div>+        OUT_UPDATE_SZ(iter.second->depthSlot);</div>
<div>+        OUT_UPDATE_SZ(iter.second->dataTypeSlot);</div>
<div>+        OUT_UPDATE_SZ(iter.second->channelOrderSlot);</div>
<div>+        OUT_UPDATE_SZ(iter.second->dimOrderSlot);</div>
<div>+      }</div>
<div><font color="#1F497D">[Yang Rong]: Because ImageInfo is a struct, maybe can read/write it once.</font></div>
<div>+</div>
<div>+      OUT_UPDATE_SZ(imageSet->indexMap.size());</div>
<div>+      for (auto iter : imageSet->indexMap) {</div>
<div>+        OUT_UPDATE_SZ(iter.first);</div>
<div>+        OUT_UPDATE_SZ(iter.second->arg_idx);</div>
<div>+        OUT_UPDATE_SZ(iter.second->idx);</div>
<div>+        OUT_UPDATE_SZ(iter.second->wSlot);</div>
<div>+        OUT_UPDATE_SZ(iter.second->hSlot);</div>
<div>+        OUT_UPDATE_SZ(iter.second->depthSlot);</div>
<div>+        OUT_UPDATE_SZ(iter.second->dataTypeSlot);</div>
<div>+        OUT_UPDATE_SZ(iter.second->channelOrderSlot);</div>
<div>+        OUT_UPDATE_SZ(iter.second->dimOrderSlot);</div>
<div>+      }</div>
<div>+    }</div>
<div>+</div>
<div>+    /* Code. */</div>
<div>+    const char * code = getCode();</div>
<div>+    OUT_UPDATE_SZ(getCodeSize());</div>
<div>+    for (i = 0; i < getCodeSize(); i++) {</div>
<div>+      OUT_UPDATE_SZ(code[i]);</div>
<div>+    }</div>
<div><font color="#1F497D">[YangRong]: Also write code once?</font></div>
<div><font face="Times New Roman"> </font></div>
<div>+</div>
<div>+    OUT_UPDATE_SZ(magic_end);</div>
<div>+</div>
<div>+    outs.write((char *)&ret_size, sizeof(ret_size));</div>
<div>+    outs.write(souts.str().c_str(), souts.str().size());</div>
<div>+    ret_size += sizeof(ret_size);</div>
<div>+    return ret_size;</div>
<div>+  }</div>
<div>+</div>
<div>+  size_t Kernel::deserializeFromBin(std::istream& ins) {</div>
<div>+    size_t total_size = 0;</div>
<div>+    size_t ret_size = 0;</div>
<div>+    uint32_t magic = 0;</div>
<div>+    size_t patch_num = 0;</div>
<div>+    size_t image_map_sz = 0;</div>
<div>+    size_t sampler_map_sz = 0;</div>
<div>+    size_t code_size = 0;</div>
<div>+</div>
<div>+    ins.read((char *)&total_size, sizeof(total_size));</div>
<div>+    ret_size = total_size + sizeof(total_size);</div>
<div>+</div>
<div>+    IN_UPDATE_SZ(magic);</div>
<div>+    if (magic != magic_begin)</div>
<div>+      return 0;</div>
<div>+</div>
<div>+    size_t name_len;</div>
<div>+    IN_UPDATE_SZ(name_len);</div>
<div>+    char* c_name = new char[name_len];</div>
<div>+    ins.read(c_name, name_len);</div>
<div>+    total_size -= sizeof(char)*name_len;</div>
<div>+</div>
<div>+    name = c_name;</div>
<div>+    delete[] c_name;</div>
<div>+</div>
<div>+    IN_UPDATE_SZ(argNum);</div>
<div>+    GBE_NEW_ARRAY_NO_ARG(KernelArgument, argNum);</div>
<div>+</div>
<div>+    args = GBE_NEW_ARRAY_NO_ARG(KernelArgument, argNum);</div>
<div>+    for (uint32_t i = 0; i < argNum; i++) {</div>
<div>+      KernelArgument& arg = args[i];</div>
<div>+      IN_UPDATE_SZ(arg.type);</div>
<div>+      IN_UPDATE_SZ(arg.size);</div>
<div>+      IN_UPDATE_SZ(arg.bufSize);</div>
<div>+    }</div>
<div>+</div>
<div>+    IN_UPDATE_SZ(patch_num);</div>
<div>+    for (uint32_t i = 0; i < patch_num; i++) {</div>
<div>+      unsigned int tmp;</div>
<div>+      PatchInfo patch;</div>
<div>+      IN_UPDATE_SZ(tmp);</div>
<div>+      patch.type = tmp;</div>
<div>+      IN_UPDATE_SZ(tmp);</div>
<div>+      patch.subType = tmp;</div>
<div>+      IN_UPDATE_SZ(tmp);</div>
<div>+      patch.offset = tmp;</div>
<div>+</div>
<div>+      patches.push_back(patch);</div>
<div>+    }</div>
<div>+</div>
<div>+    IN_UPDATE_SZ(curbeSize);</div>
<div>+    IN_UPDATE_SZ(simdWidth);</div>
<div>+    IN_UPDATE_SZ(stackSize);</div>
<div>+    IN_UPDATE_SZ(useSLM);</div>
<div>+</div>
<div>+    samplerSet = GBE_NEW(ir::SamplerSet);</div>
<div>+</div>
<div>+    IN_UPDATE_SZ(sampler_map_sz); //samplerMap</div>
<div>+    if (sampler_map_sz){</div>
<div>+      for (uint32_t i = 0; i < sampler_map_sz; i++) {</div>
<div>+        uint32_t key;</div>
<div>+        ir::SamplerRegSlot reg_slot;</div>
<div>+</div>
<div>+        IN_UPDATE_SZ(key);</div>
<div>+        IN_UPDATE_SZ(reg_slot.reg);</div>
<div>+        IN_UPDATE_SZ(reg_slot.slot);</div>
<div>+        samplerSet->samplerMap.insert(std::make_pair(key, reg_slot));</div>
<div>+      }</div>
<div>+    }</div>
<div>+</div>
<div>+    IN_UPDATE_SZ(sampler_map_sz);  //regMap</div>
<div>+    if (sampler_map_sz){</div>
<div>+      for (uint32_t i = 0; i < sampler_map_sz; i++) {</div>
<div>+        ir::Register key;</div>
<div>+        ir::SamplerRegSlot reg_slot;</div>
<div>+</div>
<div>+        IN_UPDATE_SZ(key);</div>
<div>+        IN_UPDATE_SZ(reg_slot.reg);</div>
<div>+        IN_UPDATE_SZ(reg_slot.slot);</div>
<div>+        samplerSet->regMap.insert(std::make_pair(key, reg_slot));</div>
<div>+      }</div>
<div>+    }</div>
<div>+</div>
<div>+    imageSet = GBE_NEW(ir::ImageSet);</div>
<div>+</div>
<div>+    IN_UPDATE_SZ(image_map_sz); //regMap</div>
<div>+    if (image_map_sz){</div>
<div>+      for (uint32_t i = 0; i < image_map_sz; i++) {</div>
<div>+        ir::Register reg;</div>
<div>+        ImageInfo *img_info = GBE_NEW(struct ImageInfo);;</div>
<div>+</div>
<div>+        IN_UPDATE_SZ(reg);</div>
<div>+        IN_UPDATE_SZ(img_info->arg_idx);</div>
<div>+        IN_UPDATE_SZ(img_info->idx);</div>
<div>+        IN_UPDATE_SZ(img_info->wSlot);</div>
<div>+        IN_UPDATE_SZ(img_info->hSlot);</div>
<div>+        IN_UPDATE_SZ(img_info->depthSlot);</div>
<div>+        IN_UPDATE_SZ(img_info->dataTypeSlot);</div>
<div>+        IN_UPDATE_SZ(img_info->channelOrderSlot);</div>
<div>+        IN_UPDATE_SZ(img_info->dimOrderSlot);</div>
<div>+</div>
<div>+        imageSet->regMap.insert(std::make_pair(reg, img_info));</div>
<div>+      }</div>
<div>+    }</div>
<div>+</div>
<div>+    IN_UPDATE_SZ(image_map_sz); //indexMap</div>
<div>+    if (image_map_sz){</div>
<div>+      for (uint32_t i = 0; i < image_map_sz; i++) {</div>
<div>+        uint32_t index;</div>
<div>+        ImageInfo *img_info = GBE_NEW(struct ImageInfo);;</div>
<div>+</div>
<div>+        IN_UPDATE_SZ(index);</div>
<div>+        IN_UPDATE_SZ(img_info->arg_idx);</div>
<div>+        IN_UPDATE_SZ(img_info->idx);</div>
<div>+        IN_UPDATE_SZ(img_info->wSlot);</div>
<div>+        IN_UPDATE_SZ(img_info->hSlot);</div>
<div>+        IN_UPDATE_SZ(img_info->depthSlot);</div>
<div>+        IN_UPDATE_SZ(img_info->dataTypeSlot);</div>
<div>+        IN_UPDATE_SZ(img_info->channelOrderSlot);</div>
<div>+        IN_UPDATE_SZ(img_info->dimOrderSlot);</div>
<div>+</div>
<div>+        imageSet->indexMap.insert(std::make_pair(index, img_info));</div>
<div>+      }</div>
<div>+    }</div>
<div>+</div>
<div>+    IN_UPDATE_SZ(code_size);</div>
<div>+    if (code_size) {</div>
<div>+      char * code = GBE_NEW_ARRAY_NO_ARG(char, code_size);</div>
<div>+      ins.read(code, code_size*sizeof(char));</div>
<div>+      total_size -= sizeof(char)*code_size;</div>
<div>+      setCode(code, code_size);</div>
<div>+    }</div>
<div>+</div>
<div>+    IN_UPDATE_SZ(magic);</div>
<div>+    if (magic != magic_end)</div>
<div>+      return 0;</div>
<div>+</div>
<div>+    if (total_size)</div>
<div>+      return 0;</div>
<div>+</div>
<div>+    return ret_size;</div>
<div>+  }</div>
<div>+</div>
<div>+#undef OUT_UPDATE_SZ</div>
<div>+#undef IN_UPDATE_SZ</div>
<div>+</div>
<div>+ /*********************** End of Program class member function </div>
<div>+ *************************/</div>
<div>+</div>
<div>   static void programDelete(gbe_program gbeProgram) {</div>
<div>     gbe::Program *program = (gbe::Program*)(gbeProgram);</div>
<div>     GBE_SAFE_DELETE(program);</div>
<div>diff --git a/backend/src/backend/program.hpp b/backend/src/backend/program.hpp index f1ab20e..6d53253 100644</div>
<div>--- a/backend/src/backend/program.hpp</div>
<div>+++ b/backend/src/backend/program.hpp</div>
<div>@@ -67,7 +67,7 @@ namespace gbe {</div>
<div>   }</div>
<div> </div>
<div>   /*! Describe a compiled kernel */</div>
<div>-  class Kernel : public NonCopyable</div>
<div>+  class Kernel : public NonCopyable, public Serializable</div>
<div>   {</div>
<div>   public:</div>
<div>     /*! Create an empty kernel with the given name */ @@ -76,6 +76,8 @@ namespace gbe {</div>
<div>     virtual ~Kernel(void);</div>
<div>     /*! Return the instruction stream (to be implemented) */</div>
<div>     virtual const char *getCode(void) const = 0;</div>
<div>+    /*! Set the instruction stream.*/</div>
<div>+    virtual const void setCode(const char *, size_t size) = 0;</div>
<div>     /*! Return the instruction stream size (to be implemented) */</div>
<div>     virtual size_t getCodeSize(void) const = 0;</div>
<div>     /*! Get the kernel name */</div>
<div>@@ -128,9 +130,37 @@ namespace gbe {</div>
<div>     size_t getImageSize(void) const { return imageSet->getDataSize(); }</div>
<div>     /*! Get defined image value array */</div>
<div>     void getImageData(ImageInfo *images) const { imageSet->getData(images); }</div>
<div>+</div>
<div>+    static const uint32_t magic_begin = TO_MAGIC('K', 'E', 'R', 'N');</div>
<div>+    static const uint32_t magic_end = TO_MAGIC('N', 'R', 'E', 'K');</div>
<div>+</div>
<div>+    /* format:</div>
<div>+       magic_begin |</div>
<div>+       name_size |</div>
<div>+       name |</div>
<div>+       arg_num |</div>
<div>+       args |</div>
<div>+       PatchInfo_num |</div>
<div>+       PatchInfo |</div>
<div>+       curbeSize |</div>
<div>+       simdWidth |</div>
<div>+       stackSize |</div>
<div>+       useSLM |</div>
<div>+       samplers |</div>
<div>+       images |</div>
<div>+       code_size |</div>
<div>+       code |</div>
<div>+       magic_end</div>
<div>+    */</div>
<div>+</div>
<div>+    /*! Implements the serialization. */</div>
<div>+    virtual size_t serializeToBin(std::ostream& outs);</div>
<div>+    virtual size_t deserializeFromBin(std::istream& ins);</div>
<div>+</div>
<div>+</div>
<div>   protected:</div>
<div>     friend class Context;      //!< Owns the kernels</div>
<div>-    const std::string name;    //!< Kernel name</div>
<div>+    std::string name;    //!< Kernel name</div>
<div>     KernelArgument *args;      //!< Each argument</div>
<div>     vector<PatchInfo> patches; //!< Indicates how to build the curbe</div>
<div>     uint32_t argNum;           //!< Number of function arguments</div>
<div>@@ -146,7 +176,7 @@ namespace gbe {</div>
<div>   };</div>
<div> </div>
<div>   /*! Describe a compiled program */</div>
<div>-  class Program : public NonCopyable</div>
<div>+  class Program : public NonCopyable, public Serializable</div>
<div>   {</div>
<div>   public:</div>
<div>     /*! Create an empty program */</div>
<div>@@ -186,6 +216,31 @@ namespace gbe {</div>
<div>     size_t getGlobalConstantSize(void) const { return constantSet->getDataSize(); }</div>
<div>     /*! Get the content of global constant arrays */</div>
<div>     void getGlobalConstantData(char *mem) const { constantSet->getData(mem); }</div>
<div>+</div>
<div>+    static const uint32_t magic_begin = TO_MAGIC('P', 'R', 'O', 'G');</div>
<div>+    static const uint32_t magic_end = TO_MAGIC('G', 'O', 'R', 'P');</div>
<div>+</div>
<div>+    /* format:</div>
<div>+       magic_begin | kernel_number | constant_number |</div>
<div>+       const_data_size |</div>
<div>+       const_data |</div>
<div>+       constant_1_size |</div>
<div>+       constant_1 |</div>
<div>+       ........   |</div>
<div>+       constant_n_size |</div>
<div>+       constant_n |</div>
<div>+       kernel_1_size |</div>
<div>+       kernel_1   |</div>
<div>+       ........   |</div>
<div>+       kernel_n_size   |</div>
<div>+       kernel_n   |</div>
<div>+       magic_end</div>
<div>+    */</div>
<div>+</div>
<div>+    /*! Implements the serialization. */</div>
<div>+    virtual size_t serializeToBin(std::ostream& outs);</div>
<div>+    virtual size_t deserializeFromBin(std::istream& ins);</div>
<div>+</div>
<div>   protected:</div>
<div>     /*! Compile a kernel */</div>
<div>     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</div>
<div>--- a/backend/src/ir/constant.hpp</div>
<div>+++ b/backend/src/ir/constant.hpp</div>
<div>@@ -28,6 +28,9 @@</div>
<div> #include "sys/vector.hpp"</div>
<div> </div>
<div> namespace gbe {</div>
<div>+</div>
<div>+class Program;</div>
<div>+</div>
<div> namespace ir {</div>
<div> </div>
<div>   /*! Describe one constant (may be a scalar or an array) */ @@ -52,6 +55,8 @@ namespace ir {</div>
<div>     /*! Nothing happens here */</div>
<div>     INLINE ~Constant(void) {}</div>
<div>     const std::string& getName(void) const { return name; }</div>
<div>+    uint32_t getSize (void) const { return size; }</div>
<div>+    uint32_t getAlignment (void) const { return alignment; }</div>
<div>     uint32_t getOffset(void) const { return offset; }</div>
<div>     uint16_t getReg(void) const { return reg; }</div>
<div>     void setReg(uint16_t reg) { this->reg = reg; } @@ -102,6 +107,7 @@ namespace ir {</div>
<div>       return *this;</div>
<div>     }</div>
<div>   private:</div>
<div>+    friend class gbe::Program;</div>
<div>     vector<char> data;         //!< The constant data serialized in one array</div>
<div>     vector<Constant> constants;//!< Each constant description</div>
<div>     GBE_CLASS(ConstantSet);</div>
<div>diff --git a/backend/src/ir/image.hpp b/backend/src/ir/image.hpp index 04e78e6..61d9426 100644</div>
<div>--- a/backend/src/ir/image.hpp</div>
<div>+++ b/backend/src/ir/image.hpp</div>
<div>@@ -32,6 +32,8 @@ extern "C" {</div>
<div> }</div>
<div> </div>
<div> namespace gbe {</div>
<div>+  class Kernel;</div>
<div>+</div>
<div> namespace ir {</div>
<div> </div>
<div>   class Context;</div>
<div>@@ -61,6 +63,7 @@ namespace ir {</div>
<div>     ImageSet() {}</div>
<div>     ~ImageSet();</div>
<div>   private:</div>
<div>+    friend class gbe::Kernel;</div>
<div>     map<Register, struct ImageInfo *> regMap;</div>
<div>     map<uint32_t, struct ImageInfo *> indexMap;</div>
<div>     GBE_CLASS(ImageSet);</div>
<div>diff --git a/backend/src/ir/sampler.hpp b/backend/src/ir/sampler.hpp index f968299..bcb6c74 100644</div>
<div>--- a/backend/src/ir/sampler.hpp</div>
<div>+++ b/backend/src/ir/sampler.hpp</div>
<div>@@ -28,6 +28,8 @@</div>
<div> #include "sys/map.hpp"</div>
<div> </div>
<div> namespace gbe {</div>
<div>+  class Kernel;</div>
<div>+</div>
<div> namespace ir {</div>
<div> </div>
<div>   /*! A sampler set is a set of global samplers which are defined as constant global @@ -67,6 +69,7 @@ namespace ir {</div>
<div>     SamplerSet(const SamplerSet& other) : samplerMap(other.samplerMap.begin(), other.samplerMap.end()) { }</div>
<div>     SamplerSet() {}</div>
<div>   private:</div>
<div>+    friend class gbe::Kernel;</div>
<div>     void appendReg(const Register reg, uint32_t key, Context *ctx);</div>
<div>     map<uint32_t, SamplerRegSlot> samplerMap;</div>
<div>     map<Register, SamplerRegSlot> regMap; diff --git a/backend/src/sys/platform.hpp b/backend/src/sys/platform.hpp index a665356..8b28b7b 100644</div>
<div>--- a/backend/src/sys/platform.hpp</div>
<div>+++ b/backend/src/sys/platform.hpp</div>
<div>@@ -24,6 +24,9 @@</div>
<div> #include <cstdlib></div>
<div> #include <cstdio></div>
<div> #include <iostream></div>
<div>+#include <ostream></div>
<div>+#include <istream></div>
<div>+#include <string></div>
<div> #include <cassert></div>
<div> #include <new></div>
<div> </div>
<div>@@ -323,6 +326,25 @@ private:</div>
<div>   INLINE NonCopyable& operator= (const NonCopyable&) {return *this;}  };</div>
<div> </div>
<div>+#define TO_MAGIC(A, B, C, D)  (A<<24 | B<<16 | C<<8 | D)</div>
<div>+</div>
<div>+class Serializable</div>
<div>+{</div>
<div>+public:</div>
<div>+  INLINE Serializable(void) = default;</div>
<div>+</div>
<div>+  /* We do not want to be copied. */</div>
<div>+  INLINE Serializable(const Serializable&) = delete;  INLINE </div>
<div>+ Serializable& operator= (const Serializable&) = delete;</div>
<div>+</div>
<div>+  virtual size_t serializeToBin(std::ostream& outs) = 0;  virtual </div>
<div>+ size_t deserializeFromBin(std::istream& ins) = 0;</div>
<div>+</div>
<div>+  /* These two will follow LLVM's ABI. */</div>
<div>+  virtual size_t serializeToLLVM(void) { return 0;/* not implemented </div>
<div>+now. */}</div>
<div>+  virtual size_t deserializeFromLLVM(void) { return 0;/* not </div>
<div>+implemented now. */} };</div>
<div>+</div>
<div> ////////////////////////////////////////////////////////////////////////////////</div>
<div> /// Disable some compiler warnings</div>
<div> ////////////////////////////////////////////////////////////////////////////////</div>
<div>--</div>
<div>1.7.9.5</div>
<div> </div>
<div>_______________________________________________</div>
<div>Beignet mailing list</div>
<div><font face="Times New Roman"><a href="mailto:Beignet@lists.freedesktop.org"><font face="Calibri">Beignet@lists.freedesktop.org</font></a></font></div>
<div><font face="Times New Roman"><a href="http://lists.freedesktop.org/mailman/listinfo/beignet"><font face="Calibri">http://lists.freedesktop.org/mailman/listinfo/beignet</font></a></font></div>
<div><font face="Times New Roman"> </font></div>
</span></font>
</body>
</html>