diff --git a/.clang-format b/.clang-format
index 7b2366f3326bf1245b546194250b66b30b1837c0..c6d26b29a79f8b1be3be3d4fc9424a9bfb1f3813 100644
--- a/.clang-format
+++ b/.clang-format
@@ -147,6 +147,7 @@ SpacesInParentheses: false
 SpacesInSquareBrackets: false
 
 WhitespaceSensitiveMacros: ['CBM_ENUM_DICT']
+StatementMacros: ['CBM_PARALLEL_FOR']
 
 Standard: c++11
 
diff --git a/algo/base/compat/OpenMP.h b/algo/base/compat/OpenMP.h
index 9129cdde38b7e09184ad95943abc0ea1570ba305..16991f1bedc53ba27eb2a0cf737fdfda8653dfdf 100644
--- a/algo/base/compat/OpenMP.h
+++ b/algo/base/compat/OpenMP.h
@@ -10,6 +10,21 @@
 #include <omp.h>
 #endif
 
+#define CBM_PRAGMA(...) _Pragma(#__VA_ARGS__)
+
+// OpenMP parallel for
+// If OpenMP is not available, this macro expands to nothing
+//
+// Hiding the pragma in a macro isn't technically necessary, as the compiler will ignore it if OpenMP is not available.
+// But it slightly increases readability as it's indented to the same level as the code it applies to.
+//
+// Accepts the same arguments as the OpenMP parallel for pragma.
+#ifdef HAVE_OMP
+#define CBM_PARALLEL_FOR(...) CBM_PRAGMA(omp parallel for __VA_ARGS__)
+#else
+#define CBM_PARALLEL_FOR(...)
+#endif
+
 namespace cbm::algo::openmp
 {
 
diff --git a/algo/unpack/Unpack.cxx b/algo/unpack/Unpack.cxx
index e5698e0c1fe556e6aea3071c3ed22cb506384095..9d001ade182936c87f5cb12dce02535a9f483f95 100644
--- a/algo/unpack/Unpack.cxx
+++ b/algo/unpack/Unpack.cxx
@@ -10,6 +10,7 @@
 #include <xpu/host.h>
 
 #include "compat/Algorithm.h"
+#include "compat/OpenMP.h"
 #include "log.hpp"
 
 using namespace std;
@@ -178,7 +179,7 @@ namespace cbm::algo
 
     xpu::push_timer("Unpack");
     xpu::t_add_bytes(sizeBytes);
-#pragma omp parallel for schedule(dynamic)
+    CBM_PARALLEL_FOR(schedule(dynamic))
     for (size_t i = 0; i < numMs; i++) {
       auto result = algos.at(msEqIds[i])(msContent[i], msDesc[i], ts.start_time());
       msDigis[i]  = std::move(result.first);
@@ -196,7 +197,7 @@ namespace cbm::algo
 
     xpu::push_timer("Merge");
     xpu::t_add_bytes(nDigisTotal * sizeof(Digi));
-#pragma omp parallel for schedule(dynamic)
+    CBM_PARALLEL_FOR(schedule(dynamic))
     for (unsigned int i = 0; i < numMs; i++) {
       unsigned int offset = 0;
       for (unsigned int x = 0; x < i; x++)