Pushed the whole patchset. Thanks for the contribution.
On Wed, Sep 11, 2013 at 06:07:39PM +0800, [email protected] wrote: > From: Junyan He <[email protected]> > > 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 <[email protected]> > --- > 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 > [email protected] > http://lists.freedesktop.org/mailman/listinfo/beignet _______________________________________________ Beignet mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/beignet
