Skip to content

Commit 89614ce

Browse files
authored
[libc] Move RPC interface to libc/shared to export it (#117034)
Summary: Previous patches have made the `rpc.h` header independent of the `libc` internals. This allows us to include it directly rather than providing an indirect C API. This patch only does the work to move the header. A future patch will pull out the `rpc_server` interface and simply replace it with a single function that handles the opcodes.
1 parent 4ab5e90 commit 89614ce

File tree

9 files changed

+222
-196
lines changed

9 files changed

+222
-196
lines changed

libc/src/__support/RPC/rpc.h renamed to libc/shared/rpc.h

Lines changed: 81 additions & 81 deletions
Large diffs are not rendered by default.

libc/src/__support/RPC/rpc_util.h renamed to libc/shared/rpc_util.h

Lines changed: 51 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,8 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
#ifndef LLVM_LIBC_SRC___SUPPORT_RPC_RPC_UTIL_H
10-
#define LLVM_LIBC_SRC___SUPPORT_RPC_RPC_UTIL_H
11-
12-
#include "src/__support/macros/attributes.h"
13-
#include "src/__support/macros/config.h"
9+
#ifndef LLVM_LIBC_SHARED_RPC_UTIL_H
10+
#define LLVM_LIBC_SHARED_RPC_UTIL_H
1411

1512
#include <stddef.h>
1613
#include <stdint.h>
@@ -20,7 +17,10 @@
2017
#define RPC_TARGET_IS_GPU
2118
#endif
2219

23-
namespace LIBC_NAMESPACE_DECL {
20+
#ifndef RPC_INLINE
21+
#define RPC_INLINE inline
22+
#endif
23+
2424
namespace rpc {
2525

2626
template <typename T> struct type_identity {
@@ -40,26 +40,26 @@ template <class T> struct is_const<const T> : type_constant<bool, true> {};
4040

4141
/// Freestanding implementation of std::move.
4242
template <class T>
43-
LIBC_INLINE constexpr typename remove_reference<T>::type &&move(T &&t) {
43+
RPC_INLINE constexpr typename remove_reference<T>::type &&move(T &&t) {
4444
return static_cast<typename remove_reference<T>::type &&>(t);
4545
}
4646

4747
/// Freestanding implementation of std::forward.
4848
template <typename T>
49-
LIBC_INLINE constexpr T &&forward(typename remove_reference<T>::type &value) {
49+
RPC_INLINE constexpr T &&forward(typename remove_reference<T>::type &value) {
5050
return static_cast<T &&>(value);
5151
}
5252
template <typename T>
53-
LIBC_INLINE constexpr T &&forward(typename remove_reference<T>::type &&value) {
53+
RPC_INLINE constexpr T &&forward(typename remove_reference<T>::type &&value) {
5454
return static_cast<T &&>(value);
5555
}
5656

5757
struct in_place_t {
58-
LIBC_INLINE explicit in_place_t() = default;
58+
RPC_INLINE explicit in_place_t() = default;
5959
};
6060

6161
struct nullopt_t {
62-
LIBC_INLINE constexpr explicit nullopt_t() = default;
62+
RPC_INLINE constexpr explicit nullopt_t() = default;
6363
};
6464

6565
constexpr inline in_place_t in_place{};
@@ -75,15 +75,15 @@ template <typename T> class optional {
7575

7676
bool in_use = false;
7777

78-
LIBC_INLINE ~OptionalStorage() { reset(); }
78+
RPC_INLINE ~OptionalStorage() { reset(); }
7979

80-
LIBC_INLINE constexpr OptionalStorage() : empty() {}
80+
RPC_INLINE constexpr OptionalStorage() : empty() {}
8181

8282
template <typename... Args>
83-
LIBC_INLINE constexpr explicit OptionalStorage(in_place_t, Args &&...args)
83+
RPC_INLINE constexpr explicit OptionalStorage(in_place_t, Args &&...args)
8484
: stored_value(forward<Args>(args)...) {}
8585

86-
LIBC_INLINE constexpr void reset() {
86+
RPC_INLINE constexpr void reset() {
8787
if (in_use)
8888
stored_value.~U();
8989
in_use = false;
@@ -93,60 +93,54 @@ template <typename T> class optional {
9393
OptionalStorage<T> storage;
9494

9595
public:
96-
LIBC_INLINE constexpr optional() = default;
97-
LIBC_INLINE constexpr optional(nullopt_t) {}
96+
RPC_INLINE constexpr optional() = default;
97+
RPC_INLINE constexpr optional(nullopt_t) {}
9898

99-
LIBC_INLINE constexpr optional(const T &t) : storage(in_place, t) {
99+
RPC_INLINE constexpr optional(const T &t) : storage(in_place, t) {
100100
storage.in_use = true;
101101
}
102-
LIBC_INLINE constexpr optional(const optional &) = default;
102+
RPC_INLINE constexpr optional(const optional &) = default;
103103

104-
LIBC_INLINE constexpr optional(T &&t) : storage(in_place, move(t)) {
104+
RPC_INLINE constexpr optional(T &&t) : storage(in_place, move(t)) {
105105
storage.in_use = true;
106106
}
107-
LIBC_INLINE constexpr optional(optional &&O) = default;
107+
RPC_INLINE constexpr optional(optional &&O) = default;
108108

109-
LIBC_INLINE constexpr optional &operator=(T &&t) {
109+
RPC_INLINE constexpr optional &operator=(T &&t) {
110110
storage = move(t);
111111
return *this;
112112
}
113-
LIBC_INLINE constexpr optional &operator=(optional &&) = default;
113+
RPC_INLINE constexpr optional &operator=(optional &&) = default;
114114

115-
LIBC_INLINE constexpr optional &operator=(const T &t) {
115+
RPC_INLINE constexpr optional &operator=(const T &t) {
116116
storage = t;
117117
return *this;
118118
}
119-
LIBC_INLINE constexpr optional &operator=(const optional &) = default;
119+
RPC_INLINE constexpr optional &operator=(const optional &) = default;
120120

121-
LIBC_INLINE constexpr void reset() { storage.reset(); }
121+
RPC_INLINE constexpr void reset() { storage.reset(); }
122122

123-
LIBC_INLINE constexpr const T &value() const & {
124-
return storage.stored_value;
125-
}
123+
RPC_INLINE constexpr const T &value() const & { return storage.stored_value; }
126124

127-
LIBC_INLINE constexpr T &value() & { return storage.stored_value; }
125+
RPC_INLINE constexpr T &value() & { return storage.stored_value; }
128126

129-
LIBC_INLINE constexpr explicit operator bool() const {
130-
return storage.in_use;
131-
}
132-
LIBC_INLINE constexpr bool has_value() const { return storage.in_use; }
133-
LIBC_INLINE constexpr const T *operator->() const {
127+
RPC_INLINE constexpr explicit operator bool() const { return storage.in_use; }
128+
RPC_INLINE constexpr bool has_value() const { return storage.in_use; }
129+
RPC_INLINE constexpr const T *operator->() const {
134130
return &storage.stored_value;
135131
}
136-
LIBC_INLINE constexpr T *operator->() { return &storage.stored_value; }
137-
LIBC_INLINE constexpr const T &operator*() const & {
132+
RPC_INLINE constexpr T *operator->() { return &storage.stored_value; }
133+
RPC_INLINE constexpr const T &operator*() const & {
138134
return storage.stored_value;
139135
}
140-
LIBC_INLINE constexpr T &operator*() & { return storage.stored_value; }
136+
RPC_INLINE constexpr T &operator*() & { return storage.stored_value; }
141137

142-
LIBC_INLINE constexpr T &&value() && { return move(storage.stored_value); }
143-
LIBC_INLINE constexpr T &&operator*() && {
144-
return move(storage.stored_value);
145-
}
138+
RPC_INLINE constexpr T &&value() && { return move(storage.stored_value); }
139+
RPC_INLINE constexpr T &&operator*() && { return move(storage.stored_value); }
146140
};
147141

148142
/// Suspend the thread briefly to assist the thread scheduler during busy loops.
149-
LIBC_INLINE void sleep_briefly() {
143+
RPC_INLINE void sleep_briefly() {
150144
#if defined(LIBC_TARGET_ARCH_IS_NVPTX)
151145
if (__nvvm_reflect("__CUDA_ARCH") >= 700)
152146
asm("nanosleep.u32 64;" ::: "memory");
@@ -164,7 +158,7 @@ LIBC_INLINE void sleep_briefly() {
164158
}
165159

166160
/// Conditional to indicate if this process is running on the GPU.
167-
LIBC_INLINE constexpr bool is_process_gpu() {
161+
RPC_INLINE constexpr bool is_process_gpu() {
168162
#ifdef RPC_TARGET_IS_GPU
169163
return true;
170164
#else
@@ -173,14 +167,14 @@ LIBC_INLINE constexpr bool is_process_gpu() {
173167
}
174168

175169
/// Wait for all lanes in the group to complete.
176-
LIBC_INLINE void sync_lane(uint64_t lane_mask) {
170+
RPC_INLINE void sync_lane(uint64_t lane_mask) {
177171
#ifdef RPC_TARGET_IS_GPU
178172
return __gpu_sync_lane(lane_mask);
179173
#endif
180174
}
181175

182176
/// Copies the value from the first active thread to the rest.
183-
LIBC_INLINE uint32_t broadcast_value(uint64_t lane_mask, uint32_t x) {
177+
RPC_INLINE uint32_t broadcast_value(uint64_t lane_mask, uint32_t x) {
184178
#ifdef RPC_TARGET_IS_GPU
185179
return __gpu_read_first_lane_u32(lane_mask, x);
186180
#else
@@ -189,7 +183,7 @@ LIBC_INLINE uint32_t broadcast_value(uint64_t lane_mask, uint32_t x) {
189183
}
190184

191185
/// Returns the number lanes that participate in the RPC interface.
192-
LIBC_INLINE uint32_t get_num_lanes() {
186+
RPC_INLINE uint32_t get_num_lanes() {
193187
#ifdef RPC_TARGET_IS_GPU
194188
return __gpu_num_lanes();
195189
#else
@@ -198,7 +192,7 @@ LIBC_INLINE uint32_t get_num_lanes() {
198192
}
199193

200194
/// Returns the id of the thread inside of an AMD wavefront executing together.
201-
LIBC_INLINE uint64_t get_lane_mask() {
195+
RPC_INLINE uint64_t get_lane_mask() {
202196
#ifdef RPC_TARGET_IS_GPU
203197
return __gpu_lane_mask();
204198
#else
@@ -207,7 +201,7 @@ LIBC_INLINE uint64_t get_lane_mask() {
207201
}
208202

209203
/// Returns the id of the thread inside of an AMD wavefront executing together.
210-
LIBC_INLINE uint32_t get_lane_id() {
204+
RPC_INLINE uint32_t get_lane_id() {
211205
#ifdef RPC_TARGET_IS_GPU
212206
return __gpu_lane_id();
213207
#else
@@ -216,7 +210,7 @@ LIBC_INLINE uint32_t get_lane_id() {
216210
}
217211

218212
/// Conditional that is only true for a single thread in a lane.
219-
LIBC_INLINE bool is_first_lane(uint64_t lane_mask) {
213+
RPC_INLINE bool is_first_lane(uint64_t lane_mask) {
220214
#ifdef RPC_TARGET_IS_GPU
221215
return __gpu_is_first_in_lane(lane_mask);
222216
#else
@@ -225,7 +219,7 @@ LIBC_INLINE bool is_first_lane(uint64_t lane_mask) {
225219
}
226220

227221
/// Returns a bitmask of threads in the current lane for which \p x is true.
228-
LIBC_INLINE uint64_t ballot(uint64_t lane_mask, bool x) {
222+
RPC_INLINE uint64_t ballot(uint64_t lane_mask, bool x) {
229223
#ifdef RPC_TARGET_IS_GPU
230224
return __gpu_ballot(lane_mask, x);
231225
#else
@@ -235,22 +229,22 @@ LIBC_INLINE uint64_t ballot(uint64_t lane_mask, bool x) {
235229

236230
/// Return \p val aligned "upwards" according to \p align.
237231
template <typename V, typename A>
238-
LIBC_INLINE constexpr V align_up(V val, A align) {
232+
RPC_INLINE constexpr V align_up(V val, A align) {
239233
return ((val + V(align) - 1) / V(align)) * V(align);
240234
}
241235

242236
/// Utility to provide a unified interface between the CPU and GPU's memory
243237
/// model. On the GPU stack variables are always private to a lane so we can
244238
/// simply use the variable passed in. On the CPU we need to allocate enough
245239
/// space for the whole lane and index into it.
246-
template <typename V> LIBC_INLINE V &lane_value(V *val, uint32_t id) {
240+
template <typename V> RPC_INLINE V &lane_value(V *val, uint32_t id) {
247241
if constexpr (is_process_gpu())
248242
return *val;
249243
return val[id];
250244
}
251245

252246
/// Advance the \p p by \p bytes.
253-
template <typename T, typename U> LIBC_INLINE T *advance(T *ptr, U bytes) {
247+
template <typename T, typename U> RPC_INLINE T *advance(T *ptr, U bytes) {
254248
if constexpr (is_const<T>::value)
255249
return reinterpret_cast<T *>(reinterpret_cast<const uint8_t *>(ptr) +
256250
bytes);
@@ -259,15 +253,14 @@ template <typename T, typename U> LIBC_INLINE T *advance(T *ptr, U bytes) {
259253
}
260254

261255
/// Wrapper around the optimal memory copy implementation for the target.
262-
LIBC_INLINE void rpc_memcpy(void *dst, const void *src, size_t count) {
256+
RPC_INLINE void rpc_memcpy(void *dst, const void *src, size_t count) {
263257
__builtin_memcpy(dst, src, count);
264258
}
265259

266-
template <class T> LIBC_INLINE constexpr const T &max(const T &a, const T &b) {
260+
template <class T> RPC_INLINE constexpr const T &max(const T &a, const T &b) {
267261
return (a < b) ? b : a;
268262
}
269263

270264
} // namespace rpc
271-
} // namespace LIBC_NAMESPACE_DECL
272265

273-
#endif // LLVM_LIBC_SRC___SUPPORT_RPC_RPC_UTIL_H
266+
#endif // LLVM_LIBC_SHARED_RPC_UTIL_H

libc/src/__support/RPC/CMakeLists.txt

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,6 @@ if(NOT LIBC_TARGET_OS_IS_GPU)
22
return()
33
endif()
44

5-
add_header_library(
6-
rpc
7-
HDRS
8-
rpc.h
9-
rpc_util.h
10-
DEPENDS
11-
libc.src.__support.common
12-
libc.src.__support.CPP.algorithm
13-
libc.src.__support.CPP.atomic
14-
libc.src.__support.CPP.functional
15-
libc.src.__support.CPP.optional
16-
libc.src.__support.GPU.utils
17-
)
18-
195
add_object_library(
206
rpc_client
217
SRCS
@@ -25,5 +11,4 @@ add_object_library(
2511
DEPENDS
2612
libc.include.gpu_rpc
2713
libc.src.__support.GPU.utils
28-
.rpc
2914
)

libc/src/__support/RPC/rpc_client.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "rpc_client.h"
10-
#include "rpc.h"
10+
1111
#include "src/__support/macros/config.h"
1212

1313
namespace LIBC_NAMESPACE_DECL {

libc/src/__support/RPC/rpc_client.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#ifndef LLVM_LIBC_SRC___SUPPORT_RPC_RPC_CLIENT_H
1010
#define LLVM_LIBC_SRC___SUPPORT_RPC_RPC_CLIENT_H
1111

12-
#include "rpc.h"
12+
#include "shared/rpc.h"
1313

1414
#include "include/llvm-libc-types/rpc_opcodes_t.h"
1515
#include "src/__support/CPP/type_traits.h"
@@ -18,6 +18,12 @@
1818
namespace LIBC_NAMESPACE_DECL {
1919
namespace rpc {
2020

21+
using ::rpc::Buffer;
22+
using ::rpc::Client;
23+
using ::rpc::Port;
24+
using ::rpc::Process;
25+
using ::rpc::Server;
26+
2127
static_assert(cpp::is_trivially_copyable<Client>::value &&
2228
sizeof(Process<true>) == sizeof(Process<false>),
2329
"The client is not trivially copyable from the server");

libc/test/integration/startup/gpu/rpc_interface_test.cpp

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,27 +17,43 @@ using namespace LIBC_NAMESPACE;
1717
// as long as they are mirrored.
1818
static void test_interface(bool end_with_send) {
1919
uint64_t cnt = 0;
20-
rpc::Client::Port port = rpc::client.open<RPC_TEST_INTERFACE>();
21-
port.send(
22-
[&](rpc::Buffer *buffer, uint32_t) { buffer->data[0] = end_with_send; });
23-
port.send(
24-
[&](rpc::Buffer *buffer, uint32_t) { buffer->data[0] = cnt = cnt + 1; });
25-
port.recv([&](rpc::Buffer *buffer, uint32_t) { cnt = buffer->data[0]; });
26-
port.send(
27-
[&](rpc::Buffer *buffer, uint32_t) { buffer->data[0] = cnt = cnt + 1; });
28-
port.recv([&](rpc::Buffer *buffer, uint32_t) { cnt = buffer->data[0]; });
29-
port.send(
30-
[&](rpc::Buffer *buffer, uint32_t) { buffer->data[0] = cnt = cnt + 1; });
31-
port.send(
32-
[&](rpc::Buffer *buffer, uint32_t) { buffer->data[0] = cnt = cnt + 1; });
33-
port.recv([&](rpc::Buffer *buffer, uint32_t) { cnt = buffer->data[0]; });
34-
port.recv([&](rpc::Buffer *buffer, uint32_t) { cnt = buffer->data[0]; });
20+
LIBC_NAMESPACE::rpc::Client::Port port =
21+
LIBC_NAMESPACE::rpc::client.open<RPC_TEST_INTERFACE>();
22+
port.send([&](LIBC_NAMESPACE::rpc::Buffer *buffer, uint32_t) {
23+
buffer->data[0] = end_with_send;
24+
});
25+
port.send([&](LIBC_NAMESPACE::rpc::Buffer *buffer, uint32_t) {
26+
buffer->data[0] = cnt = cnt + 1;
27+
});
28+
port.recv([&](LIBC_NAMESPACE::rpc::Buffer *buffer, uint32_t) {
29+
cnt = buffer->data[0];
30+
});
31+
port.send([&](LIBC_NAMESPACE::rpc::Buffer *buffer, uint32_t) {
32+
buffer->data[0] = cnt = cnt + 1;
33+
});
34+
port.recv([&](LIBC_NAMESPACE::rpc::Buffer *buffer, uint32_t) {
35+
cnt = buffer->data[0];
36+
});
37+
port.send([&](LIBC_NAMESPACE::rpc::Buffer *buffer, uint32_t) {
38+
buffer->data[0] = cnt = cnt + 1;
39+
});
40+
port.send([&](LIBC_NAMESPACE::rpc::Buffer *buffer, uint32_t) {
41+
buffer->data[0] = cnt = cnt + 1;
42+
});
43+
port.recv([&](LIBC_NAMESPACE::rpc::Buffer *buffer, uint32_t) {
44+
cnt = buffer->data[0];
45+
});
46+
port.recv([&](LIBC_NAMESPACE::rpc::Buffer *buffer, uint32_t) {
47+
cnt = buffer->data[0];
48+
});
3549
if (end_with_send)
36-
port.send([&](rpc::Buffer *buffer, uint32_t) {
50+
port.send([&](LIBC_NAMESPACE::rpc::Buffer *buffer, uint32_t) {
3751
buffer->data[0] = cnt = cnt + 1;
3852
});
3953
else
40-
port.recv([&](rpc::Buffer *buffer, uint32_t) { cnt = buffer->data[0]; });
54+
port.recv([&](LIBC_NAMESPACE::rpc::Buffer *buffer, uint32_t) {
55+
cnt = buffer->data[0];
56+
});
4157
port.close();
4258

4359
ASSERT_TRUE(cnt == 9 && "Invalid number of increments");

0 commit comments

Comments
 (0)