[Beignet] [Patch V3 1/2] add platform info in the gen binary code.
Zhigang Gong
zhigang.gong at linux.intel.com
Tue Jul 15 23:07:16 PDT 2014
LGTM, will push latter, thanks.
On Wed, Jul 16, 2014 at 09:31:05AM +0800, xionghu.luo at intel.com wrote:
> From: LuoXionghu <xionghu.luo at intel.com>
>
> the size of the platform info is 3 bytes, right after the '/0GENC'.
> check the header magic number and platform info before deserializeFromBin.
>
> v2: supports IVB/BYT/HSW binary on its' platform, and BYT binary runs on IVB.
> v3: fix 'BYT' overwritten by 'IVB';
>
> Signed-off-by: LuoXionghu <xionghu.luo at intel.com>
> ---
> backend/src/backend/gen_program.cpp | 56 +++++++++++++++++++++++++++++++------
> backend/src/gbe_bin_generater.cpp | 23 +++++++++++++++
> 2 files changed, 70 insertions(+), 9 deletions(-)
>
> diff --git a/backend/src/backend/gen_program.cpp b/backend/src/backend/gen_program.cpp
> index 84e8c2a..c846786 100644
> --- a/backend/src/backend/gen_program.cpp
> +++ b/backend/src/backend/gen_program.cpp
> @@ -196,15 +196,36 @@ namespace gbe {
> #endif
> }
>
> +#define BINARY_HEADER_LENGTH 8
> +#define IS_GEN_BINARY(binary) (*binary == '\0' && *(binary+1) == 'G'&& *(binary+2) == 'E' &&*(binary+3) == 'N' &&*(binary+4) == 'C')
> +#define FILL_GEN_BINARY(binary) do{*binary = '\0'; *(binary+1) = 'G'; *(binary+2) = 'E'; *(binary+3) = 'N'; *(binary+4) = 'C';}while(0)
> +#define FILL_DEVICE_ID(binary, src_hw_info) do {*(binary+5) = src_hw_info[0]; *(binary+6) = src_hw_info[1]; *(binary+7) = src_hw_info[2];}while(0)
> +#define DEVICE_MATCH(typeA, src_hw_info) ((IS_IVYBRIDGE(typeA) && !strcmp(src_hw_info, "IVB")) || \
> + (IS_IVYBRIDGE(typeA) && !strcmp(src_hw_info, "BYT")) || \
> + (IS_BAYTRAIL_T(typeA) && !strcmp(src_hw_info, "BYT")) || \
> + (IS_HASWELL(typeA) && !strcmp(src_hw_info, "HSW")) )
> +
> static gbe_program genProgramNewFromBinary(uint32_t deviceID, const char *binary, size_t size) {
> using namespace gbe;
> std::string binary_content;
> - //the first 5 bytes are header to differentiate from llvm bitcode binary.
> - binary_content.assign(binary+5, size-5);
> + //the header length is 8 bytes: 1 byte is binary type, 4 bytes are bitcode header, 3 bytes are hw info.
> + char src_hw_info[4]="";
> + src_hw_info[0] = *(binary+5);
> + src_hw_info[1] = *(binary+6);
> + src_hw_info[2] = *(binary+7);
> +
> + // check whether is gen binary ('/0GENC')
> + if(!IS_GEN_BINARY(binary)){
> + return NULL;
> + }
> + // check the whether the current device ID match the binary file's.
> + if(!DEVICE_MATCH(deviceID, src_hw_info)){
> + return NULL;
> + }
> +
> + binary_content.assign(binary+BINARY_HEADER_LENGTH, size-BINARY_HEADER_LENGTH);
> GenProgram *program = GBE_NEW(GenProgram, deviceID);
> std::istringstream ifs(binary_content, std::ostringstream::binary);
> - // FIXME we need to check the whether the current device ID match the binary file's.
> - deviceID = deviceID;
>
> if (!program->deserializeFromBin(ifs)) {
> delete program;
> @@ -255,11 +276,28 @@ namespace gbe {
> }
>
> //add header to differetiate from llvm bitcode binary.
> - //the header length is 5 bytes: 1 binary type, 4 bitcode header.
> - *binary = (char *)malloc(sizeof(char) * (sz+5) );
> - memset(*binary, 0, sizeof(char) * (sz+5) );
> - memcpy(*binary+5, oss.str().c_str(), sz*sizeof(char));
> - return sz+5;
> + //the header length is 8 bytes: 1 byte is binary type, 4 bytes are bitcode header, 3 bytes are hw info.
> + *binary = (char *)malloc(sizeof(char) * (sz+BINARY_HEADER_LENGTH) );
> + memset(*binary, 0, sizeof(char) * (sz+BINARY_HEADER_LENGTH) );
> + FILL_GEN_BINARY(*binary);
> + char src_hw_info[4]="";
> + if(IS_IVYBRIDGE(prog->deviceID)){
> + src_hw_info[0]='I';
> + src_hw_info[1]='V';
> + src_hw_info[2]='B';
> + if(IS_BAYTRAIL_T(prog->deviceID)){
> + src_hw_info[0]='B';
> + src_hw_info[1]='Y';
> + src_hw_info[2]='T';
> + }
> + }else if(IS_HASWELL(prog->deviceID)){
> + src_hw_info[0]='H';
> + src_hw_info[1]='S';
> + src_hw_info[2]='W';
> + }
> + FILL_DEVICE_ID(*binary, src_hw_info);
> + memcpy(*binary+BINARY_HEADER_LENGTH, oss.str().c_str(), sz*sizeof(char));
> + return sz+BINARY_HEADER_LENGTH;
> }else{
> #ifdef GBE_COMPILER_AVAILABLE
> std::string str;
> diff --git a/backend/src/gbe_bin_generater.cpp b/backend/src/gbe_bin_generater.cpp
> index d9ae946..86c4406 100644
> --- a/backend/src/gbe_bin_generater.cpp
> +++ b/backend/src/gbe_bin_generater.cpp
> @@ -39,6 +39,7 @@
> #include "backend/program.h"
> #include "backend/program.hpp"
> #include "backend/src/sys/platform.hpp"
> +#include "src/cl_device_data.h"
>
> using namespace std;
>
> @@ -159,6 +160,22 @@ void program_build_instance::serialize_program(void) throw(int)
> size_t sz = 0, header_sz = 0;
> ofs.open(bin_path, ofstream::out | ofstream::trunc | ofstream::binary);
>
> + char src_hw_info[4]="";
> + if(IS_IVYBRIDGE(gen_pci_id)){
> + src_hw_info[0]='I';
> + src_hw_info[1]='V';
> + src_hw_info[2]='B';
> + if(IS_BAYTRAIL_T(gen_pci_id)){
> + src_hw_info[0]='B';
> + src_hw_info[1]='Y';
> + src_hw_info[2]='T';
> + }
> + }else if(IS_HASWELL(gen_pci_id)){
> + src_hw_info[0]='H';
> + src_hw_info[1]='S';
> + src_hw_info[2]='W';
> + }
> +
> if (str_fmt_out) {
>
> if(gen_pci_id){
> @@ -170,6 +187,9 @@ void program_build_instance::serialize_program(void) throw(int)
> OUTS_UPDATE_SZ(gen_header[2]);
> OUTS_UPDATE_SZ(gen_header[3]);
> OUTS_UPDATE_SZ(gen_header[4]);
> + OUTS_UPDATE_SZ(src_hw_info[0]);
> + OUTS_UPDATE_SZ(src_hw_info[1]);
> + OUTS_UPDATE_SZ(src_hw_info[2]);
> }
>
> string array_name = "Unknown_name_array";
> @@ -213,6 +233,9 @@ void program_build_instance::serialize_program(void) throw(int)
> OUTF_UPDATE_SZ(gen_header[2]);
> OUTF_UPDATE_SZ(gen_header[3]);
> OUTF_UPDATE_SZ(gen_header[4]);
> + OUTF_UPDATE_SZ(src_hw_info[0]);
> + OUTF_UPDATE_SZ(src_hw_info[1]);
> + OUTF_UPDATE_SZ(src_hw_info[2]);
> sz = gbe_prog->serializeToBin(ofs);
> }else{
> char *llvm_binary;
> --
> 1.8.1.2
>
> _______________________________________________
> Beignet mailing list
> Beignet at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/beignet
More information about the Beignet
mailing list