Skip to content

Commit 570f74d

Browse files
[SYCL] Provide _invalid_parameter symbol in device code on Windows (#18400)
Provides a fix for #18426: Provides symbols necessary for `std::array` to work in device code in debug mode on Windows. --------- Co-authored-by: aelovikov-intel <[email protected]>
1 parent 9c2b9df commit 570f74d

File tree

2 files changed

+55
-5
lines changed

2 files changed

+55
-5
lines changed
+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
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

sycl/test-e2e/Basic/std_array.cpp

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
// REQUIRES: windows
1+
// Check that std::array is supported on device in debug mode on Windows.
22

3-
// RUN: not clang-cl -fsycl -o %t.exe %s /Od /MDd /Zi /EHsc 2>&1 | FileCheck %s
3+
// REQUIRES: windows
44

5-
// FIXME: This code should have compiled cleanly.
6-
// CHECK: error: SYCL kernel cannot call an undefined function without SYCL_EXTERNAL attribute
7-
// CHECK: note: '_invalid_parameter' declared here
5+
// RUN: %clangxx --driver-mode=cl -fsycl -o %t.exe %s /Od /MDd /Zi /EHsc
6+
// RUN: %{run} %t.exe
87

98
#include <sycl/queue.hpp>
109

0 commit comments

Comments
 (0)