[Beignet] [PATCH OCL20 v2 3/4] Add pipe packet size check

Xiuli Pan xiuli.pan at intel.com
Tue Mar 1 04:47:57 UTC 2016


From: Pan Xiuli <xiuli.pan at intel.com>

Get pipe packet type from metadata and pass type size to kernel
check type size is fit in clSetKernelArg

Signed-off-by: Pan Xiuli <xiuli.pan at intel.com>
---
 backend/src/backend/program.cpp       |  2 ++
 backend/src/backend/program.h         |  1 +
 backend/src/ir/function.hpp           |  1 +
 backend/src/llvm/llvm_gen_backend.cpp | 32 ++++++++++++++++++++++++++++++++
 src/cl_kernel.c                       |  6 ++++++
 5 files changed, 42 insertions(+)

diff --git a/backend/src/backend/program.cpp b/backend/src/backend/program.cpp
index 8f78e1f..afae77b 100644
--- a/backend/src/backend/program.cpp
+++ b/backend/src/backend/program.cpp
@@ -1061,6 +1061,8 @@ namespace gbe {
         return (void *)(info->typeQual.c_str());
       case GBE_GET_ARG_INFO_NAME:
         return (void *)(info->argName.c_str());
+      case GBE_GET_ARG_INFO_TYPESIZE:
+        return (void *)((size_t)info->typeSize);
       default:
         assert(0);
     }
diff --git a/backend/src/backend/program.h b/backend/src/backend/program.h
index a84ddb1..4dd3ae3 100644
--- a/backend/src/backend/program.h
+++ b/backend/src/backend/program.h
@@ -61,6 +61,7 @@ enum gbe_get_arg_info_value {
   GBE_GET_ARG_INFO_TYPE = 2,
   GBE_GET_ARG_INFO_TYPEQUAL = 3,
   GBE_GET_ARG_INFO_NAME = 4,
+  GBE_GET_ARG_INFO_TYPESIZE = 5,
   GBE_GET_ARG_INFO_INVALID = 0xffffffff
 };
 
diff --git a/backend/src/ir/function.hpp b/backend/src/ir/function.hpp
index 4b076e6..b6379f3 100644
--- a/backend/src/ir/function.hpp
+++ b/backend/src/ir/function.hpp
@@ -181,6 +181,7 @@ namespace ir {
       std::string accessQual;
       std::string typeQual;
       std::string argName; // My different from arg->getName()
+      uint32_t typeSize;
 
       bool isImage1dT() const {
         return typeName.compare("image1d_t") == 0;
diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp
index 7f5b642..b6cee6c 100644
--- a/backend/src/llvm/llvm_gen_backend.cpp
+++ b/backend/src/llvm/llvm_gen_backend.cpp
@@ -238,6 +238,37 @@ namespace gbe
     return CPV;
   }
 
+#define TYPESIZE(TYPE,VECT,SZ) else if(name == std::string(#TYPE).append(#VECT)) return VECT*SZ;
+#define TYPESIZEVEC(TYPE,SZ)\
+  else if(name == #TYPE) return SZ;\
+  TYPESIZE(TYPE,2,SZ)\
+  TYPESIZE(TYPE,3,SZ)\
+  TYPESIZE(TYPE,4,SZ)\
+  TYPESIZE(TYPE,8,SZ)\
+  TYPESIZE(TYPE,16,SZ)
+
+  static uint32_t getTypeSize(Module* M, const ir::Unit &unit, std::string& name) {
+      if(name == "size_t") return sizeof(size_t);
+      TYPESIZEVEC(char,1)
+      TYPESIZEVEC(uchar,1)
+      TYPESIZEVEC(short,2)
+      TYPESIZEVEC(ushort,2)
+      TYPESIZEVEC(half,2)
+      TYPESIZEVEC(int,4)
+      TYPESIZEVEC(uint,4)
+      TYPESIZEVEC(float,4)
+      TYPESIZEVEC(double,8)
+      TYPESIZEVEC(long,8)
+      TYPESIZEVEC(ulong,8)
+      else{
+        StructType *StrTy = M->getTypeByName("struct."+name);
+        if(StrTy)
+          return getTypeByteSize(unit,StrTy);
+      }
+      return 0;
+  }
+#undef TYPESIZEVEC
+#undef TYPESIZE
   /*! Handle the LLVM IR Value to Gen IR register translation. This has 2 roles:
    *  - Split the LLVM vector into several scalar values
    *  - Handle the transparent copies (bitcast or use of intrincics functions
@@ -2066,6 +2097,7 @@ namespace gbe
           continue;
         }
         if(llvmInfo.isPipeType()) {
+          llvmInfo.typeSize = getTypeSize(F.getParent(),unit,llvmInfo.typeName);
           ctx.input(argName, ir::FunctionArgument::PIPE, reg, llvmInfo, getTypeByteSize(unit, type), getAlignmentByte(unit, type), BtiMap.find(&*I)->second);
           continue;
         }
diff --git a/src/cl_kernel.c b/src/cl_kernel.c
index abbabbd..8c2f733 100644
--- a/src/cl_kernel.c
+++ b/src/cl_kernel.c
@@ -141,6 +141,12 @@ cl_kernel_set_arg(cl_kernel k, cl_uint index, size_t sz, const void *value)
       return CL_INVALID_ARG_VALUE;
     if(value != NULL)
       mem = *(cl_mem*)value;
+    if(arg_type == GBE_ARG_PIPE) {
+      _cl_mem_pipe* pipe= cl_mem_pipe(mem);
+      size_t type_size = (size_t)interp_kernel_get_arg_info(k->opaque, index,5);
+      if(pipe->packet_size != type_size)
+          return CL_INVALID_ARG_VALUE;
+    }
     if(value != NULL && mem) {
       if( CL_SUCCESS != is_valid_mem(mem, ctx->buffers))
         return CL_INVALID_MEM_OBJECT;
-- 
2.5.0



More information about the Beignet mailing list