cancel
Showing results for 
Search instead for 
Did you mean: 

Archives Discussions

neko
Adept I

New Omega drivers seem to not work with SPIR 1.2

Hi,

we are using SPIR 1.2 for binary generation mainly as kernel sources obfuscation, which are statically included into our libraries (simple C-like byte arrays). This was working fine until the last update of AMD driver 14.09 into the newset one, omega catalyst driver 14.12.

This issue was also experienced with attached minimalistic examle using the same steps of compilation:

0.) build clang (spir complier) according to this manual: https://github.com/KhronosGroup/SPIR

----- compilation ------

1.) ${CLANG_PATH}/clang -cc1 -x cl -triple spir-unknown-unknown -cl-spir-compile-options "-cl-fast-relaxed-math" -emit-llvm-bc -include ${OPENCL_SPIR_H_PATH}/opencl_spir.h -w -Wno-constant-logical-operand -o ${OUTPUT_PATH}/kernel.binary ${KERNEL_PATH}/kernel.cl, which should generate valid SPIR LLVM IR binary file

2.) convert binary into C-like array, using for example xxd or similiar utility

3.) include this converted binary into source code

---- runtime ----

4.) call clCreateProgramWithBinary(); with included binary and build program using: clBuildProgram(); with "-x spir -spir-std=1.2 -cl-fast-relaxed-math" as compilation flags

5.) use standard way of kernel creation and exectution ...

After execution of this simple example or any other program which uses SPIR under 14.12 catalyst driver all resutling data are pretty much undefined. We tried profiling with CodeXL and various debugging, where was clearly visible that all kernels have no effect at all and results are only dumps of unitialized GPU memory. Classical kernel compilation from sources works fine, tho.

We tested this on both Windows 7 and Ubuntu 14.04 (trusty tahr) with the same results.

To run attached example simply type: ./sample in command line, result should be grayscale RAW image file (out.raw). To switch between run-time compilation from sources and from binaries comment out / leave uncommented line 16: #define BINARY.

0 Likes
1 Solution

Hi Martin,

I agree we should have noticed developers of such changes.

I believe you didn't get any errors from clBuildProgram, because the SPIR binary can still be built, but as it is a 32 bits one the address it is dealing with are incorrect in a 64 bits environment

What I would advise is to ship both the 32 bits and 64 bits SPIR binaries within your application.

Then in your OpenCL code you can check if the device is a 32 bits one or 64 bits one and thus load the correct binary :

   clGetDeviceInfo(...,CL_DEVICE_ADDRESS_BITS,...)

clGetDeviceInfo

Also if you look at SPIR documentation KhronosGroup/SPIR · GitHub, it talks briefly about the difference of 32 and 64 bits binaries

* <triple>: for 32 bit SPIR use spir-unknown-unknown, for 64 bit SPIR use spir64-unknown-unknown.

The above is true for any OpenCL implementation supporting SPIR


View solution in original post

0 Likes
7 Replies
dipak
Big Boss

I've asked someone to check this problem. As I know, he was working on SPIR. Once I get any update, I'll share with you.

Regards,

0 Likes

Hi, could you please as least verify that this is a bug? If not, we'd like to know what should we do to make the SPIR work.

Thanks,

Martin

0 Likes

That's what Dipak is working on - see if it's replicatable.

0 Likes

Hi,

My apologies for this delayed reply. I have been working on SPIR for few weeks. I want to share my findings with you for the attached sample case.

I followed the procedure mentioned in the below github link to create binaries of llvm and clang.

https://github.com/KhronosGroup/SPIR

One of the important thing is installation of proper version of clang. Initially I faced some problems to generate and consume the SPIR code, but latter discovered that it was due wrong version of clang. So, please make sure you've installed the right one. To check the version, you can use the following the command:

=> clang --version

I've attached the output which I got when ran for a compatible clang version. Kindly check it. If you have different version then try to use the right version. The clang source should be from khronosgroup.

Then I generated the SPIR binary with below option.

=> clang -cc1 -emit-llvm-bc -cl-std=CL1.2 -triple spir64-unknown-unknown -include opencl_spir.h MatrixTranspose_Kernels.cl -w

During the consume, I passed following flag in clBuildProgram.

-x spir -spir-std=1.2

The above steps worked fine for me.

I've attached the corresponding cl, llvm file and spir binary. Kindly check whether you get any difference (say, spir_kernel calling convention, kernel argument info metadata in your llvm file) compared to mine .

0 Likes

Hi,

So actually the problem is certainly they have a 64 bits application and were generating a 32 bits SPIR binary.

In their command line we can see -triple spir-unknown-unknown

While to build a 64 bits binary with SPIR we need to use this option

-triple spir64-unknown-unknown.


Our driver behaviour change with this new release and we now generate 64 bits ISA if the application is a 64 bits one.

Therefore a 64 bits application needs a 64 bits SPIR binary to run correctly.

Benjamin


Thanks to all of you for your suggestions. We will try and let you know in this thread.

On the other hand, we would like to avoid situations like this in the future. What happened is that we have released our code to our customers and after new omega driver release, it silently stopped working (OpenCL didn't emit any error code - it just didn't work). Is there anything we can do to assure forward compatibility for future drivers? I am thinking about some AMD's official SPIR guide, which would cover such situations. Is there anything like this?

Thanks,

Martin

0 Likes

Hi Martin,

I agree we should have noticed developers of such changes.

I believe you didn't get any errors from clBuildProgram, because the SPIR binary can still be built, but as it is a 32 bits one the address it is dealing with are incorrect in a 64 bits environment

What I would advise is to ship both the 32 bits and 64 bits SPIR binaries within your application.

Then in your OpenCL code you can check if the device is a 32 bits one or 64 bits one and thus load the correct binary :

   clGetDeviceInfo(...,CL_DEVICE_ADDRESS_BITS,...)

clGetDeviceInfo

Also if you look at SPIR documentation KhronosGroup/SPIR · GitHub, it talks briefly about the difference of 32 and 64 bits binaries

* <triple>: for 32 bit SPIR use spir-unknown-unknown, for 64 bit SPIR use spir64-unknown-unknown.

The above is true for any OpenCL implementation supporting SPIR


0 Likes