
{"id":1335,"date":"2025-09-25T12:53:08","date_gmt":"2025-09-25T09:53:08","guid":{"rendered":"https:\/\/paragroup.cse.uoi.gr\/wpsite\/?page_id=1335"},"modified":"2025-12-15T16:23:32","modified_gmt":"2025-12-15T14:23:32","slug":"ompi-on-the-jetson-nano-boards","status":"publish","type":"page","link":"https:\/\/paragroup.cse.uoi.gr\/wpsite\/software\/ompi\/documentation\/ompi-on-the-jetson-nano-boards\/","title":{"rendered":"OMPi on the NVIDIA Jetson Nano boards"},"content":{"rendered":"<p>Installing and using OMPi on an NVIDIA Jetson Nano board is not much different from <a href=\"https:\/\/paragroup.cse.uoi.gr\/wpsite\/software\/ompi\/documentation\/ompi-ppg-basic-installation-usage\/\">deploying OMPi on any other system<\/a>. Below, you can find detailed instructions for a Jetson Nano environment.<\/p>\n<h2>Minimum requirements<\/h2>\n<ul>\n<li>Meson <strong>0.58.0<\/strong> &#8212; <em>needed for building OMPi<\/em><\/li>\n<li>Jetson Linux (L4T) &#8212; <em>needed for supporting OpenMP on the CPU<\/em><\/li>\n<li>JetPack SDK <strong>4.2<\/strong> &#8212; <em>additionally needed for OpenMP offloading to the GPU<\/em><\/li>\n<\/ul>\n<h2>Installation<\/h2>\n<p>Set up OMPi\u00a0as follows:<\/p>\n<pre>meson setup build --prefix=\u2039install-dir\u203a<\/pre>\n<div class=\"su-spoiler su-spoiler-style-default su-spoiler-icon-plus su-spoiler-closed\" data-anchor=\"jit-conf\" 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 configuration: Just-in-time kernel compilation<\/div><div class=\"su-spoiler-content su-u-clearfix su-u-trim\">\n<p>For offloading purposes, OMPi by default enables just-in-time (JIT) kernel compilation. In this mode, the produced kernel files are in the PTX format. This speeds up compilation, but may introduce a minor delay at first kernel launch, as compilation is delegated to the runtime. This delay can be minimized if the CUDA binary cache is exploited; make sure the cache is enabled by setting the corresponding environment variable.<\/p>\n<pre>export CUDA_CACHE_DISABLE=0<\/pre>\n<p>Alternatively, OMPi gives the user the\u00a0offline compilation option to produce executable CUBIN files, which eliminates runtime delays at the cost of slower compilation, via the <code>-Dcuda-jit=false<\/code> flag:<\/p>\n<pre>meson setup build --prefix=\u2039install-dir\u203a -Dcuda-jit=false<\/pre>\n<\/div><\/div>\n<p>Then OMPi can be compiled and installed as usual:<\/p>\n<pre>cd build\/\r\nmeson compile\r\nmeson install<\/pre>\n<p>Note that the user does not need to provide any additional flags; the OpenMP <code>cuda<\/code> module is installed by default.<\/p>\n<h2>Usage<\/h2>\n<h3>Compilation<\/h3>\n<p>Compiling OpenMP applications with OMPi on a Jetson Nano board is a quite straightforward process. Simply run:<\/p>\n<pre>ompicc --devs=cuda app.c # or --devs=all<\/pre>\n<p>The compiler will produce the main application executable (a.out) and several kernel executables, specifically one for each OpenMP target construct\u00a0existing\u00a0in the\u00a0application.<\/p>\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 target regions, the user can additionally generate N parallel jobs\u00a0to handle the compilation of the kernels, by using the <code>-jN<\/code> device option, as follows:<\/p>\n<pre>ompicc --devs=cuda <strong>--devopt -jN<\/strong> app.c<\/pre>\n<\/div><\/div>\n<h3>Testing the CUDA module<\/h3>\n<p>The correct installation of OMPi along with its <code>cuda<\/code> module,\u00a0can be verified by running:<\/p>\n<pre>ompiconf --devvinfo<\/pre>\n<p>On a Jetson Nano 2GB, this command must print out the following information, assuming that <code>cuda<\/code> is the only module installed:<\/p>\n<pre>1 configured device module(s): cuda\r\n\r\nMODULE [cuda]:\r\n------\r\nOMPi CUDA device module.\r\nAvailable devices : 1\r\n\r\ndevice id &lt; 0 &gt; {\r\n GPU device name : NVIDIA Tegra X1\r\n Compute capability : 5.3\r\n CUDA toolkit version : 10.2\r\n Num of multiprocessors : 1\r\n Cores per multiprocessor : 128\r\n Total num of cores : 128\r\n Maximum thread block size : 1024\r\n Global memory : 1.9 GBytes\r\n Shared memory per block : 48 KBytes\r\n}\r\n------<\/pre>\n<p>The programmer can moreover verify that the module is working properly by compiling the following sample application and running it:<\/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>Source code: Sample application utilizing the GPU<\/div><div class=\"su-spoiler-content su-u-clearfix su-u-trim\">\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 CUDA device \r\n     *\/\r\n<strong><span class=\"cp\">    #pragma omp target device(0)<\/span><\/strong>\r\n    <span class=\"p\">{<\/span>\r\n        <strong><span class=\"k\">if<\/span> <\/strong><span class=\"p\">(<\/span><span class=\"n\">omp_is_initial_device<\/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 CUDA device\\n\"); <\/span>\r\n    <span class=\"p\">}\r\n    <strong>return<\/strong> 0;\r\n}\r\n<\/span><\/pre>\n<\/div><\/div>\n<h3>Mini-tutorial: Writing OpenMP applications which exploit the GPU<\/h3>\n<p>Targeting the Maxwell GPU of a Jetson Nano board is\u00a0made possible by using the OpenMP <em>target<\/em>-related constructs. With these constructs, the programmer indirectly launches a CUDA grid, that consists of multiple CUDA blocks containing multiple CUDA\u00a0threads. Below you can find information about the syntax and usage of the most popular constructs. For detailed information, please consult the official OpenMP specifications.<\/p>\n<div class=\"su-spoiler su-spoiler-style-default su-spoiler-icon-plus su-spoiler-closed\" data-anchor=\"target-parallel\" data-scroll-offset=\"0\" data-anchor-in-url=\"no\"><div class=\"su-spoiler-title\" tabindex=\"0\" role=\"button\"><span class=\"su-spoiler-icon\"><\/span>Construct: #pragma omp target parallel<\/div><div class=\"su-spoiler-content su-u-clearfix su-u-trim\">\n<pre>#pragma omp target parallel\r\n    &lt;structured-block&gt;<\/pre>\n<p>This construct launches a CUDA block consisting of multiple threads. The default number of launched threads is 128, but can be alternatively specified using the <code>num_threads(N)<\/code> clause.<\/p>\n<\/div><\/div>\n<div class=\"su-spoiler su-spoiler-style-default su-spoiler-icon-plus su-spoiler-closed\" data-anchor=\"target-teams\" data-scroll-offset=\"0\" data-anchor-in-url=\"no\"><div class=\"su-spoiler-title\" tabindex=\"0\" role=\"button\"><span class=\"su-spoiler-icon\"><\/span>Construct: #pragma omp target teams<\/div><div class=\"su-spoiler-content su-u-clearfix su-u-trim\">\n<pre>#pragma omp target teams\r\n    &lt;structured-block&gt;<\/pre>\n<p>This construct\u00a0launches multiple CUDA blocks consisting of one thread. The default number of launched blocks is 1, but\u00a0can be alternatively specified\u00a0using the <code>num_teams(N)<\/code> clause.<\/p>\n<\/div><\/div>\n<div class=\"su-spoiler su-spoiler-style-default su-spoiler-icon-plus su-spoiler-closed\" data-anchor=\"target-teams-dist-par-for\" data-scroll-offset=\"0\" data-anchor-in-url=\"no\"><div class=\"su-spoiler-title\" tabindex=\"0\" role=\"button\"><span class=\"su-spoiler-icon\"><\/span>Construct: #pragma omp target teams distribute parallel for<\/div><div class=\"su-spoiler-content su-u-clearfix su-u-trim\">\n<pre>#pragma omp target teams distribute parallel for\r\n    &lt;for-loops&gt;<\/pre>\n<p>This construct is a combination of the previous constructs and launches multiple CUDA blocks consisting of multiple threads and additionally distributes the iterations of a loop across the launched blocks and threads.<\/p>\n<\/div><\/div>\n<h3>\u00a0<\/h3>\n","protected":false},"excerpt":{"rendered":"<p>Installing and using OMPi on an NVIDIA Jetson Nano board is not much different from deploying OMPi on any other system. Below, you can find detailed instructions for a Jetson Nano environment. Minimum requirements Meson 0.58.0 &#8212; needed for building OMPi Jetson Linux (L4T) &#8212; needed for supporting OpenMP on the CPU JetPack SDK 4.2 [&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-1335","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/paragroup.cse.uoi.gr\/wpsite\/wp-json\/wp\/v2\/pages\/1335","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=1335"}],"version-history":[{"count":9,"href":"https:\/\/paragroup.cse.uoi.gr\/wpsite\/wp-json\/wp\/v2\/pages\/1335\/revisions"}],"predecessor-version":[{"id":1436,"href":"https:\/\/paragroup.cse.uoi.gr\/wpsite\/wp-json\/wp\/v2\/pages\/1335\/revisions\/1436"}],"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=1335"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}