
{"id":1369,"date":"2025-10-17T15:22:06","date_gmt":"2025-10-17T12:22:06","guid":{"rendered":"https:\/\/paragroup.cse.uoi.gr\/wpsite\/?page_id=1369"},"modified":"2025-12-15T16:16:22","modified_gmt":"2025-12-15T14:16:22","slug":"ompi-offloading-to-opencl-gpus","status":"publish","type":"page","link":"https:\/\/paragroup.cse.uoi.gr\/wpsite\/software\/ompi\/documentation\/ompi-offloading-to-opencl-gpus\/","title":{"rendered":"OMPi: Offloading to OpenCL GPUs"},"content":{"rendered":"<h2>Introduction<\/h2>\n<p>The latest version of OMPi extends GPU support by adding the ability to offload computations to any GPU through <a href=\"https:\/\/www.khronos.org\/opencl\/\" target=\"_blank\">OpenCL<\/a>. OMPi analyzes the OpenMP target directives appearing in a user application and generates kernel source files written in the OpenCL C language; these are then compiled into OpenCL kernels, and get linked\u00a0with an OpenCL library that offers OpenMP facilities during kernel execution. OpenCL support is provided by the new OMPi\u00a0<code>opencl<\/code> module.<\/p>\n<h2>Requirements<\/h2>\n<p>The requirements for the <code>opencl<\/code>\u00a0module to be activated are the following:<\/p>\n<ul>\n<li>The standard OpenCL header and development packages must be installed (usually named <code>opencl-headers, opencl-dev or ocl-icd-devel<\/code>)<\/li>\n<li>A\u00a0GPU that supports OpenCL version \u2265 1.2; you can always double-check this by running the\u00a0<code>clinfo<\/code> utility, if it is installed on your system.<\/li>\n<li>The corresponding vendor drivers and\/or relevant libraries must be installed (we cannot provide help on how to install them as this differs from vendor to vendor;\u00a0 Intel\u00a0drivers most probably can be found in the <code>intel-neo<\/code> repository; for AMD you need the <code>amdgpu<\/code>\u00a0and\/or <code>ROCm<\/code> drivers;\u00a0 NVIDIA includes the OpenCL drivers\/libraries in their CUDA SDK).<\/li>\n<\/ul>\n<h2>Installing OMPi with OpenCL support<\/h2>\n<p>You do not need any special preparations; simply deploy OMPi on your system as usual:<\/p>\n<pre>meson setup build --prefix=&lt;install-dir&gt;\r\ncd build\/\r\nmeson compile\r\nmeson install<\/pre>\n<p>If all the requirements listed above are met, the installation process will automatically detect the GPU(s) and build the <code>opencl<\/code>\u00a0module; if something is missing, the module won&#8217;t be included. You can verify the correct installation of the <code>opencl<\/code> module by executing:<\/p>\n<pre>ompiconf --devvinfo<\/pre>\n<p>which lists all the identified modules\/devices, along with their <em>numeric device IDs<\/em>. If the above command fails to show an OpenCL-capable GPU, double check that all requirements are met and ensure you have installed OMPi correctly.<\/p>\n<div class=\"su-spoiler su-spoiler-style-default su-spoiler-icon-plus su-spoiler-closed\" data-anchor=\"devinfo-example\" data-scroll-offset=\"0\" data-anchor-in-url=\"no\"><div class=\"su-spoiler-title\" tabindex=\"0\" role=\"button\"><span class=\"su-spoiler-icon\"><\/span>Sample output of devvinfo<\/div><div class=\"su-spoiler-content su-u-clearfix su-u-trim\">\n<p>The <code>ompiconf --devvinfo<\/code> command (or \u00a0<code>ompiconf --devvinfo=opencl<\/code>) should give an output similar to the following (here an integrated Intel UHD770 GPU was detected by OMPi):<\/p>\n<pre>MODULE [opencl]: \r\n------ \r\nOMPi module for OpenCL devices \r\nAvailable devices : 1 \r\n \r\ndevice id &lt; 0 &gt; { \u00a0\r\n \u00a0GPU device name \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0: Intel(R) UHD Graphics 770 \r\n \u00a0GPU device vendor \u00a0\u00a0\u00a0\u00a0\u00a0: Intel(R) Corporation \r\n \u00a0Vendor device driver \u00a0\u00a0: 24.22.29735.20 \r\n \u00a0OpenCL ver. (platform) : 3.0 \r\n \u00a0OpenCL ver. (device) \u00a0\u00a0: 3.0 \r\n \u00a0OpenCL ver. (compiler) : 1.0, 1.1, 1.2, 3.0 \r\n \u00a0Num of compute units \u00a0\u00a0: 32 \r\n \u00a0Max workgroup size \u00a0\u00a0\u00a0\u00a0: 512 \r\n \u00a0Local memory \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0: 64 KBytes \r\n \u00a0Global memory \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0: 13.9 GBytes \r\n \u00a0Coarse grain SVM \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0: yes \r\n \u00a0Fine grain buffer SVM \u00a0: no \r\n \u00a0Fine grain system SVM \u00a0: no \r\n \u00a0Unified host memory \u00a0\u00a0\u00a0: yes \r\n \u00a0Supports \"double\" type : no \r\n \r\n \u00a0Intel GPU details: \r\n \u00a0\u00a0\u00a0| 1 slice(s) \r\n \u00a0\u00a0\u00a0| 2 subslice(s) per slice (max) \r\n \u00a0\u00a0\u00a0| 16 EUs per subslice (max) \r\n \u00a0\u00a0\u00a0| 7 threads per EU (max) \r\n} \r\n------\r\n<\/div><\/div><\/pre>\n<h2>Quick start<\/h2>\n<p>To offload to a GPU through OpenCL, you need to compile your applications with a\u00a0<code>--devs=opencl<\/code>\u00a0argument:<\/p>\n<pre>ompicc --devs=opencl app.c<\/pre>\n<div class=\"su-spoiler su-spoiler-style-default su-spoiler-icon-plus su-spoiler-closed\" data-anchor=\"devs-usage\" data-scroll-offset=\"0\" data-anchor-in-url=\"no\"><div class=\"su-spoiler-title\" tabindex=\"0\" role=\"button\"><span class=\"su-spoiler-icon\"><\/span>Note<\/div><div class=\"su-spoiler-content su-u-clearfix su-u-trim\">\n<p>If you use the <code>--devs=opencl<\/code>\u00a0compilation option, the numeric device IDs are those printed by\u00a0<code>ompiconf --devinfo=opencl<\/code>\u00a0. For example, in our system we get:\u00a0<\/p>\n<p><code>MODULE [opencl] provides device(s) : 0 1<\/code><\/p>\n<p>You\u00a0may\u00a0instead compile using the\u00a0<code>--devs=all<\/code>\u00a0option to produce kernels that may run on any GPU target, <em>including<\/em> OpenCL.\u00a0Be careful that in this case the numeric device IDs may be different depending on what other modules\u00a0are active. In the case you use\u00a0<code>--devs=all<\/code>, the\u00a0correct device IDs can be found by exectuting\u00a0<code>ompiconf --devinfo<\/code>. In our system it reported:<\/p>\n<p><code>MODULE [cuda] provides device(s) : 0<\/code><br \/>\n <code> MODULE [opencl] provides device(s) : 1 2<\/code><\/p>\n<p>Thus the numeric IDs of the two OpenCL-capable GPUs are now 1 and 2.<\/p>\n<\/div><\/div>\n<p>The compiler will produce the main application executable (<code>a.out<\/code>) and a number of OpenCL kernel files, one for each\u00a0<code>target<\/code> construct in the\u00a0OpenMP application.<\/p>\n<div class=\"su-spoiler su-spoiler-style-default su-spoiler-icon-plus su-spoiler-closed\" data-anchor=\"sample-app\" data-scroll-offset=\"0\" data-anchor-in-url=\"no\"><div class=\"su-spoiler-title\" tabindex=\"0\" role=\"button\"><span class=\"su-spoiler-icon\"><\/span>Sample OpenMP application utilizing the GPU<\/div><div class=\"su-spoiler-content su-u-clearfix su-u-trim\">\n<p>Here is a sample application that can be used to verify the\u00a0successful deployment of the <code>opencl<\/code>\u00a0module:<\/p>\n<pre><strong>#include<\/strong> &lt;stdio.h&gt;\r\n<strong>#include<\/strong> &lt;omp.h&gt;\r\n\r\n<strong>int<\/strong> main(<strong>void<\/strong>)\r\n{\r\n    \/* \r\n     * Expected result (assuming that the GPU device ID is 0):\r\n     * Running on OpenCL device \r\n     *\/\r\n    <strong>int<\/strong> x;\r\n<strong><span class=\"cp\">    #pragma omp target map(tofrom:x) device(0)<\/span><\/strong>\r\n    <span class=\"p\">{<\/span>\r\n        <span class=\"k\">x = <\/span><span class=\"n\">omp_is_initial_device<\/span><span class=\"p\">();<\/span>\r\n    <span class=\"p\">}\r\n\r\n<\/span><strong><span class=\"k\">    if<\/span> <\/strong><span class=\"p\">(<\/span><span class=\"n\">x<\/span><span class=\"p\">)<\/span> \r\n        <span class=\"n\">printf<\/span><span class=\"p\">(<\/span><span class=\"s\">\"Running on host<\/span><span class=\"se\">\\n<\/span><span class=\"s\">\"<\/span><span class=\"p\">);<\/span>    \r\n<strong><span class=\"k\">    else<\/span> <\/strong>\r\n        <span class=\"n\">printf<\/span><span class=\"p\">(<\/span><span class=\"s\">\"Running on an OpenCL device\\n\");\r\n<\/span><span class=\"p\"><strong>    \r\n    return<\/strong> 0; \r\n} <\/span><\/pre>\n<\/div><\/div>\n<div class=\"su-spoiler su-spoiler-style-default su-spoiler-icon-plus su-spoiler-closed\" data-anchor=\"multiple-jobs\" data-scroll-offset=\"0\" data-anchor-in-url=\"no\"><div class=\"su-spoiler-title\" tabindex=\"0\" role=\"button\"><span class=\"su-spoiler-icon\"><\/span>Advanced usage: Speeding up compilation<\/div><div class=\"su-spoiler-content su-u-clearfix su-u-trim\">\n<p>When an\u00a0application contains several <code>target<\/code> regions, compilation times may become substantial. One can generate multiple compilation jobs that handle the compilation of different kernels in parallel, by using the\u00a0<code>-j&lt;number&gt;<\/code> device option. For example to have 4 parallel kernel compilation jobs, use <code>ompicc<\/code> as follows:<\/p>\n<pre>ompicc --devs=all <strong>--devopt -j4<\/strong> app.c<\/pre>\n<\/div><\/div>\n<h2>Limitations<\/h2>\n<p>Currently, the <code>opencl<\/code>\u00a0module has a number of limitations:<\/p>\n<ol>\n<li>Only the datatypes supported by OpenCL C can be used; some GPUs may lack\u00a0<code>double<\/code>\u00a0support.<\/li>\n<li>Only static loop scheduling is supported in <code>target teams distribute parallel for<\/code> directives,<\/li>\n<li>Stand-alone <code>parallel<\/code>\u00a0constructs are not handled yet; the <code>parallel<\/code>\u00a0construct must be part of a combined \u00a0<code>target<\/code>,\u00a0<code>teams<\/code>\u00a0and\/or\u00a0<code>distribute<\/code>\u00a0construct.<\/li>\n<li>OpenCL\u00a0\u2265 1.2 is required; in addition the\u00a0OpenCL C driver\/compiler must allow <code>__global<\/code> declarations at\u00a0file scope; while this requirement\u00a0is not part of the OpenCL 1.2 standard (it is even optional in OpenCL 2.0), all major vendors support it.<\/li>\n<\/ol>\n<h2>Notes<\/h2>\n<p>The OMPi <code>opencl<\/code>\u00a0module has been tested with the following GPUs:<\/p>\n<ul>\n<li>Integrated Intel GPUs (UHD 770, Iris Xe)<\/li>\n<li>AMD Radeon GPUs (R9 285, RX 550)<\/li>\n<li>NVIDIA GPUs (GeForce GT730, Tesla P40, Ampere A2)<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Introduction The latest version of OMPi extends GPU support by adding the ability to offload computations to any GPU through OpenCL. OMPi analyzes the OpenMP target directives appearing in a user application and generates kernel source files written in the OpenCL C language; these are then compiled into OpenCL kernels, and get linked\u00a0with an OpenCL [&hellip;]<\/p>\n","protected":false},"author":4,"featured_media":0,"parent":120,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-1369","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/paragroup.cse.uoi.gr\/wpsite\/wp-json\/wp\/v2\/pages\/1369","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/paragroup.cse.uoi.gr\/wpsite\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/paragroup.cse.uoi.gr\/wpsite\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/paragroup.cse.uoi.gr\/wpsite\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/paragroup.cse.uoi.gr\/wpsite\/wp-json\/wp\/v2\/comments?post=1369"}],"version-history":[{"count":17,"href":"https:\/\/paragroup.cse.uoi.gr\/wpsite\/wp-json\/wp\/v2\/pages\/1369\/revisions"}],"predecessor-version":[{"id":1428,"href":"https:\/\/paragroup.cse.uoi.gr\/wpsite\/wp-json\/wp\/v2\/pages\/1369\/revisions\/1428"}],"up":[{"embeddable":true,"href":"https:\/\/paragroup.cse.uoi.gr\/wpsite\/wp-json\/wp\/v2\/pages\/120"}],"wp:attachment":[{"href":"https:\/\/paragroup.cse.uoi.gr\/wpsite\/wp-json\/wp\/v2\/media?parent=1369"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}