How to set up Intel C-for-media development environment. GPGPU programming on Intel GEN graphics
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:
- Get Intel C for Media package
- Extract package in desired directory <install_dir>
- 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
Any CPU with intel graphic GEN 9 or higher onboard. Kabylake is used for the current article.
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:
- Runtime libraries:
- Runtime headers:
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
LoadProgramcall 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.
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:
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.
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 ./hw_x64.histogram_64
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.