<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>