[Beignet] [PATCH] add support for build option -cl-fast-relaxed-math

Guo Yejun yejun.guo at intel.com
Thu Dec 10 16:56:55 PST 2015


current code handles this option at clang level, actually, it is
also necessary at LLVM -> GEN stage.

Signed-off-by: Guo Yejun <yejun.guo at intel.com>
---
 backend/src/backend/gen_program.cpp | 14 ++++++++++++--
 backend/src/backend/gen_program.hpp |  4 ++--
 backend/src/backend/program.cpp     | 20 ++++++++++++++------
 backend/src/backend/program.h       |  3 ++-
 backend/src/backend/program.hpp     |  3 ++-
 src/cl_program.c                    |  2 +-
 6 files changed, 33 insertions(+), 13 deletions(-)

diff --git a/backend/src/backend/gen_program.cpp b/backend/src/backend/gen_program.cpp
index 5149d49..0ea86d0 100644
--- a/backend/src/backend/gen_program.cpp
+++ b/backend/src/backend/gen_program.cpp
@@ -394,10 +394,15 @@ namespace gbe {
                                            size_t stringSize,
                                            char *err,
                                            size_t *errSize,
-                                           int optLevel)
+                                           int optLevel,
+                                           const char* options)
   {
     using namespace gbe;
-    GenProgram *program = GBE_NEW(GenProgram, deviceID, module, llvm_ctx, asm_file_name);
+    uint32_t fast_relaxed_math = 0;
+    if (strstr(options, "-cl-fast-relaxed-math") != NULL)
+      fast_relaxed_math = 1;
+
+    GenProgram *program = GBE_NEW(GenProgram, deviceID, module, llvm_ctx, asm_file_name, fast_relaxed_math);
 #ifdef GBE_COMPILER_AVAILABLE
     std::string error;
     // Try to compile the program
@@ -469,6 +474,7 @@ namespace gbe {
     int optLevel = 1;
     std::string dumpASMFileName;
     size_t start = 0, end = 0;
+    uint32_t fast_relaxed_math = 0;
 
     if(options) {
       char *p;
@@ -476,6 +482,9 @@ namespace gbe {
       if (p)
         optLevel = 0;
 
+      if (strstr(options, "-cl-fast-relaxed-math") != NULL)
+        fast_relaxed_math = 1;
+
     char *options_str = (char *)malloc(sizeof(char) * (strlen(options) + 1));
       memcpy(options_str, options, strlen(options) + 1);
       std::string optionStr(options_str);
@@ -495,6 +504,7 @@ namespace gbe {
     }
 
     GenProgram* p = (GenProgram*) program;
+    p->fast_relaxed_math = fast_relaxed_math;
     if (!dumpASMFileName.empty()) {
         p->asm_file_name = dumpASMFileName.c_str();
         FILE *asmDumpStream = fopen(dumpASMFileName.c_str(), "w");
diff --git a/backend/src/backend/gen_program.hpp b/backend/src/backend/gen_program.hpp
index cc1d526..00b484a 100644
--- a/backend/src/backend/gen_program.hpp
+++ b/backend/src/backend/gen_program.hpp
@@ -60,8 +60,8 @@ namespace gbe
   {
   public:
     /*! Create an empty program */
-    GenProgram(uint32_t deviceID, const void* mod = NULL, const void* ctx = NULL, const char* asm_fname = NULL) :
-      deviceID(deviceID),module((void*)mod), llvm_ctx((void*)ctx), asm_file_name(asm_fname) {}
+    GenProgram(uint32_t deviceID, const void* mod = NULL, const void* ctx = NULL, const char* asm_fname = NULL, uint32_t fast_relaxed_math = 0) :
+      Program(fast_relaxed_math), deviceID(deviceID),module((void*)mod), llvm_ctx((void*)ctx), asm_file_name(asm_fname) {}
     /*! Current device ID*/
     uint32_t deviceID;
     /*! Destroy the program */
diff --git a/backend/src/backend/program.cpp b/backend/src/backend/program.cpp
index 14b802a..8b703f3 100644
--- a/backend/src/backend/program.cpp
+++ b/backend/src/backend/program.cpp
@@ -106,7 +106,7 @@ namespace gbe {
     return it->offset; // we found it!
   }
 
-  Program::Program(void) : constantSet(NULL) {}
+  Program::Program(uint32_t fast_relaxed_math) : fast_relaxed_math(fast_relaxed_math), constantSet(NULL) {}
   Program::~Program(void) {
     for (map<std::string, Kernel*>::iterator it = kernels.begin(); it != kernels.end(); ++it)
       GBE_DELETE(it->second);
@@ -126,7 +126,10 @@ namespace gbe {
     if(module){
       cloned_module = llvm::CloneModule((llvm::Module*)module);
     }
-    if (llvmToGen(*unit, fileName, module, optLevel, OCL_STRICT_CONFORMANCE, OCL_PROFILING_LOG) == false) {
+    bool strictMath = true;
+    if (fast_relaxed_math || !OCL_STRICT_CONFORMANCE)
+      strictMath = false;
+    if (llvmToGen(*unit, fileName, module, optLevel, strictMath, OCL_PROFILING_LOG) == false) {
       if (fileName)
         error = std::string(fileName) + " not found";
       delete unit;
@@ -139,10 +142,10 @@ namespace gbe {
       unit = new ir::Unit();
       if(cloned_module){
         //suppose file exists and llvmToGen will not return false.
-        llvmToGen(*unit, fileName, cloned_module, 0, OCL_STRICT_CONFORMANCE, OCL_PROFILING_LOG);
+        llvmToGen(*unit, fileName, cloned_module, 0, strictMath, OCL_PROFILING_LOG);
       }else{
         //suppose file exists and llvmToGen will not return false.
-        llvmToGen(*unit, fileName, module, 0, OCL_STRICT_CONFORMANCE, OCL_PROFILING_LOG);
+        llvmToGen(*unit, fileName, module, 0, strictMath, OCL_PROFILING_LOG);
       }
     }
     assert(unit->getValid());
@@ -161,9 +164,14 @@ namespace gbe {
     const uint32_t kernelNum = set.size();
     if (OCL_OUTPUT_GEN_IR) std::cout << unit;
     if (kernelNum == 0) return true;
+
+    bool strictMath = true;
+    if (fast_relaxed_math || !OCL_STRICT_CONFORMANCE)
+      strictMath = false;
+
     for (const auto &pair : set) {
       const std::string &name = pair.first;
-      Kernel *kernel = this->compileKernel(unit, name, !OCL_STRICT_CONFORMANCE, OCL_PROFILING_LOG);
+      Kernel *kernel = this->compileKernel(unit, name, !strictMath, OCL_PROFILING_LOG);
       if (!kernel) {
         error +=  name;
         error += ":(GBE): error: failed in Gen backend.\n";
@@ -885,7 +893,7 @@ namespace gbe {
 
       p = gbe_program_new_from_llvm(deviceID, NULL, out_module, llvm_ctx,
                                     dumpASMFileName.empty() ? NULL : dumpASMFileName.c_str(),
-                                    stringSize, err, errSize, optLevel);
+                                    stringSize, err, errSize, optLevel, options);
       if (err != NULL)
         *errSize += clangErrSize;
       if (OCL_OUTPUT_BUILD_LOG && options)
diff --git a/backend/src/backend/program.h b/backend/src/backend/program.h
index 51797ee..8684b05 100644
--- a/backend/src/backend/program.h
+++ b/backend/src/backend/program.h
@@ -239,7 +239,8 @@ typedef gbe_program (gbe_program_new_from_llvm_cb)(uint32_t deviceID,
                                                    size_t string_size,
                                                    char *err,
                                                    size_t *err_size,
-                                                   int optLevel);
+                                                   int optLevel,
+                                                   const char* options);
 extern gbe_program_new_from_llvm_cb *gbe_program_new_from_llvm;
 
 /*! link the programs from llvm level. */
diff --git a/backend/src/backend/program.hpp b/backend/src/backend/program.hpp
index 59e4ba1..8cbb012 100644
--- a/backend/src/backend/program.hpp
+++ b/backend/src/backend/program.hpp
@@ -263,7 +263,7 @@ namespace gbe {
   {
   public:
     /*! Create an empty program */
-    Program(void);
+    Program(uint32_t fast_relaxed_math);
     /*! Destroy the program */
     virtual ~Program(void);
     /*! Clean LLVM resource of the program */
@@ -321,6 +321,7 @@ namespace gbe {
     virtual size_t serializeToBin(std::ostream& outs);
     virtual size_t deserializeFromBin(std::istream& ins);
     virtual void printStatus(int indent, std::ostream& outs);
+    uint32_t fast_relaxed_math : 1;
 
   protected:
     /*! Compile a kernel */
diff --git a/src/cl_program.c b/src/cl_program.c
index 77acc13..fb8eea5 100644
--- a/src/cl_program.c
+++ b/src/cl_program.c
@@ -408,7 +408,7 @@ cl_program_create_from_llvm(cl_context ctx,
       goto error;
   }
 
-  program->opaque = compiler_program_new_from_llvm(ctx->device->device_id, file_name, NULL, NULL, NULL, program->build_log_max_sz, program->build_log, &program->build_log_sz, 1);
+  program->opaque = compiler_program_new_from_llvm(ctx->device->device_id, file_name, NULL, NULL, NULL, program->build_log_max_sz, program->build_log, &program->build_log_sz, 1, NULL);
   if (UNLIKELY(program->opaque == NULL)) {
     err = CL_INVALID_PROGRAM;
     goto error;
-- 
1.9.1



More information about the Beignet mailing list