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