OpenMP Updates and Fixes for C++ in Visual Studio 2019 version 16.10

Chris Pulido

In our previous blog post about improved OpenMP support in Visual Studio, we announced the addition of the -openmp:llvm switch in Visual Studio 2019 version 16.9 to enable compiled programs to target LLVM’s OpenMP runtime library for the x64 architecture. This switch supports all the OpenMP 2.0 directives that -openmp supports, as well as unsigned integer indices in parallel for loops, and a subset of the SIMD directives that are supported under -openmp:experimental. It also enabled a few correctness fixes. Starting in Visual Studio 2019 version 16.10 Preview 2, the -openmp:llvm switch now works for x86 and arm64. We have also fixed a couple of bugs in 16.10 Preview 3.

-openmp:llvm Now Available for x86 and arm64

Starting in Visual Studio 2019 version 16.10 Preview 2, in addition to X64 support, we have added support for targeting LLVM’s OpenMP runtime library with -openmp:llvm for the x86 and ARM64 architectures. Compiling with -openmp:llvm will automatically add a dynamic link to libomp140.i386.dll (or libomp140d.i386.dll under /DEBUG) when targeting x86, or libomp140.aarch64.dll (or libomp140d.aarch64.dll under /DEBUG) when targeting ARM64. You can find these libraries under the Visual Studio installation directory at VC\Redist\MSVC\<version>\debug_nonredist\<arch>\Microsoft.VC142.OpenMP.LLVM.

As a reminder, the -openmp:llvm switch is experimental, and features from OpenMP 3.0 that were added with the -openmp:llvm switch in Visual Studio version 16.9 are still only supported with the additional -openmp:experimental flag in Visual Studio version 16.10, and thus are provided with certain limitations in 16.10. In particular, #pragma omp task is not yet available on x86 or arm64, and there is only limited functionality on x64 in 16.10. Lastly, future versions of the LLVM OpenMP runtime DLLs may not be backwards compatible and the current version of these DLLs is not redistributable.

Bug Fixes in 16.10 Preview 3

  • return statements inside parallel regions now issue a helpful error message since they are non-conforming. The snippet below would previously crash the compiler with an internal compiler error.
#include <iostream>

int main()
{
    std::cout << "Hello World!\n";

#pragma omp parallel for schedule(dynamic)
    for (auto i = 0; i < 100; ++i)
    {
        // should issue error C3010: 'return': jump out of OpenMP structured block not allowed
        return -1;  
    }

    return 0;
}
  • The if clause now chooses the correct scope for a variable. In the snippet below, the inner if clause was referencing the outer shared variable i which has a value of 1, rather than the inner private variable i which has the value of 0, causing the program to print “nested” four times instead of one. A similar fix was also applied to the num_threads clause.
#include <stdio.h>
#include <omp.h>
int main(void)
{
  int i = 1;
  int retVal = 0;
  #pragma omp parallel if(retVal) default(none) private(i)
  {
    printf("hello\n");
    i = 0;
    #pragma omp parallel if(i) default(none) num_threads(4)
    {
      printf("nested\n");
    }
  }
  return 0;
}

Our OpenMP Plans

As of 16.10, the currently supported standard is still OpenMP 2.0, though we have made some improvements and fixed some long-standing bugs. We have started the long process to support newer versions of the OpenMP standard. Our goal is to support the most recent OpenMP standard, and this will be done step-by-step, with new features leveraging LLVM’s OpenMP runtime. Our next step for OpenMP will be to support the additional features added in the OpenMP 3.1 standard. Then we will add support for the pragmas and clauses added in the OpenMP 4.5 standard that do not involve offloading. Which features are added first after that will depend on your feedback. We would love to hear from you which specific OpenMP features you would like to see first.

Feedback

We encourage you to try out this update in the latest Visual Studio 2019 version 16.10 Preview. If you encounter a correctness issue in code generated with the -openmp:llvm switch or bugs in the libomp140 DLLs shipped with Visual Studio, please let us know. We can be reached via the comments below, via twitter (@visualc), or via Developer Community.