[Beignet] [V2 PATCH 1/4] Add the serialization support for backend
Yang, Rong R
rong.r.yang at intel.com
Mon Sep 9 02:01:31 PDT 2013
See my comment about some string value, and there are some warnings just like:
/home/champson/temp/beignet/backend/src/backend/program.cpp:82:20: warning: deleting object of polymorphic class type âgbe::ir::SamplerSetâ?which has non-virtual destructor might cause undefined behaviour [-Wdelete-non-virtual-dtor]
-----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, September 05, 2013 6:48 PM
To: beignet at lists.freedesktop.org
Cc: Junyan He
Subject: [Beignet] [V2 PATCH 1/4] Add the serialization support for backend
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 | 315 +++++++++++++++++++++++++++++++++++
backend/src/backend/program.hpp | 59 ++++++-
backend/src/ir/constant.cpp | 99 +++++++++++
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, 859 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..f487bf6 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,320 @@ 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];
+ ins.read(c_name, name_len*sizeof(char));
+ total_size += sizeof(char)*name_len;
Maybe need set c_name[name_len+1] to \0 here, or write name_len+1 byte.
+ 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..2bf52cc 100644
--- a/backend/src/ir/constant.cpp
+++ b/backend/src/ir/constant.cpp
@@ -40,6 +40,105 @@ 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];
+ 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);
+
+ const ir::Constant constant(c_name, size, align, offset);
+ 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