<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/116552>116552</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Problem compiling OpenMP Wasm with Emscripten in Windows
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
maniatic0
</td>
</tr>
</table>
<pre>
With the recent (as of Nov 2024) port of OpenMP to Wasm/Emscripten [[1](https://github.com/llvm/llvm-project/pull/71297), [2](https://github.com/llvm/llvm-project/pull/95169), [3](https://reviews.llvm.org/D142593?id=492403)], I decided to port some high perf libs with it. While compiling it and building in Windows using CMake/Ninja I found an issue with ```kmp_i18n_default.inc```'s generation. It's getting generated with Window's print modifiers rather than Unix ones, which crashes with an OOM when executed.
After tracking how those strings are generated, I found the issue in ```message-converter.py``` at https://github.com/llvm/llvm-project/blob/54dad9e269f365d0eff2f63c5ee843564eecca7e/openmp/runtime/tools/message-converter.py#L58
It should generate Unix modifiers even if my compilation platform is Windows.
## Steps to Reproduce
In a Windows machine, configure OpenMP with Cmake and then check the generated ```kmp_i18n_default.inc``` (you don't need to compile unless you want to check the crash). Observe that it has Windows printf modifers rather than the expected Unix ones for Emscripten.
For example, I use https://github.com/maniatic0/wasm-win-openmp-fix/blob/main/build.bat
```
call emcmake cmake ^
-DOPENMP_STANDALONE_BUILD=ON ^
-DOPENMP_ENABLE_OMPT_TOOLS=OFF ^
-DOPENMP_ENABLE_LIBOMPTARGET=OFF ^
-DLIBOMP_HAVE_OMPT_SUPPORT=OFF ^
-DLIBOMP_OMPT_SUPPORT=OFF ^
-DLIBOMP_OMPD_SUPPORT=OFF ^
-DLIBOMP_USE_DEBUGGER=OFF ^
-DLIBOMP_FORTRAN_MODULES=OFF ^
-DLIBOMP_ENABLE_SHARED=OFF ^
-DLIBOMP_ARCH=wasm32 ^
-DCMAKE_INSTALL_PREFIX=%BUILD_DIR% ^
-G "Ninja Multi-Config" ^
-B %BUILD_DIR% ^
-S %OPENMP_DIR%
```
The file is generated at ```%BUILD_DIR%\runtime\src\kmp_i18n_default.inc```
## Suggestion
I think a configuration variable like ```LIBOMP_ARCH``` could help fix the issue. Something like ```LIBOMP_PLATFORM=None|Unix|Windows```, which could be checked in ```message-converter.py``` (if the variable is None/Empty, it should default to the platform check).
## Workaround
After configuring with CMake and before compiling, fix the modifiers. This can be done with a Python script, which is what I do with https://github.com/maniatic0/wasm-win-openmp-fix/blob/main/fix_kmp_i18n_default.py at https://github.com/maniatic0/wasm-win-openmp-fix/blob/d40c146aa0e04ce17686d5ab831b474e94266d39/build.bat#L33
## Crash
Not sure if this is an issue in itself, but for completeness. The way I found the above problem with the string generation was due to OOM crashes coming from ```__kmp_str_buf_vprint``` in ```kmp_str.cpp``` https://github.com/llvm/llvm-project/blob/54dad9e269f365d0eff2f63c5ee843564eecca7e/openmp/runtime/src/kmp_str.cpp#L206
My comments are marked with ```<---```
```
int __kmp_str_buf_vprint(kmp_str_buf_t *buffer, char const *format,
va_list args) {
int rc;
KMP_STR_BUF_INVARIANT(buffer);
for (;;) {
int const free = buffer->size - buffer->used;
int size;
// Try to format string.
{
/* On Linux* OS Intel(R) 64, vsnprintf() modifies args argument, so
vsnprintf() crashes if it is called for the second time with the same
args. To prevent the crash, we have to pass a fresh intact copy of args
to vsnprintf() on each iteration.
Unfortunately, standard va_copy() macro is not available on Windows*
OS. However, it seems vsnprintf() does not modify args argument on
Windows* OS.
*/
#if !KMP_OS_WINDOWS
va_list _args;
va_copy(_args, args); // Make copy of args.
#define args _args // Substitute args with its copy, _args.
#endif // KMP_OS_WINDOWS
rc = KMP_VSNPRINTF(buffer->str + buffer->used, free, format, args); // <--- This fails with -1 (encoding issue) when used with Window's modifiers
#if !KMP_OS_WINDOWS
#undef args // Remove substitution.
va_end(_args);
#endif // KMP_OS_WINDOWS
}
// No errors, string has been formatted.
if (rc >= 0 && rc < free) {
buffer->used += rc;
break;
}
// Error occurred, buffer is too small.
if (rc >= 0) {
// C99-conforming implementation of vsnprintf returns required buffer size
size = buffer->used + rc + 1;
} else {
// Older implementations just return -1. Double buffer size.
size = buffer->size * 2; // <--- This treats the constraint/encoding issues as not enough buffer. This grows until crashing
}
// Enlarge buffer.
__kmp_str_buf_reserve(buffer, size);
// And try again.
}
KMP_DEBUG_ASSERT(buffer->size > 0);
KMP_STR_BUF_INVARIANT(buffer);
return rc;
} // __kmp_str_buf_vprint
```
```KMP_VSNPRINTF``` is defined as ```vsnprintf_s``` at https://github.com/llvm/llvm-project/blob/54dad9e269f365d0eff2f63c5ee843564eecca7e/openmp/runtime/src/kmp_safe_c_api.h#L52
>From the [standard](https://en.cppreference.com/w/c/io/vfprintf), the negative return value means that there was a constraint or encoding issue (which would be correct as it's using Windows modifiers rather than Unix ones). This is then treated as an unknown error that the buffer is not big enough, so it's doubled in size which then runs out of memory. More info in my [notes](https://github.com/maniatic0/wasm-win-openmp-fix/blob/main/Notes.txt).
I have to note that there is a comment in the code about older implementations returning negative numbers for errors about the buffer not being big enough, so I'm not sure if this is an issue.
[1] https://github.com/llvm/llvm-project/pull/71297
[2] https://github.com/llvm/llvm-project/pull/95169
[3] https://reviews.llvm.org/D142593?id=492403
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzMWVtv8ziP_jXuDdEgkXO86EWaw7zB1yZF0k73LlBsOtbUlrKSnLT76xeUbMdp0_ew3wK7g0FmKtMk9ZB8SMncGLGXiHdB7z7oTW94YVOl73IuBbciat_sVPxx9ypsCjZF0BihtBCwITegEliqI7A26wZsBAelLa2tDigfn8AqeOUmD9h8lptIi4NFCc7KfSfoTQM2TK09mCAcB2wesPle2LTYtSJFr2TZsfrP7UGrfzCyAZsfiiwL2HzQYaNBwEYBm5BC9u9pG_U6_dFZW3hNm8ajwJNpkYaW0vuAzaedLuuNwiCcizgIp90R67ZDUkOvT2ABMUYixphwcMgYlSOkYp_CAXUCmdgZOBGuwrbgNRUZQqTyg8iE3IOwwGUMu0JksftbwquQsToZKAwtTB75GwZsvhTyHw4LSFQhY-AShDEFesVBv-3_fcsPW9EZym2MCS8y2xIyqh8GbGBgjxI1t0LJFixsuWQtWSofYeyVejecxEELaSFXsUgEagOa2xQ12JRLeJHiHZREQ2CcUhGlEGluUiw3zSWsVo9wSlECvmNUWIxbQXsatMf-d5xY0qV59EZepOoENlUGwVgt5N4A13j2zUPuQaA89SgIecYgR2P4Hm8jJY-oLerW4aN-CNzCH-fPLlO7gM173ZjHI2T9URL2e3Ebk4Ql_TDqIQ67Ya_fRYwiPqBgqQPK_ED5VEgrclqySmUmYPOr7rHwoTdsgrKwYFJVZHG9cw_0OQZ4RAkigfyjzCYXVDhk3CZK5yBMlUgXaAcsDFgIG4sHQxm7xoNWcRHhhXUJvE7DnEepkEjAR0omYl9orErfRXiS8zd0WWwpyFGK0ZuLzTmhfi9BiW0-VAGxkgEbWJDoq8rvD6GQGRoDJHLi0rpHtTGXdAEbtWC1M6iPSOlpqb5SXkPhMznxMH7OZNKC7weMyOM6rSFRGs7EdgHmXGnAd54fMvR5WRj8WXrVZBuw-Ymb_PYk5K3PldtEvJ9TLedC0l_ECq0dtxcRrOvZ_RnxLAPMIxcE_xv0Zv4ZAMDtdPU0Wz4-bTfP4-V0_LBazrb3L4uHaRBOV8uGbC04W47vH2bb1ePT8_Z5tXrYkOR8_o3aUvphcU8vjNd_zZ6vy3uJ7Y_x36XuzcvT02r9c-k_EZz-luDLZradzu5f_vprtv4iWEvNV-vn9Xi5fVxNXx5m3yBQypYIbH6M17Pp9yrH68mPIJxS3EP2WdXkcfyv2Xax3DyPHx62T-vZfPEfQTgNWM_FajtdrAPW-_TWXxAw5vvCY5FZcTtx9Rmwz-rv4eeKNvS8jKcXuJpq_vc5RUioHIVpVDi30Gg0F8aC3qSiwd7E6CjoTX7ep67QVbHfoyGCu6ApsKmQb8BrYvIceORa8F2GkAmqhkpvMw415USOZFPMDpCI93NLacFG5Uj699fVPD2Mn-er9WMQTpdKYjCYEGUEg0lJNQ006r7obO3QsxbGf9C2AjYUifOu3pww4AzT2HWwH2RG1F2jxJUokl6qu4KzTCx5BeRXpd-4ps76tT1XABMcnvQfK9LfYaJ0Y6QhRyoo63bVgudUGIi4pP3HSpaTC4enD5sqCZ5fz1gJAyfi7wXEyov-L_JqIt63X1Lw8PGL4eC3rcTddtTp9jlvY7sbYWfQH_bjHt8Nw86uO-jiqMv6_TgcXTA8Cx_C8EpUJq6vNdaXyoKhHuwSQhiCqh4HhQRhDWYJIbkrrOteFJoMLUo0LhAIJ_5xMUXxnToiHLTaZZh7uGnZT2CNmRFO3EBcIOUVTXXVpBepnAQTrfJzRm8dxsbq7a5ItkfXes8Z3cz9Uq4VHQ5ngf-bMY34ic2bDrHwgbX7zQg8upErR2n9cJpz_VZNzeeyDye3t7fXSe1ykWbrq1ixYXORDmPjXZEkqN0slnJXlsatU3FTEk1KVj_ybSaMBa73ho5sweC-4nsyp6MgrBb-5WaD9fb-Zb5dLP8erxfj5XPAhpWpUS1aaaCcCtiQ1sP7T9q9fu9XohEhCKfgVd0G4cyI_0K4bSwUBuOzL-XrJPXFKoDPBHjWH5R_fstljrYaUk1nypfGsJLwIGTx7v5_AwtpMQvYcE3u97sE6NFIPx3S1tio4i7jMKSfgiJOkkY1DQB8ebUqC5EQJTveyzKMHXCurjBSVHkix0ax8Rw_6SXLLXhWcNA07tvmoDuBE0LKj64WD9wY4AS4SQlBHlEMDh90SncpcKnXqi8uKwnIiXdtdTz8jL7750UmSttCcouZaznGchlzHVPGkcUKPB5pRTuXygI_cpG5nqXq023APqtebVrwQ53w6PObehlibr54Giv0al2APi7DA9WEUKs92yMLl5nhuOWSckUCAetQTaw229fFcrp63TRfqgpr62AN7z89KyHwT9mkqr8gvK-y1_XNZmxate0YEyHRb8hpqN7ZFDtjhS1s-bC8TTDgzU289FkRytjtw738_V505KqTBP7eLJ_Wi-XzvC58V62WCv3-c7lSg9fojjw171zZqWdA3_gTLrLS79sOkQfKSPkLD-pbFFd3Q0D6v1w_1FPEb0QpYGEhY_TQVp6sMaf-ZioYz-ldBw5lfI5bg_J-E8xgMP2GrZYKUGulja8W11DpRLpDlCV85xsRR4BkbOhiM6Pw0PDXD1jfh6uCfvSZ5y5jRGGjl5tE78U08reLte9dn5HfoKKo0NqH3RuhurZKgcl5lv3M8ytulqonoxFNurR_lwQ0oFD9-ilDJeeqB4220NKAxv8shMa4csI1iYZm11ouu02FhIOO3UPn88YBM4PfuLjKYtrqhWcG_imMLV2C204LpqogYmv41PqFU36JjYF9rRVfLFYjt8aTPTVSzd00ML-sGQPc8yBKVezT0kI5aO-1u0GUVmS-YdBg_jshlxnX-2o_1VYupxON7n6lMSJMfDCujAq14jH1O_0BfM9FXXxf_KDycofz7Xizma2fL9nIYzlzefU_mV-gClyjKigJShevzmDfn4PrxUv-PA-4BjyhxxSoer1O7K35f3Ar2Rh3eYLbaMsPopW6-0h2cdNFkz0lZNC7r1r-tftzlDQza0xQo4yw3MApYHOyI1TA5sekaufuJp6UStxzK45YxefIswIhRy6Nv8WzKWp0hw_eKAlQGi5rgvjHnx9P9VlbaY2RpRgIf9_t79Xr681f3WqPypISxt9vuur0QeUSCvkm1Ul6jq-dbRAlVehO7Msq9eNj5UnsyMPdA7jk9q47K7qQBlThvrPkmCv90YJHOmcLmSh6If-gWEhl0fzys8ifno-XpLVl3-3nm4JFPXGS4WZshA-NOxWRe568Yne0pF1cJVMfbopGnQGyyHcUDBqVfd8sNTRQdZAivfYF2EXABrkT-O6IfHnz4T9R_XnxXXygqlSxf0eV_zpVqQq_qvrdT1M38V0Yj8IRv8G7ziDsDPv9zjC8Se8Gu2gYDTsYdxIcdJNh2O102sNRt9Pv90bYHt6IO9Zm3U6nM-gMen0Wtvrd7iDsRO3hAIf9pDcIum3MuchqH24cpHedTr_XYzcZ32Fm3AdGxiSeqtmOcLnRd27fu2Jvgm6bZujzVm6ssBnePZX3D-evY-VnhlduyluJxhfG85eym0Jnd3-Mu2-iAZuX3h_v2H8HAAD__-c29YY">