|
| 1 | +//==---------------- Wrapper around corecrt.h ------------------------------==// |
| 2 | +// |
| 3 | +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | +// See https://llvm.org/LICENSE.txt for license information. |
| 5 | +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | +// |
| 7 | +//===----------------------------------------------------------------------===// |
| 8 | + |
| 9 | +// When std::array is used in device code, MSVC's STL uses a _invalid_parameter |
| 10 | +// function. This causes issue when _invalid_parameter is invoked from device |
| 11 | +// code: |
| 12 | + |
| 13 | +// 1. `_invalid_parameter` is provided via ucrtbased.dll at runtime: DLLs are |
| 14 | +// not loaded for device code, thus causing undefined symbol errors. |
| 15 | + |
| 16 | +// 2. MSVC's STL never defined the function as SYCL_EXTERNAL, errors are thrown |
| 17 | +// when device code tries to invoke `_invalid_parameter`. |
| 18 | + |
| 19 | +// As a workaround, this wrapper wraps around corecrt.h and defines a custom |
| 20 | +// _invalid_parameter for device code compilation. |
| 21 | + |
| 22 | +// This new SYCL_EXTERNAL definition of _invalid_parameter has to be declared |
| 23 | +// before corecrt.h is included: Thus, we have this STL wrapper instead of |
| 24 | +// declaring _invalid_parameter function in SYCL headers. |
| 25 | + |
| 26 | +#pragma once |
| 27 | + |
| 28 | +#if defined(__SYCL_DEVICE_ONLY__) && defined(_DEBUG) |
| 29 | + |
| 30 | +#include <cstdint> // For uintptr_t |
| 31 | +#include <sycl/detail/defines_elementary.hpp> // For __DPCPP_SYCL_EXTERNAL |
| 32 | + |
| 33 | +extern "C" __DPCPP_SYCL_EXTERNAL void __cdecl _invalid_parameter( |
| 34 | + wchar_t const *, wchar_t const *, wchar_t const *, unsigned int, |
| 35 | + uintptr_t) { |
| 36 | + // Do nothing when called in device code |
| 37 | +} |
| 38 | + |
| 39 | +#endif |
| 40 | + |
| 41 | +#if defined(__has_include_next) |
| 42 | +// GCC/clang support go through this path. |
| 43 | +#include_next <corecrt.h> |
| 44 | +#else |
| 45 | +// MSVC doesn't support "#include_next", so we have to be creative. |
| 46 | +// Our header is located in "stl_wrappers/corecrt.h" so it won't be picked by |
| 47 | +// the aforementioned include. MSVC's installation, on the other hand, has the |
| 48 | +// layout where the following would result in the <corecrt.h> we want. This is |
| 49 | +// obviously hacky, but the best we can do... |
| 50 | +#include <../ucrt/corecrt.h> |
| 51 | +#endif |
0 commit comments