
{"id":1350,"date":"2025-09-25T14:43:05","date_gmt":"2025-09-25T11:43:05","guid":{"rendered":"https:\/\/paragroup.cse.uoi.gr\/wpsite\/?page_id=1350"},"modified":"2025-12-15T16:19:45","modified_gmt":"2025-12-15T14:19:45","slug":"ompi-offloading-to-vulkan-gpus","status":"publish","type":"page","link":"https:\/\/paragroup.cse.uoi.gr\/wpsite\/software\/ompi\/documentation\/ompi-offloading-to-vulkan-gpus\/","title":{"rendered":"OMPi: Offloading to Vulkan GPUs"},"content":{"rendered":"<h2>Introduction<\/h2>\n<p>The latest version of OMPi enables offloading to Vulkan-supported GPUs through the <code>vulkan<\/code> module. OMPi analyzes the OpenMP target directives appearing in a user application and generates kernel source files, written in\u00a0shader language (GLSL).<\/p>\n<p>The <code>vulkan<\/code> module can:<\/p>\n<ol>\n<li>Compile the shader files to SPIR-V binaries,<\/li>\n<li>Optimize the generated binaries in terms of size and performance,<\/li>\n<li>Initialize and finalize a Vulkan device,<\/li>\n<li>Transfer data between the CPU and a Vulkan device,<\/li>\n<li>Offload compute shaders to the requested Vulkan device.<\/li>\n<\/ol>\n<h2>Requirements<\/h2>\n<p>The current requirements of the <code>vulkan<\/code>\u00a0module are the following:<\/p>\n<ul>\n<li>Vulkan Loader\n<ul>\n<li><code>sudo apt-get install libvulkan-dev <br \/>\n <\/code><strong>OR<\/strong><code> <\/code><\/li>\n<li><code>dnf install vulkan-loader-devel<\/code><\/li>\n<\/ul>\n<\/li>\n<li>Vulkan Validation layers and SPIR-V tools\n<ul>\n<li><code>sudo apt install vulkan-validationlayers spirv-tools glslang-tools<\/code><br \/>\n <strong>OR<\/strong><\/li>\n<li><code>sudo dnf install mesa-vulkan-drivers vulkan-validation-layers-devel glslang<\/code><\/li>\n<\/ul>\n<\/li>\n<li>Vulkan Utilities\n<ul>\n<li><code>sudo apt-get install\u00a0vulkan-tools<br \/>\n <\/code><strong>OR<\/strong><code> <\/code><\/li>\n<li><code>dnf install vulkan-tools<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>On Arch Linux,ou can run\u00a0<code>sudo pacman -S vulkan-devel<\/code>\u00a0to install all the required tools.<\/p>\n<p>Before proceeding with the installation, verify the Vulkan installation and SPIR-V utilities by executing:<\/p>\n<p><code>$ vulkaninfo<\/code><\/p>\n<p><code>$ glslangValidator -v<br \/>\n <\/code><\/p>\n<p>The commands should display information about the Vulkan devices and Glslang\u00a0version, respectively.<\/p>\n<h2>Installing OMPi<\/h2>\n<p>The first step is to\u00a0deploy OMPi on your system. Initially, you need to\u00a0build OMPi 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>During the installation process, if your system satisfies the minimum requirements and has at least one Vulkan-enabled GPU installed, OMPi will automatically build the <code>vulkan<\/code>\u00a0module.\u00a0The correct installation of the module can be verified by running:<\/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 a Vulkan GPU, please revisit the minimum requirements 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 should give an output similar to the following (here an Ampere A2 GPU was identified by OMPi):<\/p>\n<pre>MODULE [vulkan]:\r\n------\r\nOMPi Vulkan device module.\r\nAvailable devices : 1\r\n\r\ndevice id &lt; 0 &gt; { \r\n Name: NVIDIA A2\r\n API version: 4210991 - Driver version: 2392933632\r\n Vendor ID: 4318\r\n Maximum workgroup sizes: (2147483647, 65535, 65535)\r\n Maximum invocations: 1024\r\n 15724544 Kbytes of memory\r\n}\r\n------<\/pre>\n<\/div><\/div>\n<h2>Quick start<\/h2>\n<p>Compiling your OpenMP application with Vulkan GPU offloading requires a simple\u00a0<code>--devs=all<\/code>\u00a0argument:<\/p>\n<pre>ompicc --devs=all 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\u00a0<code>--devs=vulkan<\/code>\u00a0compilation option, the numeric device IDs are those printed by\u00a0<code>ompiconf --devinfo=vulkan<\/code>. For example, in our system we get:\u00a0<\/p>\n<p><code>MODULE [vulkan] 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,\u00a0<em>including<\/em>\u00a0Vulkan.\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 [vulkan] provides device(s) : 1 2<\/code><\/p>\n<p>Thus the numeric IDs of the two Vulkan-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 several SPIR-V kernel binaries, one for each OpenMP <code>target<\/code> construct in the\u00a0application.<\/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>vulkan<\/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 Vulkan device \r\n     *\/\r\n    <strong>int<\/strong> is_initial_device = 1;\r\n<strong><span class=\"cp\">    #pragma omp target map(tofrom:is_initial_device) device(0)<\/span><\/strong>\r\n    <span class=\"p\">{<\/span>\r\n        <span class=\"k\">is_initial_device<\/span><span class=\"k\"> =<\/span> <span class=\"n\">omp_is_initial_device<\/span><span class=\"p\">();<\/span>\r\n    <span class=\"p\">}\r\n<\/span><\/pre>\n<pre><span class=\"p\"><strong>    printf<\/strong>(\"Running on %s.\\n\", (<\/span><span class=\"p\">is_initial_device == 0) ? \r\n                               \"Vulkan device\" : \"host\");<\/span><\/pre>\n<pre><span class=\"p\"><strong>    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: Multiple compilation jobs<\/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>vulkan<\/code> module has a number of limitations:<\/p>\n<ol>\n<li>Structs are allowed, but the above restriction also applies to struct fields,<\/li>\n<li>Only static loop scheduling is supported in <code>target teams distribute parallel for<\/code> directives,<\/li>\n<li>Pointers and conditional jumps are not allowed in the offloaded kernels.<\/li>\n<\/ol>\n<h2>Notes<\/h2>\n<p>The OMPi <code>vulkan<\/code> module has been tested with the following GPUs:<\/p>\n<ul>\n<li>NVIDIA Ampere A2<\/li>\n<li>NVIDIA Tesla P40<\/li>\n<li>AMD RX 550<\/li>\n<li>Intel UHD 770<\/li>\n<li>VideoCore VII (Raspberry Pi 5)<\/li>\n<li>VideoCore VI (Raspberry Pi 4)<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Introduction The latest version of OMPi enables offloading to Vulkan-supported GPUs through the vulkan module. OMPi analyzes the OpenMP target directives appearing in a user application and generates kernel source files, written in\u00a0shader language (GLSL). The vulkan module can: Compile the shader files to SPIR-V binaries, Optimize the generated binaries in terms of size and [&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-1350","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/paragroup.cse.uoi.gr\/wpsite\/wp-json\/wp\/v2\/pages\/1350","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=1350"}],"version-history":[{"count":16,"href":"https:\/\/paragroup.cse.uoi.gr\/wpsite\/wp-json\/wp\/v2\/pages\/1350\/revisions"}],"predecessor-version":[{"id":1431,"href":"https:\/\/paragroup.cse.uoi.gr\/wpsite\/wp-json\/wp\/v2\/pages\/1350\/revisions\/1431"}],"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=1350"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}