OpenCL kernel in Fortran

OpenCL kernel in Fortran

Hi Steve,

Intel has recently released Intel SDK for OpenCL Applications 2014 with preview support for SPIR 1.2 code generation and consumption. 
My question is simple, are there any talks about writing OpenCL kernels in Fortran or should I stop holding my breath? 
The academic world would love it.

Nick

 

Nick
20 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Check out FortranCL. I've gotten this to work with Intel Visual Fortran and the Intel OpenCL SDK. I started to write a paper on it but had to put it aside for other things. I assume you didn't really mean write the kernel in Fortran - the whole idea is that the kernel is in OpenCL. But you can certainly load and run OpenCL kernels from Fortran, passing data back and forth. There are examples in the FortranCL package.

Steve - Intel Developer Support

Here's some basic instructions and a pre-built FortranCL library. Note that this is x64 only.

To use the pre-built library, create a Fortran console application using one of the example files and set the following project properties:

  • Fortran > Language > Enable Fortran 2003 Semantics
  • Fortran > General > Additional Include Directories > directory where you unpacked FortranCL-x64.zip
  • Linker > General > Additional Library Directories > the Lib\X64 directory of the Intel SDK for OpenCL installation
  • Linker > Input > Additional Dependencies > opencl.lib
  • Add FortranCL.lib from the unpacked ZIP to the project as a source file

You will need to use Build > Configuration Manager to create a new x64 platform configuration.

Now you can build and run your OpenCL program. If you use the Sum example, make sure that sum.cl is in the project folder.

Attachments: 

AttachmentSize
Download FortranCL-x64_0.zip217.71 KB
Steve - Intel Developer Support

Many thanks for the links.
I was actually thinking about kernels in Fortran, excerpt from the SPIR FAQ:

What set of problems is SPIR supposed to solve?

Enable third-party code generation targeting OpenCL platforms without going through OpenCL C:

    For example, a compiler for an alternative device language (not OpenCL C) can generate SPIR and have it run on any OpenCL backend that supports the cl_khr_spir extension. There is no need to generate OpenCL C as an intermediate. The alternative language could be many things, such as an established language (like FORTRAN), an exotic domain specific language, or a single source programming environment with automatic code partitioning. However, the language semantics must be mappable to SPIR and satisfy the constraints of OpenCL target systems.

As I understand it that would require replacing, in the SPIR Reference Flow, the OpenCL C to SPIR IR generator by an OpenCL Fortran (?) to SPIR one. That sounds challenging but not totally infeasible knowing that OpenACC to SPIR is on its way.

It's quite possible that I'm missing the big picture here so please feel free to correct whatever I'm not catching.

 

 

Nick

I had not heard of SPIR before - this appears to be some sort of intermediary between the programmer and OpenCL - I am somewhat baffled as to what problem it is trying to solve. I have never heard the term "OpenCL C" before, but I admit I am not an expert on OpenCL.

OpenCL is executed natively by graphics processors and coprocessors - it is supported by Intel HD Graphics in recent Intel processors and by Intel Xeon Phi, as well as in graphics processors and accelerators from NVidia and AMD. Typically one writes the computational kernel in the OpenCL language and use calls from the "native" language (C, Fortran, etc.) to "compile" the kernel and then send the kernel and the data to the coprocessor, which executes it and sends the data back.

It looks to me as if SPIR is providing the ability to "precompile" OpenCL code so that you don't have to expose it to whoever uses your application (often OpenCL kernels are read from source files, though there's no requirement to do so.)

Maybe I'm missing something, but SPIR seems to make OpenCL more complicated than it needs to be. If your desire is to harness the computational resources of graphics processors in a manufacturer-independent fashion, OpenCL is one way to do that. (OpenMP 4.0 is another way.) As I noted, you can use OpenCL from Fortran.

My advice to you is to ignore SPIR and just use OpenCL directly.

Steve - Intel Developer Support

Steve,

SPIR is an LLVM-based intermediate representation which has a number of goals. One of them, which you correctly point out, is to allow developers to ship their OpenCL programs in a portable binary format (LLVM bitcode), instead of shipping their OpenCL C source code with their applications (and yes, "OpenCL C" is the term for the C99-based language defined by the OpenCL standard for writing device programs).

Another goal, which in my opinion is far more interesting, is having the ability to target SPIR from languages *other* than OpenCL C. This isn't something that developers would use directly, but rather something that would be generated by compiler backends. We are already seeing some high-level programming models starting to target SPIR in order to produce applications that can utilise OpenCL devices, such as C++ AMP, Halide, and the recently announced SYCL standard. This is exactly what Nick is asking about in his original question - will we see a Fortran->SPIR compiler that allows one to write OpenCL kernels in Fortran?  

 

Nick,

Fortran is a very popular language, and so I wouldn't be at all surprised if we see one or more efforts to produce a compiler for writing OpenCL kernels using Fortran, built on top of SPIR. Indeed, we already have CUDA FORTRAN, which is essentially the same thing for NVIDIA devices (and is probably implemented on top of PTX, which sits at a similar level in the software stack to SPIR). The OpenACC work is one step in this direction, and probably has a lot of overlap with such an effort. SPIR has only recently been ratified (this January), so it might be a little while before we see anything like this in the wild, but there's definitely a lot of interest in this area and lots of support from some of the key vendors (especially Intel, despite Steve's comments above).

James

James,

Thanks for the background. I didn't get all of that from the SPIR web pages. I can see the usefulness of the idea of compiling to SPIR. It's not something we'll be looking at for a while, but I'll make sure it's on our list of ideas.

Steve - Intel Developer Support

I am sorry to revive this old topic, but how did you build the FortranCL library, Steve?, I would like to have a 32-bit version and I was trying to compile it without success using VS2013 w/ Intel Parallel Studio 2015. Thanks for your help!

I did not try to build a 32-bit version. I'm out of the office this week but my recollection is that the Intel OpenCL library I used was 64-bit only.

Steve - Intel Developer Support

well, I was able to run the examples given in the fortrancl page. I downloaded the source code to try to compile it in 32-bits when I have some time...

I am working in a code written in Fortran and up to this moment I was using Fortran-C interop capabilities to use OpenCL... the bad thing is that I ended with a lot of custom structs to contain the common variables used in the Fortran code (it is quite old code), I think that this approach would be beneficial for my purposes...

by the way, I found this web page http://www.cass-hpc.com/solutions/libraries/clfortran-pure-fortran-inter... . The problem is that in order to obtain a copy of the code one have to request it by e-mail, anyone have experience with it?... I already requested it in order to test it...

by the way. Steve, how did you compiled FortranCL under windows?. I tried to compile it using VS2013 and Intel Visual Fortran 15.0 without success. I compiled in x64, one proyect for the c files and another for the Fortran ones, they create the *.mod and *.lib files, but then when I tried to use them in one of the examples of FortranCL the program throws linking errors (the typical symbol was not found)

Thanks for your help!

I did it like any other mixed-language application. You do need to either make the C project(s) a dependent of the main program or explicitly add the paths to the libraries. Nothing special here, though I had to also add the path to the OpenCL library.

Steve - Intel Developer Support

Thanks Steve, finally I was able to compile FortranCL in both x86 and x64 (any advantage of using x64 instead of x86?). I attached my project with two examples (sum and device Fortran Projects). Some remarks:

  • The FortranCL source files are compiled in two projects: FortranCL_CLIBS (for *.c) and FortranCL (for *.f90). These are configured as "Static Library" projects (no *.exe target). FortranCL depends on FortranCL_CLIBS (defined in "Project Dependencies" option under VS2013) and also the option "Link Library Dependencies" under Properties/Librarian is enabled (to include the C libs under FortranCL.lib file, if I am not wrong)
  • Then any of the examples (sum and devices projects) are made dependent on FortranCL project with the "Project Dependencies" option
  • I changed the statement #include <config.h> to #include "config.h" and #include <string_f.h> to #include "string_f.h" and added the headers in the C project to ease the configuration.
  • Finally, the OpenCL relevant folders are included just in the FortranCL_CLIBS project (under C/C++ and Librarian in Project's Properties).

Well, as I am not an expert programmer I would appreciate any suggestion / complain to my configuration, hehehe. By the way, I received a copy of CLFORTRAN, the OpenCL Fortran functions look just like the C API ones, but unfortunately I have not been able to execute a kernel with it (the examples are about writing/reading buffers, platform configuration, etc, but no kernel execution). I have asked support to the provider without answer, so it is seems that for the moment I will stick with the FortranCL project.

Attachments: 

AttachmentSize
Download FortranCL_VS2013_x86.rar1.18 MB

I picked x64 because it was simpler with Intel's OpenCL toolkit and there's little point nowadays in targeting IA-32 for such things. The configuration you used is very similar to mine.

Steve - Intel Developer Support

My apologies for bumping this thread again and for spamming:

- The new SPIR-V specs are out (this new version is not tied to LLVM and self contained). 
- Vulkan and SPIR-V session.
- A nice article about SPIR-V ecosystem here.
- GLSL to SPIR-V.
- The first public SPIR-V binary reader and writer (it seems easy enough to adapt in Fortran). 
SPIR-V and GCC?

Interesting times. The "only" thing missing is a Fortran to SPIR-V translator...

Nick

 

 

 

 

Nick

Dear Steve,

My name is Ljubomir and I'm practically beginner in GPU programing. However, I'm writing a numerous CFD codes in Fortran, so, the next logical step for me is utilization of the GPU computing. Currently I'm trying to compile source files that you posted for FortranCL, and I stumble on a problem. The problem that I have is compiling the .c files under the Visual Studio 2010. When I try to compile for example utils.c file, following set of errors in output appear:

1>------ Build started: Project: PROBA C, Configuration: Debug Win32 ------

1> cl_buffer_low.c

1>d:\programi u fortranu\lbbgk-vs2010\fortran cl\proba c\source\cl_buffer_low.c(26): error C2091: function returns function

1>d:\programi u fortranu\lbbgk-vs2010\fortran cl\proba c\source\cl_buffer_low.c(30): error C2065: 'buffer' : undeclared identifier

1>d:\programi u fortranu\lbbgk-vs2010\fortran cl\proba c\source\cl_buffer_low.c(30): error C2100: illegal indirection

1>d:\programi u fortranu\lbbgk-vs2010\fortran cl\proba c\source\cl_buffer_low.c(30): error C2065: 'context' : undeclared identifier

1>d:\programi u fortranu\lbbgk-vs2010\fortran cl\proba c\source\cl_buffer_low.c(30): error C2100: illegal indirection

1>d:\programi u fortranu\lbbgk-vs2010\fortran cl\proba c\source\cl_buffer_low.c(30): warning C4047: 'function' : 'cl_context' differs in levels of indirection from 'int'

1>d:\programi u fortranu\lbbgk-vs2010\fortran cl\proba c\source\cl_buffer_low.c(30): warning C4024: 'clCreateBuffer' : different types for formal and actual parameter 1

1>d:\programi u fortranu\lbbgk-vs2010\fortran cl\proba c\source\cl_buffer_low.c(30): error C2065: 'flags' : undeclared identifier

1>d:\programi u fortranu\lbbgk-vs2010\fortran cl\proba c\source\cl_buffer_low.c(30): error C2100: illegal indirection

1>d:\programi u fortranu\lbbgk-vs2010\fortran cl\proba c\source\cl_buffer_low.c(30): error C2065: 'size' : undeclared identifier

1>d:\programi u fortranu\lbbgk-vs2010\fortran cl\proba c\source\cl_buffer_low.c(30): error C2100: illegal indirection

1>d:\programi u fortranu\lbbgk-vs2010\fortran cl\proba c\source\cl_buffer_low.c(30): warning C4047: '=' : 'int' differs in levels of indirection from 'cl_mem'

1>d:\programi u fortranu\lbbgk-vs2010\fortran cl\proba c\source\cl_buffer_low.c(31): error C2065: 'errcode_ret' : undeclared identifier

1>d:\programi u fortranu\lbbgk-vs2010\fortran cl\proba c\source\cl_buffer_low.c(31): error C2100: illegal indirection

1>d:\programi u fortranu\lbbgk-vs2010\fortran cl\proba c\source\cl_buffer_low.c(36): error C2091: function returns function

1>d:\programi u fortranu\lbbgk-vs2010\fortran cl\proba c\source\cl_buffer_low.c(36): error C2084: function 'void (__cdecl *FC_FUNC_())(cl_context *,const int *,const cl_long *,int *,cl_mem *)' already has a body

1> d:\programi u fortranu\lbbgk-vs2010\fortran cl\proba c\source\cl_buffer_low.c(25) : see previous definition of 'FC_FUNC_'

1>d:\programi u fortranu\lbbgk-vs2010\fortran cl\proba c\source\cl_buffer_low.c(38): error C2065: 'status' : undeclared identifier

1>d:\programi u fortranu\lbbgk-vs2010\fortran cl\proba c\source\cl_buffer_low.c(38): error C2100: illegal indirection

1>d:\programi u fortranu\lbbgk-vs2010\fortran cl\proba c\source\cl_buffer_low.c(38): error C2065: 'memobj' : undeclared identifier

1>d:\programi u fortranu\lbbgk-vs2010\fortran cl\proba c\source\cl_buffer_low.c(38): error C2100: illegal indirection

1>d:\programi u fortranu\lbbgk-vs2010\fortran cl\proba c\source\cl_buffer_low.c(38): warning C4047: 'function' : 'cl_mem' differs in levels of indirection from 'int'

1>d:\programi u fortranu\lbbgk-vs2010\fortran cl\proba c\source\cl_buffer_low.c(38): warning C4024: 'clReleaseMemObject' : different types for formal and actual parameter 1

1>d:\programi u fortranu\lbbgk-vs2010\fortran cl\proba c\source\cl_buffer_low.c(43): error C2091: function returns function

1>d:\programi u fortranu\lbbgk-vs2010\fortran cl\proba c\source\cl_buffer_low.c(45): error C2065: 'status' : undeclared identifier

1>d:\programi u fortranu\lbbgk-vs2010\fortran cl\proba c\source\cl_buffer_low.c(45): error C2100: illegal indirection

1>d:\programi u fortranu\lbbgk-vs2010\fortran cl\proba c\source\cl_buffer_low.c(45): error C2065: 'memobj' : undeclared identifier

1>d:\programi u fortranu\lbbgk-vs2010\fortran cl\proba c\source\cl_buffer_low.c(45): error C2100: illegal indirection

1>d:\programi u fortranu\lbbgk-vs2010\fortran cl\proba c\source\cl_buffer_low.c(45): warning C4047: 'function' : 'cl_mem' differs in levels of indirection from 'int'

1>d:\programi u fortranu\lbbgk-vs2010\fortran cl\proba c\source\cl_buffer_low.c(45): warning C4024: 'clRetainMemObject' : different types for formal and actual parameter 1

========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

 

In my opinion this is a Compiler issue. Please help.

Thank you in advance,

Ljubomir  

 

You're not compiling anything I posted. I provided a prebuilt library and no C code. You may have gotten that from the FortranCL project page. You're also using the Microsoft Visual C++ compiler so I'm not sure what I can do for you. It did build when I did it. Maybe you haven't set up your project environment correctly.

Steve - Intel Developer Support

Dear Steve,

Thank you for your answer. The thing is that I'm using a NVidia graphic card, while the prebuilt library that you posted is related to the Intel OpenCL SDK. Regarding to that, I have successfully compiled the pre-built FortranCL library (that you posted) on my laptop with Intel graphics, but I'm struggling with the machine whit the NVidia graphic card. For that reason I have downloaded FortranCL source files, and then using the mixed language settings in Visual Studio 2010 I try to compile and build the library for the NVidia card. I have setup project in VS2010 for mixed-language (similar as the Edgardo Doerner from the post Wed, 03/04/2015 - 12:09), but when I try to compile and build,  previously posted error appear. For Fortran and C compiler I'm using Intel Composer XE 2011. Can you please advice what I'm doing wrong, and also what should I do in order to form a prebuilt library for the NVidia. Also, I apologise if I was incomprehensible when I said that I wont to compile source files that you posted for FortranCL. I was referring to your post from Fri, 05/23/2014 - 08:14, where you pointed out that the FortranCL source files are available, and not to the prebuilt library. Thank you in advance.

Sincerely,

Ljubomir     

The library I built works fine with an NVidia card even when built using the Intel SDK - my desktop system has one. I can't help you with compiling with someone else's OpenCL SDK, though.

Your problem is in building C source. It doesn't have anything to do directly with Intel Fortran. You are using the Microsoft C compiler judging from the error messages. Even though you have Intel C++, you have to set the project property to "Use Intel C++". I suspect that is not the problem here, though.

You are welcome to ask for help in the Intel C++ forum if you select Intel C++ for the project. I am not a C expert so can't tell from the messages what they are trying to tell you.

Steve - Intel Developer Support

Steve,

Thank you very much for your help and support. Your comments was very helpful.

Sincerely,

Ljubomir

Leave a Comment

Please sign in to add a comment. Not a member? Join today