< Back to blog

How to set up Intel C-for-media development environment. GPGPU programming on Intel GEN graphics

Evgeny Fedorov
Written byEvgeny Fedorov
Photo by Shahadat Shemul
Photo by Shahadat Shemul on Unsplash

The Intel C-for-Media compiler(CMC) is an open-source compiler that implements C-for-Media (CM) programming language. CM is a new GPU kernel programming language for Intel HD Graphics. CMC is available for Linux and Windows systems. This current article is focused on Linux as it’s the main development platform of the author.

If you are a Windows user installation is pretty easy:

  1. Get Intel C for Media package
  2. Extract package in desired directory <install_dir>
  3. Set environment variable INSTALLDIR = <install_dir>

Linux is where things became interesting as there are some inconsistencies between libraries.

Ok, let's go and run your first GPU kernel program.

Step 1. Set the environment

1.1 Hardware

Any CPU with intel graphic GEN 9 or higher onboard. Kabylake is used for the current article.

1.2 Software

It’s pretty flexible. Only fresh compiler is desirable. Here is what I used:

  • CentOS 7.6
  • CMake 3.12
  • GCC 8.2
  • git 1.8
  • make 3.82
  • Python 3.5

Step 2. Build and install CMC toolchain

To develop GPU kernels using CMC we need the following packages:

  • The Intel(R) C-for-Media compiler — Clang-based open-source compiler for creating GPU kernels.
  • Libva — an implementation for open-source Video Acceleration API (VA-API), which provides access to graphics hardware acceleration capabilities for video processing.
  • Intel(R) Media Driver for VA-API — user-mode driver.
  • Intel Graphics Compiler for OpenCL™ — an LLVM based compiler for OpenCL™.

Let's proceed through all the steps:

2.1 Build and install libva

There is a simple way to build this component using the cmake build system.

git clone https://github.com/intel/libva.git libva
cd libva
./autogen.sh --with-drivers-path=/opt/intel/mediasdk/lib64/ --prefix=/usr --libdir=/usr/lib64
make -j8
sudo make install
cd ..

2.2 Build and install Intel(R) Media Driver for VA-API

Media driver also can be built using cmake.

git clone https://github.com/intel/media-driver.git media-driver
git clone https://github.com/intel/gmmlib.gitmkdir build && cd build
cmake ../media-driver
cmake --build  . -j `nproc`

After these steps, driver and CM runtime are installed in the system:

  • User mode driver: /opt/intel/mediasdk/lib64
  • Runtime libraries: /usr/local/lib64
  • Runtime headers: /usr/local/include/igfxcmrt

2.3 Build and install Intel(R) C-for-Media compiler

Build compiler where “-i” param specifies output directory. Lets call it <cmc_install_dir>, it will be needed later.

git clone https://github.com/intel/cm-compiler.git cm-compiler
cd cm-compiler
support/scripts/build.bash -d -c -p /usr/local/bin -i `pwd`/../bin

Copy “test” directory which contains examples into <cmc_install_dir>:

cp test ../bin -r
cd ../bin

Edit examples makefile:

  • Add path to CMC runtime headers from first step to “INCL” set.
  • Update path to runtime library (igfxcmrt.so) in compilation command.
  • Change path to compilers headers in HW_CMCFLAGS to <cmc_install_dir>/include.
  • Add path to cmc compiler binary.

This can be achieved by using the following command:

sed -i 's/-I$(CM_ROOT)\/runtime\/include/-I\/usr\/local\/include\/igfxcmrt\ -I\/usr\/include\/libdrm/' test/open_examples/Makefile.linux
sed -i "s@^CMC :=@CMC := `pwd`\/bin\/cmc\ #@" test/open_examples/Makefile.linux
sed -i "s@\$(CM_ROOT)/runtime/lib/x64/igfxcmrt64.so@/usr/local/lib64/libigfxcmrt.so@" test/open_examples/Makefile.linux

2.4 Build Intel Graphics Compiler for OpenCL™

Clone compiler and build it according to instructions.

git clone https://github.com/intel/intel-graphics-compiler.git igc
git clone -b release_80 https://github.com/llvm-mirror/llvm llvm_source
git clone -b release_80 https://github.com/llvm-mirror/clang llvm_source/tools/clang
git clone -b ocl-open-80 https://github.com/intel/opencl-clang llvm_source/projects/opencl-clang
git clone -b llvm_release_80 https://github.com/KhronosGroup/SPIRV-LLVM-Translator llvm_source/projects/llvm-spirv
git clone https://github.com/intel/llvm-patches llvm_patchesmkdir build_igc
cd build_igc
cmake ../igc/IGC
cmake --build . -j `nproc`

Only Genx_IR tool is required from this package so just copy it to <cmc_install_dir>/bin

cp Release/Tools/GenX_IR ../bin/bin/

2.5 Installation notes

There are two ways to load and execute GPU kernel programs: with Just-in-time compilation and without.

  • JIT way. In this way step 2.4 is not needed but you will need jitter library which is provided with CM runtime from github. NOTE: library provided as binary file built by gcc-4.8.2, so if you want to use it you should build all environment and your code by this compiler.
  • “Nojitter” way. In this case, you don’t need jitter library, but you should specify target architecture and add “nojitter” string as the last argument to LoadProgram call in an example code.

I prefer the nojitter way, and this article will only focus on that method.

Step 3. Run samples

3.1 Modify samples to work in “nojitter” mode

Edit example makefile from step 2.3.

Create variable GEN_MODE and set it to the target platform. I set KBL as using KabyLake based graphics.

1. Add following flags to HW_CMCFLAGS to specify the target platform:

  • Qxcm_jit_target=$(GEN_MODE)
  • Qxcm_vme_arch=$(GEN_MODE)

2. Add some other useful flags:

  • Qxcm ( not necessary, it is enabled by default as described by intel, but I recommend adding it)
  • Qxcm_opt_report (errors reporting)
  • Qxcm_print_asm_count (to output count of assembly instructions)

3. Update paths to CMC and runtime library.

Example script to do these steps:

sed -i "s@-march=\$(GEN_MODE)@-isystem `pwd`/include -Qxcm_jit_target=\$(GEN_MODE) -Qxcm_opt_report -Qxcm_print_asm_count -Qxcm_vme_arch=\$(GEN_MODE) -Qxcm #@" test/open_examples/Makefile.linux

3.2 Build and run sample

Now, let's run any sample, E.g. histogram_64

For this change LoadProgram call to “nojitter”, then build and run example:

cd ../bin/test/open_examples/histogram_64
sed -i "s@program));@ssprogram,\"nojitter\"));@" histogram.cpp
make -f ../Makefile.linux

That is it! Now you are ready to create your own GPU kernels to run them on Intel graphics. In the next article, we will create one.