Skip to content

Commit 459e122

Browse files
bso-intelbadervictor-edsjoppermaelovikov-intel
authored
[SYCL] Initial changes for C++11 ABI=0 support (#12193)
This PR attempts to support the usage case where the user sets _GLIBCXX_USE_CXX11_ABI=0 to use pre-C++11 ABI. In fact, this change addresses a specific issue with using different versions of the libstdc++ library (https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html has more details on this issue). One of the major changes I made in this PR involves calling `get_info<>()` API, which can return `stdA::string` as the requested information. Due to the ABI incompatibility issues, this API internally splits into 3 cases depending on the template parameter `<T>`. 1. `<T>`s that return a `std::string`. 2. `<T>`s that return a `std::vector<std::string>` 3. `<T>`s that return something other than 1 or 2 above. The case 1 and 2 should return `detail::string` and `std::vector<detail::string>` instead and reconstruct `std::string`s. This is required because ABIs can be different between the header and CPP files. All these 3 cases are implemented using `get_info_impl<T>`. Then, I changed the macro definition of `__SYCL_PARAM_TRAITS_SPEC` to return different types depending on the `<T>` return_types. This way, we can only change the boundary between the header file and the entry point of the libsycl. --------- Signed-off-by: Byoungro So <[email protected]> Co-authored-by: Alexey Bader <[email protected]> Co-authored-by: Victor Perez <[email protected]> Co-authored-by: Julian Oppermann <[email protected]> Co-authored-by: aelovikov-intel <[email protected]> Co-authored-by: Sergey Semenov <[email protected]>
1 parent f639a20 commit 459e122

16 files changed

+467
-75
lines changed

sycl/include/sycl/detail/string.hpp

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
//==----------------- string.hpp - SYCL standard header file ---------------==//
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+
#include <cstring>
10+
#include <string>
11+
12+
#pragma once
13+
14+
namespace sycl {
15+
inline namespace _V1 {
16+
namespace detail {
17+
18+
// This class and detail::string_view class are intended to support
19+
// different ABIs between libsycl and the user program.
20+
// This class is not inteded to replace std::string for general purpose usage.
21+
class string {
22+
char *str = nullptr;
23+
24+
public:
25+
string() noexcept = default;
26+
~string() { delete[] str; }
27+
28+
string(std::string_view strn) {
29+
size_t len = strn.length();
30+
str = new char[len + 1];
31+
strn.copy(str, len);
32+
str[len] = 0;
33+
}
34+
35+
friend void swap(string &lhs, string &rhs) noexcept {
36+
std::swap(lhs.str, rhs.str);
37+
}
38+
39+
string(string &&other) noexcept { swap(*this, other); }
40+
string(const string &other) {
41+
if (other.str == nullptr)
42+
return;
43+
*this = string{other.str};
44+
}
45+
46+
string &operator=(string &&other) noexcept {
47+
swap(*this, other);
48+
return *this;
49+
}
50+
string &operator=(const string &other) {
51+
*this = string{other};
52+
return *this;
53+
}
54+
55+
string &operator=(std::string_view strn) {
56+
*this = string{strn};
57+
return *this;
58+
}
59+
60+
const char *c_str() const noexcept { return str ? str : ""; }
61+
62+
friend bool operator==(const string &lhs, std::string_view rhs) noexcept {
63+
return rhs == lhs.c_str();
64+
}
65+
friend bool operator==(std::string_view lhs, const string &rhs) noexcept {
66+
return lhs == rhs.c_str();
67+
}
68+
};
69+
70+
} // namespace detail
71+
} // namespace _V1
72+
} // namespace sycl
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//==-------------- string_view.hpp - SYCL standard header file -------------==//
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+
#include <string>
10+
11+
#pragma once
12+
13+
namespace sycl {
14+
inline namespace _V1 {
15+
namespace detail {
16+
17+
// This class and detail::string class are intended to support
18+
// different ABIs between libsycl and the user program.
19+
// This class is not inteded to replace std::string_view for general purpose
20+
// usage.
21+
class string_view {
22+
const char *str = nullptr;
23+
24+
public:
25+
string_view() noexcept = default;
26+
string_view(const string_view &strn) noexcept = default;
27+
string_view(string_view &&strn) noexcept = default;
28+
string_view(std::string_view strn) noexcept : str(strn.data()) {}
29+
30+
string_view &operator=(string_view &&strn) noexcept = default;
31+
string_view &operator=(const string_view &strn) noexcept = default;
32+
33+
string_view &operator=(std::string_view strn) noexcept {
34+
str = strn.data();
35+
return *this;
36+
}
37+
38+
const char *data() const noexcept { return str; }
39+
40+
friend bool operator==(const string_view &lhs,
41+
std::string_view rhs) noexcept {
42+
return rhs == lhs.data();
43+
}
44+
friend bool operator==(std::string_view lhs,
45+
const string_view &rhs) noexcept {
46+
return lhs == rhs.data();
47+
}
48+
};
49+
50+
} // namespace detail
51+
} // namespace _V1
52+
} // namespace sycl

sycl/include/sycl/detail/util.hpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
#ifndef __SYCL_DEVICE_ONLY
1212

1313
#include <sycl/detail/defines.hpp>
14-
14+
#ifdef __INTEL_PREVIEW_BREAKING_CHANGES
15+
#include <sycl/detail/string.hpp>
16+
#endif
1517
#include <cstring>
1618
#include <mutex>
1719
#include <vector>
@@ -67,6 +69,26 @@ struct CmpCStr {
6769

6870
using SerializedObj = std::vector<unsigned char>;
6971

72+
#ifdef __INTEL_PREVIEW_BREAKING_CHANGES
73+
template <typename T> struct ABINeutralT { using type = T; };
74+
// We need special handling of std::string to handle ABI incompatibility
75+
// for get_info<>() when it returns std::string and vector<std::string>.
76+
// For this purpose, get_info_impl<>() is created to handle special
77+
// cases, and it is only called internally and not exposed to the user.
78+
// The following ReturnType structure is intended for general return type,
79+
// and special return types (std::string and vector of it).
80+
81+
template <> struct ABINeutralT<std::string> { using type = detail::string; };
82+
83+
template <> struct ABINeutralT<std::vector<std::string>> {
84+
using type = std::vector<detail::string>;
85+
};
86+
87+
template <typename T> using ABINeutralT_t = typename ABINeutralT<T>::type;
88+
#else
89+
template <typename T> using ABINeutralT_t = T;
90+
#endif
91+
7092
} // namespace detail
7193
} // namespace _V1
7294
} // namespace sycl

sycl/include/sycl/device.hpp

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,30 @@
88

99
#pragma once
1010

11-
#include <sycl/aspects.hpp> // for aspect
12-
#include <sycl/backend_types.hpp> // for backend
13-
#include <sycl/detail/defines_elementary.hpp> // for __SY...
14-
#include <sycl/detail/export.hpp> // for __SY...
15-
#include <sycl/detail/info_desc_helpers.hpp> // for is_d...
16-
#include <sycl/detail/owner_less_base.hpp> // for Owne...
17-
#include <sycl/detail/pi.h> // for pi_n...
18-
#include <sycl/device_selector.hpp> // for Enab...
19-
#include <sycl/ext/oneapi/experimental/device_architecture.hpp> // for arch...
20-
#include <sycl/info/info_desc.hpp> // for part...
21-
#include <sycl/platform.hpp> // for plat...
22-
23-
#include <cstddef> // for size_t
24-
#include <memory> // for shar...
25-
#include <string> // for string
26-
#include <type_traits> // for add_...
27-
#include <variant> // for hash
28-
#include <vector> // for vector
11+
#include <sycl/aspects.hpp>
12+
#include <sycl/backend_types.hpp>
13+
#include <sycl/detail/defines_elementary.hpp>
14+
#include <sycl/detail/export.hpp>
15+
#include <sycl/detail/info_desc_helpers.hpp>
16+
#include <sycl/detail/owner_less_base.hpp>
17+
#include <sycl/detail/pi.h>
18+
#ifdef __INTEL_PREVIEW_BREAKING_CHANGES
19+
#include <sycl/detail/string.hpp>
20+
#include <sycl/detail/string_view.hpp>
21+
#endif
22+
#include <sycl/detail/util.hpp>
23+
#include <sycl/device_selector.hpp>
24+
#include <sycl/ext/oneapi/experimental/device_architecture.hpp>
25+
#include <sycl/info/info_desc.hpp>
26+
#include <sycl/platform.hpp>
27+
28+
#include <cstddef>
29+
#include <memory>
30+
#include <string>
31+
#include <type_traits>
32+
#include <typeinfo>
33+
#include <variant>
34+
#include <vector>
2935

3036
namespace sycl {
3137
inline namespace _V1 {
@@ -214,8 +220,17 @@ class __SYCL_EXPORT device : public detail::OwnerLessBase<device> {
214220
/// type associated with the param parameter.
215221
///
216222
/// \return device info of type described in Table 4.20.
223+
#ifdef __INTEL_PREVIEW_BREAKING_CHANGES
224+
template <typename Param>
225+
typename detail::is_device_info_desc<Param>::return_type get_info() const {
226+
return detail::convert_from_abi_neutral(get_info_impl<Param>());
227+
}
228+
#else
217229
template <typename Param>
218-
typename detail::is_device_info_desc<Param>::return_type get_info() const;
230+
detail::ABINeutralT_t<
231+
typename detail::is_device_info_desc<Param>::return_type>
232+
get_info() const;
233+
#endif
219234

220235
/// Check SYCL extension support by device
221236
///
@@ -291,6 +306,13 @@ class __SYCL_EXPORT device : public detail::OwnerLessBase<device> {
291306
template <backend BackendName, class SyclObjectT>
292307
friend auto get_native(const SyclObjectT &Obj)
293308
-> backend_return_t<BackendName, SyclObjectT>;
309+
310+
#ifdef __INTEL_PREVIEW_BREAKING_CHANGES
311+
template <typename Param>
312+
typename detail::ABINeutralT_t<
313+
typename detail::is_device_info_desc<Param>::return_type>
314+
get_info_impl() const;
315+
#endif
294316
};
295317

296318
} // namespace _V1

sycl/include/sycl/exception.hpp

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,21 @@ class __SYCL_EXPORT exception : public virtual std::exception {
7474

7575
exception(std::error_code, const char *Msg);
7676

77+
#ifdef __INTEL_PREVIEW_BREAKING_CHANGES
78+
exception(std::error_code Ec, const std::string &Msg)
79+
: exception(Ec, nullptr, Msg.c_str()) {}
80+
#else
7781
exception(std::error_code, const std::string &Msg);
82+
#endif
7883

7984
// new SYCL 2020 constructors
8085
exception(std::error_code);
86+
#ifdef __INTEL_PREVIEW_BREAKING_CHANGES
87+
exception(int EV, const std::error_category &ECat, const std::string &WhatArg)
88+
: exception(EV, ECat, WhatArg.c_str()) {}
89+
#else
8190
exception(int, const std::error_category &, const std::string &);
91+
#endif
8292
exception(int, const std::error_category &, const char *);
8393
exception(int, const std::error_category &);
8494

@@ -111,24 +121,32 @@ class __SYCL_EXPORT exception : public virtual std::exception {
111121

112122
protected:
113123
// base constructors used by SYCL 1.2.1 exception subclasses
114-
exception(std::error_code ec, const char *Msg, const pi_int32 PIErr,
124+
exception(std::error_code Ec, const char *Msg, const pi_int32 PIErr,
115125
std::shared_ptr<context> Context = nullptr)
116-
: exception(ec, std::string(Msg), PIErr, Context) {}
126+
: exception(Ec, std::string(Msg), PIErr, Context) {}
117127

118-
exception(std::error_code ec, const std::string &Msg, const pi_int32 PIErr,
128+
exception(std::error_code Ec, const std::string &Msg, const pi_int32 PIErr,
119129
std::shared_ptr<context> Context = nullptr)
120-
: exception(ec, Context, Msg + " " + detail::codeToString(PIErr)) {
130+
: exception(Ec, Context, Msg + " " + detail::codeToString(PIErr)) {
121131
MPIErr = PIErr;
122132
}
123133

124134
exception(const std::string &Msg)
125135
: MMsg(std::make_shared<std::string>(Msg)), MContext(nullptr) {}
126136

127137
// base constructor for all SYCL 2020 constructors
128-
// exception(context *ctxPtr, std::error_code ec, const std::string
138+
// exception(context *ctxPtr, std::error_code Ec, const std::string
129139
// &what_arg);
130-
exception(std::error_code ec, std::shared_ptr<context> SharedPtrCtx,
140+
#ifdef __INTEL_PREVIEW_BREAKING_CHANGES
141+
exception(std::error_code Ec, std::shared_ptr<context> SharedPtrCtx,
142+
const std::string &what_arg)
143+
: exception(Ec, SharedPtrCtx, what_arg.c_str()) {}
144+
exception(std::error_code Ec, std::shared_ptr<context> SharedPtrCtx,
145+
const char *WhatArg);
146+
#else
147+
exception(std::error_code Ec, std::shared_ptr<context> SharedPtrCtx,
131148
const std::string &what_arg);
149+
#endif
132150
};
133151

134152
class __SYCL2020_DEPRECATED(
@@ -143,12 +161,12 @@ class __SYCL2020_DEPRECATED(
143161
runtime_error(const std::string &Msg, pi_int32 Err)
144162
: exception(make_error_code(errc::runtime), Msg, Err) {}
145163

146-
runtime_error(std::error_code ec, const std::string &Msg,
164+
runtime_error(std::error_code Ec, const std::string &Msg,
147165
const pi_int32 PIErr)
148-
: exception(ec, Msg, PIErr) {}
166+
: exception(Ec, Msg, PIErr) {}
149167

150168
protected:
151-
runtime_error(std::error_code ec) : exception(ec) {}
169+
runtime_error(std::error_code Ec) : exception(Ec) {}
152170
};
153171

154172
class __SYCL2020_DEPRECATED("use sycl::exception with sycl::errc::kernel or "
@@ -230,10 +248,10 @@ class __SYCL2020_DEPRECATED(
230248
: exception(make_error_code(errc::invalid), Msg, Err) {}
231249

232250
protected:
233-
device_error(std::error_code ec) : exception(ec) {}
251+
device_error(std::error_code Ec) : exception(Ec) {}
234252

235-
device_error(std::error_code ec, const std::string &Msg, const pi_int32 PIErr)
236-
: exception(ec, Msg, PIErr) {}
253+
device_error(std::error_code Ec, const std::string &Msg, const pi_int32 PIErr)
254+
: exception(Ec, Msg, PIErr) {}
237255
};
238256

239257
class __SYCL2020_DEPRECATED(

0 commit comments

Comments
 (0)